From patchwork Tue May 24 11:33:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576873 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 EE568C433EF for ; Tue, 24 May 2022 11:37:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236756AbiEXLhh (ORCPT ); Tue, 24 May 2022 07:37:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235208AbiEXLhf (ORCPT ); Tue, 24 May 2022 07:37:35 -0400 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80048.outbound.protection.outlook.com [40.107.8.48]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0E0440A01 for ; Tue, 24 May 2022 04:37:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RoYbKNLBsdQlJI5g6YAquuqvgFn0UMQuD3wcosRhYVj4+SEbkThB8OmavuEcccb0ZiecRbLmbXUpv3Ai9aWvv0s/Rv5T5bwkI7NAXAZbGmoqNUC5V5Nmi8ArUFL1IPdXRDnpCP48MQBVEpCe9iTB43349rLc8EFrL4CcXw3TPkAC9ra1dw3BmjgBG/6G5oz3Qo8U9xaa7CskOBAu7sosQTHpHGGQr/WBPcMwL2jKxBx+UiuutvieP5foKq+m5m8GUBnvRLSm/D9K7NK/+a2qIv27sBayHq2G8IcMEZO4lZPm27b8g3qTDecpHxnfnBRyf0i07cWv42EnPutVtLJPzQ== 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=bHZWAy9rAH81C43m9OTTcovuMhYZKMnPxf7s3MIWjGY=; b=V3xUyLyDNGM3nyu7z8Ws9P030GHUvNlZa41DviHxlRfe24rb4Sj/aVKJ6zlGCFXs87YyhJiWcqTJTqCfMSJ/Aa0WLop8GYN2aKJOc0nB4bfghqTtZOx+/Zp/ZuZeUjaQQ/NiDGDaKmisYmxu1G8GkDWb3NSVeYI2idymnQ+ucgQZ4DhnY7TemkGHvpHeNXJa4mBzV7VrngN90srP6aT11hTRIAJFuV8zGBbZXsAds84gmd8AN8hR8gKCs+fN3pdD+zdYErlkAn7F2lxx0vXF36FZKFkrb4/zoKc9SyOqSjYQ21SdOomlJcNnSGN5Jjf7mwARVs6XRTN0yISOfPMm+A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bHZWAy9rAH81C43m9OTTcovuMhYZKMnPxf7s3MIWjGY=; b=H0fN1wSTc0LR3I6YBWsobsqp49qqZxOAWdHzhWHowkFdkX7o10+qYcbjG8WRGmm79kQBONzo1K25WycbfWrtkvXTDFZ7qOnsmW1vwIORn0qdmELh/GfQibPmhBqpummjZYT3WXTUU1WMVzo688Tlcq/u2WN3StWmMZe/58ylxkE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:37:29 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:28 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 01/96] celeno: add Kconfig Date: Tue, 24 May 2022 14:33:27 +0300 Message-Id: <20220524113502.1094459-2-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3f106e8e-0809-44a9-e4be-08da3d79c842 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: x5SdiXP5VOtVpZpyYpzS5k2zqCr/xWzf1DzQ1/JGzsmHyXVJgb5thwZYgKzQyFXWEeGN3rzhR6B6sZEkXOnXDg5jeu+gICLiAJ8QAVsU159liglepvXhk8pqxmcf95ANNuQtMHejPzSFqvcz2dZO/IB5/f7cUFNzab4MgDL02liFHxQ3jEIYkrNeOY+Dv/jIeiuDSeyT3QpVLneBtcxvx1ZCGMdt5hWVcxIDMgSO+hSwhl/0u8OIkpf9Ec4BwJPxlftzakOHYtwZ2RvBzepMPpPZOOBpXIENsLjOHsfR+bERWWBvndb+p48hAqU8mKFK1dsJYXyTGVwD7IJBIeKf2JhPfcv8SZzIuvDJLVFClQQSdfbVHMw0sJNuzVSSvbzTyQ9l8hUhRoEb5JZnlihJaUUxq7RNmaA+LJN09L++F+ycj2ZCS1GFvDhtRHQINwOcme6CstDDnsWdFMmKSsS3jisGbWK5Od+m0Aq1D44njyA3E9Fsoi7zm40qYaTWrYEjaTU0vGydk1OhLv646DGMZQNzHEmoKl0IyOecQG8HTXDp+QfWcNDkQlVKUkA5UHEGk1b+t/X/V35Frf4DIcGtp/qNPfZteCME2AXukW1xzaiJdGQWBAijw0NADvVGrIh+8c9cctCZAuNBQQKWzHno7FRz83ixW3Ib0Fdz5usMd8OZrFsc5X9MG70PHixu6xbwWkfolaACguQosNVpL3OUIw== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: PosR73sa+Qbw73I226nz0MfhfYNcuKqduqgq04U65pv82eu+tVjIyOPzm4g8xuJ5PLUCL5TTodW7RHtAgQC8H31WJBc2bNmAxtFvvVE8Cx8N6q2o2sSSh7MLgNPjKqfvnwMC74vAeEPGvPSvtaG0ddp0XJ0JDMxFyLitYjpwGH8lOUuqCVfpoaJAPJy7Ev/bX5/NhfvCjoy9TfuaHhu9rorZq/x6RfA0XfIhOhBTU1d25G09+kf+fEF56sT3sP1o22Vr1S8HXddqEwcvtdQJXdYFn0j4pl+A2UZixyVEIRjzjqWqMJ8dRskd+Equ63GM6gKVXfUGeIIvNgyi2V4tt0LBux6O6GKOIkdS/X83a/TMk8KZegKDGYeULbyawY6wIEzKO4lumqjNoJyDrbQNFXt1+8EKZmgJ8pK6pAZ+FvVbZn+Yuhxnw4K7ot3gWyZFlOjwuHIqPRolCqzkJ96Qdu8uz/9S7guvWr4FozkE/JD2l3kjqoZ5ecjqZgNQOPPTgtlsvZEvfa/JY93XsihjHLhcBY2t7HKYcoPw2WJ8GNVhKNCDCSjBDalAQRCEXpgMoGqUzJf4yUMBrBnHqtZDm89aW8fZdutEwP7TkPP0yQQdTxawQ/1XySw+cUM8YGdlfFnuFRNo7XbW6oaa2LdxaBhAiF1XdzQrJi7T/ThPuq4ovkdO9jsNkLyrX7phrmFkTnyaG2SuH9vafBwvKa4UIGi5HQdKeqJHaPdQhvKZ0LAUsuTgJA8zDSOpgfXR6pgaTqdf3vQat4TNhDBvxAzPw2oaTXpE/BrOuaWFdKjjtiAbWcr/HZxF7fsmjqzOt3wu5Tdw/k5KE9R5rHFsIB1AFZ3s/McF/kbAm4f/oPQrd8b3T15DCYdNmKyvgY4uWvmdItQ/aF6CEI+tyoofGOlVd0/3QLOH1Tcq/n8TPw7OecWmhxbLMPJiW3UganbglF7vaF5wlxz8L9gOTP9TEEeymcMRSrIUNaudhU5qtLqNQzOv3qFT+A/2Cy/ya428Xs91zUbmgPdD8nUlYtzsOm719QsmKbcwygPjsZgANS8eqaxjrkSTl4txabMHVqP1VOMdDpOVXle+Bp6XsiKnuinfxi4NLe/Rk/0rI/BqluibRtQQXkmNtM307emhVS8G+suh4MUZeIk8woRNbg0H0IF44iAss6um1sT9R4orbvRMQhYUawrlDsXxlzzFGkLBhQqnHFqbNJU2GRZdKtJ9K4DcMHoxhr1nRhclrElBr5X1p8Vq6RJQcXF0uLOrMjHcmZepWzWiZnLCADnBNcl/BYGRHBtfBP3jiOn9u4e++HAgGeJMOaM8wWS9XiS68j5dJE6lxNxTkqzDK4o3539Im8bm4E0K6Q/5oOzdNbd3BEzjdahzkMookE7ZY/bF8A97CmQdehHcPo7yRjkFiJ64j39hawYO3tK+C1ZDY1NVQHf28jBxpaaYLDF6gkdsq2rov2UPRE0ZsXzHP22Us/G7PUaHYrfFDs/Fg7tajYpibA6nQIFtHj8OVh+2TAeGI0YJSNMyZafq6VEmCEgc1Hat0zjsRIEWYqLZ9RLHZRsxWSrj2+Dt5R3z75VMK24TNLtEY0pLC5lzaXOgmU+RLGqcBQWoNbq1gMqaEu879PsTOTae+VNAKTDS8tcgBUHUnor7jUujt9F/AvhsP8l4EbsRB67RplR50S7rlZhQwVUgFHOPZwBwWfx+iNWJQKNbAoFWw70AECwIQk9ipSlyHePCSqzOJUBQoPS/9C5AZ/Jb4PmN8Ak= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3f106e8e-0809-44a9-e4be-08da3d79c842 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:28.8072 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 5z09+1j7780kNnKJHr7ffmlXjtmIIRAthUY5za3F5jTnyalwnlxZwNrpfGcA4IGs22qq73AeRwTmct+CT68dQw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/Kconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 drivers/net/wireless/celeno/Kconfig diff --git a/drivers/net/wireless/celeno/Kconfig b/drivers/net/wireless/celeno/Kconfig new file mode 100755 index 000000000000..a5e8a9af1ee1 --- /dev/null +++ b/drivers/net/wireless/celeno/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +config WLAN_VENDOR_CELENO + bool "Celeno 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_CELENO + +source "drivers/net/wireless/celeno/cl8k/Kconfig" + +endif # WLAN_VENDOR_CELENO From patchwork Tue May 24 11:33:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575991 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 676C5C433F5 for ; Tue, 24 May 2022 11:37:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233408AbiEXLhl (ORCPT ); Tue, 24 May 2022 07:37:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236755AbiEXLhj (ORCPT ); Tue, 24 May 2022 07:37:39 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2085.outbound.protection.outlook.com [40.107.104.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 05FF741F81 for ; Tue, 24 May 2022 04:37:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=X9t3fdlT+36Vy5azH/tZm8r2cvOwcH7yG++WWkFGPrvIa+aQgjDzDGcFh7Ns6DhEeIpBeaOehUf5W55JZffiMB51ZTnlMXGbp4Eh/ZsoM3pXt3WdcJ5Dex94H89KpfAmg4fPnrP2tCm1ZmAKZlMklWYz0bmOd1omxq09sfYFwJUr1tw0eOqf9Op0wNq95dJ00ffD3cJGR7ZXfZU/BcDyTgdGyngHXuyiOmZEsHMm2wNRTf6hmz59v0Bw8a3EAbz5UsyBYAmniJu7UvdqkfK7vhx+5nC7xOtVn4bd4Jfo3v4b3mznBN/mCjpRyUgemFzY4L1o8FEFVUms/AmiHt5fnA== 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=rAE/vzEP9FkrDsZbpq8+7wccIy0yBWTgCP5Wew1Yplg=; b=kRLFsYDxLoiA38d2Iiy844NLQL9UqIWM7OinDR4o5LFror6+0Jc7RvUg8zkcUNSVP///bWSofNB4wbTy84WYyBUVyNSSVQzI6DRjkwT+p9xvpluIYRiYWOzJD4MQMhPuVA9ErOd87wQxnulXhddrKRulyd8svTD5xvQG8f+DAh9bloxxAX/5xiVfw1YXzfwCXvhUdIRUfRNBK7oQ+HZLfbn0syYbcJ4u9s2vEoxROni+kZRbZ85kprASVYRbN6dfg9m6VputWdbNpR5Ohq54NdSxSZi57Pkq9CjItTol8XtbU3NNyEwLLaBQMH8ZyBIkR6dHzWNZv8BJQFp4lP8DoQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rAE/vzEP9FkrDsZbpq8+7wccIy0yBWTgCP5Wew1Yplg=; b=y0i9agzY45cbtTic0SPrrgm+G4pSkbRs+DLUFRoTKays7lZUHJmtBr13eDORhVwBI8Eng0cyGwxdvNjUESrXq0MPFaL1isjCV2UT7N3t/lWXBS+v0OmSA8g8GUofNhxtBZcMNA70dZPKdCYwABXBFOx0TN+bQamhCQWnBLSrNw4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:37:36 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:36 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 02/96] celeno: add Makefile Date: Tue, 24 May 2022 14:33:28 +0300 Message-Id: <20220524113502.1094459-3-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 15a5881f-f3d9-4d13-f8e1-08da3d79ccc4 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: aOxrrYvVVcoY31ku01DvKudCkKUnp3Hb2VjbHa+TycDkbgn2Wx6wIToDZmZKHF+1r9BORzhFX04j62zI2reQPozv/f8WXlQGkM3ur8xVkvPBDT77qotM7CV0+gFjgX9g0Hi+nSKHJ3g3a25tBora/t4ZF+eT+ye5boeHoPqCU58RkxCrgmk1URLKvh8SAg/H9Nsb4QQfNjkRmsOa2yzGhxVf0e0aPRMT5gjf7Kpda9IsmPQsj1HQF6lNw2tKTHVUqyiBRP78FfXezWyFJyxVVbGOqfdRg9Uo9W6KO0NTNWkHwvm7eB67+xg61p3z5Ke6S6lLw2ajmMs4k7AwZumscKbZu99YYhiNOTiuX8lflF4V1pAUqL0r6700hU/QdYw3yFYBCBeW+gEA/CIjU+ixrz6JayH6JPc+aCyPWSPs7nnA+0jwudfrJuN7vouEo5dsYOfa9dxBBedkWsC98femchCSOFEt6yJ9rIE0aXMjn4SpNO3+m0FcWv77yDYuv9DWCHxp5nLHPVA8PWrBwhv3en3IWoctWQ4DVMwYnS+1puK4FahkmYNcOm66Dcv9g2XSXWy68wtLoOmrnYrbzs4ZycJ0fIiqXLxR6QdaNxUCCkfsBVUo6jFsILCZtvg4OlXJc17HVjM/FIt3p0m8F4vAaYAdDS47jPMhR4YZvRKc5IRZuwv6cUZtXBkaqWJab01XM/U9hs/05ZQIJi5K+ZALXA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(4744005)(508600001)(186003)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: NlaohjHMI2V8G/fgeYwWc87Qj7YlZqvl7dc5gacM1vhbqeoc0xXJOb+cMA44FTgiZGVcbX2onXtS5hdxlCpdqFUoOOcBMfHrn3DUa2nn8Xdxl187Ld7+U1MlMLxsF2t9qw0d45hJd02o59EuRd+MCngQtFsRHiYqsnWEirUBLZ7Vrlx6IC0/XdIOMe0TMoqHRE1jRTjpUGkr1LsRf4AVJoD/ZlPO0Xc9TJfNJg5xMLhAu7OYMag2SnICPT6sGMSjBh7jRxHJfOFtvzZ+TH+ZOU1yrL7hCYoD/It3BK19G8y131uPHD265ghpW2cpI0QRA/L/NjP0EB1nUzrLUSZu4fq+lOdo2zCAaC0T+byK1tljvivJmpH+zSFgQ309vtZHWZhWHqQa61ElllwI2aAQZzz+8T4f27oQcddH0bjixXaxxGprHsvAcTnkn7VbUlqrm/rdkQu/b19WrBbFK+JR8PEBVuLkiN1Zd9J3P2ZCYGOcf11S0b7JvlyZWOfn3dzGWtnJscmH6oiqux8n0LslfkyenpQkRZKinVRDrR5L4ptfwkL3DWF3AK+4Batrr4ltDorA3XXAriWPRHa4QQA2KivJPG2QdfCAroNPj3L4YMBUknqd2X5EIhu3TUB2WU+pg+6fTxye0BAjc68uHkLGcHlf9g9jqkwme0uW65rUp5EppaawIP9IQhOtuSAI7MI2aeH6h0TxG/z4hw7o8hczWNFOSM4zTAfeAl0jWRLyhcIvw68DKvarV5Z2CHxWnbFFKuyQ1mEzJAg3SF5qfgVMIpioWSRduaSAqyHaUZRXkUFDEOc0h1tlM4rdXM17ivOmykh5s+Oisu/39NXlmZ8ezmykmXmfLep1+ljfN23M1nvLfUqHj5YXHYN65f+xpWleqWCNqHn/cKO6Ws9jIjUWvt9j1y1tGOdjfJKsCcjWl0kOqkJ8bPkj+bQux7YY18mLTP04824hg9b9CCVbBEm0gUCrsjrYmgOeaxf7XEzQ7whErAykK7s/MWm+LhCUJdE9icGLy9sGuAgALK3plpkErNKbUgdIS4BU8jR4ZhuMx05rmWTWUDuPCzxX2tIEk1ndvtgpGoatXDZk+yHRptAGREule3k+mtjOkhWAX1hXVHIoWa+QEpkzHNCpR7TBXECufj5kV7K/obSWO2NutvsEB66JmjcmIww9lByJLbjlrIxMVqL/CpzngP4Xn3CsmnrS8dMZwKUmpFzheVjvLb2m0SIixBCrwuCCeftV7IoFU67WLGequaqPbB3fAnEjTJjQYqgi3NlVEl6NU1G8MTF4g8afVnjQuiwWyn9bopGWPC25rD3l0v+9G6zkSdX7o7NKZzNQiEs85EJcquDwB/ynPLWEWyJ6ybIsyFBsveTcpBUQlXfmJGWybqguvjNioA2MLO1T5YtlSpX9cY3hEgDlPu6muWj0Ioi2u92Gd/JeeoGQXhtmy69wn2lrlM3u8VIw5m5zop38/xgk1CQZkHwb8D6wFqvRC6QFpw3t5UUcBzX1q8B1DPDoYx41DMhHlHnwXrBVbGrKJTxPtupxKXuL7sLF30AzQv1NAJ+NsNP3yAxvB6LjVRfxA2VD9POJkLfWgqTOgjCbiTI30Iv4e/D1r5eIrKspwQTG/Qj+ldwKIErXygaYhBaGLmbUnMNfIIh7xU+Ibm5Wsh8rBUUqXSKr0sGjmIQzS+Xa0Ga6DvfItDfRdr6ckE5Lt81E4MK+0FcG5VV3airb90uEhW1qjf5rJ9fuKDsw0zifIzYDJGK2dzI= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 15a5881f-f3d9-4d13-f8e1-08da3d79ccc4 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:36.4019 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: QDhMXqYvMK0gYfRYAEHrNiq/AeSiq3NZs5T/gAWE7jfIW73Sm2VLqNcqj+j05ZjNjkoQoLkuwMGLIIC6BzBL7w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/Makefile | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 drivers/net/wireless/celeno/Makefile diff --git a/drivers/net/wireless/celeno/Makefile b/drivers/net/wireless/celeno/Makefile new file mode 100755 index 000000000000..b7a44afcb867 --- /dev/null +++ b/drivers/net/wireless/celeno/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +obj-$(CONFIG_CL8K) += cl8k/ From patchwork Tue May 24 11:33:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576872 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 A2EFCC433FE for ; Tue, 24 May 2022 11:37:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236295AbiEXLhm (ORCPT ); Tue, 24 May 2022 07:37:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236759AbiEXLhl (ORCPT ); Tue, 24 May 2022 07:37:41 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2085.outbound.protection.outlook.com [40.107.104.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4BA94AE15 for ; Tue, 24 May 2022 04:37:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VvxIVmO4hz0SY+m7usjHUFCrqqP4foJbh9LnHQKr1XLpOzBoH/VOc+7/MyIef2fI3EHxupnpVdpCv8gTMnOs00iJse8nKkDSvYZU14U09EA0IA12ryf6mP5eN9F09FvlgzDP6BSvPDYhDrHKe1Qo+uBuY1jPHkezf81Ledgf+2kXa0woxuPHKcparxT+3K5mPFgQOmZT2zhWIrByycdUj+USWbUm77im76EUAcw1G7N6OfqhctZg3kImqH4N//5pUjKG9EQWbM8jQ7Jssa9QkT+STDlMJmxKjhYEoGj3Wp6naXODaG8cGqSt5nvVdyvVxoQFw7a9Ieyn4i8TSm1f9w== 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=/g2OLxRte3SsbqJ2/0gdLBV+VxiAwUXr3Ed7N4TdzIk=; b=b9RylYU6bLwxZEw53PVQGh8FqvCndsh6veF+mjvJRt5Nn1A+QJo1MRre/sAEqwwgbosZ9+XzYACNyuyWDDXbxNlk0ZnpaefepgwwNhZEmHW6XBIFg4Ixz5hycVxa6O+ZDDM0sX5aRCYM1Hrmu/fPb+mLWA2UJaYcFPdMmz1b8YBRbxVbWvYIpgBBxPAJbrW+TkYSibe/lp8QFUGspCOJFzRtZDcQh6hIKDbH0XdYPvixeYKPCeNr0cUs8AybWYXgAYHWs7i2nbWFN9oKiPip43AJC+MHSpNJEksX1Q/RKUf6O36RcLhYJJkgVWAEQBlt71ZINuc325DDOXkQU360MA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/g2OLxRte3SsbqJ2/0gdLBV+VxiAwUXr3Ed7N4TdzIk=; b=XXw1ij5w8ijkmDjIRgS74lHVsFYOltWwJGjkVZLfctoAFEwDT/7pKG+QvGYUXPwuEBLKSUYagu9E4oohKybZ0XzhozbPzrbtlxKpl87MMh1T7V6JXDy2cGTO5xJaMp3xfPCDyPz5IkzBQKrcwAbSvDvPeecXeQAM6/sMrvlUJY8= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:37:37 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:37 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 03/96] cl8k: add Kconfig Date: Tue, 24 May 2022 14:33:29 +0300 Message-Id: <20220524113502.1094459-4-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0db6b24d-bfcf-4d73-3910-08da3d79cd35 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: y8aWoLkOM+6HQFAkxj6heqYqtzX6sn6cT1N/yIpwQWDszD79657MYocWZCDwhvrCGXlH2KL25F1fpI9hHca6I7oqO3IM+juuWgPOcYyZnKAI6og/zoBwbG5sia3BkhASMUsvHgMyGFMASbxWTsvZ4yP3IySqMRoWSZRNOiyIKAMpfCoS5dOS9eRZtXfc2BF0yEasy+kG7HSEM1Z5aGhD4A5oCAqePGhli1BgIUWVqE9usrbd7ptozS8yrM46oPomQil0L17LrdIWtg42l85I/8ZRDfSL5Kb7Q1IBJItPYWrqzFBNi4WgW9VRshf5hiET6ejf33G+fM/2VOoAx0qBcSH9G/zIC0W9devaStKuTikaL4fVtE6CBgig/LkC3KsgGaqBkaypNuAIyHRI0KKyAvcEG94vQcwwPmg5KeGbkgg6XGO9X4vTQimD0PcvTDzccM3P0TAJqmEKD2q3eoZMjsWmlse8qHAs6D+XswEKcLXlMpFLTdrIYRGibE/GOF0JGmcqtojI2W5/rfejx321xoUkRYPTg++M6+rM7E2ptGDDwo8VIX7BoSP2H28/JRR6M5RJL8/1zoyF0EqIp4npd+SsIUWnioDZ/Yvss7Jcplf74U/PwXZbCPQBVGYRljDHiXsn22m+vaHm/VzUPWKllMQcClrWa8TTOkx+eD3sdihxmp6TnrBw33RKOBUjdP2POI6cNCFLcVaYLAoksfZ4lUnF16yIrI3Bs4ad/g5Xk6I= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: G18CZpSBA84HrPsP+GLt+/aYJXzo5lcfWfqEqVr+Wij89aHD1wSTmbaeskhxkcneXKtPXJD5XGSvPoBH9ZOz/TScJHPbRWOt+YqqQ3KYt3GneZiMF6nc7vMpJlO32veYPCkRMM5WKeRZ3JV8NZFdfJqF5g7LRKhHZcdVWpDYyKPJ13lOaiX6LFj7XbYHDLZ4sDb1X9ySuZuZyp+Qpzgopqld+xDLfksX17q2SvS9C2sALOqqfmjfuvsoXNI6kvXNkdKmQWRyOWwuGSPPd2L0u0am0q8YE/Ly5IDqmAV83D15Cbk8MzZkZL3ae/weNcCTqEk4lbj+cwzsC6Vfgtlj6axpZmJH5ofSiYGzjdsA0XAr6snFX5zXZchdhSX/RDOkP00Usdi8bOrZmJtAr/XXltO92TSirlM3Sllh2ROQo/J1HxjaOph1ev4lIGvVjsnjj4rh4eOfSvzOhS7Bep8DPsNjkqWyxN/FueXChXsnQiGOU+ItmJwWhyQtYdRMo5poVlqI7f7zj8QkF90xDd8XsuK9shz5aYWUz1abmOvNOuHlXqL1cEhHp+jQNU87tTDZ4hPmlvHWMcPH4pyZIQa/xN16iSH3bb5Nns0xOBPWmfyJLgz1/TcfOb7xjlft9dgQyhEJWBcSU5bX3gwiw/lmvmB0nPhm4KPh3dqu9VgtuYsvLnqOOyaA2z1RfvVmkZ5VG+EelcAPEoTBhnYZEXVAHofno/kV4Jomur/Vm2Yj/tFoTCbFnbxW+r3E5QTMIJHrjWWUCLp4UK/AUEUQHMnNIZfCRfYpaffAkXtWfmYeP5M2GNWzG8p/t5o2BHjU1kp5igjFcvsVyK8cu0sshrgQbffBeC2QtwDv4DRwWis991MYby9iF8DdP26zV/eQALlQumYHBi5V+4g8vZmHlPYf4adgDp7pYfNePvXORegI8Qx7Cj6SmoH1no/7tsJ+hiZ+q4u1MWKMRLbJmFH++FvZLEdmu5ut5B7ubNW6LRpD/0LnwCU+yJKQd62j0wsBuW6IRzfNTXBlVK6ERuy0+BvzSiG/f88WL6E57r1LrJG/gt48rLRuzS2E6J/kDWDWkuAXrFMUxx/F7xIogOFSPql2kvKcGlSAaHBZhj2PDkqv5AWh82YMOpFOGD5qQ1jnIYp3PabGSamsp+We2lnj6TJ9n+54moZx1JTPQWQfkscZxTxpFLnTiyyCRU0EPR12MPNEy7GFm6P//49U4zXJEdlXRo26XuWgCNlVMN1j90SPrjX4mbMiD1M1g3Q14gBlcyT+kWc8sdEE1DZDUMOu9EJWUBdimJzkVvSA7IEwhqjDxZJB8p1b1rFWCv5Px6LLS3Lu85/abx6nb5J6bRHTYxVH0egb+mkR8NgOXHob4zadv+reYRD7RqeF/EEON5LKp8+dJ5il98JWhxHzftgArb8cvJcW8pH65jP+6SKoPV4mnu/9D1dORkhxa5RFvf+C2QwpVp72ViwknVF62wxoWKiKy/u96LXvxZcM6aBBurJwSgA76G5RzxjRMbgDm5C+FpdXDhsao9HjVKdrhsUVmlAWMsNZcUwlZb/7Qsx4CfvZBudR55nuXsJGbDDUqj+TPqmDj1KKi0u2tD3fG6Akc4arwY4f7i5o/pGL8L7/T62TT6wU6tkQF2L5NCraRTTnfaNlVbkZI2diySmCCK/MUVH9vpj+ecT/E1Qvb0vPvU6r/R3rILTo2/ueBYLie92bDh07l1polFYm0MxhsBvrK0+vhdn6M/r6+yI+rIu9mgEo4OQ= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0db6b24d-bfcf-4d73-3910-08da3d79cd35 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:37.1219 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: v/P5om1BZNS/67Qreei+0LLi+cvMmNH+AJ47ZRQIMof+5nl5lMtzZroDDensZCmtJg9Whu+01bNOby4H2N8Zug== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/Kconfig | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/Kconfig diff --git a/drivers/net/wireless/celeno/cl8k/Kconfig b/drivers/net/wireless/celeno/cl8k/Kconfig new file mode 100644 index 000000000000..7af6dfafa6af --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/Kconfig @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +config CL8K + tristate "Celeno CL8K WLAN support" + depends on m + depends on MAC80211 + help + This option enables support for Celeno CL8K WLAN. + Select M (recommended), if you have a wireless module. + +config CL8K_VERSION + string "Version" + depends on CL8K + default "8.1.x" + help + Sets module version, which may be important for FW compatibility + analysis and syncing upstream codebase with the internal codebase. + +config CL8K_EEPROM_STM24256 + bool "EEPROM STM24256 support" + depends on CL8K + default n + help + Enables EEPROM STM24256 (specific for some of the platforms). + +config CL8K_DYN_BCAST_RATE + bool "Enable dynamic broadcast rate selection" + depends on CL8K + default n + help + Enables dynamic broadcast rate selection, + that allows to tune rate of broadcast frames taking into account + capabilities of all associated stations. + +config CL8K_DYN_MCAST_RATE + bool "Enable dynamic multicast rate selection" + depends on CL8K + default n + help + Enables dynamic multicast rate selection, + that allows to tune rate of multicast frames taking into account + capabilities of all associated stations. From patchwork Tue May 24 11:33:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575989 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 3ED8EC433EF for ; Tue, 24 May 2022 11:37:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236768AbiEXLhr (ORCPT ); Tue, 24 May 2022 07:37:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236764AbiEXLho (ORCPT ); Tue, 24 May 2022 07:37:44 -0400 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-eopbgr150084.outbound.protection.outlook.com [40.107.15.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25E814C798 for ; Tue, 24 May 2022 04:37:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bFNzUVscc2IkkHmLnLgmfue7Ib7INcKZTLbdZAsvYDMWTL3UZiEBKmAPBRLqgsSdU8YOpSxbMvX1r7rZwfFx2MeMzsyX8zbCFRrMfKmvMduT9/rmH78bVpvbqRYrDzo/y2EQUaGny+GzqsAoKguh+VTtQtA1Lej6DBCv/Jku9jE4udwC0x0OD9mmsk6fu1aQPI3eBQcUbn99V91pgaE5lxnowbRv6sD7bqPlT+BOAfiItoAoclo2CzWYvP/UvrxN8/ZdZauPjfqAHzi9GgYJJNiO4JMhpfoVrBL+gNb+ZmFxeGS+pLXF0OAd9L0LmWBwzKQFAkFMcO8x2j3cAvh1sw== 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=bXQoUGCypQEtzmTxrkaO7q/cSd9t758qDLwK3u8/EFc=; b=huLl00MLlhX3x5q6Zr0D/26W/YQ+4svc6gxvIbSVj3VOuFGBFlUvRlBAD/rLAeIF4QiFOJAnXhi72PBEgYuOPIB7gF0pLOVN1dz1AfntLMt2B/smNKkjConAZSThw0PEii+XjqdVLnUYvAdQqJjetT8zfDC/CtOcuXTQEOCMOzE30ch1FCws7ZkONORUiSIrDViz92ZioY+Rk9M5nIX52zy2nLLpOR7f2v/UZ2EQjwWHsEhNWguaVqH6TvsnijZaT4HdUJqLSBCuD4O7uv8VHMUaDINcFCPTkvJn1pcXUE40upzThKV2KMNR2YFezewJZA22ZymOlSaYLKkXFfg7iQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bXQoUGCypQEtzmTxrkaO7q/cSd9t758qDLwK3u8/EFc=; b=SvDQos0RMufjRwtDeRjw6PopR+FpkteHHFHb8f6L/0d2E5HPKe7S+N2t3oXIZDfiIkEdqXJFv51tOqV78KjYf7rbSvPB/F4BMvFluFPEb6oZMImlcn9pm4V05Pf5j8muJVIK1/mC2TLAsRjQ0W2w0bgos3WraoQr0rdoYUIzBSc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0501.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:3c::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:38 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:38 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 04/96] cl8k: add Makefile Date: Tue, 24 May 2022 14:33:30 +0300 Message-Id: <20220524113502.1094459-5-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b9438722-b8a2-436e-03a9-08da3d79cdc9 X-MS-TrafficTypeDiagnostic: AM6P192MB0501:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fcIqv9eSs7PLL1OIoo/4ugfKMRZfqvpzYAZP08XZXXJ1F9DzyqTrJBXLlrvgdFWPAB/wFqQi1NtzatSX80FuIgQlcgHaq+4vhJlLgiVRcNlF7UaFq5g/SGfhzqL6cSNMyQp5fC0/tn479npEEvfrLI0IDmvyMQBz69GR1Ke5X66U81kgeCyBcpl5Iy0h+6/bR+VKpZI8R+FZmDnjXx79CZ7XimX5oC8OMQJ2gYNP4Mokdo0d+wcvWrMx6wIRQVCCit0TwPXkrnIqXBkOpnECZt7+vBeAnjL8lqFChYdUjI/dXLtBOvI3hUJRIkVxgDkR/5+dqFncdwf+FcwN0FAWOLZS+Ipd46Yo9n7KPw1cyBG3eM8FfEYR8Apca/DtQviNCBkEOn1vH4Fzh/MVnlNn6OPWId2prwIsSXH3fr2/yPOY7mieJPT+VntWfGCA6/yTkWEJbALQOaAugVLzPrW75DfbLWAN6JQnoQxCArrjjxj0nYZCjY78Rz3Az4kY3MCiEZ6dWUB+oFSBWDpDkmV95xAo81Q3ic4WtP6YLMGc91GSGQtuoIpiLT2G4KxJPBHRd3hsytZJppJRH1rgcUXzUOmTV771+T0pbQh6co7/aHzYIFw4u5+iCNCiwCHnegDM+W26l4jtpwpBWwvMSfvlxxS8scDkhKAe4mkj9zal6TsMvizLBnttQUf9deBc+jtLHUQX7e8rkR8gg/E+0OqoYAoYad1lEzsLiX7Z5tq+5vM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(376002)(136003)(39850400004)(366004)(346002)(396003)(6512007)(186003)(38100700002)(2616005)(1076003)(9686003)(86362001)(6666004)(6506007)(107886003)(38350700002)(52116002)(6916009)(66946007)(83380400001)(54906003)(6486002)(4326008)(316002)(8676002)(5660300002)(41300700001)(66476007)(36756003)(66556008)(8936002)(508600001)(2906002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: KkDoh9c6GkLwuJVs7P9Cy6HbmTUQVbUB8EDOLsX/WTEkyEWaMQ1GleYmWrXkZwQ+X5rdnNTq65kw2sGPqu8UG7zn98d6t483XkGBLbt9I0BR0zQqiYn8qE8WEXRuQxgrO43rmi12CmwiR6osKQd1oxECCbDFU9PEXbO7l1ExxMisoSWPdagwrsfLOrzQC5nD/6oxUB4y+ZGF8ZrDiMeWn7jUt/UM0qlxqP+ymnp1ICKWDW9S8YCN8X42kKWzbu4kDAAsPfkh1/fippzuUHGGhDqfNqbs9cQ9o5oqc63YLvoe2zDAtbnWxlb3QrwLy9p6AEnBPlo+3gQaBTad4WQBIP/fshS/Dl0z1E/RykcJ6VFBidoyeaxJz2RGc6HVXhAz7EMSsX0443Dyv/YAmbPRGlPiv+V3UtuKi/F8AaEnwcJRr+ttF8vgPhkLXDNLHyCs078VL78ICHa40WcugGGUQW3rso/KJS74a4VSWeWCUOBS26RnUNfPWuKTIO++XtXImTmzkX+mnQFFbazGLruqu3yfq7zrteaCvgQD5KDu5RJ8LiwZOb+3U5ow7FCdQjZQJbzjLCQ+D7Q/pkm1KBi5yVzF1eN5BAdG6DBDPkRWfO3ViJhi4ON0dzQK0mLlHDviTjzRLn0RYcNxMIlKQnIVdq0FaQxCtHXwYa+wUOg71iP56iMNA1UoJPQiMDMLPvI+I/TDNOzKqMf4zo/42jwJtnTPHwUjw7r2weoYO2uAnKw0OMIQeBiVteXW//7HN6kEESu0mY/J9t0OeDmo4g62A9bICW0F0f/158YG0SC+1xh74m3Kg8RZeqab9tx+zMNbv/pbThaap2IC+EHwrFo+fMjs3M3kbipb6v+fWOkSN7Yus1aur925FcshRTVVgy5SsNuFOi7g4NyeavbhjnOUGU1yIkDr3WhNHHSW8m4sbPNA6s9mCpYPKnO84FbrdNKMtFntluJ0RzXWZAH5K7LeE5vDnnRrF7ZXZ31FBnwsRPpbGX83yrlFYiu6h/Pr9RN920AJgjUMdQU165KOCy6S5keY/U1KVCV5eqYkhlqp+SiD52MfZPLi3ilcTY0NRdHbiwlqnZIS0fGcMOghePtNNxF1fe9SaR2862etE66Ui1LTLIDTqhKEmqjA/UqO1rSEEDokt3nZ6OzRcDsPk8YbfU9tKwgPB2hBg4XWrVIN9nr+8YFbCK+59mHU/+18mfY2MtoVaCBPkulLQzz1W5xYAfBubM4dAevZl+z5GJV4Z10i3w7svE+xocbdoBuA2jZq6krtEWNa0YfYXHGeggypulmgz265c/C/+sywkjksXfrCwoDRSBM7VjrOq+bVQngp67IK6YLV2bXjHCz+v3HhUj/OzMDzjq1YCa19ofPoyiGUeFF+SdTEVJm7uZ2MWWk1czHDUPxYN8EjrxpsfLz2ImHYyRUZMHFnF5S3rAp1KrqhmDmYMce+bcrEfTQopq5shH4uKwlutJ5IZesKGoEpHfvODFJ/UBuhJiS+dijiBdmgdvc5YZPODD1QP8uvvz1vbELiNamTay0baddyBqVZ6VI3ZmjE9kZVgvBxCsTDQ4KOvgGil+92iaU7ugx9H6mqIrbD6zxj+5naQc1NrXKaATJdydTypDb7rSVo2x3M4G38x7k0B+6Qlj27JDrNUECOkB97ju7rpsiTpRlQPcLiI/9H7tVo+0QhgJTQ1WgtIJxN51WvXubHa+DMB7zODAj0V44lTsQaTaWTMv/+XFyaNznXsY56+o0zPP6FNySQT9Q= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9438722-b8a2-436e-03a9-08da3d79cdc9 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:38.0592 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: HVZCcgxC3Tckxsl9V4moCOTSnHPUDXwFmjI6OfvlKZO24Vqj6fBha16ob8lHJjFNMtiGKtrzs4H5WJkddRFifg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0501 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/Makefile | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/Makefile diff --git a/drivers/net/wireless/celeno/cl8k/Makefile b/drivers/net/wireless/celeno/cl8k/Makefile new file mode 100644 index 000000000000..9ff98cda5261 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/Makefile @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +obj-$(CONFIG_CL8K) += cl8k.o + +ccflags-y += -I$(src) -I$(srctree)/net/wireless -I$(srctree)/net/mac80211/ +ccflags-y += -I$(src) -Werror + +define cc_ver_cmp +$(shell [ "$$($(CC) -dumpversion | cut -d. -f1)" -$(1) "$(2)" ] && echo "true" || echo "false") +endef + +ifeq ($(call cc_ver_cmp,ge,8),true) +ccflags-y += -Wno-error=stringop-truncation +ccflags-y += -Wno-error=format-truncation +endif + +# Stop these C90 warnings. We use C99. +ccflags-y += -Wno-declaration-after-statement -g + +cl-objs += \ + wrs.o \ + phy.o \ + key.o \ + sta.o \ + hw.o \ + chip.o \ + fw.o \ + utils.o \ + channel.o \ + rx.o \ + tx.o \ + main.o \ + mac_addr.o \ + ampdu.o \ + dfs.o \ + enhanced_tim.o \ + e2p.o \ + calib.o \ + stats.o \ + power.o \ + motion_sense.o \ + bf.o \ + sounding.o \ + debug.o \ + temperature.o \ + recovery.o \ + rates.o \ + radio.o \ + config.o \ + tcv.o \ + traffic.o \ + vns.o \ + maintenance.o \ + ela.o \ + rfic.o \ + vif.o \ + dsp.o \ + pci.o \ + version.o \ + regdom.o \ + mac80211.o \ + platform.o \ + scan.o + +ifneq ($(CONFIG_CL8K),) +cl8k-y += $(cl-objs) +endif From patchwork Tue May 24 11:33:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575990 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 7CFF8C433F5 for ; Tue, 24 May 2022 11:37:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236759AbiEXLhn (ORCPT ); Tue, 24 May 2022 07:37:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236757AbiEXLhm (ORCPT ); Tue, 24 May 2022 07:37:42 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2085.outbound.protection.outlook.com [40.107.104.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3510E4130C for ; Tue, 24 May 2022 04:37:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TIu92YdZ+wP6TFIkYh7Jbtc5SX9mtJffceOXIjTi/9gYCl+hLsVXaXByuEDZoTCcWXU7VW3f8eMGCYSkIG8x/u+MhjMWe5k0xIDC/+nHtbMj+uWwxX9yc2D9EeapEEL9mkPogZR2mPJ2Qfv+FJltl1eYur1aflT7Y/Uprmc+LfcxRhz06fkyKVAwURdczleYQTHJz4y7fIJv8SH8Rue8u1qdEmoRfZLXorHx7kXN8thIBuC+iiWb+lNZQVOXtQraoG3XPMiaspoBbaT3ixog3UxYcHGsO61coZo7ITy+sUP5oAvBxf9aNyb23CgbRZa6MAkFZjMTeouPKOG9M6qpOA== 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=fZ40xLq4tpWp7KWz3O5Vi5mtsv/Yh/b0n8cCXY3vghE=; b=ClKnab2gClB5bhzspS3ZwGxBRv+vR7IfwhWxiRGsxQt1naGEFjZL/g42CBo8JR+NekH3PQZJzD16fewLs46cvfE89sJsa1PjzzQlXXnCv5NtiH5eFkVJ/BcOWxNLVpSNPKOc6wJjApioAAq9E4QOyE/K43srjLA3gkLoIp49z/TA/PJGBu2JNN6gvqbDctJnNoaLM6i1hn4v1Z12JMwMdX5Vc0eOdGVK7z4JXcdJvh0PpcBRb+xGqjSDQ63k8mE0ssLOmWORDcrkEm3klBkkT9SHqF1s9QJO+HjNTwFoBHz2EtP8JsE1TfADbKPsbB8fudtar8TyFE6+3rQ6MKsaMg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fZ40xLq4tpWp7KWz3O5Vi5mtsv/Yh/b0n8cCXY3vghE=; b=v/udtxWlIYhxLoKWsnxy5CgZ2x7nZTvDMamp06MnAQhMinpf2QNUfO6v/UxaxTqZs8wBPSShLISinN97uZyNRzu5GkM+403sC40E0KjTZaG4Nedmex0dlyzvrHSTU6haEZYmtK1nF6uur8oYQr/EFOgDNNGzk0PXXKEX5y2NwLE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:37:39 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:38 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 05/96] cl8k: add ampdu.c Date: Tue, 24 May 2022 14:33:31 +0300 Message-Id: <20220524113502.1094459-6-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d0f46ebe-f43b-4268-1e97-08da3d79ce4c X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: cqb3Rrq4sTUyCHQVEYwZB4aJSbp0H8YL8prQjhCm3Zjg+u5Ox5OyCI12/Hdg/3odgSLfZZHSlcP2Ir5LdfXZmDeBScMimLn83XJFfH6wqd8fqtiJ+C3RRj3XvkTVSGSVLw4obn/jQ5Ayovymu+5P3C22HX+33L/h2B9y0zWdC20yFg+ympa6TrEaDQtmRhenecGDMaSKo3eWkRZWJL+nSjq/5jNi8I5FAisZEhwV6IsYubPiz68g0G3V4IcY7fFT1C9PyM9eaVmhVgZesdl9vJKz+eAuYi5b9p8mgc8krkmj6ka5j1bkzucd2gF6RJMENG+9W+eoPFpCnolZf80dh1vKTKoEJjME9nKHPvinsa4HQ3acWQld6+zka6j+FrBr0v5x0yJr2pv/2IdAr5RD0J8tY06+oHzskufIx7Jky+4MBW39Arpk6P0BbubYAdcNuJDbeFEoiEkhASxY7+hCv7w6/Vmr6HSymIRFJUuP+r+zoFnJPE3x4u+TW0rTdQRTudMfGuz99nk+l3SODUj+RPNuyNGnocDTDGdCHMEQ2cymJRe/bwW4eSfK97/QBzmOz6JpcYjbRWJwHTCwUNQQStQRNB76zImuC71a2ld+mrNImhVW0PMQHm84ERtQFI4A3sQ+NMKU7JMHGT2s3c5ZXC1sH0akTTORBFcEcN68jnjuwCQju1kZwnSP9XqQQ3wBywMLt5q/tu6XiqNtEVBvBPEIcGmhO3MwwjOlkV6PTxI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: RswMRZef7mso3kyBJQ4rwjH2jSCJEvOIBuqTaiPlXX83iBVQEGLokrRb2WoiCfx5aCgYG9MiY5f2zrgwzfuLGAOGUoE+p86mySs73ooxscwLfSV4kYQjv5NwKy6qnl0O2FNTjb0/QvRrPuoHb1thZTRWaW/DcNfnBEGwYyQmXsGVZrHjTPnvk5YSpJUu0YhjUZxEeMcoyTt3zcsXRw0KE0GSl3ATvdT30C8touh0jOc1aaH8BC0NNChvg7JWMosTpHAAVBwOqeZeiKeHOvhi1hLkrfsmhgTvNx8kvDeH0Tnue7mRLg6zq/AGSZG4H9hj42D3I1GPbMyDaaErRVOWBxZlV0mTd7CWDZg7rxI1lax+W/7DChuEsJ2S71uJjAQRTuJlOyxvuVhu8Z4M40P+IrCUiTBArb0g8JDVvUHkGOL1y/qc8g9UxXo44e2aZxU3FPSzlzbsb9wQ/5MDZYHZkLG4k3c0vegofJ3a+bShwKcWqiwiJAZ+hfQAK0hrgd/KBIygv9zHIL/ToRDFFb+aBGIf6MD3Pr0cg2j7k9WIXDeB8oKL40QonoJ5JstUGgys1c0Xz2SBabyfkL/bE7TpFJgS18x8dX7LvtpB9AYu9srCxGHb8zFtwZfkqBqzmjwwOnIJGLoWgRZCgfQFNolUihGXIZQzcXK0PEgQma3GyIXBgjqfhJF3P6RAbCDOh7QooFiv0F+kse97VzwyVnxewUfOjhkhs9gxPWzXPyyU4+HRmUEYPAp30EYvPN+LSFBe8S38A12lSAO/XuIEP5T2HIhKPhOZ4pvlP72miSgEJnatyjBSxYt+QlrkvfARfcAifpcHqTiJo4Qv4H7UbLlYprkLkbKlMP7v/VV7ZE0GTOZD5TjqrhY9IbgL0j41JBrFF0AGFkuC8jwWZqLq6tcWWTU04f4NQ7oSx+kSXebzLM4c33vMXXiBdQ6bssO/bscB1Zsxa07Fg62S2kMdmU4+nKgGToI7L1jnABvkJSyF5eJnF4C7AxuAyG+HvWehyEsAXTw3Y6PNdvQ+mQwqJjtGUWunb0aRKGsLOvgfjlo7jkW0q8FlC/O+LusNhlcESh6AR1flpU+6+gE6qwRmfpN24R85098CAMJC7L6MtTczvpNctJPHlb0n2QhaiV7ZTCuPMN4MElI48YwY4rAtTvZnDw3rpBQ8wHx+2/xXt4eOV95NIOMMWq3Ll5+X3D12D5yv/FRmEBBWcmzygmIGi7JD0Ms/2pBL4VZYs6M/M2p+qjEQC9FDik+u/mMVe46j244a5/t5guB7VfZ1E+8UktBht2r5ng7Hf1TQq5hOM6LL79vDxHmSqBkMOHeKCst33hbI+MYDhBgPFKLCDiXNcZjsolGPfVZusW6MoFnZJVooBh3x9eTrSdWiPhpFkGev/GL8PUN8HgzVz4mRsjCbZ8hfO196LjKKw/lT9bxlrrlcqQaVUQP67r0ql0h47U40ElEeD/arHwDNmoll2gLS7kWA7VbiFy/V2iLakArgkovzJYjaUZjzmIKXC+d3Jo+jcdxsnZsap9uNuxycPR+uGV8pBwJOwswhxz1szN91uEzEyRrHgd2YzWxv8qoWNZdoMIRmqLEU2CdUWgvm85vYLCF3CnGHVLreQ4AzESOYq9LURngURZDNcSIGo1N0PUV9t0XZzuE+2SJfeZ3r4qFasjJoEaKba8uErtbv1fHWnHRW+Bn3F+pMsYkyZwemvCDjS6suBnxPvueonXEWT0yNJ3l8xCPYebaHAe+UFKCuSPftV8g= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d0f46ebe-f43b-4268-1e97-08da3d79ce4c X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:38.9186 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: QN8S5dbiBIG/5mtyHPm3zk9oljLPokn78qYl3gDGIIWlwDgrusVkEGvg3L7D1EAHRJvielnpmw+8tdOzxu+xRw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/ampdu.c | 331 +++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/ampdu.c diff --git a/drivers/net/wireless/celeno/cl8k/ampdu.c b/drivers/net/wireless/celeno/cl8k/ampdu.c new file mode 100644 index 000000000000..6609bc62d340 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/ampdu.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "hw.h" +#include "recovery.h" +#include "utils.h" +#include "ampdu.h" + +int cl_ampdu_rx_start(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u16 tid, + u16 ssn, + u16 buf_size) +{ + /* @IEEE80211_AMPDU_RX_START: start RX aggregation */ + if (!cl_hw->conf->ci_agg_rx) + return -EOPNOTSUPP; + + cl_dbg_trace(cl_hw, "sta_idx [%u] tid [%u]\n", cl_sta->sta_idx, tid); + + buf_size = min(buf_size, cl_hw->conf->ce_max_agg_size_rx); + + if (cl_hw->conf->ci_fast_rx_en) + cl_rx_reorder_init(cl_hw, cl_sta, tid, buf_size); + + cl_msg_tx_ba_add(cl_hw, BA_AGMT_RX, cl_sta->sta_idx, tid, buf_size, ssn); + + return 0; +} + +void cl_ampdu_rx_stop(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u16 tid) +{ + /* @IEEE80211_AMPDU_RX_STOP: stop RX aggregation */ + cl_dbg_trace(cl_hw, "sta_idx [%u] tid [%u]\n", cl_sta->sta_idx, tid); + + if (cl_hw->conf->ci_fast_rx_en) + cl_rx_reorder_close(cl_sta, tid); +} + +int cl_ampdu_tx_start(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + struct cl_sta *cl_sta, + u16 tid, + u16 ssn) +{ + /* @IEEE80211_AMPDU_TX_START: start TX aggregation */ + struct mm_available_ba_txq_cfm *cfm = NULL; + int ret = 0; + + if (!ieee80211_hw_check(cl_hw->hw, AMPDU_AGGREGATION) || !cl_hw->conf->ci_agg_tx) + return -ENOTSUPP; + + if (!cl_txq_is_agg_available(cl_hw)) { + cl_dbg_warn(cl_hw, "No free aggregation queue for sta_idx [%u] tid [%u]\n", + cl_sta->sta_idx, tid); + return -1; + } + + ret = cl_msg_tx_available_ba_txq(cl_hw, cl_sta->sta_idx, tid); + if (ret) + return ret; + + /* Read FW confirm message */ + cfm = (struct mm_available_ba_txq_cfm *)(cl_hw->msg_cfm_params[MM_AVAILABLE_BA_TXQ_CFM]); + if (!cfm) + return -ENOMSG; + + /* Check if status is valid */ + if (cfm->status != BA_TXQUEUE_INVALID && cfm->status != BA_TXQUEUE_VALID) { + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", cfm->status); + cl_msg_tx_free_cfm_params(cl_hw, MM_AVAILABLE_BA_TXQ_CFM); + return -EIO; + } + + if (cfm->status == BA_TXQUEUE_INVALID) { + cl_dbg_warn(cl_hw, "BA_TXQUEUE_INVALID - sta_idx [%u] tid [%u]\n", + cfm->sta_idx, cfm->tid); + cl_msg_tx_free_cfm_params(cl_hw, MM_AVAILABLE_BA_TXQ_CFM); + return -1; + } + + cl_msg_tx_free_cfm_params(cl_hw, MM_AVAILABLE_BA_TXQ_CFM); + cl_txq_agg_request_add(cl_hw, cl_sta->sta_idx, tid); + cl_baw_start(&cl_sta->baws[tid], ssn); + + /* Mandatory callback once setup preparations are done at lower level */ + ieee80211_start_tx_ba_cb_irqsafe(vif, cl_sta->addr, tid); + + return 0; +} + +int cl_ampdu_tx_operational(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u16 tid, + u16 buf_size, + bool amsdu_supported) +{ + /* @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational */ + struct mm_ba_add_cfm *cfm = NULL; + struct cl_baw *baw = &cl_sta->baws[tid]; + u16 ssn = baw->ssn; + int ret = 0; + + buf_size = min(buf_size, cl_hw->conf->ce_max_agg_size_tx); + + /* Send MM_BA_ADD_TX_REQ message to firmware */ + ret = cl_msg_tx_ba_add(cl_hw, BA_AGMT_TX, cl_sta->sta_idx, tid, buf_size, ssn); + if (ret) + return ret; + + /* Handle message confirmation */ + cfm = (struct mm_ba_add_cfm *)(cl_hw->msg_cfm_params[MM_BA_ADD_TX_CFM]); + if (!cfm) + return -ENOMSG; + + if (cfm->status != BA_AGMT_ESTABLISHED) { + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", cfm->status); + cl_msg_tx_free_cfm_params(cl_hw, MM_BA_ADD_TX_CFM); + cl_txq_agg_request_del(cl_hw, cl_sta->sta_idx, tid); + return -EIO; + } + + cl_baw_operational(cl_hw, baw, cfm->agg_idx, amsdu_supported); + cl_agg_cfm_set_ssn(cl_hw, ssn, cfm->agg_idx); + cl_hw->ipc_env->ring_indices_elem->indices->new_ssn_idx[cfm->agg_idx] = cpu_to_le32(ssn); + + if (amsdu_supported) + cl_tx_amsdu_set_max_len(cl_hw, cl_sta, tid); + else + cl_dbg_trace(cl_hw, "AMSDU not supported - sta_idx=%u\n", cl_sta->sta_idx); + + cl_txq_agg_alloc(cl_hw, cl_sta, cfm, buf_size); + cl_msg_tx_free_cfm_params(cl_hw, MM_BA_ADD_TX_CFM); + + return 0; +} + +void _cl_ampdu_tx_stop(struct cl_hw *cl_hw, + struct cl_tx_queue *tx_queue, + struct cl_sta *cl_sta, + u8 tid) +{ + struct mm_ba_del_cfm *cfm = NULL; + u8 fw_agg_idx = tx_queue->index; + + if (cl_recovery_in_progress(cl_hw)) + goto out; + + /* + * TX stop flow: + * 1) Flush TX queues - done in cl_ampdu_tx_stop() + * 2) Poll confirmation queue and clear enhanced TIM + * 3) Send MM_STA_DEL_REQ message to firmware + * 4) Poll again confirmation and flush confirmation queue + * 5) Reset write index + */ + cl_agg_cfm_poll_empty(cl_hw, fw_agg_idx, false); + + /* Send MM_BA_DEL_REQ message to firmware */ + if (cl_msg_tx_ba_del(cl_hw, cl_sta->sta_idx, tid)) + goto out; + + cfm = (struct mm_ba_del_cfm *)(cl_hw->msg_cfm_params[MM_BA_DEL_CFM]); + if (!cfm) { + cl_dbg_err(cl_hw, "Unable to fetch CFM\n"); + goto out; + } + + /* Check confirmation status */ + if (cfm->status != BA_AGMT_DELETED && cfm->status != BA_AGMT_DOES_NOT_EXIST) + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", cfm->status); + + cl_msg_tx_free_cfm_params(cl_hw, MM_BA_DEL_CFM); + +out: + cl_agg_cfm_poll_empty(cl_hw, fw_agg_idx, true); + cl_txq_agg_free(cl_hw, tx_queue, cl_sta, tid); + + /* Reset the synchronization counters between the fw and the IPC layer */ + cl_hw->ipc_env->ring_indices_elem->indices->txdesc_write_idx.agg[fw_agg_idx] = 0; +} + +int cl_ampdu_tx_stop(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct cl_sta *cl_sta, + u16 tid) +{ + /* + * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting + * queued packets, now unaggregated. After all packets are transmitted the + * driver has to call ieee80211_stop_tx_ba_cb_irqsafe(). + * @IEEE80211_AMPDU_TX_STOP_FLUSH: stop TX aggregation and flush all packets, + * called when the station is removed. There's no need or reason to call + * ieee80211_stop_tx_ba_cb_irqsafe() in this case as mac80211 assumes the + * session is gone and removes the station. + * @IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: called when TX aggregation is stopped + * but the driver hasn't called ieee80211_stop_tx_ba_cb_irqsafe() yet and + * now the connection is dropped and the station will be removed. Drivers + * should clean up and drop remaining packets when this is called. + */ + + /* !!! Comment in agg-tx.c, ___ieee80211_stop_tx_ba_session(): !!! + * !!! HW shall not deny going back to legacy !!! + * !!! Therefore cl_ampdu_tx_stop() always returns 0 !!! + */ + + struct cl_tx_queue *tx_queue = cl_sta->agg_tx_queues[tid]; + struct cl_baw *baw = &cl_sta->baws[tid]; + + spin_lock_bh(&cl_hw->tx_lock_agg); + + cl_baw_stop(baw); + cl_txq_agg_request_del(cl_hw, cl_sta->sta_idx, tid); + + /* Check if BA session exist */ + if (!tx_queue) { + spin_unlock_bh(&cl_hw->tx_lock_agg); + + if (!cl_recovery_in_progress(cl_hw)) + cl_dbg_warn(cl_hw, "Queue doesn't exist - sta_idx [%u] tid [%u]\n", + cl_sta->sta_idx, tid); + + goto out; + } + + if (action == IEEE80211_AMPDU_TX_STOP_CONT) { + /* + * The order of flow here is very important here to avoid reorder problem! + * 1) Take single lock to block single traffic + * 2) Stop agg traffic. + * 3) Transfer agg-to-single and push all skbs from agg queue to single queue. + * 4) Transfer BA window pending queue to single queue. + * 5) Release single lock + */ + spin_lock_bh(&cl_hw->tx_lock_single); + cl_txq_agg_stop(cl_sta, tid); + cl_txq_transfer_agg_to_single(cl_hw, tx_queue); + cl_baw_pending_to_single(cl_hw, cl_sta, baw); + spin_unlock_bh(&cl_hw->tx_lock_single); + } else { + cl_txq_agg_stop(cl_sta, tid); + cl_txq_flush_agg(cl_hw, tx_queue, false); + cl_baw_pending_purge(baw); + } + + cl_tx_amsdu_anchor_reset(&cl_sta->amsdu_anchor[tid]); + + spin_unlock_bh(&cl_hw->tx_lock_agg); + + _cl_ampdu_tx_stop(cl_hw, tx_queue, cl_sta, tid); + +out: + /* Mandatory callback once we've made our own tear down ops */ + if (action != IEEE80211_AMPDU_TX_STOP_FLUSH) + ieee80211_stop_tx_ba_cb_irqsafe(vif, cl_sta->addr, tid); + + return 0; +} + +#define HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_OFFSET 3 +#define HE_EXP_MAX 22 /* 2 ^ 22 = 4194304 < 6500631 */ + +static void _cl_ampdu_size_exp(struct ieee80211_sta *sta, + u8 *ampdu_exp_he, + u8 *ampdu_exp_vht, + u8 *ampdu_exp_ht) +{ + struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + u8 mac_cap_info3 = he_cap->he_cap_elem.mac_cap_info[3]; + u8 he_exp; + + if (sta->ht_cap.ht_supported) + *ampdu_exp_ht = IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor; + + if (sta->vht_cap.vht_supported) { + u32 vht_exp = (sta->vht_cap.cap & + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + + *ampdu_exp_vht = IEEE80211_HT_MAX_AMPDU_FACTOR + vht_exp; + } + + he_exp = (mac_cap_info3 & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >> + HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_OFFSET; + + if (sta->vht_cap.vht_supported) { + if (he_exp) + *ampdu_exp_he = min(IEEE80211_HE_VHT_MAX_AMPDU_FACTOR + he_exp, HE_EXP_MAX); + else + *ampdu_exp_he = *ampdu_exp_vht; + } else if (sta->ht_cap.ht_supported) { + if (he_exp) + *ampdu_exp_he = IEEE80211_HE_HT_MAX_AMPDU_FACTOR + he_exp; + else + *ampdu_exp_he = *ampdu_exp_ht; + } +} + +static void _cl_ampdu_size_exp_6g(struct ieee80211_sta *sta, u8 *ampdu_exp_he) +{ + u8 mac_cap_info3 = sta->he_cap.he_cap_elem.mac_cap_info[3]; + u8 he_exp_ext = (mac_cap_info3 & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >> + HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_OFFSET; + + if (he_exp_ext) { + *ampdu_exp_he = min(IEEE80211_HE_VHT_MAX_AMPDU_FACTOR + he_exp_ext, HE_EXP_MAX); + } else { + struct ieee80211_he_6ghz_capa *he_6g_cap = &sta->he_6ghz_capa; + u8 he_exp_6ghz = (le16_to_cpu(he_6g_cap->capa) & + HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_MASK) >> + HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_OFFSET; + + *ampdu_exp_he = min(HE_6GHZ_CAP_MAX_AMPDU_LEN_FACTOR + he_exp_6ghz, HE_EXP_MAX); + } +} + +void cl_ampdu_size_exp(struct cl_hw *cl_hw, struct ieee80211_sta *sta, + u8 *ampdu_exp_he, u8 *ampdu_exp_vht, u8 *ampdu_exp_ht) +{ + if (cl_band_is_6g(cl_hw)) + _cl_ampdu_size_exp_6g(sta, ampdu_exp_he); + else + _cl_ampdu_size_exp(sta, ampdu_exp_he, ampdu_exp_vht, ampdu_exp_ht); + + cl_dbg_info(cl_hw, "ampdu_size_exp: he = %u, vht = %u, ht = %u\n", + *ampdu_exp_he, *ampdu_exp_vht, *ampdu_exp_ht); +} + From patchwork Tue May 24 11:33:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576871 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 698FDC433EF for ; Tue, 24 May 2022 11:37:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236757AbiEXLhp (ORCPT ); Tue, 24 May 2022 07:37:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236762AbiEXLhn (ORCPT ); Tue, 24 May 2022 07:37:43 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2085.outbound.protection.outlook.com [40.107.104.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DDB241316 for ; Tue, 24 May 2022 04:37:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=S9qL6GqEX/MTFU3ewN/3JBl6PV1MTTrKKaXc/+tmIV8VdtxKg2EUwpyKjejgYxNkFKuzqeUG6u9MLpN7rUtpqK3ZSF3uZaDUUVHbC0vPH9KJQKoiw8yRmPopMOTIO6jI74cLuUw3soSOc76HPapm8DtaJrnf5TEbnJj3o+vQ8jD+4GanMKjkiKlrvBf8E2j/EvEDDQkWOG32fT80SJQx5aiLhbdE14Z9Cz1ZYubNQaM5jql+XYGMkIiDUbKl3HBAvkb8xjA8lA0wjmYxZc6GPHf2ZfdGc62aZDyEUPHbFV6gcftcxkTifOAwIEtweCQWI6Fe4/JFqCRDRdkbELq5wg== 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=RZMHGy4DdrTWQAHsrgOqt1xMFTWy9K8tbxa7wkjdddA=; b=f0PbTXfM9Sa3Chb8RvxeNP0fHH6GBuVM6L1ulKs5aWn7PwWAnxcmyRK56vYUluBiejX00S+rnxwiJK2PBINjDTtWNgaMsb3Q65/eXxSatEFx3mW2pIj+tubKzOyXqV/uGOk9FlUks5TvagJKkjIsJlYMV+TTx4tNRaJOmHJ5h2HnDIl+GOakmgb8LegrexTWR3jEVJup4NXCmMLeIK+4y7+db7h9mgDcqi4UJ+f/oG48gwg7LcOi7qTCEyAg41+W1ufLCBx5dXIEbL/g+jSabTfI5yKopDK8KDRJLDtfr2wpattYhNQkyTX+KBJSPp1iBW4/4R3fJwhCvl7yOlWBjA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RZMHGy4DdrTWQAHsrgOqt1xMFTWy9K8tbxa7wkjdddA=; b=JqQ2QVZvB7PghCzEAc8+f04hRjGbwxbkXV3mDstQ60d6EzZAy1smIeVFDjybInVzeSEQPYn5QtZKROrsTSu6XzjOWHhJVh2NHJkUbjQlBjgJFkY340pQrOMHYXCrnjeFrBIUz883yZu+6RvpbwT5XX2UQfESwmy/rXNo+9Hf+lw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:37:40 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:39 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 06/96] cl8k: add ampdu.h Date: Tue, 24 May 2022 14:33:32 +0300 Message-Id: <20220524113502.1094459-7-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0d062a4b-bcbf-4df1-f14f-08da3d79cedf X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: NqGmWhs1G2StI/zN4/vjw0BAEriyxJgFFZd4JPmNrf96+KdplZfza0zQJH81n5jo0d3CrT2TAlaKrZe6aSAac2WG0EU2edZw9R50tl9q+bAX5n1s9vWxy6/vWvjRN9YJSdPaKN9qp61d8vjwJJSrFiesZ37LCjUoxIRImicbTm7TS46zbG3a8z/r38nznSq0MF5qd3mOvXaD+w+xNICRumPm5EkP9Lji1W7K8BGyCyqIS0cQfwjbfAWQwExb1y9nk8z9iX6VSqPMWGSQ18NTe7UEUsAqoRVJg4DpbzuAYcl/RfyC1Q/mIpUQ9hQ1OsLZlqPoJTCce60Puox/LNmEsu6VxGahtlY9eAH4oBpSqS2jUlAXyfKIK2JFjkJmsCjjnrVnZzvp+RDiOnMGdPCH3D5FT352QtMqFzCBViyhm1/zE/cUASj6J+bfOgPuBoH4iIaydwF4Awfe0f9zB6py7N2SII6GSp/xHZyjOiZAUzW6Qoh6mIBrf2+CkYTiJsaagxDYViM6c1irder39VJa46X/X4lHdcyLskM9JLm6K3banvLGvS+2uYDzNivngUtgDE7PT9NXmEFSIdhd4c32yKaeJGaguJy1oRVHTFDnf7hVJUYqU2YbKzk9cwBrsNUyyVruWp2m8A10xqcaT02UbsKguuW4QhItn09q6y9pAR5VkltrKsZi6DPB/PVNPvMNvNbUBfRcK7QLgIJQfUkFPOXFu0tQC7s571Ut+LPqzxg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: duzAcQlal7QgulgSeRAQvzg0evvIghFn8R1NFgvZVmf7wGPtibKWl9RpyUmG/9uJ497/r2fw4svZ18vEofadamdenPaMm/r1pvbLSsBvoUnJ8l8l51Sl3O0sgI0wYVQH+VpvPTgasDn/qvU6upOwuMmdOMEcRzA8+Xce9nV7s016tCa8iVLBE17Zf2Cpt6xawj30PP0f4pkbUfJX3ypndN7Thg1edcR63fFHXTXNCac89LxNhcdyn4CJt8AT61qhT0ME72E2SNDIwXJbxbegBvKSQiNRB6RtOp+LRtH936B4Cb/nP5h7xOoQqYrKiTL3+nyEBYa1i2m+y7NsKYVjLtVonII3DIck7Qu3A7cB32uPt1CXE7R4WBgCCRGcOBSVKI3KMhvke2qjFykgDLi3cfK0Z/F12OSVRZ+Y7YaNVhBvVCbrR9j0vhl2tTbur/AkCSZK+pje2PBEeAHZHaCMKOAAXfFNimOshsUQYg7+hU/UrwyqJFAhDpzjMWZRhMieyRxIYjtNoPU/4JORBEAqrJ1qNPqGynqjOhojzkU8hdQsLeXNp8JQ6Kw19x86tFdmEzPBQOUEOUvJwmtBeu8m/rsPjtxKWkoE9ikeSvT71ZNRsmz3necW5xXOydTk6/xMm6SCkD2bOKEGcsRA7n8vkCAMTALf3gc4RxZeDSgOT6L9thRKP2cyYIcMnCBztK87WCl/CI3Cjd1EbyFwLr02+qBm+UBwkWsQZWfJY14bWYeSMtAqltgRTRGrNVdjr2qFCoiF6iC2Rf6JtpY2ARKY5cFs1E0Y1D8BdTxiIMyxnGEcFhI679+lBJ8OcheQF2iU7ywjaW7A9fK1rX6lSmqg7mbly00/Tu/8MGaFTVyiv/68MY6mWM8PA7vJec6hsvBKQFOq2+z9OVIQJgVWx1nLNghuNzKps8mT+fLEv2O/OMRYDtSrLkzkpTqHDqpL5dO6nBj+2B5Mq0uTInl7htWBNnfLCHm10Kuwec0CnptlUvBWU/44MIt1q8x9jQl3xerAoS2BIHRy48vj9rFNXUMDb9dJLwl0rA0N7zDuQaMCfaqglKlflC+pYEF1/OTc4sRxDNn/M4A+7AXdqD1rUkN3Gzj2K/TtUB5+dBVjjt8fX+bK23LvgUYRvUghbtlTh4/Cra5AT3YYyl8iX3nAkHuJtzrnhDr8Zkqaj/Z3p1BkkzMx//BnUcTxHVncD+CJowAHmGqbcpmPP0MNaIwDin/GuNp7bcoYq2V5SRgnLixUIOfQx3VgjMX0PsNB2RXDffcCkMPlHuXD1O3fHvB23RJxbjftPPk7fxq/L42wNLk+C2UDud5b0MXMrxEa3ZcROMtLju2xixt0EvUP8hcyN9pdjiMwThMDoKcOuRoXfHcA87fi654bxjnvybJSj/a8sJsLKMHNCKAy0/RpT+IVQz533JkQyHda6G2SJADvEiST47RkA5aSBeNxs7LZQ/zMkamG72nrqCqNjNmBrXeKDfFdkfSFE8SGJqMR2sC1UwVuDIfLnv78wZMp8d/RD0f71x3ae924eoKjE28nCse1QMGgTRXm17WHEnYuSnAvmrVHtngtMaBc996TVoOvvLq3EwZsSbpy/Iw6Xcw7OfFmmvLWYzIoWFNXiPAZJNwDCqwNI2sQr7rnfuuevp24P3XUwHpjjPqtEFPe2XRH28VQDaYok5qXVhrYF2HGjyV3uba83/aZ2JZtiNu9L3OnkLU4oRicdX1y5x1hlXAimbvyE2WpOYx8LTkezvslxONkL4jtYLU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0d062a4b-bcbf-4df1-f14f-08da3d79cedf X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:39.9184 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: aXgnV4cf63XMu0PvHZvHWSjEKhGWXhU7H+52xK76X8hW2/xIq1RQcXY2vJQmkxTP2/1xX0j1s2qD8KwUpPzMhQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/ampdu.h | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/ampdu.h diff --git a/drivers/net/wireless/celeno/cl8k/ampdu.h b/drivers/net/wireless/celeno/cl8k/ampdu.h new file mode 100644 index 000000000000..62c3f60c8c86 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/ampdu.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_AMPDU_H +#define CL_AMPDU_H + +#include "sta.h" + +int cl_ampdu_rx_start(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u16 tid, + u16 ssn, + u16 buf_size); +void cl_ampdu_rx_stop(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u16 tid); +int cl_ampdu_tx_start(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + struct cl_sta *cl_sta, + u16 tid, + u16 ssn); +int cl_ampdu_tx_operational(struct cl_hw *hw, + struct cl_sta *cl_sta, + u16 tid, + u16 buf_size, + bool amsdu_supported); +void _cl_ampdu_tx_stop(struct cl_hw *cl_hw, + struct cl_tx_queue *tx_queue, + struct cl_sta *cl_sta, + u8 tid); +int cl_ampdu_tx_stop(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct cl_sta *cl_sta, + u16 tid); +void cl_ampdu_size_exp(struct cl_hw *cl_hw, struct ieee80211_sta *sta, + u8 *ampdu_exp_he, u8 *ampdu_exp_vht, u8 *ampdu_exp_ht); + +#endif /* CL_AMPDU_H */ From patchwork Tue May 24 11:33:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575988 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 DA900C4332F for ; Tue, 24 May 2022 11:37:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236772AbiEXLhu (ORCPT ); Tue, 24 May 2022 07:37:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236771AbiEXLhr (ORCPT ); Tue, 24 May 2022 07:37:47 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D90D43382 for ; Tue, 24 May 2022 04:37:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iiKDUIbf59c46mJZzKILqt6qk4BLi7mg2+O4bRNd65IXB9RD7rAabO75rFfw2N2WQqUFKCZK7rO2hH25Xe90m9CbOAswIIilDKH8WV8LMn24/B7gGMTyg71aflwtoYIo9HRT91LRvxs2WWxCNK7OPEwJNpTS3TwLB3gENzyKsLxtNVhnLdeLTl7tV1D3E2PV90Cilo8DwtMCGh11LUoOCGndnS8WLBxMRKJQglexuJhzDWKYez90Gl+FhrK6Wu+JbMrsAwGZQXpKsMd9ff83BspMx2vQeQZBJeqeWB+GXGBXkJ9WhBthPxZh5+RE7fUrBEg4KZRc320f6B4dbX12dw== 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=aeb3FHhx+tyxQtFSK2dzU3Egjt5EmUVBktfGqECSgX8=; b=Jsa+un4khak5yMXFfDK+To/0F/NmOfL8tUMSDUJvXxpbfMvz+jhaUpXVRfMhjadxKuJg7kIXNvQNOj14UtJ8nyyt3zaAQNl9DMzLpny/nahxe61rDZQ5HallIwMLmNqIbmrqRvH8smf6RW5jX+T4KM2TUcA/guHA+ZMTwRpYAFVVEtzT2KYK5LmI/ZNbNSAkZWKubn2lWKk0RgLX8ZtkUOE2H+iIF0b06bV+zkvC0FW/WDWcOy6uq2Laztn0SuQLvtaAa0kCfDAksIPlHNVaDf3uBGq4Sh1bQPvXKuNeoxxZtMsSJoWJfLNywuSFCEpinnoixcg1fyoUipr2kRBTJg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=aeb3FHhx+tyxQtFSK2dzU3Egjt5EmUVBktfGqECSgX8=; b=KAMo0CQk3RBs69jcYzaHNsKEG1TXs8E0oBKrrL+4XOqiifuXxx4Dh98RkYJKs5avHbz8INXD3J5p+SK99Jo5ebvsBh1oh1c5muK8mSgG0MgdWk93LZMBCeSuCQQYO9i5E7204wyvB/T4AK3SGH6PFYF6sguOeWZNztESIZQx7kI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:40 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:40 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 07/96] cl8k: add bf.c Date: Tue, 24 May 2022 14:33:33 +0300 Message-Id: <20220524113502.1094459-8-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 46645a11-422f-49d0-5c42-08da3d79cf52 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: HsDqmtLPpNk+/YVlkwL21WeFoely674JNYelMmB0AmkDz5B7WVUGBgnfRFFNESrQpAZmXbYqU3dzXjeQwkcMIzisTmx3OTQvb9/Qb5I0epAwUVauhP76TdAeGALJMnOL1y7rqKY+KNAAy0q/ms9CbOW1VSKaunbsYze4gV2h8PNnnKAD+zaJ7HELsvTsZ+QbhKapC3gragGAnMcNFu+Zo45f03jiRAaoten6AcDITYvEyKTX/5ROEEOKwq0bf66oqeOiCMuVKYlkpEl9tF/D78rGk0cVaoy5YsnqGgL+gHPPUZ3QCGDjiMWn0jXca0rhnWq9CEv1j3ZBLldmJwF3nnQ3woAmyTns9BM8GeoA80l6rDJZKv5LBBF4K6JPGuxpJMSl/jPdwr+uJLWGBr/wXd/flmkiJqGhOmRTd8V2l2D/jpvmyKyYSYWuw3qpcPTIjDn/8eu9T6TCG+1+L2i0py71155DSF6SVR/OSdBDobCZHouInzHqjTH4gOW1mtElzeT/7EsGhKYN1nD3OmVKbS46fQ1MkJsUBHnbUCJ8nEuRpN7yQkvL/EwslV0dYbMRDILpFn6O+jAoXogIiY6u7FXTq64qarRAMgKAX787zFdPNllWfWxPsA1qLNFt27vc2IAGpl2ONwKJVtukq2V5+aaSJvh/7hPPLviqBJLNYlo2c+ZbmJPn7KBQJheCzX5/+scgY3UdH8l/8Le5OZSFAic4gh/APh2qjky/u198rWw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(30864003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VOYkJz3hVsm1XgEb1LTENF6LlnHCe98lW4iRH0+9tQDHIOkC/0Tw5EskWWk16P5tkh3h3beOBWI1xuIrFnaP1e9GYcdWfiAFcOsEKTiCYXm500AbiWG1XpvqLpHFFP8EIjlpSyOBkfgUxZVCnYF8RKYgPMmKC9dDbHxxIm3kFVGoozQCXifJAyzP2iG02NC7PD9eQ6yRDWlirilgfZdQOYSSWkL7CgnzqxOnHzRRNxDMX9cuq+HuNrMMg6Qfi0TKF6Px+b9hhNXWjvBnoaQ1gD77b0nRgWfhUAKrACeCa1LgZfJJlsIoiMxfGZdVZXJifV4Q+Fd91kpLaQULd7ldFtHjddKH7L8v2VZP1KgY02xt7atAkVQnqWQKunyWaTxnB1UNz3mjo+Z3MCyaxkCvg8hA1FwQqQzDHs81iHeY8bJhHGuO+a4+xsX2dFokfdyyGbeDWd7ME+wZqbotl9kL3hQ3YnIXfXI3eBo/Y9mYcGO+CSyGC2Ja10AuFzo9gZBHUEaxt4ywTznDOVM9tg+ew0qfxk29zmkm0b39OTAgPy4tqaOrRjSYbeSr1j3kl0tPZ/WxikPjyGdNofprCPsHD59fTlTfuCV9/s8GnCv2awhrvEeAic7CH7oKLkE4sEZXrS8s+rp7vEbB6ASN0kD2/gdAadxgN166KUrEDBxgd119Ogh0QbrXGCntlwYvEIc9O9xIbFCCCWyfsOUW0YhF/7urYbcEs2q7C4x7wBi6iOSMK/5BFfC9XsXzMX117iUkQQURTqUojv05AQpTUcOwePZcWrteN7AMgBKWJqRcD6koecr0PbSv0dal+z300qbI6ZiqyHnWCjD9IN8bC3wky3Qt86o7HCNqhHGwIYHoUKcdN1VFkjA1CBNm4HVUg0UbJ8H4QDeXshRNzfYWO5xQPBDJHmv5Zfnx4Li8TNSmWlD82lLO7BEQDJph1kesSTxNobjPU6wg5TG1zqpwSf6TjAtJkkqVuG+0bGNByNN8iWPDLNC1ox3yInc0P/YHJKBbdpM6uoZIYDdAriFPzhCRj+r7oe4e42DGtx/JKzmb70JJjrkfloYVwkFNhjrNDVKG3GYg5JJxqhtYvKqsNlPioI/Zom4pm1ZZVmFQr847Po4Gr0vVVBRiJDnZ2/Vve0eLGAd68nd/gBSsyLujgMHLIp4SilMiw961NADhcEshKMmK8vo9IzaUGdRHat+0iehGA/mjo5IKT6Kpef42JcHxYCAGzFl4SzD/nVV932qYUibSBLvIrPqZaGvq3ziK1RXXTMwP98j+nbaf0RkcRv6MqQ6ZiXH7bl/144fF14+OYkDBcBeFxII0BSF5e1fRjlxJPaPjMkioAiE5/RCjJ3Q90x4zhV3pFTDLa9hNrR6yrCHRGs+28ynmY7NFwQ9Im1IjZ2+lhzIYN1PQ3FceygtoKho78NL+du1wbk3mIbxt5YKg3+aEjl9Zcw3SkCsjjlIERMxxkXnLjNvATn0p5t3mIMDix+nckOJG8gAmndamDZ0URhPRNq83Es/DhjruGa5Fp6k4ScGr7Lfd3VcfmxERxgcbCy3DlbqORCocx4Jr8X+/dykwGdTfYbVe8gO8ipY3TgyReDZmIyZM2KokBN0cCyxwBnpsxWMkTgD+o7guYULagndbswxSCGLU8+xGdfwHBDKujeID1Smc0C4jyeSwVLjHtdRygoisXB+Bpj33TH2pPm5xz61IlTfyvPPC8yaI7rpxQ0qy8qmbfxXc9ngdDmbPI4LcM/8gxW1tNp/PkPs= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 46645a11-422f-49d0-5c42-08da3d79cf52 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:40.6862 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: RNUOF8/gscT/mJhU0CzIR3cStl/ves9dhIB9ej82Mv4/tuEQBKHeLfMVm0PeDwQ98Z27BhpiDDaioaJWuiF5Bg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/bf.c | 346 ++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/bf.c diff --git a/drivers/net/wireless/celeno/cl8k/bf.c b/drivers/net/wireless/celeno/cl8k/bf.c new file mode 100644 index 000000000000..49d16e13e6e4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/bf.c @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "hw.h" +#include "traffic.h" +#include "sta.h" +#include "sounding.h" +#include "debug.h" +#include "bf.h" + +#define CL_BF_MIN_SOUNDING_NR 3 + +#define bf_pr(cl_hw, level, ...) \ + do { \ + if ((level) <= (cl_hw)->bf_db.dbg_level) \ + pr_debug("[BF]" __VA_ARGS__); \ + } while (0) + +#define bf_pr_verbose(cl_hw, ...) bf_pr((cl_hw), DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define bf_pr_err(cl_hw, ...) bf_pr((cl_hw), DBG_LVL_ERROR, ##__VA_ARGS__) +#define bf_pr_warn(cl_hw, ...) bf_pr((cl_hw), DBG_LVL_WARNING, ##__VA_ARGS__) +#define bf_pr_trace(cl_hw, ...) bf_pr((cl_hw), DBG_LVL_TRACE, ##__VA_ARGS__) +#define bf_pr_info(cl_hw, ...) bf_pr((cl_hw), DBG_LVL_INFO, ##__VA_ARGS__) + +static bool cl_bf_is_beamformee_capable_he(struct ieee80211_sta *sta, bool mu_cap) +{ + u8 phy_cap_info4 = sta->he_cap.he_cap_elem.phy_cap_info[4]; + + if (mu_cap) + return (phy_cap_info4 & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER); + else + return (phy_cap_info4 & IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE); +} + +static bool cl_bf_is_beamformee_capable_vht(struct ieee80211_sta *sta, bool mu_cap) +{ + u32 vht_cap = sta->vht_cap.cap; + + if (mu_cap) + return (vht_cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); + else + return (vht_cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); +} + +static bool cl_bf_is_beamformee_capable(struct cl_sta *cl_sta, bool mu_cap) +{ + struct ieee80211_sta *sta = cl_sta->sta; + + if (sta->he_cap.has_he) + return cl_bf_is_beamformee_capable_he(sta, mu_cap); + + if (sta->vht_cap.vht_supported) + return cl_bf_is_beamformee_capable_vht(sta, mu_cap); + + return false; +} + +void cl_bf_enable(struct cl_hw *cl_hw, bool enable, bool trigger_decision) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + + if (cl_hw->bf_db.enable == enable) + return; + + if (!conf->ci_bf_en && enable) { + bf_pr_err(cl_hw, "Unable to enable - BF is globally disabled\n"); + return; + } + + cl_hw->bf_db.enable = enable; + bf_pr_verbose(cl_hw, "%s\n", enable ? "Enable" : "Disable"); + + if (trigger_decision) + cl_sta_loop_bh(cl_hw, cl_bf_sounding_decision); +} + +static void cl_bf_timer_callback(struct timer_list *t) +{ + /* + * If timer expired it means that we started sounding but didn't get any + * indication for (10 * sounding_interval). + * So we disable sounding for this station (even when in starts again traffic). + */ + struct cl_bf_sta_db *bf_db = from_timer(bf_db, t, timer); + struct cl_sta *cl_sta = container_of(bf_db, struct cl_sta, bf_db); + struct cl_hw *cl_hw = cl_sta->cl_vif->cl_hw; + + bf_pr_trace(cl_hw, "Failed to get reply (%u)\n", cl_sta->sta_idx); + bf_db->indication_timeout = true; + cl_bf_sounding_decision(cl_hw, cl_sta); +} + +static void cl_bf_reset_sounding_info(struct cl_sta *cl_sta) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + bf_db->synced = false; + bf_db->sounding_start = false; + bf_db->sounding_indications = 0; +} + +void cl_bf_sounding_start(struct cl_hw *cl_hw, enum sounding_type type, struct cl_sta **cl_sta_arr, + u8 sta_num, struct cl_sounding_info *recovery_elem) +{ +#define STA_INDICES_STR_SIZE 64 + + /* Send request to start sounding */ + u8 i, bw = CHNL_BW_MAX; + char sta_indices_str[STA_INDICES_STR_SIZE] = {0}; + u8 str_len = 0; + + for (i = 0; i < sta_num; i++) { + struct cl_sta *cl_sta = cl_sta_arr[i]; + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + bw = cl_sta->wrs_sta.assoc_bw; + bf_db->synced = false; + bf_db->sounding_start = true; + bf_db->sounding_indications = 0; + + str_len += snprintf(sta_indices_str, STA_INDICES_STR_SIZE - str_len, "%u%s", + cl_sta->sta_idx, (i == sta_num - 1 ? ", " : "")); + } + + bf_pr_trace(cl_hw, "Start sounding: Sta = %s\n", sta_indices_str); + cl_sounding_send_request(cl_hw, cl_sta_arr, sta_num, SOUNDING_ENABLE, type, bw, NULL, 0, + recovery_elem); + +#undef STA_INDICES_STR_SIZE +} + +void cl_bf_sounding_stop(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + if (bf_db->sounding_start) { + /* Send request to stop sounding */ + cl_bf_reset_sounding_info(cl_sta); + bf_pr_trace(cl_hw, "Sta = %u, Stop sounding\n", cl_sta->sta_idx); + cl_sounding_send_request(cl_hw, &cl_sta, 1, SOUNDING_DISABLE, SOUNDING_TYPE_HE_SU, + 0, NULL, 0, NULL); + bf_pr_trace(cl_hw, "Sta: %u, Beamforming disabled\n", cl_sta->sta_idx); + } +} + +void cl_bf_sounding_decision(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + if (cl_bf_is_enabled(cl_hw) && + cl_bf_is_beamformee_capable(cl_sta, false) && + !bf_db->indication_timeout && + ((bf_db->beamformee_sts + 1) >= CL_BF_MIN_SOUNDING_NR) && + (bf_db->traffic_active || cl_hw->bf_db.force)) { + if (!bf_db->sounding_start) { + if (cl_sta->su_sid == INVALID_SID) + cl_bf_sounding_start(cl_hw, SOUNDING_TYPE_HE_SU, &cl_sta, 1, NULL); + else + bf_pr_verbose(cl_hw, "[%s]: STA %u already belongs to sid %u\n", + __func__, cl_sta->sta_idx, cl_sta->su_sid); + } + } else { + del_timer(&bf_db->timer); + cl_bf_sounding_stop(cl_hw, cl_sta); + } +} + +static u8 cl_bf_get_sts_he(struct ieee80211_sta *sta) +{ + u8 *phy_cap_info = sta->he_cap.he_cap_elem.phy_cap_info; + + if (phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G || + phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) + return u8_get_bits(phy_cap_info[4], + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK); + else + return u8_get_bits(phy_cap_info[4], + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK); +} + +static u8 cl_bf_get_sts_vht(struct ieee80211_sta *sta) +{ + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + + return u32_get_bits(vht_cap->cap, IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); +} + +static u8 cl_bf_get_sts(struct ieee80211_sta *sta) +{ + if (sta->he_cap.has_he) + return cl_bf_get_sts_he(sta); + + return cl_bf_get_sts_vht(sta); +} + +void cl_bf_update_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + /* Old & new BF state for main rate */ + bool bf_on_old = bf_db->is_on; + bool bf_on_new = cl_bf_is_on(cl_hw, cl_sta, bf_db->num_ss); + + /* Old & new BF state for fallback rate */ + bool bf_on_old_fbk = bf_db->is_on_fallback; + bool bf_on_new_fbk = cl_bf_is_on(cl_hw, cl_sta, bf_db->num_ss_fallback); + + if (bf_on_old != bf_on_new || bf_on_old_fbk != bf_on_new_fbk) { + /* BF state for main rate or fallback rate changed */ + + /* Save the new state */ + bf_db->is_on = bf_on_new; + bf_db->is_on_fallback = bf_on_new_fbk; + + /* Update the firmware */ + if (cl_msg_tx_set_tx_bf(cl_hw, cl_sta->sta_idx, bf_on_new, bf_on_new_fbk)) + pr_err("%s: failed to set TX-BF\n", __func__); + } +} + +void cl_bf_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct ieee80211_sta *sta) +{ + /* Beamformee capabilities */ + bool su_beamformee_capable = cl_bf_is_beamformee_capable(cl_sta, false); + bool mu_beamformee_capable = cl_bf_is_beamformee_capable(cl_sta, true); + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + WARN_ON_ONCE(sta->rx_nss == 0); + bf_db->beamformee_sts = cl_bf_get_sts(sta); + bf_db->nc = min_t(u8, sta->rx_nss, WRS_SS_MAX) - 1; + cl_sta->su_sid = INVALID_SID; + + bf_pr_trace(cl_hw, + "sta_idx: %u, su_beamformee_capable: %u, mu_beamformee_capable: %u, " + "beamformee_sts: %u, nc = %u\n", + cl_sta->sta_idx, su_beamformee_capable, mu_beamformee_capable, + bf_db->beamformee_sts, bf_db->nc); + + if (bf_db->beamformee_sts == 0) + bf_db->beamformee_sts = 3; + + /* + * Init the BF timer + * Period is set to 0. It will be updated before enabling it. + */ + timer_setup(&bf_db->timer, cl_bf_timer_callback, 0); +} + +void cl_bf_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + /* Disable timer before removing the station */ + del_timer_sync(&bf_db->timer); + + /* + * Remove the sounding sequence associated with the STA and possibly start another sequence + * for other stations that participate in the same sounding sequence with the STA + */ + if (cl_sta->su_sid != INVALID_SID) { + bf_db->sounding_remove_required = true; + cl_sounding_stop_by_sid(cl_hw, cl_sta->su_sid, true); + } +} + +void cl_bf_sta_active(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool active) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + if (bf_db->traffic_active != active) { + bf_pr_trace(cl_hw, "Sta: %u, Active: %s\n", + cl_sta->sta_idx, active ? "True" : " False"); + + bf_db->traffic_active = active; + cl_bf_sounding_decision(cl_hw, cl_sta); + } +} + +void cl_bf_reset_sounding_ind(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + cl_sta->bf_db.sounding_indications = 0; +} + +bool cl_bf_is_enabled(struct cl_hw *cl_hw) +{ + return cl_hw->bf_db.enable; +} + +bool cl_bf_is_on(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 nss) +{ + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + return (cl_bf_is_enabled(cl_hw) && + bf_db->sounding_start && + bf_db->sounding_indications && + (nss <= min(cl_hw->conf->ci_bf_max_nss, bf_db->nc))); +} + +void cl_bf_sounding_req_success(struct cl_hw *cl_hw, struct cl_sounding_info *new_elem) +{ + /* + * Start a timer to check that we are receiving indications from the station. + * The period of the timer is set to 10 times the sounding-interval. + */ + u8 i; + struct cl_sta *cl_sta; + struct cl_bf_sta_db *bf_db; + unsigned long period = CL_SOUNDING_FACTOR * cl_sounding_get_interval(cl_hw); + + for (i = 0; i < new_elem->sta_num; i++) { + cl_sta = new_elem->su_cl_sta_arr[i]; + bf_db = &cl_sta->bf_db; + + if (cl_sta) { + cl_sta->bf_db.sounding_start = true; + cl_sta->su_sid = new_elem->sounding_id; + + /* Don't enable BF timer in case of force mode */ + if (!cl_hw->bf_db.force) + mod_timer(&bf_db->timer, jiffies + msecs_to_jiffies(period)); + } + } +} + +void cl_bf_sounding_req_failure(struct cl_hw *cl_hw, struct cl_sounding_info *new_elem) +{ + u8 i; + struct cl_sta *cl_sta; + struct cl_bf_sta_db *bf_db; + + for (i = 0; i < new_elem->sta_num; i++) { + cl_sta = new_elem->su_cl_sta_arr[i]; + + if (cl_sta) { + bf_db = &cl_sta->bf_db; + bf_db->sounding_start = false; + bf_db->sounding_indications = 0; + } + } +} + +void cl_bf_init(struct cl_hw *cl_hw) +{ + cl_bf_enable(cl_hw, cl_hw->conf->ci_bf_en, false); +} + From patchwork Tue May 24 11:33:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576870 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 B3FA4C433F5 for ; Tue, 24 May 2022 11:37:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236760AbiEXLht (ORCPT ); Tue, 24 May 2022 07:37:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236765AbiEXLhq (ORCPT ); Tue, 24 May 2022 07:37:46 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84D1440A01 for ; Tue, 24 May 2022 04:37:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QhYsoxiOhaDPwPOCV7YqWNPUSrrcElUK85lxUiBvQ6yYPPDJUVGn35sB5GlnQLsCI/KJ0CDZwgfvGPNGf2UN++3lVY+Ykd50eeAAKSsf6qXvRlICdNxhVl4KGIVmO9mlXFW8jp/qQxVfUgPxbUa0CkJ991QIvM8eelfq5va3OFdOSLVdtV9LWZALSszaozDXSaueLSOtJHaDgYWMdjzsYeYhQJoIEwfOSjgt6df1ZDSBwpxsIz0QcZHbNiyqLfkTHUsgB5ZSQrJRl8emJMLvua4B3SiOYkrltFj+LOe8BdRcTTmVzumyQIQV9fRJQUpItXq7wbOBJVWNtPR207jFLg== 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=cNQ6pE+vvFRa6s/LeF2OE00Kc+/AD9sf0peaVC7hHrc=; b=D/Lt6tbQxTvQoXpqGzbGnHGQskSOzx48K9U1gUI4nGVgw/boZbsSvsYLBJ0/zQtbJpcGvDdYsnU2jxBAjXZs+GC5uJyE26NR2jWWeNaTvQ0LnkGixAD2FKsHwju1hDutA5BWTyxm7Em8E9bZSr82o2GQIe23Id910ezFtUvSneJd3rruVJjSoT3GXfQ9tYJ6iFhJ8oHyfVx37gnI9vVasdjQrtRyPdw8qspPSlM1WbR0yFO6KZ4WDRd5u4VnPIglGXf+fSlurAwSww4sPrQlRZglNsUoWL6XTTqbZXW0pK+uUy3gxkn8wFdb1rbJfNjwmB1kVTujqHFj7S2R3sgjMw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cNQ6pE+vvFRa6s/LeF2OE00Kc+/AD9sf0peaVC7hHrc=; b=mVBGq71kA1U3hVih/lLxHW4t6aJbcMj07w7iiK1lOgXq3LmLLVlIntDuK9NCY6Xp7v6gE+SDlKlwH1EkgRkS3UAnDVzWUGndVqCK8UnedG64ZaswFWMbJtxGBUQKyWShwThD+qEjQPnFAkSYRQp3SqDj0WbYHp+/82DfbuGryoU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:41 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:41 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 08/96] cl8k: add bf.h Date: Tue, 24 May 2022 14:33:34 +0300 Message-Id: <20220524113502.1094459-9-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 64f93661-c531-4029-5da4-08da3d79cfc5 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: I3NvIY77cr7+j2pb2o9kCTRo9vr+b2arONAWmn0wjfapuIK8n8PeK/9DgsBicgzsqwo5M8ZT3cQTjsCWOBEg8Jhm1xj452A31cEftqd2vKdn3NunC4N27oSnpwKFSG2SjpX3ixAk5Halah2FFDuuODEbApsFLptHZG6LyIPfHk45+3FIHdUNosV02cLKgHfpT9F76t9z4ocy2mSH/24U2dwgsMRq8LlSnyW/4c0c+CqFv+OW7MyCEZBjmp/mzzvpqSyrYrIaBWOU+AmrU8+7bh/Zk0UUC8Ri5nDUNx9JREFIYSgHZhW1N5xIiWHoBB+sWYIjppEDTkis8Ix094fHUcV/4cd4hJdbzEvcLa06b4GVCEE4P7vtF4yCMUzV3KjVF3RxmOtTHCOjWxTl9U4eJ+jAkG7A6H6I+kVyC5ewo76zEkeMtcooeR8UhgYx8KlkzlKL7pHnbBFfdf0blci4GC/UQlaptEd1pkBhgsRjgGkRpJMRq8ok7mrRojxACCZ6k3togqYufUmxAweY2LlcMBof857rBUgybzBbAMoLxBNLoYYBYPs4OVZRjW63NX2RDX0z++vRDZzHCOnqgKcvKSQ4ph1FcpFddwV4hmDQDi35pKlSVZUwiZEAX9xVb6iPknfHnmLt1OEHuVUCACGT30h2zUjDYMu8IKmmZqWZzxD3o40JENmy/S7T1CPS/7q469YOs+bejQvbu3V7KuN4w6umSAVjJhYZfhgxAQncCJw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: X3Nxbechh5VKzGMr5KA9NmnqBpI3naFwGExx23zxiICnd4RPBUQs2smoBZdCNPkzMAZX3YRSk0QTuQaRTG+4hT/P/SEGly3wuhzsgXyIYdhPz9El0EapwCp/+f4KDSRWBZAsICP4B6G3UoEfzr5MsDW/cVpEBBjOPVTKBXj7ioRi2DpcIoK3506XITmyPZHhfHzSonFE94A/K5ZR9wIS4rBNCUr9r73bJCFOsHPA5WwUqvPsq5unGeXgaKuKz1nfu61rn4YqDfDHP161MqtxZg0oV3GGWHAC0/xX9z4/FJuOXjlHlcl1GYAzc2D+KRdsuwoDu6e4iqryTmf+lfT98GtjLz/s7pFN5VmEmUeXIOYX3bnDZhe61/P4BQVTtsxoRBuZU/JXJLXonkrnx5qmmcdvmCgk8wZU5Ti+qqfQrP+KI8/Ohc5wsHSu48ZRE44M9A+/XzYRDbuUgwSe7hfNyXjckSasdBq6yHXai+wQV7H5f//eR3lnSB7baYj1xOI5tddBsb1ukqsnj+p75XgGIXuVVNwOK6WLJHnexRQNiyi72HfES/Ej7fH6x8EqopXEtwLEVokacet1PxXS0/GEv4RBEYw6zQ3yVY+bLjU7+KbLv9cj33fLHSILgwWdJdCJRuy3cXV8/atVWuOYuSS6q6qA4Y/5xDmH10qkXDqnrBtumIOTiI9YjEg8E2sn0ZY8caGlO7uNwKPJH7GuewcgydrVDJAQKuZB4398xa/0wJoB6fmmZ9cVEgYbWsK5xeqAWbYhRLbnLRvVK6FNcYb72LBupncAobZLbCF2vsUJx5R+DZqk/yBYGJOKfJlXY5PYe7I2Pc9M65Oab2KpsKKFJD8Kcjm24vvbKX82QxfNczwS4Eozkf5ZZ0UP4uCcX/wvOYwCv7XmFFm5ApzYydatylcPQKwT0I0HCwoIOQxwGjtKU30fVtLlZm4lsYHZGRwCgpA0QISoBlxG/4nWxbmT2B1m6qNpjGeM8hRvRYHCiSX0hFg5qwSY4tKSJfpxJwiLiQ8I/O+WLmHTnU1FTPzboIwHdxRMsGdZsAa083ye58YBCGrnMdW8FpbvdCGLhgvBNYhNdXU+cjlc+otNxsyfQvmA2nOz4Z4gSNh+XfX81gUiWo6oIp8F9lGp49cAQJ8GWuheYZT95wdA28A2u2MofxGXOwrj2wjwis19hrlVMtLAnzlxarYVHsDAHY3d/3qhBnitU+OQ7I0OU8LLHoGHFbLLhoDa45Jdcfo2nh10Bctvfdy3OVRHCBTXmUbSLTGQGe/OQ5Ca+IVCIJWGNEtaZYokh0Yy54cIk45Ef4E0SiBOXchuQT1eLJCCL8aDBQx7+OPL2BoimIYaBRuo2GU91Gsoa7SivEZjN7U5UYJ7DoJD6+te41fmyHC3BRUN9OU0yCliposmhAiv/zmSn3/Xv0NlpvYr2njAP7tl7lwSQjs28HEJo1yO3yNd65hDaVEtwSHPY+izfTVWTiY2oHZN5ZXBT/PMcwBoRyesqlU5tt0VezuFIS3N63fs7CduV7RigNvcNrHoy5LLcOEaOXlkUWI1PesY+FbiijrU9Zk1wFpSxsM1xm0AkDFP4uLgXqZG2MPzGguUzUmv0+AEtTM5Y4tNIn5+cnJVx8l1cq1O2yIdmvezEJEqVerkUd9Miigf0ORLyYrI5O6R7Nu7NuV7tqM7O5O+dW2I4AjJGWfIB26asW48bDtwy7L5H9JIVPi7U+aamtdC02JFVcy+kHU2HWiSOd9PGpOVToUh4fuuxVM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 64f93661-c531-4029-5da4-08da3d79cfc5 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:41.3907 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: rVGt1lrUHsTl2/zyHk6OgWDWqa816rEFqqmMKGfmtJZ8Pr5pKV6PmYahEvrYlq9jlwTKHxPezL5onSMwOOr/Kg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/bf.h | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/bf.h diff --git a/drivers/net/wireless/celeno/cl8k/bf.h b/drivers/net/wireless/celeno/cl8k/bf.h new file mode 100644 index 000000000000..efe433f55f7f --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/bf.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_BF_H +#define CL_BF_H + +#include "debug.h" +#include "sounding.h" + +/* + * BF (=BeamForming, 802.11) + */ + +struct cl_bf_db { + bool enable; + bool force; + enum cl_dbg_level dbg_level; +}; + +struct cl_bf_sta_db { + bool traffic_active; + bool sounding_start; + bool sounding_remove_required; + bool indication_timeout; + bool synced; + bool is_on; + bool is_on_fallback; + u8 num_ss; + u8 num_ss_fallback; + u8 beamformee_sts; + u8 nc; + u32 sounding_indications; + struct timer_list timer; +}; + +void cl_bf_init(struct cl_hw *cl_hw); +void cl_bf_update_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_bf_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct ieee80211_sta *sta); +void cl_bf_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_bf_sta_active(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool active); +void cl_bf_reset_sounding_ind(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +bool cl_bf_is_enabled(struct cl_hw *cl_hw); +bool cl_bf_is_on(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 nss); +void cl_bf_enable(struct cl_hw *cl_hw, bool enable, bool trigger_decision); +void cl_bf_sounding_start(struct cl_hw *cl_hw, enum sounding_type type, struct cl_sta **cl_sta_arr, + u8 sta_num, struct cl_sounding_info *recovery_elem); +void cl_bf_sounding_stop(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_bf_sounding_decision(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_bf_sounding_req_success(struct cl_hw *cl_hw, struct cl_sounding_info *new_elem); +void cl_bf_sounding_req_failure(struct cl_hw *cl_hw, struct cl_sounding_info *new_elem); + +#endif /* CL_BF_H */ From patchwork Tue May 24 11:33:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575987 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 7D2C1C433F5 for ; Tue, 24 May 2022 11:37:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236779AbiEXLhy (ORCPT ); Tue, 24 May 2022 07:37:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236765AbiEXLhx (ORCPT ); Tue, 24 May 2022 07:37:53 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82A7C50440 for ; Tue, 24 May 2022 04:37:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nWb1HP9cWdqeKVdp4Yyj+ztXk7OqholIx11fpios0ZATVIxmm/dZH6ndmWZ24jLitf51uOaTEizbahUyGT6PnuyLxyR17Q5eA01a3k8U3NBsTWnrbGAkWPAYrStEBiRQMJNr6AJlMh+dzb7w63N0eX/RGcP6yKbAtowrpsO444kipFoT3arvDbX0fSI1eQtGQT1nfWKN5aVIgW9YYo6nicRMa3xVVXhwEOQHtcGfKmAb01TUc7iu1K9+axhpZajbabdP9HYqvAxKnYZ2fw2RW59TqF5ksmT+HE2pc/E+ARRCDOsoD4ND5DWPlUyvhTgcBPpd+BLNmJb+fl2VY7rbaw== 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=Qzv2jPsnGYTcfr/HotGEQgGPAUtEydE8OCifMXELhRo=; b=R3VsxQrjCFdlzBSGgZImNs85xtLjxzznHkc7mjj64Q/J3ctPDpyqH42C+3OIv1scRriTq2qQ2ZizunVWBE0PpiGmekBkWOqEguAZnjRz7P2QJ3y2c09l8yQYRDyM3dmp14ml7/hWWdapn13cKu3yuFJPvib9oE1ZjNozYF8vrKJq11NB2PJ1MB0dnDiqMJdstW/H6RG3o0sYMXYRZ9pytwbyDdZydiqpExRMMK6PeLtE0KqCTHydYpHIZ7YXs2Xs/mJHWyHZsBudSygvnuPblkq7Pfl9xmeAmdYNSXX8qbEhLu9eyQnL8lHwcC+uLEyXb4H06CYIKoeZ80Ns+baIhw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Qzv2jPsnGYTcfr/HotGEQgGPAUtEydE8OCifMXELhRo=; b=Rb4HXqrvF1eF1zVtbJgAdipRRSmjoJrKwle1q+fsMqPNAcBm+8hS4f0s565cfPHT1+F7AwsCj09Nll15RjMmx4jQXeubvvPPLl88hdi8HETJ1H3CRFlznW2aMSNb8ptAR7NS3WxVtE73t/72O506JrrGtac/xynorDs6lMcVqGU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:43 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:42 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 09/96] cl8k: add calib.c Date: Tue, 24 May 2022 14:33:35 +0300 Message-Id: <20220524113502.1094459-10-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 33932f94-65a8-4498-a0a6-08da3d79d030 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oGi6FNcJqR3HhOL7APO14hdCjxgmw3buh9z9ZtC634x3/pzhGfp76XZMKKYQHdKpvTAal7fgbf4gRjwlH6uxOHtWd0/zdURl0lfhaKHA+lcLeiIDoyK3YzuNpZ1IRqYAS9LIpq68C8HpZc3yspbYy5F2sljxZPkwUXh8RLsTF1itCJc+XRv2TMoMS1RgHv3ZemIopFBhXpnqIFGXxngp0tO/MQ6kp7ge0NigxEcjk3WEknN93lITHXU58u0NaStPCAhJG96i6/FohxTxX3n5dLjAbWTmvAv33bxDEMIh2Z//gwQxMQTD1AIRkwr4d9mIYf54uJBJOiympU2P5uSb3SV9NBKRAAXv5VDrznosJscoGGVnGrhuLSHuTLBhGwZAP0g16/S6w2krzZUO5XIUl224e8+AopFY+faeVOoDDOluV+b0oCEvrnQEYG5UzfP362vOQQpvO7ge+nWUz1ev6xfLAdiA5vKchMaiOrWyLuvdpov9IgwreHWCOjo/COAyCoq7nJ+qLSC+CIX5M+1iF0UuPR3ewGk0uarCg2TrXZGKzGPio0nOxEUCfjbnS6NusoFdghnRdq8leKvFlpj28oFT2naAyr6c/4We8+aPeTIPe6QMZ95lTpRSX+meRMpvyeJfCWo1WE3WUrzqlwsb1sy+IJQiv2paQ5aTmynFyONDXoH2kYi8Po9QJ4aSOUB2YOkyEm5plfWyXaeV2+D13n2jTyFyaj11FMWhmsNF/krV00K4K+U1fGnm9HBzAPgs X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(30864003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001)(579004)(559001)(309714004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: oDC0Q6m1I4eYXdrkfqHkjY/fbZdKk4e6y+EYiMRQ89zBdGm0uEe3urVh/dH4qwBESu0gkcxLPRidaTH11KTaeMPcPXjg3GFc+HriKCjIhcx3/lX9glved0Gxef01nR15w1gxW3727as8IP/ROvMLQnMb1zPAKxBTu0QDvrGVhQFPrLsYdSEggrciVAzc8TA0LAxQVUrcXamXU+V5CW7JXEMO9DA3g5wS36lqZi4KEe4OtpM3xXbmeG6uzwhSai+Kt3utmM/iRCvbuZHZ2MDyrE97YvNfdD8LxR2tzacJbuua+Y5LU9pr5Poo0wuimSGJX5hVlf5Ig33N65FFc3T5sMoGMonXDz0rn/p3+PtzRG9sP8SiSVv50RPu2F/bTnSEn9GnT2QewIPxfTZXnzXTeUG7thzjHKZw7r+4xv5IIJIrST/tK6lwxdKpVtieov2m8yoMwJ/AYFRvW2s6MRK/p8yVJlNPZGIfDAuoKxuG85+aco4fcovLueQgoPKtQZ/bNy7a68vuHpecZirv/SnO9+H2lH45KLwgEikTURybta70hoUEe+DLDYk99Z/ra1jlRCrZJghS7Fw8dikwlVcTcIdRAwd03jBQ9e5EGuMIaWa3kPUEHE0E4CQYVKNpG+uCD2x+p6zbgZ5tEEXjeUn9Nyk9aqgC/5poq+AG9HG7ar/2J+XtRD5rp4UirIe+lXgRi4mhaWaL/V3FOwkvIYMmJyDySAzo63Rgt9XqZ/NISa+48Ui41RBv99p+d34cBwmidJ7VOidNuuyKLQixHWV2zrZWuOI0GBnx0JEBStTuJa5x+BNQYrZDF1rw48Db6AHIV14AbZTN36+VJ3l3KIDg+M3Q8wcvGtfMI3Tzkv/sJtFQzqBFbFvw0pCG0jE1bnFrl7KQeO7EkMmn+wD1M0PGD005WTCdpOWbU+JZBsWr7OCHJZV026DHJ/wWC8TwlR79eHIrK+Uu7cg2YYOQhuvEmwhTPeQNeB+GxKWbJvhPzTO2Xbn71PdNtSOfW24UNYVk8vFZXrkLOStY7p7WvEdEYhzvzuq0RjCxzzIz4vm1mCy3XL+YwYxI5EjHY2eD58h1mHsB9fSy1zPeKEgdo7RRga6d9MBMXYe2Q3duG5W1xa/XiWAxOUlMZCApGk/0zklLzLm1arwQBzBGduMIh8SucfMKZnmreL/aU0NxMJiRIvvDY9iUxlSavdz1qqtnpYRy6k1oTnnvBM/d8bMBsarXsLjt91IDNRMgLUsci6JGQHKIy1H8Cams59s+GV4SQXUUC5jkFvDsBmLdvLv7nH8eCYFBF5Zq9MLgGIxN5PFVN/UYBozHga2KSnQ8ejKvLNlQciTkEAbm/bKLkO7T0DshdtSpyi0WDjcvXZa2bfGjUSGqKYQ0Q4z18gVdE0sysf7ku0v685LK035euT7kMdXBCbC3BZ8j5K3S+mbHUWYYJweIFluyRdjJ0UPr2ZomN13U+SuKKHojQ1fkspOaV8xI5KArwHbfimWoJoFGgrdU61kBBtPP3i0RPyUnW27oUmEBmynbp56XO+qI3WjSzNUWt0ybTGU3udtFsaWqcexgvTrkwBnByk5UBUy8mL3dQBPDETbCSg8pKuQCH45P1ZcGPoYppSY9I6I/fOx4MBbVRTyrVr26pHFyVtMBMOKXhPtWF2IwmX1RHmbG9DfJbHSnjUy8g3Ty0p4vv0U5n8c9AnTg5IJqGZ0TMXHyIPn5VtxLTBRQeo1lqHBIxZSNbDW9K8vpUu9D99w6T/s7nEJLPNg= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 33932f94-65a8-4498-a0a6-08da3d79d030 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:42.1874 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 44y7XGjEJGs85OUsGZW4+iXtObur3FXcNV6hgAqoxnLTo8l97ZMRKLt+WndOf6yXr8r5hh4fK6D/1cU6ziVajA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/calib.c | 2266 ++++++++++++++++++++++ 1 file changed, 2266 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/calib.c diff --git a/drivers/net/wireless/celeno/cl8k/calib.c b/drivers/net/wireless/celeno/cl8k/calib.c new file mode 100644 index 000000000000..93fe6a2e00ee --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/calib.c @@ -0,0 +1,2266 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_defs.h" +#include "chip.h" +#include "config.h" +#include "radio.h" +#include "e2p.h" +#include "rfic.h" +#include "debug.h" +#include "utils.h" +#include "calib.h" + +static void cl_calib_common_init_cfm(struct cl_iq_dcoc_data *iq_dcoc_data) +{ + int i; + + for (i = 0; i < CALIB_CFM_MAX; i++) + iq_dcoc_data->dcoc_iq_cfm[i].status = CALIB_FAIL; +} + +void cl_calib_common_fill_phy_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db, + u8 flags) +{ + struct cl_chip *chip = cl_hw->chip; + u8 bw = cl_hw->bw; + u8 channel_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, cl_hw->channel, bw); + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + + if (flags & SET_PHY_DATA_FLAGS_DCOC) + cl_calib_dcoc_fill_data(cl_hw, iq_dcoc_db); + + if (flags & SET_PHY_DATA_FLAGS_IQ_TX_LOLC) + cl_calib_iq_lolc_fill_data(cl_hw, iq_dcoc_db->iq_tx_lolc); + + if (flags & SET_PHY_DATA_FLAGS_IQ_TX) + cl_calib_iq_fill_data(cl_hw, iq_dcoc_db->iq_tx, + chip->calib_db.iq_tx[tcv_idx][channel_idx][bw][sx]); + + if (flags & SET_PHY_DATA_FLAGS_IQ_RX) + cl_calib_iq_fill_data(cl_hw, iq_dcoc_db->iq_rx, + chip->calib_db.iq_rx[tcv_idx][channel_idx][bw][sx]); +} + +int cl_calib_common_tables_alloc(struct cl_hw *cl_hw) +{ + struct cl_iq_dcoc_data *buf = NULL; + u32 len = sizeof(struct cl_iq_dcoc_data); + dma_addr_t phys_dma_addr; + + buf = dma_alloc_coherent(cl_hw->chip->dev, len, &phys_dma_addr, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + cl_hw->iq_dcoc_data_info.iq_dcoc_data = buf; + cl_hw->iq_dcoc_data_info.dma_addr = phys_dma_addr; + + cl_calib_common_init_cfm(cl_hw->iq_dcoc_data_info.iq_dcoc_data); + return 0; +} + +void cl_calib_common_tables_free(struct cl_hw *cl_hw) +{ + struct cl_iq_dcoc_data_info *iq_dcoc_data_info = &cl_hw->iq_dcoc_data_info; + u32 len = sizeof(struct cl_iq_dcoc_data); + dma_addr_t phys_dma_addr = iq_dcoc_data_info->dma_addr; + + if (!iq_dcoc_data_info->iq_dcoc_data) + return; + + dma_free_coherent(cl_hw->chip->dev, len, (void *)iq_dcoc_data_info->iq_dcoc_data, + phys_dma_addr); + iq_dcoc_data_info->iq_dcoc_data = NULL; +} + +static void _cl_calib_common_start_work(struct work_struct *ws) +{ + struct cl_calib_work *calib_work = container_of(ws, struct cl_calib_work, ws); + struct cl_hw *cl_hw = calib_work->cl_hw; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + struct cl_chip *chip = cl_hw->chip; + + cl_calib_iq_init_calibration(cl_hw); + + if (cl_chip_is_both_enabled(chip)) + cl_calib_iq_init_calibration(cl_hw_other); + + /* Start cl_radio_on after calibration ends */ + cl_radio_on_start(cl_hw); + + if (cl_chip_is_both_enabled(chip)) + cl_radio_on_start(cl_hw_other); + + kfree(calib_work); +} + +void cl_calib_common_start_work(struct cl_hw *cl_hw) +{ + struct cl_calib_work *calib_work = kzalloc(sizeof(*calib_work), GFP_ATOMIC); + + if (!calib_work) + return; + + calib_work->cl_hw = cl_hw; + INIT_WORK(&calib_work->ws, _cl_calib_common_start_work); + queue_work(cl_hw->drv_workqueue, &calib_work->ws); +} + +s16 cl_calib_common_get_temperature(struct cl_hw *cl_hw, u8 cfm_type) +{ + struct calib_cfm *dcoc_iq_cfm = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->dcoc_iq_cfm[cfm_type]; + u16 raw_bits = (le16_to_cpu(dcoc_iq_cfm->raw_bits_data_0) + + le16_to_cpu(dcoc_iq_cfm->raw_bits_data_1)) / 2; + + return cl_temperature_calib_calc(cl_hw, raw_bits); +} + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +static u16 cl_calib_common_eeprom_get_idx(struct cl_hw *cl_hw, int bw_idx, u16 channel, + u16 channels_plan[], u8 num_of_channels) +{ + int i; + + for (i = 0; i < num_of_channels; i++) + if (channels_plan[i] == channel) + return i; + + return U16_MAX; +} + +static u16 cl_calib_common_eeprom_get_addr(struct cl_hw *cl_hw, int bw_idx, u16 channel) +{ + int idx = 0; + u16 addr = 0; + u16 *channels; + u8 num_of_channels; + + switch (bw_idx) { + case CHNL_BW_20: + channels = cl_hw->conf->ci_calib_eeprom_channels_20mhz; + + if (cl_hw_is_tcv0(cl_hw)) { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV0; + } else { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV1; + } + break; + case CHNL_BW_40: + channels = cl_hw->conf->ci_calib_eeprom_channels_40mhz; + + if (cl_hw_is_tcv0(cl_hw)) { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV0; + } else { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV1; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV1; + } + break; + case CHNL_BW_80: + channels = cl_hw->conf->ci_calib_eeprom_channels_80mhz; + + if (cl_hw_is_tcv0(cl_hw)) { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0; + } else { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1; + } + break; + case CHNL_BW_160: + channels = cl_hw->conf->ci_calib_eeprom_channels_80mhz; + + if (cl_hw_is_tcv0(cl_hw)) { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0; + } else { + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1; + idx = cl_calib_common_eeprom_get_idx(cl_hw, bw_idx, channel, channels, + num_of_channels); + addr = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1; + } + break; + default: + return U16_MAX; + } + + if (idx == U16_MAX) + return U16_MAX; + + return ((u16)addr + (u16)(idx * sizeof(struct eeprom_calib_data))); +} + +static void cl_calib_common_write_lolc_to_eeprom(struct cl_calib_db *calib_db, + struct eeprom_calib_data *calib_data, + u8 ch_idx, u8 bw, u8 sx_idx, u8 tcv_idx) +{ + memcpy(calib_data->lolc, + calib_db->iq_tx_lolc[tcv_idx][ch_idx][bw][sx_idx], + sizeof(u32) * MAX_ANTENNAS); +} + +static void cl_calib_common_write_dcoc_to_eeprom(struct cl_calib_db *calib_db, + struct eeprom_calib_data *calib_data, + u8 ch_idx, u8 bw, u8 sx_idx, u8 tcv_idx) +{ + memcpy(calib_data->dcoc, + calib_db->dcoc[tcv_idx][ch_idx][bw][sx_idx], + sizeof(struct cl_dcoc_calib) * MAX_ANTENNAS * DCOC_LNA_GAIN_NUM); +} + +static void cl_calib_common_write_iq_to_eeprom(struct cl_calib_db *calib_db, + struct eeprom_calib_data *calib_data, + u8 ch_idx, u8 bw, u8 sx_idx, u8 tcv_idx) +{ + memcpy(calib_data->iq_tx, + calib_db->iq_tx[tcv_idx][ch_idx][bw][sx_idx], + sizeof(struct cl_iq_calib) * MAX_ANTENNAS); + memcpy(calib_data->iq_rx, + calib_db->iq_rx[tcv_idx][ch_idx][bw][sx_idx], + sizeof(struct cl_iq_calib) * MAX_ANTENNAS); +} + +static s8 cl_calib_common_find_worst_iq_tone(struct cl_iq_report iq_report_dma) +{ + u8 tone = 0; + s8 worst_tone = S8_MIN; + + for (tone = 0; tone < IQ_NUM_TONES_CFM; tone++) + if (worst_tone < iq_report_dma.ir_db[IQ_POST_IDX][tone]) + worst_tone = iq_report_dma.ir_db[IQ_POST_IDX][tone]; + + return worst_tone; +} + +static void cl_calib_common_write_score_dcoc(struct cl_hw *cl_hw, + struct eeprom_calib_data *calib_data) +{ + u8 lna, ant; + + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + struct cl_dcoc_report *dcoc_calib_report = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->report.dcoc[lna][ant]; + + calib_data->score[ant].dcoc_i_mv[lna] = + (s16)le16_to_cpu(dcoc_calib_report->i_dc); + calib_data->score[ant].dcoc_q_mv[lna] = + (s16)le16_to_cpu(dcoc_calib_report->q_dc); + } + } +} + +static void cl_calib_common_write_score_lolc(struct cl_hw *cl_hw, + struct eeprom_calib_data *calib_data) +{ + u8 ant; + struct cl_iq_dcoc_report *report = &cl_hw->iq_dcoc_data_info.iq_dcoc_data->report; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + calib_data->score[ant].lolc_score = + (s16)(le16_to_cpu(report->lolc_report[ant].lolc_qual)) >> 8; + } +} + +static void cl_calib_common_write_score_iq(struct cl_hw *cl_hw, + struct eeprom_calib_data *calib_data) +{ + u8 ant; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + struct cl_iq_report iq_report_dma_tx = + cl_hw->iq_dcoc_data_info.iq_dcoc_data->report.iq_tx[ant]; + struct cl_iq_report iq_report_dma_rx = + cl_hw->iq_dcoc_data_info.iq_dcoc_data->report.iq_rx[ant]; + + calib_data->score[ant].iq_tx_score = iq_report_dma_tx.ir_db_avg_post; + calib_data->score[ant].iq_rx_score = iq_report_dma_rx.ir_db_avg_post; + calib_data->score[ant].iq_tx_worst_score = + cl_calib_common_find_worst_iq_tone(iq_report_dma_tx); + calib_data->score[ant].iq_rx_worst_score = + cl_calib_common_find_worst_iq_tone(iq_report_dma_rx); + } +} + +static void cl_calib_common_write_score_to_eeprom(struct cl_hw *cl_hw, + struct eeprom_calib_data *calib_data) +{ + cl_calib_common_write_score_dcoc(cl_hw, calib_data); + cl_calib_common_write_score_lolc(cl_hw, calib_data); + cl_calib_common_write_score_iq(cl_hw, calib_data); +} + +static void cl_calib_common_write_eeprom(struct cl_hw *cl_hw, u32 channel, u8 bw, u8 sx_idx, + u8 tcv_idx) +{ + u8 ch_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel, bw); + u16 eeprom_addr = cl_calib_common_eeprom_get_addr(cl_hw, bw, channel); + struct eeprom_calib_data calib_data; + struct cl_calib_db *calib_db = &cl_hw->chip->calib_db; + + if (eeprom_addr == U16_MAX) + return; + + calib_data.valid = true; + calib_data.temperature = cl_calib_common_get_temperature(cl_hw, CALIB_CFM_IQ); + cl_calib_common_write_lolc_to_eeprom(calib_db, &calib_data, ch_idx, bw, sx_idx, tcv_idx); + cl_calib_common_write_dcoc_to_eeprom(calib_db, &calib_data, ch_idx, bw, sx_idx, tcv_idx); + cl_calib_common_write_iq_to_eeprom(calib_db, &calib_data, ch_idx, bw, sx_idx, tcv_idx); + cl_calib_common_write_score_to_eeprom(cl_hw, &calib_data); + + cl_e2p_write(cl_hw->chip, (u8 *)&calib_data, (u16)sizeof(struct eeprom_calib_data), + eeprom_addr); +} + +static bool cl_calib_common_is_channel_included_in_eeprom_bitmap(struct cl_hw *cl_hw) +{ + u16 i; + u16 *eeprom_valid_ch = NULL; + u16 num_of_channels; + + switch (cl_hw->bw) { + case CHNL_BW_20: + eeprom_valid_ch = cl_hw->conf->ci_calib_eeprom_channels_20mhz; + + if (cl_hw_is_tcv0(cl_hw)) + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0; + else + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1; + break; + case CHNL_BW_40: + eeprom_valid_ch = cl_hw->conf->ci_calib_eeprom_channels_40mhz; + + if (cl_hw_is_tcv0(cl_hw)) + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0; + else + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1; + break; + case CHNL_BW_80: + eeprom_valid_ch = cl_hw->conf->ci_calib_eeprom_channels_80mhz; + + if (cl_hw_is_tcv0(cl_hw)) + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0; + else + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1; + break; + case CHNL_BW_160: + eeprom_valid_ch = cl_hw->conf->ci_calib_eeprom_channels_160mhz; + + if (cl_hw_is_tcv0(cl_hw)) + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0; + else + num_of_channels = EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1; + break; + default: + return false; + } + for (i = 0; i < num_of_channels; i++) + if (cl_hw->channel == eeprom_valid_ch[i]) + return true; + + return false; +} +#endif /* CONFIG_CL8K_EEPROM_STM24256 */ + +int cl_calib_common_handle_set_channel_cfm(struct cl_hw *cl_hw, struct cl_calib_params calib_params) +{ + struct cl_iq_dcoc_data *iq_dcoc_data = cl_hw->iq_dcoc_data_info.iq_dcoc_data; + u8 mode = calib_params.mode; + + cl_dbg_trace(cl_hw, "\n ------ FINISH CALIB CHANNEL -----\n"); + + /* + * In case any of the requested calibrations failed - no need to copy + * the other Calibration data, and fail the whole calibration process. + */ + if ((mode & SET_CHANNEL_MODE_CALIB_DCOC && + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_DCOC].status != CALIB_SUCCESS) || + (mode & SET_CHANNEL_MODE_CALIB_IQ && + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_IQ].status != CALIB_SUCCESS)) { + cl_dbg_err(cl_hw, "Calibration failed! mode = %u, DCOC_CFM_STATUS = %u, " + "IQ_CFM_STATUS = %u\n", mode, + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_DCOC].status, + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_IQ].status); + /* Set status to CALIB_FAIL to ensure that FW is writing the values. */ + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_DCOC].status = CALIB_FAIL; + iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_IQ].status = CALIB_FAIL; + return -EINVAL; + } + + cl_dbg_trace(cl_hw, "mode = %u\n", mode); + + if (mode & SET_CHANNEL_MODE_CALIB_DCOC) + cl_calib_dcoc_handle_set_channel_cfm(cl_hw, calib_params.first_channel); + + if (mode & SET_CHANNEL_MODE_CALIB_IQ) + cl_calib_iq_handle_set_channel_cfm(cl_hw, calib_params.plan_bitmap); + + if (mode & SET_CHANNEL_MODE_CALIB_LOLC) + cl_calib_iq_lolc_handle_set_channel_cfm(cl_hw, calib_params.plan_bitmap); + +#ifdef CONFIG_CL8K_EEPROM_STM24256 + if (cl_hw->chip->conf->ci_calib_eeprom_en && cl_hw->chip->conf->ce_production_mode && + cl_hw->chip->is_calib_eeprom_loaded && cl_hw->chip->conf->ce_calib_runtime_en) + if (cl_calib_common_is_channel_included_in_eeprom_bitmap(cl_hw)) + cl_calib_common_write_eeprom(cl_hw, cl_hw->channel, cl_hw->bw, + cl_hw->sx_idx, cl_hw->tcv_idx); +#endif + + return 0; +} + +int cl_calib_common_check_errors(struct cl_hw *cl_hw) +{ + u8 tcv_idx = cl_hw->tcv_idx; + u16 dcoc_erros = cl_hw->chip->calib_db.errors[tcv_idx].dcoc; + u16 lolc_erros = cl_hw->chip->calib_db.errors[tcv_idx].lolc; + u16 iq_tx_erros = cl_hw->chip->calib_db.errors[tcv_idx].iq_tx; + u16 iq_rx_erros = cl_hw->chip->calib_db.errors[tcv_idx].iq_rx; + + if (!cl_hw->chip->conf->ci_calib_check_errors) + return 0; + + if (dcoc_erros > 0 || lolc_erros > 0 || iq_tx_erros > 0 || iq_rx_erros > 0) { + CL_DBG_ERROR(cl_hw, "Abort: dcoc_erros %u, lolc_erros %u," + " iq_tx_erros %u, iq_rx_erros %u\n", + dcoc_erros, lolc_erros, iq_tx_erros, iq_rx_erros); + return -ECANCELED; + } + + return 0; +} + +static const u8 calib_channels_24g[CALIB_CHAN_24G_MAX] = { + 1, 6, 11 +}; + +static const u8 calib_channels_5g_plan[CALIB_CHAN_5G_PLAN] = { + 36, 52, 100, 116, 132, 149 +}; + +static const u8 calib_channels_6g_plan[CALIB_CHAN_6G_PLAN] = { + 1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225 +}; + +static const u8 calib_channels_5g_bw_20[] = { + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161, 165 +}; + +static const u8 calib_channels_5g_bw_40[] = { + 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, 149, 157 +}; + +static const u8 calib_channels_5g_bw_80[] = { + 36, 52, 100, 116, 132, 149 +}; + +static const u8 calib_channels_5g_bw_160[] = { + 36, 100 +}; + +static const u8 calib_channels_6g_bw_20[] = { + 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, + 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233 +}; + +static const u8 calib_channels_6g_bw_40[] = { + 1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121, 129, 137, 145, 153, 161, + 169, 177, 185, 193, 201, 209, 217, 225 +}; + +static const u8 calib_channels_6g_bw_80[] = { + 1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225 +}; + +static const u8 calib_channels_6g_bw_160[] = { + 1, 33, 65, 97, 129, 161, 193, 225 +}; + +static void cl_calib_dcoc_handle_data(struct cl_hw *cl_hw, s16 calib_temperature, u8 channel, u8 bw) +{ + struct cl_chip *chip = cl_hw->chip; + int lna, chain; + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + u8 channel_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel, bw); + struct cl_dcoc_calib *dcoc_calib; + struct cl_dcoc_calib *dcoc_calib_dma; + + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + riu_chain_for_each(chain) { + dcoc_calib = + &chip->calib_db.dcoc[tcv_idx][channel_idx][bw][sx][chain][lna]; + dcoc_calib_dma = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->iq_dcoc_db.dcoc[lna][chain]; + dcoc_calib->i = dcoc_calib_dma->i; + dcoc_calib->q = dcoc_calib_dma->q; + } + } +} + +static void cl_calib_dcoc_handle_report(struct cl_hw *cl_hw, s16 calib_temperature, + int channel, u8 bw) +{ + struct cl_chip *chip = cl_hw->chip; + int lna, chain; + struct cl_dcoc_report *dcoc_calib_report_dma; + int bw_mhz = BW_TO_MHZ(bw); + u8 dcoc_threshold = chip->conf->ci_dcoc_mv_thr[bw]; + s16 i, q; + + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + riu_chain_for_each(chain) { + dcoc_calib_report_dma = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->report.dcoc[lna][chain]; + + i = (s16)le16_to_cpu(dcoc_calib_report_dma->i_dc); + q = (s16)le16_to_cpu(dcoc_calib_report_dma->q_dc); + + if (abs(i) > dcoc_threshold || abs(q) > dcoc_threshold) { + cl_dbg_warn(cl_hw, + "Warning: DCOC value exceeds threshold [%umV]: channel %u, bw = %u, lna = %u, chain = %u, I[mV] = %d, I[Iter] = %u, Q[mV] = %d, Q[Iter] = %u\n", + dcoc_threshold, channel, bw_mhz, lna, chain, i, + le16_to_cpu(dcoc_calib_report_dma->i_iterations), q, + le16_to_cpu(dcoc_calib_report_dma->q_iterations)); + chip->calib_db.errors[cl_hw->tcv_idx].dcoc++; + } + } + } +} + +static int cl_calib_dcoc_calibrate_channel(struct cl_hw *cl_hw, u32 channel, u32 bw, + bool first_channel) +{ + u32 primary = 0; + u32 center = 0; + enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20; + struct cl_calib_params calib_params = {SET_CHANNEL_MODE_CALIB_DCOC, first_channel, 0, 0}; + + if (cl_chandef_calc(cl_hw, channel, bw, &width, &primary, ¢er)) { + cl_dbg_err(cl_hw, "cl_chandef_calc failed\n"); + return -EINVAL; + } + + cl_dbg_trace(cl_hw, "\n ------ START CALIB DCOC CHANNEL -----\n"); + cl_dbg_trace(cl_hw, "channel = %u first_channel = %u\n", channel, first_channel); + + /* Set Channel Mode to DCOC Calibration Mode */ + return cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, calib_params); +} + +static void cl_calib_dcoc_average(struct cl_chip *chip, u8 tcv_idx, u8 center, + u8 bw, u8 chain, u8 sx, u8 lna) +{ + struct cl_dcoc_calib *dcoc_db_left; + struct cl_dcoc_calib *dcoc_db_center; + struct cl_dcoc_calib *dcoc_db_right; + u8 left_idx = cl_calib_dcoc_tcv_channel_to_idx(chip, tcv_idx, + calib_channels_6g_plan[center - 1], bw); + u8 center_idx = cl_calib_dcoc_tcv_channel_to_idx(chip, tcv_idx, + calib_channels_6g_plan[center], bw); + u8 right_idx = cl_calib_dcoc_tcv_channel_to_idx(chip, tcv_idx, + calib_channels_6g_plan[center + 1], bw); + + dcoc_db_left = &chip->calib_db.dcoc[tcv_idx][left_idx][bw][sx][chain][lna]; + dcoc_db_center = &chip->calib_db.dcoc[tcv_idx][center_idx][bw][sx][chain][lna]; + dcoc_db_right = &chip->calib_db.dcoc[tcv_idx][right_idx][bw][sx][chain][lna]; + + dcoc_db_center->i = (dcoc_db_left->i + dcoc_db_right->i) / 2; + dcoc_db_center->q = (dcoc_db_left->q + dcoc_db_right->q) / 2; +} + +static int cl_calib_dcoc_calibrate_6g(struct cl_hw *cl_hw) +{ + int i; + u8 chain, lna; + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = tcv_idx; + bool first_channel = true; + struct cl_chip *chip = cl_hw->chip; + + /* Calibrate channels: 1, 33, 65, 97, 129, 161, 193, 225 */ + for (i = 0; i < CALIB_CHAN_6G_PLAN; i += 2) { + if (cl_hw->conf->ci_cap_bandwidth == CHNL_BW_160 && + (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_160, + first_channel) == 0)) + first_channel = false; + + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_80, + first_channel) == 0) + first_channel = false; + + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + /* + * For these channels 17, 49, 81, 113, 145, 177, 209 + * calculate average of closest neighbors + */ + for (i = 1; i < CALIB_CHAN_6G_PLAN - 1; i += 2) + riu_chain_for_each(chain) + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + cl_calib_dcoc_average(chip, tcv_idx, i, CHNL_BW_80, + chain, sx, lna); + cl_calib_dcoc_average(chip, tcv_idx, i, CHNL_BW_20, + chain, sx, lna); + } + + return first_channel; +} + +static int cl_calib_dcoc_calibrate_5g(struct cl_hw *cl_hw) +{ + int i; + bool first_channel = true; + + if (cl_hw->conf->ci_cap_bandwidth == CHNL_BW_160) { + if (cl_calib_dcoc_calibrate_channel(cl_hw, 36, CHNL_BW_160, first_channel) == 0) + first_channel = false; + + if (cl_calib_dcoc_calibrate_channel(cl_hw, 100, CHNL_BW_160, first_channel) == 0) + first_channel = false; + } + + for (i = 0; i < CALIB_CHAN_5G_PLAN; i++) { + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_5g_plan[i], CHNL_BW_80, + first_channel) == 0) + first_channel = false; + + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_5g_plan[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + return first_channel; +} + +static int cl_calib_dcoc_calibrate_24g(struct cl_hw *cl_hw) +{ + int i; + bool first_channel = true; + + for (i = 0; i < CALIB_CHAN_24G_MAX; i++) { + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_24g[i], CHNL_BW_40, + first_channel) == 0) + first_channel = false; + + if (cl_calib_dcoc_calibrate_channel(cl_hw, calib_channels_24g[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + return first_channel; +} + +static void cl_calib_dcoc_calibrate(struct cl_hw *cl_hw) +{ + if (cl_band_is_6g(cl_hw)) + cl_calib_dcoc_calibrate_6g(cl_hw); + else if (cl_band_is_5g(cl_hw)) + cl_calib_dcoc_calibrate_5g(cl_hw); + else if (cl_band_is_24g(cl_hw)) + cl_calib_dcoc_calibrate_24g(cl_hw); +} + +void cl_calib_dcoc_init_calibration(struct cl_hw *cl_hw) +{ + u8 tcv_idx = cl_hw->tcv_idx; + struct cl_chip *chip = cl_hw->chip; + struct cl_iq_dcoc_conf *iq_dcoc_conf = &chip->iq_dcoc_conf; + u8 fem_mode = cl_hw->fem_mode; + + /* No need to init calibration to non-Olympus phy */ + if (!IS_REAL_PHY(chip)) + return; + if (cl_hw_is_tcv0(cl_hw) && chip->conf->ci_tcv1_chains_sx0) + return; + + if (!iq_dcoc_conf->dcoc_calib_needed[tcv_idx]) { + u8 file_num_antennas = iq_dcoc_conf->dcoc_file_num_ant[tcv_idx]; + + if (file_num_antennas < cl_hw->num_antennas) { + cl_dbg_verbose(cl_hw, + "Num of antennas [%u], is larger than DCOC calibration file" + " num of antennas [%u], recalibration is needed\n", + cl_hw->num_antennas, file_num_antennas); + } else { + return; + } + } + + /* Set FEM mode to LNA Bypass Only mode for DCOC Calibration. */ + cl_fem_set_dcoc_bypass(cl_hw); + cl_afe_cfg_calib(chip); + + cl_calib_dcoc_calibrate(cl_hw); + + /* Restore FEM mode to its original mode. */ + cl_fem_dcoc_restore(cl_hw, fem_mode); + cl_afe_cfg_restore(chip); + + iq_dcoc_conf->dcoc_calib_needed[tcv_idx] = false; + iq_dcoc_conf->dcoc_file_num_ant[tcv_idx] = cl_hw->num_antennas; +} + +static u8 cl_calib_dcoc_get_chan_idx(const u8 calib_chan_list[], u8 list_len, u8 channel) +{ + u8 i = 0; + + for (i = 1; i < list_len; i++) + if (calib_chan_list[i] > channel) + return (i - 1); + + return (list_len - 1); +} + +static u8 cl_calib_dcoc_convert_to_channel_in_plan(u8 channel, u8 band) +{ + u8 idx; + + if (band == BAND_6G) { + idx = cl_calib_dcoc_get_chan_idx(calib_channels_6g_plan, + ARRAY_SIZE(calib_channels_6g_plan), channel); + return calib_channels_6g_plan[idx]; + } + + idx = cl_calib_dcoc_get_chan_idx(calib_channels_5g_plan, + ARRAY_SIZE(calib_channels_5g_plan), channel); + + return calib_channels_5g_plan[idx]; +} + +u8 cl_calib_dcoc_channel_bw_to_idx(struct cl_hw *cl_hw, u8 channel, u8 bw) +{ + if (cl_band_is_6g(cl_hw)) { + if (bw == CHNL_BW_160) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_160, + ARRAY_SIZE(calib_channels_6g_bw_160), + channel); + /* + * In case of non runtime calib - channels that don't exist in the plan list will + * not be calibrated. Thus, the calib data need to be fetched from a close channel + * that was calibrated - AKA "fallback channel". + * In this case the channel value should convert to the "fallback channel" that had + * been calibrated. The func will return the idx value of the "fallback channel" + * instead of the original idx channel. + */ + if (!cl_hw->chip->conf->ce_calib_runtime_en) + channel = cl_calib_dcoc_convert_to_channel_in_plan(channel, BAND_6G); + + if (bw == CHNL_BW_20) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_20, + ARRAY_SIZE(calib_channels_6g_bw_20), + channel); + + if (bw == CHNL_BW_40) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_40, + ARRAY_SIZE(calib_channels_6g_bw_40), + channel); + + if (bw == CHNL_BW_80) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_80, + ARRAY_SIZE(calib_channels_6g_bw_80), + channel); + } + + if (cl_band_is_5g(cl_hw)) { + if (bw == CHNL_BW_160) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_160, + ARRAY_SIZE(calib_channels_5g_bw_160), + channel); + + if (!cl_hw->chip->conf->ce_calib_runtime_en) + channel = cl_calib_dcoc_convert_to_channel_in_plan(channel, BAND_5G); + + if (bw == CHNL_BW_20) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_20, + ARRAY_SIZE(calib_channels_5g_bw_20), + channel); + + if (bw == CHNL_BW_40) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_40, + ARRAY_SIZE(calib_channels_5g_bw_40), + channel); + + if (bw == CHNL_BW_80) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_80, + ARRAY_SIZE(calib_channels_5g_bw_80), + channel); + } + + return cl_calib_dcoc_get_chan_idx(calib_channels_24g, ARRAY_SIZE(calib_channels_24g), + channel); +} + +void cl_calib_dcoc_fill_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db) +{ + struct cl_chip *chip = cl_hw->chip; + u8 lna = 0, chain = 0; + u8 bw = cl_hw->bw; + u8 channel_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, cl_hw->channel, bw); + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) + riu_chain_for_each(chain) + iq_dcoc_db->dcoc[lna][chain] = + chip->calib_db.dcoc[tcv_idx][channel_idx][bw][sx][chain][lna]; +} + +u8 cl_calib_dcoc_tcv_channel_to_idx(struct cl_chip *chip, u8 tcv_idx, u8 channel, u8 bw) +{ + u8 i = 0; + + if (cl_chip_is_6g(chip)) { + if (tcv_idx == TCV0) { + if (bw == CHNL_BW_20) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_20, + ARRAY_SIZE + (calib_channels_6g_bw_20), + channel); + + if (bw == CHNL_BW_40) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_40, + ARRAY_SIZE + (calib_channels_6g_bw_40), + channel); + + if (bw == CHNL_BW_80) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_80, + ARRAY_SIZE + (calib_channels_6g_bw_80), + channel); + + if (bw == CHNL_BW_160) + return cl_calib_dcoc_get_chan_idx(calib_channels_6g_bw_160, + ARRAY_SIZE + (calib_channels_6g_bw_160), + channel); + } else if (tcv_idx == TCV1) { + if (bw == CHNL_BW_20) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_20, + ARRAY_SIZE + (calib_channels_5g_bw_20), + channel); + + if (bw == CHNL_BW_40) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_40, + ARRAY_SIZE + (calib_channels_5g_bw_40), + channel); + + if (bw == CHNL_BW_80) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_80, + ARRAY_SIZE + (calib_channels_5g_bw_80), + channel); + + if (bw == CHNL_BW_160) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_160, + ARRAY_SIZE + (calib_channels_5g_bw_160), + channel); + } + } else { + if (channel <= NUM_CHANNELS_24G) { + for (i = 0; i < CALIB_CHAN_24G_MAX; i++) + if (calib_channels_24g[i] == channel) + return i; + } else { + if (bw == CHNL_BW_20) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_20, + ARRAY_SIZE + (calib_channels_5g_bw_20), + channel); + + if (bw == CHNL_BW_40) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_40, + ARRAY_SIZE + (calib_channels_5g_bw_40), + channel); + + if (bw == CHNL_BW_80) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_80, + ARRAY_SIZE + (calib_channels_5g_bw_80), + channel); + + if (bw == CHNL_BW_160) + return cl_calib_dcoc_get_chan_idx(calib_channels_5g_bw_160, + ARRAY_SIZE + (calib_channels_5g_bw_160), + channel); + } + } + + return 0; +} + +void cl_calib_dcoc_handle_set_channel_cfm(struct cl_hw *cl_hw, bool first_channel) +{ + struct calib_cfm *dcoc_iq_cfm = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_DCOC]; + s16 calib_temperature = cl_calib_common_get_temperature(cl_hw, CALIB_CFM_DCOC); + u8 channel = cl_hw->channel; + u8 bw = cl_hw->bw; + + cl_dbg_trace(cl_hw, "calib_temperature = %d, channel = %u, bw = %u\n", calib_temperature, + channel, bw); + + cl_calib_dcoc_handle_data(cl_hw, calib_temperature, channel, bw); + cl_calib_dcoc_handle_report(cl_hw, calib_temperature, channel, bw); + + /* + * Set the default status to FAIL, to ensure FW is actually changing the value, + * if the calibration succeeded. + */ + dcoc_iq_cfm->status = CALIB_FAIL; +} + +static void cl_calib_iq_handle_data(struct cl_hw *cl_hw, s16 calib_temperature, u8 channel, + u8 bw, u8 plan_bitmap) +{ + int chain; + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + u8 channel_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel, bw); + struct cl_iq_calib iq_calib_dma; + + riu_chain_for_each(chain) { + if ((plan_bitmap & (1 << chain)) == 0) + continue; + + iq_calib_dma = cl_hw->iq_dcoc_data_info.iq_dcoc_data->iq_dcoc_db.iq_tx[chain]; + cl_hw->chip->calib_db.iq_tx[tcv_idx][channel_idx][bw][sx][chain] = iq_calib_dma; + + iq_calib_dma = cl_hw->iq_dcoc_data_info.iq_dcoc_data->iq_dcoc_db.iq_rx[chain]; + cl_hw->chip->calib_db.iq_rx[tcv_idx][channel_idx][bw][sx][chain] = iq_calib_dma; + } +} + +static void cl_calib_iq_lolc_handle_data(struct cl_hw *cl_hw, s16 calib_temperature, + u8 channel, u8 bw, u8 plan_bitmap) +{ + int chain; + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + u8 channel_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel, bw); + __le32 lolc_calib_dma; + + riu_chain_for_each(chain) { + if ((plan_bitmap & (1 << chain)) == 0) + continue; + + lolc_calib_dma = + cl_hw->iq_dcoc_data_info.iq_dcoc_data->iq_dcoc_db.iq_tx_lolc[chain]; + cl_hw->chip->calib_db.iq_tx_lolc[tcv_idx][channel_idx][bw][sx][chain] = + le32_to_cpu(lolc_calib_dma); + } +} + +static void cl_calib_iq_lolc_handle_report(struct cl_hw *cl_hw, s16 calib_temperature, + int channel, u8 bw, u8 plan_bitmap) +{ + struct cl_iq_dcoc_report *report = &cl_hw->iq_dcoc_data_info.iq_dcoc_data->report; + int chain; + struct cl_lolc_report lolc_report_dma; + int bw_mhz = BW_TO_MHZ(bw); + s16 lolc_threshold = cl_hw->chip->conf->ci_lolc_db_thr; + s32 lolc_qual = 0; + + riu_chain_for_each(chain) { + if ((plan_bitmap & (1 << chain)) == 0) + continue; + + lolc_report_dma = report->lolc_report[chain]; + lolc_qual = (s16)(le16_to_cpu(lolc_report_dma.lolc_qual)) >> 8; + + cl_dbg_trace(cl_hw, "LOLC Quality [chain = %u] = %d, Iter = %u\n", + chain, lolc_qual, lolc_report_dma.n_iter); + + if (lolc_qual > lolc_threshold) { + cl_dbg_warn(cl_hw, + "Warning: LOLC value exceeds threshold [%ddB]: channel %u, " + "bw = %u, chain = %u, LOLC[dB] = %d, I[Iter] = %u\n", + lolc_threshold, channel, bw_mhz, chain, lolc_qual, + lolc_report_dma.n_iter); + cl_hw->chip->calib_db.errors[cl_hw->tcv_idx].lolc++; + } + } +} + +static int cl_calib_iq_calibrate_channel(struct cl_hw *cl_hw, u32 channel, u32 bw, + bool first_channel) +{ + u32 primary = 0; + u32 center = 0; + enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20; + struct cl_calib_params calib_params = { + (SET_CHANNEL_MODE_CALIB_IQ | SET_CHANNEL_MODE_CALIB_LOLC), + first_channel, SX_FREQ_OFFSET_Q2, 0 + }; + + /* Convert ant to riu chain in the calib plan_bitmap */ + calib_params.plan_bitmap = + cl_hw_ant_mask_to_riu_chain_mask(cl_hw, cl_hw->mask_num_antennas); + + if (cl_chandef_calc(cl_hw, channel, bw, &width, &primary, ¢er)) { + cl_dbg_err(cl_hw, "cl_chandef_calc failed\n"); + return -EINVAL; + } + + cl_dbg_trace(cl_hw, "\n ------ START CALIB IQ CHANNEL -----\n"); + cl_dbg_trace(cl_hw, "channel = %u first_channel = %d\n", channel, first_channel); + + /* Set channel mode to LO+IQ calibration mode */ + return cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, calib_params); +} + +static u8 cl_calib_iq_convert_plan_to_calib_db_idx(u8 chan_idx_src, u8 bw) +{ + u8 shift_idx = 0; + /* + * Calibration data is fetched from calibrated channels to previous uncalibrated channels in + * plan list. + * + * For example: channel 65 was calibrated due the channels plan list. Calibration data of + * channel 65 saved in calib_db struct in the relevant chan idx place due the BW, as the + * follow: + * chan_idx 16 for BW 20, + * chan_idx 8 for BW 40 + * chan_idx 4 for BW 80 + * chan_idx 2 for BW 160. + * + * We want to copy calib data of IQ & LOLC from channel 65 to channel 49. Doing the same + * also to the other uncalib channels: 33->17, 65->49, 97->81 etc. + * + * The chan idx of channel 49 in the calib_db by BW is: + * chan_idx 12 for BW 20, + * chan_idx 6 for BW 40 + * chan_idx 3 for BW 80 + * (no exist chan_idx for BW 160) + * + * We copy the data in calib_db from idx of channel 65 to the idx of channel 49: + * chan_idx 16 to chan_idx 12 (in BW 20) + * chan_idx 8 to chan_idx 6 (in BW 40) + * chan_idx 4 to chan_idx 3 (in BW 80) + * + * In general, the dst chan idx will be calculated by; + * dst_idx = src_idx - 4 (for BW 20) + * dst_idx = src_idx - 2 (for BW 40) + * dst_idx = src_idx - 1 (for BW 80) + * + * The way to calc this is shiftting is by the follow bitmask: + * 4 >> bw + */ + shift_idx = 4 >> bw; + + return chan_idx_src - shift_idx; +} + +static void cl_calib_iq_copy_data_to_uncalibrated_channels_6g(struct cl_hw *cl_hw) +{ + struct cl_calib_db *calib_db = &cl_hw->chip->calib_db; + int i; + u8 sx = cl_hw->sx_idx; + u8 tcv_idx = cl_hw->tcv_idx; + u8 chan_idx_src = 0; + u8 chan_idx_dst = 0; + u8 chain = 0; + u8 bw = 0; + + /* + * Copy iq & lo calib data from 6g list plan calibrate channels: 1, 33, 65, 97, 129, 161, + * 193, 22 to uncalibrated channels 17, 49, 81, 113, 145, 177, 209. copy to the correct + * channel idx for each different bw + */ + for (i = 1; i < CALIB_CHAN_6G_PLAN - 1; i += 2) + riu_chain_for_each(chain) + /* Iterate only CHNL_BW_80 and CHNL_BW_20 */ + for (bw = CHNL_BW_20; bw <= CHNL_BW_80; bw += 2) { + chan_idx_src = + cl_calib_dcoc_channel_bw_to_idx(cl_hw, + calib_channels_6g_plan[i], + bw); + + chan_idx_dst = + cl_calib_iq_convert_plan_to_calib_db_idx(chan_idx_src, bw); + memcpy(&calib_db->iq_tx[tcv_idx][chan_idx_dst][bw][sx][chain], + &calib_db->iq_tx[tcv_idx][chan_idx_src][bw][sx][chain], + sizeof(struct cl_iq_calib)); + memcpy(&calib_db->iq_rx[tcv_idx][chan_idx_dst][bw][sx][chain], + &calib_db->iq_rx[tcv_idx][chan_idx_src][bw][sx][chain], + sizeof(struct cl_iq_calib)); + calib_db->iq_tx_lolc[tcv_idx][chan_idx_dst][bw][sx][chain] = + calib_db->iq_tx_lolc[tcv_idx][chan_idx_src][bw][sx][chain]; + } +} + +static bool cl_calib_iq_calibrate_6g(struct cl_hw *cl_hw) +{ + int i; + bool first_channel = true; + + /* Calibrate channels: 1, 33, 65, 97, 129, 161, 193, 225 */ + for (i = 0; i < CALIB_CHAN_6G_PLAN; i += 2) { + if ((cl_calib_iq_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_160, + first_channel) == 0)) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_80, + first_channel) == 0) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_6g_plan[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + /* + * For these channels 17, 49, 81, 113, 145, 177, 209 + * copy data of next neighbor + */ + cl_calib_iq_copy_data_to_uncalibrated_channels_6g(cl_hw); + + return first_channel; +} + +static bool cl_calib_iq_calibrate_5g(struct cl_hw *cl_hw) +{ + int i; + bool first_channel = true; + + if (cl_calib_iq_calibrate_channel(cl_hw, 36, CHNL_BW_160, first_channel) == 0) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, 100, CHNL_BW_160, first_channel) == 0) + first_channel = false; + + for (i = 0; i < CALIB_CHAN_5G_PLAN; i++) { + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_5g_plan[i], CHNL_BW_80, + first_channel) == 0) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_5g_plan[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + return first_channel; +} + +static bool cl_calib_iq_calibrate_24g(struct cl_hw *cl_hw) +{ + int i; + bool first_channel = true; + + if (cl_hw->chip->conf->ce_production_mode) { + if (cl_calib_iq_calibrate_channel(cl_hw, 1, CHNL_BW_160, + first_channel) == 0) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, 1, CHNL_BW_80, + first_channel) == 0) + first_channel = false; + } + + for (i = 0; i < CALIB_CHAN_24G_MAX; i++) { + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_24g[i], CHNL_BW_40, + first_channel) == 0) + first_channel = false; + + if (cl_calib_iq_calibrate_channel(cl_hw, calib_channels_24g[i], CHNL_BW_20, + first_channel) == 0) + first_channel = false; + } + + return first_channel; +} + +static void cl_calib_iq_calibrate(struct cl_hw *cl_hw) +{ + if (cl_band_is_6g(cl_hw)) + cl_calib_iq_calibrate_6g(cl_hw); + else if (cl_band_is_5g(cl_hw)) + cl_calib_iq_calibrate_5g(cl_hw); + else if (cl_band_is_24g(cl_hw)) + cl_calib_iq_calibrate_24g(cl_hw); +} + +static void cl_calib_iq_init_calibration_tcv(struct cl_hw *cl_hw) +{ + u8 tcv_idx = cl_hw->tcv_idx; + + cl_calib_iq_calibrate(cl_hw); + + cl_hw->chip->iq_dcoc_conf.iq_file_num_ant[tcv_idx] = cl_hw->num_antennas; +} + +void cl_calib_restore_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore) +{ + u8 bw = iq_restore->bw; + u32 primary = iq_restore->primary; + u32 center = iq_restore->center; + u8 channel = iq_restore->channel; + + cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, CL_CALIB_PARAMS_DEFAULT_STRUCT); +} + +void cl_calib_save_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore) +{ + iq_restore->bw = cl_hw->bw; + iq_restore->primary = cl_hw->primary_freq; + iq_restore->center = cl_hw->center_freq; + iq_restore->channel = ieee80211_frequency_to_channel(cl_hw->primary_freq); + + cl_dbg_chip_trace(cl_hw, "bw = %u, primary = %d, center = %d, channel = %u\n", + iq_restore->bw, iq_restore->primary, + iq_restore->center, iq_restore->channel); +} + +int cl_calib_iq_set_idle(struct cl_hw *cl_hw, bool idle) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + bool tcv0_en = cl_chip_is_tcv0_enabled(chip) && cl_radio_is_on(cl_hw_tcv0); + bool tcv1_en = cl_chip_is_tcv1_enabled(chip) && cl_radio_is_on(cl_hw_tcv1); + + if (!idle) { + if (tcv1_en) + cl_msg_tx_set_idle(cl_hw_tcv1, MAC_ACTIVE, false); + + if (tcv0_en) + cl_msg_tx_set_idle(cl_hw_tcv0, MAC_ACTIVE, false); + + return 0; + } + + if (tcv1_en) + cl_msg_tx_idle_async(cl_hw_tcv1, false); + + if (tcv0_en) + cl_msg_tx_set_idle(cl_hw_tcv0, MAC_IDLE_SYNC, false); + + cl_dbg_info(cl_hw, "idle_async_set = %u\n", cl_hw->idle_async_set); + + if (wait_event_timeout(cl_hw->wait_queue, !cl_hw->idle_async_set, + CL_MSG_CFM_TIMEOUT_JIFFIES)) + return 0; + + cl_dbg_err(cl_hw, "Timeout occurred - MM_IDLE_ASYNC_IND\n"); + return -ETIMEDOUT; +} + +bool cl_calib_iq_calibration_needed(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_iq_dcoc_conf *iq_dcoc_conf = &chip->iq_dcoc_conf; + bool calib_needed = false; + + if (!IS_REAL_PHY(chip)) + return false; + + if (cl_hw->chip->conf->ce_calib_runtime_en) + return false; + + if (cl_hw_is_tcv0(cl_hw) && chip->conf->ci_tcv1_chains_sx0) + return false; + + if (cl_chip_is_tcv0_enabled(chip)) { + u8 num_antennas_tcv0 = chip->cl_hw_tcv0->num_antennas; + + if (iq_dcoc_conf->iq_file_num_ant[TCV0] < num_antennas_tcv0 && + !chip->conf->ci_tcv1_chains_sx0) { + cl_dbg_verbose(cl_hw, + "Num of antennas [%u], is larger than LOLC Calibration File " + "num of antennas [%u], recalibration is needed\n", + num_antennas_tcv0, iq_dcoc_conf->iq_file_num_ant[TCV0]); + calib_needed = true; + } + } + + if (cl_chip_is_tcv1_enabled(chip)) { + u8 num_antennas_tcv1 = chip->cl_hw_tcv1->num_antennas; + + if (iq_dcoc_conf->iq_file_num_ant[TCV1] < num_antennas_tcv1) { + cl_dbg_verbose(cl_hw, + "Num of antennas [%u], is larger than LOLC Calibration File " + "num of antennas [%u], recalibration is needed\n", + num_antennas_tcv1, iq_dcoc_conf->iq_file_num_ant[TCV1]); + calib_needed = true; + } + } + + return calib_needed; +} + +void cl_calib_iq_init_calibration(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + u8 fem_mode = cl_hw->fem_mode; + struct cl_iq_dcoc_conf *iq_dcoc_conf = &chip->iq_dcoc_conf; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + struct cl_calib_iq_restore iq_restore_tcv0; + struct cl_calib_iq_restore iq_restore_tcv1; + u8 save_tcv0_needed = cl_hw_tcv0 && cl_hw_tcv0->primary_freq && + !chip->conf->ci_tcv1_chains_sx0; + u8 save_tcv1_needed = cl_hw_tcv1 && cl_hw_tcv1->primary_freq; + + if (save_tcv0_needed) + cl_calib_save_channel(cl_hw_tcv0, &iq_restore_tcv0); + + if (save_tcv1_needed) + cl_calib_save_channel(cl_hw_tcv1, &iq_restore_tcv1); + + cl_fem_set_iq_bypass(cl_hw); + cl_afe_cfg_calib(chip); + + if (cl_hw_tcv0 && + (chip->iq_dcoc_conf.force_calib || + (iq_dcoc_conf->iq_file_num_ant[TCV0] < cl_hw_tcv0->num_antennas && + !chip->conf->ci_tcv1_chains_sx0))) { + cl_calib_iq_init_calibration_tcv(cl_hw_tcv0); + } + + if (cl_hw_tcv1 && + (chip->iq_dcoc_conf.force_calib || + iq_dcoc_conf->iq_file_num_ant[TCV1] < cl_hw_tcv1->num_antennas)) { + cl_calib_iq_init_calibration_tcv(cl_hw_tcv1); + } + + cl_fem_iq_restore(cl_hw, fem_mode); + cl_afe_cfg_restore(chip); + + if (save_tcv0_needed) + cl_calib_restore_channel(cl_hw_tcv0, &iq_restore_tcv0); + + if (save_tcv1_needed) + cl_calib_restore_channel(cl_hw_tcv1, &iq_restore_tcv1); +} + +void cl_calib_iq_fill_data(struct cl_hw *cl_hw, struct cl_iq_calib *iq_data, + struct cl_iq_calib *iq_chip_data) +{ + u8 ant = 0; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + iq_data[ant].coef0 = iq_chip_data[ant].coef0; + iq_data[ant].coef1 = iq_chip_data[ant].coef1; + iq_data[ant].coef2 = iq_chip_data[ant].coef2; + iq_data[ant].gain = iq_chip_data[ant].gain; + } +} + +void cl_calib_iq_lolc_fill_data(struct cl_hw *cl_hw, __le32 *iq_lolc) +{ + struct cl_calib_db *calib_db = &cl_hw->chip->calib_db; + u8 ant = 0; + u8 bw = cl_hw->bw; + u8 chan_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, cl_hw->channel, bw); + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) + iq_lolc[ant] = cpu_to_le32(calib_db->iq_tx_lolc[tcv_idx][chan_idx][bw][sx][ant]); +} + +void cl_calib_iq_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap) +{ + struct calib_cfm *dcoc_iq_cfm = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_IQ]; + s16 calib_temperature = cl_calib_common_get_temperature(cl_hw, CALIB_CFM_IQ); + u8 channel = cl_hw->channel; + u8 bw = cl_hw->bw; + + CL_DBG(cl_hw, DBG_LVL_TRACE, "calib_temperature = %d, channel = %u, bw = %u\n", + calib_temperature, channel, bw); + + cl_calib_iq_handle_data(cl_hw, calib_temperature, channel, bw, plan_bitmap); + + /* + * Set the default status to FAIL, to ensure FW is actually changing the value, + * if the calibration succeeded. + */ + dcoc_iq_cfm->status = CALIB_FAIL; +} + +void cl_calib_iq_lolc_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap) +{ + struct calib_cfm *dcoc_iq_cfm = + &cl_hw->iq_dcoc_data_info.iq_dcoc_data->dcoc_iq_cfm[CALIB_CFM_IQ]; + s16 calib_temperature = cl_calib_common_get_temperature(cl_hw, CALIB_CFM_IQ); + u8 channel = cl_hw->channel; + u8 bw = cl_hw->bw; + + cl_dbg_trace(cl_hw, "calib_temperature = %d, channel = %u, bw = %u\n", calib_temperature, + channel, bw); + + cl_calib_iq_lolc_handle_data(cl_hw, calib_temperature, channel, bw, plan_bitmap); + cl_calib_iq_lolc_handle_report(cl_hw, calib_temperature, channel, bw, plan_bitmap); + + /* + * Set the default status to FAIL, to ensure FW is actually changing the value, + * if the calibration succeeded. + */ + dcoc_iq_cfm->status = CALIB_FAIL; +} + +void cl_calib_iq_get_tone_vector(struct cl_hw *cl_hw, __le16 *tone_vector) +{ + u8 tone = 0; + u8 *vector_ptr = NULL; + + switch (cl_hw->bw) { + case CHNL_BW_20: + vector_ptr = cl_hw->conf->ci_calib_conf_tone_vector_20bw; + break; + case CHNL_BW_40: + vector_ptr = cl_hw->conf->ci_calib_conf_tone_vector_40bw; + break; + case CHNL_BW_80: + vector_ptr = cl_hw->conf->ci_calib_conf_tone_vector_80bw; + break; + case CHNL_BW_160: + vector_ptr = cl_hw->conf->ci_calib_conf_tone_vector_160bw; + break; + default: + vector_ptr = cl_hw->conf->ci_calib_conf_tone_vector_20bw; + break; + } + + for (tone = 0; tone < IQ_NUM_TONES_REQ; tone++) + tone_vector[tone] = cpu_to_le16((u16)vector_ptr[tone]); +} + +void cl_calib_iq_init_production(struct cl_hw *cl_hw) +{ + struct cl_hw *cl_hw_other = NULL; + struct cl_chip *chip = cl_hw->chip; + + if (!cl_chip_is_both_enabled(chip) || + (cl_hw_is_tcv1(cl_hw) && chip->conf->ci_tcv1_chains_sx0)) { + if (cl_calib_iq_calibration_needed(cl_hw)) + cl_calib_iq_init_calibration(cl_hw); + return; + } + + cl_hw_other = cl_hw_other_tcv(cl_hw); + if (!cl_hw_other) + return; + + if (cl_hw_other->iq_cal_ready) { + cl_hw_other->iq_cal_ready = false; + cl_calib_iq_init_calibration(cl_hw); + } else if (cl_calib_iq_calibration_needed(cl_hw)) { + cl_hw->iq_cal_ready = true; + cl_dbg_verbose(cl_hw, "IQ Calibration needed. Wait for both TCVs before starting " + "calibration.\n"); + } +} + +/* + * CL80x0: TCV0 - 5g, TCV1 - 24g + * ============================================== + * 50 48 46 44 42 40 38 36 --> Start 5g + * 100 64 62 60 58 56 54 52 + * 116 114 112 110 108 106 104 102 + * 134 132 128 126 124 122 120 118 + * 153 151 149 144 142 140 138 136 + * 3 2 1 165 161 159 157 155 --> Start 24g + * 11 10 9 8 7 6 5 4 + * 14 13 12 + */ + +/* + * CL80x6: TCV0 - 6g, TCV1 - 5g + * ============================================== + * 25 21 17 13 9 5 2 1 --> Start 6g + * 57 53 49 45 41 37 33 29 + * 89 85 81 77 73 69 65 61 + * 121 117 113 109 105 101 97 93 + * 153 147 143 139 135 131 127 123 + * 185 181 177 173 169 165 161 157 + * 217 213 209 205 201 197 193 189 + * 42 40 38 36 233 229 225 221 --> Start 5g + * 58 56 54 52 50 48 46 44 + * 108 106 104 102 100 64 62 60 + * 124 122 120 118 116 114 112 110 + * 142 140 138 136 134 132 128 126 + * 161 159 157 155 153 151 149 144 + * 165 + */ + +#define BITMAP_80X0_START_TCV0 0 +#define BITMAP_80X0_MAX_TCV0 NUM_CHANNELS_5G + +#define BITMAP_80X0_START_TCV1 NUM_CHANNELS_5G +#define BITMAP_80X0_MAX_TCV1 (NUM_CHANNELS_5G + NUM_CHANNELS_24G) + +#define BITMAP_80X6_START_TCV0 0 +#define BITMAP_80X6_MAX_TCV0 NUM_BITMAP_CHANNELS_6G + +#define BITMAP_80X6_START_TCV1 NUM_BITMAP_CHANNELS_6G +#define BITMAP_80X6_MAX_TCV1 (NUM_BITMAP_CHANNELS_6G + NUM_CHANNELS_5G) + +#define INVALID_ADDR 0xffff + +static u8 cl_get_bitmap_start_tcv1(struct cl_chip *chip) +{ + if (cl_chip_is_6g(chip)) + return BITMAP_80X6_START_TCV1; + else + return BITMAP_80X0_START_TCV1; +} + +static u8 cl_idx_to_arr_offset(u8 idx) +{ + /* Divide by 8 for array index */ + return idx >> 3; +} + +static u8 cl_idx_to_bit_offset(u8 idx) +{ + /* Reminder is for bit index (assummed array of u8) */ + return idx & 0x07; +} + +static const u8 bits_cnt_table256[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +static bool cl_is_vector_unset(const u8 *bitmap) +{ + /* Check bitmap is unset i.e. all values are CURR_BMP_UNSET */ + u8 empty_bitmap[BIT_MAP_SIZE] = {0}; + + return !memcmp(bitmap, empty_bitmap, BIT_MAP_SIZE); +} + +static bool cl_bitmap_test_bit_idx(const u8 *bitmap, u8 idx) +{ + /* Check bit at a given index is set i.e. 1 */ + u8 arr_idx = cl_idx_to_arr_offset(idx), bit_idx = cl_idx_to_bit_offset(idx); + + if (arr_idx >= BIT_MAP_SIZE) + return false; + + /* Convert non-zero to true and zero to false */ + return !!(bitmap[arr_idx] & BIT(bit_idx)); +} + +static void cl_bitmap_shift(u8 *bitmap, u8 shft) +{ + /* Shifts an array of byte of size len by shft number of bits to the left */ + u8 bitmap_tmp[BIT_MAP_SIZE] = {0}; + u8 msb_shifts = shft % 8; + u8 lsb_shifts = 8 - msb_shifts; + u8 byte_shift = shft / 8; + u8 last_byte = BIT_MAP_SIZE - byte_shift - 1; + u8 msb_idx; + u8 i; + + memcpy(bitmap_tmp, bitmap, BIT_MAP_SIZE); + memset(bitmap, 0, BIT_MAP_SIZE); + + for (i = 0; i < BIT_MAP_SIZE; i++) { + if (i <= last_byte) { + msb_idx = i + byte_shift; + bitmap[i] = bitmap_tmp[msb_idx] >> msb_shifts; + if (i != last_byte) + bitmap[i] |= bitmap_tmp[msb_idx + 1] << lsb_shifts; + } + } +} + +static bool cl_bitmap_set_bit_idx(struct cl_hw *cl_hw, u8 *bitmap, u8 bitmap_size, u8 idx) +{ + /* Set bit at a given index */ + u8 arr_idx = cl_idx_to_arr_offset(idx), bit_idx = cl_idx_to_bit_offset(idx); + + if (arr_idx >= bitmap_size) { + cl_dbg_err(cl_hw, "invalid arr_idx (%u)\n", arr_idx); + return false; + } + + bitmap[arr_idx] |= BIT(bit_idx); + return true; +} + +static u16 cl_bitmap_look_lsb_up(struct cl_hw *cl_hw, u8 *bitmap, u16 idx, bool ext) +{ + /* Find closest set bit with index higher than idx inside bitmap */ + u16 curr_idx = idx; + u8 curr = 0; + u32 chan_num = ext ? NUM_EXT_CHANNELS_6G : cl_channel_num(cl_hw); + + while (++curr_idx < chan_num) { + curr = bitmap[cl_idx_to_arr_offset(curr_idx)]; + if (curr & (1ULL << cl_idx_to_bit_offset(curr_idx))) + return curr_idx; + } + + /* No matching bit found - return original index */ + return idx; +} + +static u16 bitmap_look_msb_down(struct cl_hw *cl_hw, u8 *bitmap, u16 idx, bool ext) +{ + /* Find closest set bit with index lower than idx inside bitmap */ + u16 curr_idx = idx; + u8 curr = 0; + u32 chan_num = ext ? NUM_EXT_CHANNELS_6G : cl_channel_num(cl_hw); + + if (idx >= chan_num) { + cl_dbg_err(cl_hw, "Invalid channel index [%u]\n", idx); + return idx; + } + + while (curr_idx-- != 0) { + curr = bitmap[cl_idx_to_arr_offset(curr_idx)]; + if (curr & (1ULL << cl_idx_to_bit_offset(curr_idx))) + return curr_idx; + } + + /* No matching bit found - return original index */ + return idx; +} + +static u8 cl_address_offset_tcv1(struct cl_hw *cl_hw) +{ + /* Calculate eeprom calibration data offset for tcv1 */ + struct cl_chip *chip = cl_hw->chip; + u8 i, cnt = 0; + u8 bitmap[BIT_MAP_SIZE] = {0}; + + if (cl_e2p_read(chip, bitmap, BIT_MAP_SIZE, ADDR_CALIB_POWER_CHAN_BMP)) + return 0; + + for (i = 0; i < cl_get_bitmap_start_tcv1(chip); i++) + cnt += cl_bitmap_test_bit_idx(bitmap, i); + + return cnt; +} + +static int cl_point_idx_to_address(struct cl_hw *cl_hw, u8 *bitmap, struct point *pt) +{ + /* Calculate eeprom address for a given idx and phy (initiated point) */ + u8 i, cnt = 0; + + pt->addr = INVALID_ADDR; + + if (!cl_bitmap_test_bit_idx(bitmap, pt->idx)) + return 0; + + if (pt->phy >= MAX_ANTENNAS) { + cl_dbg_err(cl_hw, "Invalid phy number %u", pt->phy); + return -EINVAL; + } + + for (i = 0; i < pt->idx; i++) + cnt += cl_bitmap_test_bit_idx(bitmap, i); + + if (cl_hw_is_tcv1(cl_hw)) + cnt += cl_address_offset_tcv1(cl_hw); + + pt->addr = ADDR_CALIB_POWER_PHY + + sizeof(struct eeprom_phy_calib) * (cnt * MAX_ANTENNAS + pt->phy); + + return 0; +} + +static bool cl_linear_equation_signed(struct cl_hw *cl_hw, const u16 x, s8 *y, + const u16 x0, const s8 y0, const u16 x1, const s8 y1) +{ + /* Calculate y given to points (x0,y0) and (x1,y1) and x */ + s32 numerator = (x - x0) * (y1 - y0); + s32 denominator = x1 - x0; + + if (unlikely(!denominator)) { + cl_dbg_err(cl_hw, "zero denominator\n"); + return false; + } + + *y = (s8)(y0 + DIV_ROUND_CLOSEST(numerator, denominator)); + + return true; +} + +static void cl_extend_bitmap_6g(struct cl_hw *cl_hw, u8 *bitmap, u8 *ext_bitmap) +{ + u8 i, ext_idx; + + for (i = 0; i < cl_channel_num(cl_hw); ++i) { + if (cl_bitmap_test_bit_idx(bitmap, i)) { + ext_idx = CHAN_BITMAP_IDX_6G_2_EXT_IDX(i); + cl_bitmap_set_bit_idx(cl_hw, ext_bitmap, EXT_BIT_MAP_SIZE, ext_idx); + } + } +} + +static bool cl_calculate_calib(struct cl_hw *cl_hw, u8 *bitmap, + struct point *p0, struct point *p1, struct point *p2) +{ + /* Main interpolation/extrapolation function */ + bool calc_succsess = false, use_ext = false; + u16 freq0, freq1, freq2; + u8 e2p_ext_bitmap[EXT_BIT_MAP_SIZE] = {0}; + u8 *bitmap_to_use = bitmap; + + if (unlikely(cl_is_vector_unset(bitmap))) + return false; + + /* + * In case that the band is 6g and the channel index wasn't found, it might be because + * the channel is missing from the original bitmap (that includes only 20MHz channels). + * In case of center channels in 40/180/160MHz, it can't be found in the original bitmap + * and therefore we need to extend the bitmap to include these channels in order to perform + * interpolation on it. + */ + if (cl_band_is_6g(cl_hw) && p0->idx == INVALID_CHAN_IDX) { + p0->idx = cl_channel_to_ext_index_6g(cl_hw, p0->chan); + cl_extend_bitmap_6g(cl_hw, bitmap, e2p_ext_bitmap); + bitmap_to_use = e2p_ext_bitmap; + use_ext = true; + } + + p1->idx = cl_bitmap_look_lsb_up(cl_hw, bitmap_to_use, p0->idx, use_ext); + p2->idx = bitmap_look_msb_down(cl_hw, bitmap_to_use, p0->idx, use_ext); + + /* Invalid case */ + if (p1->idx == p0->idx && p2->idx == p0->idx) { + cl_dbg_err(cl_hw, "Invalid index %u or bad bit map\n", p0->idx); + return false; + } + + /* Extrapolation case */ + if (p1->idx == p0->idx) + p1->idx = bitmap_look_msb_down(cl_hw, bitmap_to_use, p2->idx, use_ext); + if (p2->idx == p0->idx) + p2->idx = cl_bitmap_look_lsb_up(cl_hw, bitmap_to_use, p1->idx, use_ext); + + if (use_ext) { + /* Convert indices from extended bitmap to eeprom bitmap */ + p1->idx = CHAN_EXT_IDX_6G_2_BITMAP_IDX(p1->idx); + p2->idx = CHAN_EXT_IDX_6G_2_BITMAP_IDX(p2->idx); + } + + /* Address from index */ + if (cl_point_idx_to_address(cl_hw, bitmap, p1) || p1->addr == INVALID_ADDR) { + cl_dbg_err(cl_hw, "Point calculation failed\n"); + return false; + } + + if (cl_point_idx_to_address(cl_hw, bitmap, p2) || p2->addr == INVALID_ADDR) { + cl_dbg_err(cl_hw, "Point calculation failed\n"); + return false; + } + + /* Read from eeprom */ + if (cl_e2p_read(cl_hw->chip, (u8 *)&p1->calib, sizeof(struct eeprom_phy_calib), p1->addr)) + return false; + + /* No interpolation required */ + if (p1->addr == p2->addr) { + p0->calib = p1->calib; + return true; + } + + /* Interpolation or extrapolation is required - read from eeprom */ + if (cl_e2p_read(cl_hw->chip, (u8 *)&p2->calib, sizeof(struct eeprom_phy_calib), p2->addr)) + return false; + + freq0 = (use_ext ? cl_channel_ext_idx_to_freq_6g(cl_hw, p0->idx) : + cl_channel_idx_to_freq(cl_hw, p0->idx)); + freq1 = cl_channel_idx_to_freq(cl_hw, p1->idx); + freq2 = cl_channel_idx_to_freq(cl_hw, p2->idx); + + /* Interpolate/extrapolate target power */ + calc_succsess = cl_linear_equation_signed(cl_hw, + freq0, &p0->calib.pow, + freq1, p1->calib.pow, + freq2, p2->calib.pow); + + /* Interpolate/extrapolate power offset */ + calc_succsess = calc_succsess && cl_linear_equation_signed(cl_hw, + freq0, &p0->calib.offset, + freq1, p1->calib.offset, + freq2, p2->calib.offset); + + /* Interpolate/extrapolate calibration temperature */ + calc_succsess = calc_succsess && cl_linear_equation_signed(cl_hw, + freq0, &p0->calib.tmp, + freq1, p1->calib.tmp, + freq2, p2->calib.tmp); + + if (unlikely(!calc_succsess)) { + cl_dbg_err(cl_hw, + "Calc failed: freq0 %u idx0 %u%s, freq1 %u idx1 %u, freq2 %u idx2 %u\n", + freq0, p0->idx, use_ext ? " (ext)" : "", + freq1, p1->idx, freq2, p2->idx); + return false; + } + + return true; +} + +static int cl_read_validate_vector_bitmap(struct cl_hw *cl_hw, u8 *bitmap) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_e2p_read(chip, bitmap, BIT_MAP_SIZE, ADDR_CALIB_POWER_CHAN_BMP)) + return -1; + + /* Test if e2p was read succsefull since it is not ALL EMPTY */ + if (cl_is_vector_unset(bitmap)) { + cl_dbg_err(cl_hw, "Vector not ready\n"); + return -EPERM; + } + + if (cl_hw_is_tcv1(cl_hw)) { + u8 bitmap_start = cl_get_bitmap_start_tcv1(chip); + + cl_bitmap_shift(bitmap, bitmap_start); + } + + return 0; +} + +static int cl_read_or_interpolate_point(struct cl_hw *cl_hw, u8 *bitmap, struct point *p0) +{ + struct point p1 = {.phy = p0->phy}; + struct point p2 = {.phy = p0->phy}; + struct point tmp_pt = *p0; + + /* Invalid address = no physical address was allocated to this channel */ + if (tmp_pt.addr != INVALID_ADDR) { + if (cl_e2p_read(cl_hw->chip, (u8 *)&tmp_pt.calib, + sizeof(struct eeprom_phy_calib), tmp_pt.addr)) + return -1; + } else { + /* Interpolate */ + if (!cl_calculate_calib(cl_hw, bitmap, &tmp_pt, &p1, &p2)) { + cl_dbg_err(cl_hw, "Interpolation Error\n"); + return -EFAULT; + } + } + + if (tmp_pt.calib.pow == 0 && tmp_pt.calib.offset == 0 && tmp_pt.calib.tmp == 0) { + u16 freq = ieee80211_channel_to_frequency(tmp_pt.chan, cl_hw->nl_band); + + cl_dbg_err(cl_hw, "Verify calibration point: addr %x, idx %u, freq %u, phy %u\n", + tmp_pt.addr, tmp_pt.idx, freq, tmp_pt.phy); + /* *Uninitiated eeprom value */ + return -EINVAL; + } + + /* Now p0 will contain "Valid" calculations of calib" */ + p0->calib = tmp_pt.calib; + return 0; +} + +static void cl_calib_power_reset(struct cl_hw *cl_hw) +{ + u8 ch_idx; + u16 phy; + u32 chan_num = cl_band_is_6g(cl_hw) ? NUM_EXT_CHANNELS_6G : cl_channel_num(cl_hw); + static const struct cl_tx_power_info default_info = { + .power = UNCALIBRATED_POWER, + .offset = UNCALIBRATED_POWER_OFFSET, + .temperature = UNCALIBRATED_TEMPERATURE + }; + + /* Initiate tx_pow_info struct to default values */ + for (ch_idx = 0; ch_idx < chan_num; ch_idx++) + for (phy = 0; phy < MAX_ANTENNAS; phy++) + cl_hw->tx_pow_info[ch_idx][phy] = default_info; +} + +static void cl_calib_fill_power_info(struct cl_hw *cl_hw, u8 chan_idx, u8 ant, + struct point *point) +{ + cl_hw->tx_pow_info[chan_idx][ant].power = point->calib.pow; + cl_hw->tx_pow_info[chan_idx][ant].offset = point->calib.offset; + cl_hw->tx_pow_info[chan_idx][ant].temperature = point->calib.tmp; +} + +#define PHY0_OFFSET_FIX_Q2 -8 /* -2db */ +#define PHY3_OFFSET_FIX_Q2 14 /* +3.5db */ + +static void cl_calib_phy_offset_adjust(struct cl_hw *cl_hw, u8 eeprom_version, + u8 phy, struct point *point) +{ + /* + * Work around: + * Add 3.5dB offset to PHY3 if EEPROM version is 0. + * Decrease 2dB offset to all PHYs if EEPROM version is 1. + */ + if (!cl_chip_is_6g(cl_hw->chip)) { + if (cl_band_is_5g(cl_hw) && eeprom_version == 0 && phy == 3) + point->calib.offset += PHY3_OFFSET_FIX_Q2; + else if (cl_band_is_24g(cl_hw) && eeprom_version == 1) + point->calib.offset += PHY0_OFFSET_FIX_Q2; + } +} + +void cl_calib_power_read(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + int ret; + u8 bitmap[BIT_MAP_SIZE] = {0}; + struct point curr_point = {0}; + u8 *phy = &curr_point.phy; + u8 *ch_idx = &curr_point.idx; + u8 ext_chan_idx = 0; + u8 ant; + u8 eeprom_version = chip->eeprom_cache->general.version; + u32 tmp_freq = 0; + + /* Initiate tx_pow_info struct to default values */ + cl_calib_power_reset(cl_hw); + + /* Vector not initiated set table to default values */ + if (unlikely(cl_read_validate_vector_bitmap(cl_hw, bitmap))) { + cl_dbg_trace(cl_hw, "initiate to default values\n"); + return; + } + + /* Perform only on calibrated boards - cl_read_validate_vector_bitmap succeeded (0) */ + for (*ch_idx = 0; *ch_idx < cl_channel_num(cl_hw); (*ch_idx)++) { + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + if (!(cl_hw->mask_num_antennas & BIT(ant))) + continue; + + /* + * In old eeprom versions (< 3) power info was saved in eeprom + * per riu chain (unintentionally) so we need to fetch it accordingly + */ + if (eeprom_version < 3) + *phy = cl_hw_ant_to_riu_chain(cl_hw, ant); + else + *phy = ant; + + ret = cl_point_idx_to_address(cl_hw, bitmap, &curr_point); + + if (ret) { + /* Don't overwrite default values */ + cl_dbg_err(cl_hw, "point idx to address failed\n"); + continue; + } + + if (cl_band_is_6g(cl_hw)) { + tmp_freq = cl_channel_idx_to_freq(cl_hw, *ch_idx); + curr_point.chan = ieee80211_frequency_to_channel(tmp_freq); + } + + ret = cl_read_or_interpolate_point(cl_hw, bitmap, &curr_point); + /* Unable to calculate new value ==> DON'T overwrite default values */ + if (unlikely(ret)) + continue; + + cl_calib_phy_offset_adjust(cl_hw, eeprom_version, *phy, &curr_point); + + if (cl_band_is_6g(cl_hw)) + ext_chan_idx = CHAN_BITMAP_IDX_6G_2_EXT_IDX(*ch_idx); + else + ext_chan_idx = *ch_idx; + + cl_calib_fill_power_info(cl_hw, ext_chan_idx, ant, &curr_point); + } + } + + if (!cl_band_is_6g(cl_hw)) + goto calib_read_out; + + /* + * Fill info for channels that are missing from the original bitmap, which are the + * center channels in 40/180/160MHz (channels 3, 7, 11, etc..). + */ + for (ext_chan_idx = 0; ext_chan_idx < NUM_EXT_CHANNELS_6G; ext_chan_idx++) { + /* Skip channels that were already filled above */ + tmp_freq = cl_channel_ext_idx_to_freq_6g(cl_hw, ext_chan_idx); + + /* Chan field needs to be updated before calling to cl_read_or_interpolate_point */ + curr_point.chan = ieee80211_frequency_to_channel(tmp_freq); + + /* If the channel is found in the bitmap - we already handled it above */ + if (cl_channel_to_bitmap_index(cl_hw, curr_point.chan) != INVALID_CHAN_IDX) + continue; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + if (!(cl_hw->mask_num_antennas & BIT(ant))) + continue; + + /* + * In old eeprom versions (< 3) power info was saved in eeprom + * per riu chain (unintentionally) so we need to fetch it accordingly + */ + if (eeprom_version < 3) + *phy = cl_hw_ant_to_riu_chain(cl_hw, ant); + else + *phy = ant; + + /* + * Addr and idx fields needs to be invalid to successfully interpolate the + * power info on the extended eeprom bitmap. + */ + curr_point.addr = INVALID_ADDR; + curr_point.idx = INVALID_CHAN_IDX; + + ret = cl_read_or_interpolate_point(cl_hw, bitmap, &curr_point); + + /* Unable to calculate new value ==> DON'T overwrite default values */ + if (unlikely(ret)) + continue; + + cl_calib_fill_power_info(cl_hw, ext_chan_idx, ant, &curr_point); + } + } +calib_read_out: + cl_dbg_trace(cl_hw, "Created tx_pow_info\n"); +} + +void cl_calib_power_offset_fill(struct cl_hw *cl_hw, u8 channel, + u8 bw, u8 offset[MAX_ANTENNAS]) +{ + u8 i, chain; + u8 chan_idx = cl_channel_to_index(cl_hw, cl_hw->channel); + s8 pow_offset; + s8 signed_offset; + + if (chan_idx == INVALID_CHAN_IDX) + return; + + for (i = 0; i < MAX_ANTENNAS; i++) { + if (!(cl_hw->mask_num_antennas & BIT(i))) + continue; + + pow_offset = cl_hw->tx_pow_info[chan_idx][i].offset; + signed_offset = cl_power_offset_check_margin(cl_hw, bw, i, pow_offset); + chain = cl_hw_ant_to_riu_chain(cl_hw, i); + offset[chain] = cl_convert_signed_to_reg_value(signed_offset); + } +} + +struct cl_runtime_work { + struct work_struct ws; + struct cl_hw *cl_hw; + u32 channel; + u8 bw; + u16 primary; + u16 center; +}; + +static int _cl_calib_runtime_and_switch_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, + u16 primary, u16 center, + struct cl_calib_params calib_params) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_calib_iq_restore iq_restore_other_tcv; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + int ret = 0; + u8 fem_mode = cl_hw->fem_mode; + u8 save_other_tcv_needed = cl_chip_is_both_enabled(chip) && cl_hw_other && + !!cl_hw_other->primary_freq; + + cl_hw->calib_runtime_needed = false; + + if (save_other_tcv_needed) + cl_calib_save_channel(cl_hw_other, &iq_restore_other_tcv); + + if (cl_chip_is_both_enabled(chip)) { + ret = cl_calib_iq_set_idle(cl_hw, true); + if (ret) + return ret; + } + + cl_fem_set_iq_bypass(cl_hw); + cl_afe_cfg_calib(chip); + + /* Calibration by the default values */ + if (cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, calib_params)) { + cl_dbg_chip_err(cl_hw, "Failed to calibrate channel %u, bw %u\n", + channel, bw); + ret = -1; + } + + cl_fem_iq_restore(cl_hw, fem_mode); + cl_afe_cfg_restore(chip); + + if (save_other_tcv_needed) + cl_calib_restore_channel(cl_hw_other, &iq_restore_other_tcv); + + /* Set channel to load the new calib data */ + ret += cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, + CL_CALIB_PARAMS_DEFAULT_STRUCT); + + if (cl_chip_is_both_enabled(chip)) + cl_calib_iq_set_idle(cl_hw, false); + + return ret; +} + +static void cl_calib_runtime_work_handler(struct work_struct *ws) +{ + struct cl_runtime_work *runtime_work = container_of(ws, struct cl_runtime_work, ws); + + cl_calib_runtime_and_switch_channel(runtime_work->cl_hw, runtime_work->channel, + runtime_work->bw, runtime_work->primary, + runtime_work->center); + + kfree(runtime_work); +} + +static bool cl_calib_runtime_is_channel_calibrated(struct cl_hw *cl_hw, u8 channel, u8 bw) +{ + int chain, lna; + u8 chan_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel, bw); + u8 tcv_idx = cl_hw->tcv_idx; + u8 sx = cl_hw->sx_idx; + + riu_chain_for_each(chain) { + if (!cl_hw->chip->calib_db.iq_tx[tcv_idx][chan_idx][bw][sx][chain].gain && + !cl_hw->chip->calib_db.iq_tx[tcv_idx][chan_idx][bw][sx][chain].coef0 && + !cl_hw->chip->calib_db.iq_tx[tcv_idx][chan_idx][bw][sx][chain].coef1 && + !cl_hw->chip->calib_db.iq_tx[tcv_idx][chan_idx][bw][sx][chain].coef2) { + cl_dbg_trace(cl_hw, "IQ TX calibration data is missing\n"); + return false; + } + + if (!cl_hw->chip->calib_db.iq_rx[tcv_idx][chan_idx][bw][sx][chain].gain && + !cl_hw->chip->calib_db.iq_rx[tcv_idx][chan_idx][bw][sx][chain].coef0 && + !cl_hw->chip->calib_db.iq_rx[tcv_idx][chan_idx][bw][sx][chain].coef1 && + !cl_hw->chip->calib_db.iq_rx[tcv_idx][chan_idx][bw][sx][chain].coef2) { + cl_dbg_trace(cl_hw, "IQ RX calibration data is missing\n"); + return false; + } + + if (!cl_hw->chip->calib_db.iq_tx_lolc[tcv_idx][chan_idx][bw][sx][chain]) { + cl_dbg_trace(cl_hw, "LOLC calibration data is missing\n"); + return false; + } + } + + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + riu_chain_for_each(chain) { + if (!cl_hw->chip->calib_db.dcoc[tcv_idx][chan_idx][bw][sx][chain][lna].i && + !cl_hw->chip->calib_db.dcoc[tcv_idx][chan_idx][bw][sx][chain][lna].q) { + cl_dbg_trace(cl_hw, "DCOC calibration data is missing\n"); + return false; + } + } + } + + /* If all the calibration data of channel exist */ + return true; +} + +bool cl_calib_runtime_is_allowed(struct cl_hw *cl_hw) +{ + if (!cl_hw) + return false; + + if (cl_hw->scanner && cl_is_scan_in_progress(cl_hw->scanner)) + return false; + + return true; +} + +void cl_calib_runtime_work(struct cl_hw *cl_hw, u32 channel, u8 bw, u16 primary, + u16 center) +{ + struct cl_runtime_work *runtime_work = kzalloc(sizeof(*runtime_work), GFP_ATOMIC); + + if (!runtime_work) + return; + + runtime_work->cl_hw = cl_hw; + runtime_work->channel = channel; + runtime_work->bw = bw; + runtime_work->primary = primary; + runtime_work->center = center; + INIT_WORK(&runtime_work->ws, cl_calib_runtime_work_handler); + queue_work(cl_hw->drv_workqueue, (struct work_struct *)(&runtime_work->ws)); +} + +int cl_calib_runtime_and_switch_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u32 primary, + u32 center) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + struct cl_calib_params calib_params = {SET_CHANNEL_MODE_CALIB, false, SX_FREQ_OFFSET_Q2, 0}; + int ret = 0; + bool calib_needed = (cl_hw->chip->conf->ci_calib_runtime_force || + !cl_calib_runtime_is_channel_calibrated(cl_hw, channel, bw)) && + !cl_hw->sw_scan_in_progress; + + mutex_lock(&cl_hw->chip->calib_runtime_mutex); + + if (!calib_needed || !cl_calib_runtime_is_allowed(cl_hw) || + (cl_chip_is_both_enabled(chip) && !cl_calib_runtime_is_allowed(cl_hw_other))) { + if (calib_needed) + cl_hw->calib_runtime_needed = true; + + /* Switch channel without calibration */ + ret = cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, + CL_CALIB_PARAMS_DEFAULT_STRUCT); + mutex_unlock(&cl_hw->chip->calib_runtime_mutex); + + return ret; + } + + /* Convert ant to riu chain in the calib plan_bitmap */ + calib_params.plan_bitmap = cl_hw_ant_mask_to_riu_chain_mask(cl_hw, + cl_hw->mask_num_antennas); + + /* This mutex needs to be held during the whole calibration process */ + mutex_lock(&cl_hw->chip->set_idle_mutex); + ret = _cl_calib_runtime_and_switch_channel(cl_hw, channel, bw, primary, center, + calib_params); + mutex_unlock(&cl_hw->chip->set_idle_mutex); + + mutex_unlock(&cl_hw->chip->calib_runtime_mutex); + + return ret; +} + From patchwork Tue May 24 11:33:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576869 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 DB050C433F5 for ; Tue, 24 May 2022 11:37:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236775AbiEXLhu (ORCPT ); Tue, 24 May 2022 07:37:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236765AbiEXLht (ORCPT ); Tue, 24 May 2022 07:37:49 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0647640A01 for ; Tue, 24 May 2022 04:37:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=i7jcpENGP9ZHize1ms1y+fU/rjgS5RX6Aa80S0SQ2jTujVbSQVGyEjhX4DWafTbZxHA6BLJHK2ytEYOfwe5U9Lw/NUG6BbQZgbvL+h2gAIh3f9ZWxcBYM1H8VZNwjDGlTNp6S3uh/RvTWpPb8rBdsyWcnnFXLlM1+Q8LfhZdfqZwI2Z5K0ISSfBgX6ZEuzbgpn9AUSA6EErZt0vI4CqGrKIf4btwLkmnoyckKIgi1EDxyo5r5hgyb6iCRa9gQxLd4oiLx71b1lJrMHx2cCGwiku67GIX3s3va2aeCLwnr9b74k2NR6kxhhsb0QUBkF9f8SMIRblEEZICOpOrGeQ49w== 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=6pb9OdR9RorX0vFEVOIWgvic/lEeuE/yg3byo4XZRIY=; b=QcqM4JqbtM2UfQB2/D0LF/dgrWcsTgnL3KoJsRRYnrN2/dyfLadvWJTssvZ9XsuOcXU5J71UAYZ5k+1D+kF1pijoUpYhaSwAt2EO6Pyjgl9v6U/AP66uvxuQjTXwXu7m4lvLQUijlijjnLo1xFZBXHoBt/DnKOe17To/cQsK0VXmp0TYsT3Y0JldjWmhj/5TneIDKij15vdu0ZMM7n/uxM4gtFbNks+PUpWFbGRCEbyv07LQ6k19MK5fN47ar0evCsh27U9gEOag1DzySwoK5/TNbr+ROCiUNl7D4suAQRMdrv3vT4m6NOCD8xUNDr4pmiVqXd3qvNdPUeM2SHTnIQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6pb9OdR9RorX0vFEVOIWgvic/lEeuE/yg3byo4XZRIY=; b=x2XW4JB6m2vS3EPfEznb9nbJvYSXV9r6e2Im8BZbXB1+P68gVrPL0I26BYaLqkgcN31JTpvMUztQ4+cnFukPxYM/FLBQJr9Iro0mnL4PbD76SSPJ//J0Z4BjruWpFrffFyaGqMhb4Gt+B6WV8KlrUp1oswV57wrDwZltC/SsUYc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:44 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:44 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 10/96] cl8k: add calib.h Date: Tue, 24 May 2022 14:33:36 +0300 Message-Id: <20220524113502.1094459-11-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 75fa00fb-7431-4332-5b0a-08da3d79d0b1 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7UfmOCJwMSF5pCYb3Ecqq2INHkFfJAmbxtdxH6oDVVk2mPCiNH0y7gZn4Ph5wUbbkGhAbP7a2IE7zt/WSuZYrvwncoJXTiuWhUDlkspeRVaJFWqLB2fMa1rtiQVU9exjYskZUzuaGPII3D1SmvrKeiq4B4ks/N2q9cqqa+FzgmCTdMNjXuom43Tb5fU+ZIOd9LyB3HhT7QT7RDDbImKXzox1wLXOPIa/KPcCBmUEvQE0Oy6MC7DABBLfa1OIgQM31S4/eBgpBGoym9tzprFo8h2LTiQkzRmccqqs3m2NYBDYWsNJRwtx0XjgS5F36XOev3JekNUcTcfW14Z2Ls6D98V7Pk1P+/ofyg8tyuMJwxz1LnJ652Byz/eHmWqSh/tdMXHY7yaqZmAQ7TlZWhWAOZ4QV5LOot+VeuuH2S+dKcUyG2W0kBF1sxbyWffXkjUXVPpMCDZ6k/6lLrq0tmu5a7bHoOK3VqO0EF9t5Z9EVGMdVJr4/PoQj9J+0eGlo6dvVh9n9jjPG6kdfMF8DeNvByoSclVeJq7qjitcs+VuUO2n4UAgxvle3sTP3cdlI+eM0crltIkCGnscfgfmSgR8XaxO3qayZ+F2+Aibyur/HxIIbNgpP+Tz7BUZXF7TKpMx6wTjk9KwXgbSW2k/zcDuS5jeH6ecKTS9FgL3okhEuQdHD4kNUe3YOQQ/6JhOMweAmbzAEBl8MajksxwC4UaJmFzVK/ubS3kkKtBbE/lPcXA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(30864003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: aggxSA0jRrujROP65F/qGjpJTkrnMe7nxLl8zcuwzoIncp51ZGiYQwBXaER4LP/rdXoXLJxaqk+jlorJZVNfTLTvrGuJv0j5qJuItPBjZJNsQERp+uPeFmCzp+5DlBgOFPWerp7TDi7MsR+ASZNpxMe8SuuEkMfotZVv+LvP9mdPRcmhbSQmqXDjv7uYzWQMi0S1zax9DWYIYW4xo+Wgah7Pih7rQEFXBzCz0tmP3Tk5gtOioiebqfhpx+e0+WWm4mZFwRM05+/DAEd/d9WwDVnpX4zmARtHhf1qm3Z5L24r4IQKp8sgVrHVFrSxlGHF6usmU5aeE7jaB1Zz3sWDZ3TOdbLv26W1Dj3WOw7U/eoxADOUmL4FriDVWiBn6BsUhAzw/0iYHqAu9CD47nKDw8ABTBluRYNZ7FIqTRAI4ICFK6q765BdzoUdli93piyBy8O5TfmDoZkxXbjto9ThurFgHNHvvYuq1LzkoMZQn0bzQYkSFiVvo+/uAyCYFun6W+7dQqGriVJYxeqhLpHJIWP0e6DCuuHYW/XPpVjEFSz4YlZGD/GNZqnA+PzAmwMCeE8UYSdWDayo/KRkqiu97ahoeqWXDFc++3/vy7QR9OJ8g8o6xdEtcrOOMqITyY+gkTJBosQaAnnGEIZS3eWwdIAvhwTWLgiBciN1kE7YSyadnW2XlNKemYv0EgLlNCJ1uxzKMDr4Bc4eDew0JnYNvbdulO6Wy726zXArTXvGEfFru+mjXfTUR1OwiBXSGOsI7/xx5qH5fFyL4P1wuXaXtBHPKfw6cdIVk30w5zCddpEFrTkjKrQP8cP50pURWYnOlpu6mqBzIK46IRqtNl+51mo7q5XWtdxp8QTI8cw1mQYkikpTwJnN99NygVai+YsRY3y7VHvB0GTYDvXTEGmbDjZuz6pDFhrRHMjK/ttiNgAmXi5vn/jfv1s8iZJNyou8EYWdTxq6T8fogQH0Mv7fydvPhWTjVonNtx5Y/XQ0iAvC4q08AMbvWexOlNE9zN15ntUwp18+hOsAWLIzM1Y+vf6RG+CKQPisDUyTP49E0mbcIMSfZTKIGU3UC8gHIfKEOBLum5dfel5Q4PjDse2Xu5Duu3jVQWidgQRJKFrCzwpXz2SaGSnIYxt46qB5VFIUTSCjKoZI/UhzZGMVpg9N1NhkpakFj41cCo+VkJwd7UMbYjYDXWzCWkS1pi2MOaDRNOgoGjQ6j1ZBCtTPFVUJUL2I4tTld2N/q1VYnBKwlpjjEpMEFDExrz48d50jh3vW6e/RfRVOvcIZm3z7ZQJNr0d4J/qzoncbNf3M3Dcd1xDF4PSfOnwnjKNbzsIHRJ1S8imdDDZ2W4+93IyRFNFo1tWEvpJLC86PFvrxyzQ4Hd9YrgZsj9THwyhMzvF5RhkH4mLsyPti8fduuSLo0OfrqTS5SndH0ju8u07Jh/3iZpfsi7vUjnC2KShXUnQAeE9NSOtqXyD3IlZefefXu+T/F8XdNR6G7fvtvy2y2RjsYJ0cCT8gs56KgHDkhrQIjBoJsOUWKP5VPzq8dEl8WmgcbW2V8bJJ51d/2Cl0xx6xSNaqK0psqg4cC1FkBwEw0a002LRE8/ZtjX1q/Wya5G9CARivbWzABJXdO+CHujafHJ8EbgkQ681YqCiGGwy2pl6bns1gTlcIX+u6Py/jQRrEC4Xpv398pC6NOetMsUiBF8bISqoqWRS47x9HqNABHSQlNdCApY2jlL6OdDCoPqWhw8S1mSmGyUqD+p+KoxCPUTM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 75fa00fb-7431-4332-5b0a-08da3d79d0b1 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:42.9387 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TFAAefCeV1xjxG1ituUNi6wun4QPP7KY6L3bHh5+2ZvfLUbYUmDYkL5CDaRC23/UrtUq3mxi8G2PG8Rc+jjRsQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/calib.h | 390 +++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/calib.h diff --git a/drivers/net/wireless/celeno/cl8k/calib.h b/drivers/net/wireless/celeno/cl8k/calib.h new file mode 100644 index 000000000000..6eb286392dd6 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/calib.h @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_CALIB_H +#define CL_CALIB_H + +#include +#include + +#include "def.h" + +#define DCOC_LNA_GAIN_NUM 8 +#define MAX_SX 2 +#define IQ_NUM_TONES_REQ 8 +#define IQ_NUM_TONES_CFM (2 * IQ_NUM_TONES_REQ) +#define SINGLETONS_MAX_NUM 1 +#define LOOPS_MAX_NUM (2 + SINGLETONS_MAX_NUM) /* 1: pre,2-11:singletone,12:post */ +#define SX_FREQ_OFFSET_Q2 5 + +enum calib_cfm_id_type { + CALIB_CFM_DCOC, + CALIB_CFM_IQ, + CALIB_CFM_MAX +}; + +enum calib_channel_idx_24g { + CALIB_CHAN_24G_1, + CALIB_CHAN_24G_6, + CALIB_CHAN_24G_11, + CALIB_CHAN_24G_MAX, +}; + +enum calib_channel_idx_5g { + CALIB_CHAN_5G_36, + CALIB_CHAN_5G_40, + CALIB_CHAN_5G_44, + CALIB_CHAN_5G_48, + CALIB_CHAN_5G_52, + CALIB_CHAN_5G_56, + CALIB_CHAN_5G_60, + CALIB_CHAN_5G_64, + CALIB_CHAN_5G_100, + CALIB_CHAN_5G_104, + CALIB_CHAN_5G_108, + CALIB_CHAN_5G_112, + CALIB_CHAN_5G_116, + CALIB_CHAN_5G_120, + CALIB_CHAN_5G_124, + CALIB_CHAN_5G_128, + CALIB_CHAN_5G_132, + CALIB_CHAN_5G_136, + CALIB_CHAN_5G_140, + CALIB_CHAN_5G_144, + CALIB_CHAN_5G_149, + CALIB_CHAN_5G_153, + CALIB_CHAN_5G_157, + CALIB_CHAN_5G_161, + CALIB_CHAN_5G_165, + CALIB_CHAN_5G_MAX +}; + +enum calib_channel_idx_6g { + CALIB_CHAN_6G_1, + CALIB_CHAN_6G_5, + CALIB_CHAN_6G_9, + CALIB_CHAN_6G_13, + CALIB_CHAN_6G_17, + CALIB_CHAN_6G_21, + CALIB_CHAN_6G_25, + CALIB_CHAN_6G_29, + CALIB_CHAN_6G_33, + CALIB_CHAN_6G_37, + CALIB_CHAN_6G_41, + CALIB_CHAN_6G_45, + CALIB_CHAN_6G_49, + CALIB_CHAN_6G_53, + CALIB_CHAN_6G_57, + CALIB_CHAN_6G_61, + CALIB_CHAN_6G_65, + CALIB_CHAN_6G_69, + CALIB_CHAN_6G_73, + CALIB_CHAN_6G_77, + CALIB_CHAN_6G_81, + CALIB_CHAN_6G_85, + CALIB_CHAN_6G_89, + CALIB_CHAN_6G_93, + CALIB_CHAN_6G_97, + CALIB_CHAN_6G_101, + CALIB_CHAN_6G_105, + CALIB_CHAN_6G_109, + CALIB_CHAN_6G_113, + CALIB_CHAN_6G_117, + CALIB_CHAN_6G_121, + CALIB_CHAN_6G_125, + CALIB_CHAN_6G_129, + CALIB_CHAN_6G_133, + CALIB_CHAN_6G_137, + CALIB_CHAN_6G_141, + CALIB_CHAN_6G_145, + CALIB_CHAN_6G_149, + CALIB_CHAN_6G_153, + CALIB_CHAN_6G_157, + CALIB_CHAN_6G_161, + CALIB_CHAN_6G_165, + CALIB_CHAN_6G_169, + CALIB_CHAN_6G_173, + CALIB_CHAN_6G_177, + CALIB_CHAN_6G_181, + CALIB_CHAN_6G_185, + CALIB_CHAN_6G_189, + CALIB_CHAN_6G_193, + CALIB_CHAN_6G_197, + CALIB_CHAN_6G_201, + CALIB_CHAN_6G_205, + CALIB_CHAN_6G_209, + CALIB_CHAN_6G_213, + CALIB_CHAN_6G_217, + CALIB_CHAN_6G_221, + CALIB_CHAN_6G_225, + CALIB_CHAN_6G_229, + CALIB_CHAN_6G_233, + CALIB_CHAN_6G_MAX, +}; + +/* MAX(CALIB_CHAN_24G_MAX, CALIB_CHAN_5G_MAX, CALIB_CHAN_6G_MAX) */ +#define CALIB_CHAN_MAX CALIB_CHAN_6G_MAX + +struct cl_dcoc_calib { + s8 i; + s8 q; +}; + +struct cl_dcoc_report { + __le16 i_dc; + __le16 i_iterations; + __le16 q_dc; + __le16 q_iterations; +}; + +struct cl_iq_report { + u8 status; + __le16 amplitude_mismatch[IQ_NUM_TONES_CFM]; + __le16 phase_mismatch[IQ_NUM_TONES_CFM]; + s8 ir_db[LOOPS_MAX_NUM][IQ_NUM_TONES_CFM]; + s8 ir_db_avg_post; +}; + +struct cl_iq_calib { + __le32 coef0; + __le32 coef1; + __le32 coef2; + __le32 gain; +}; + +struct cl_lolc_report { + u8 status; + u8 n_iter; + __le16 lolc_qual; +}; + +struct cl_gain_report { + u8 status; + u8 rx_gain; + u8 tx_gain; + u8 gain_quality; + __le16 final_p2p; + __le16 initial_p2p; +}; + +struct cl_iq_dcoc_conf { + bool dcoc_calib_needed[TCV_MAX]; + u8 dcoc_file_num_ant[TCV_MAX]; + bool iq_calib_needed; + u8 iq_file_num_ant[TCV_MAX]; + bool force_calib; +}; + +struct cl_iq_dcoc_info { + struct cl_dcoc_calib dcoc[DCOC_LNA_GAIN_NUM][MAX_ANTENNAS]; + struct cl_iq_calib iq_tx[MAX_ANTENNAS]; + __le32 iq_tx_lolc[MAX_ANTENNAS]; + struct cl_iq_calib iq_rx[MAX_ANTENNAS]; +}; + +struct cl_iq_dcoc_report { + struct cl_dcoc_report dcoc[DCOC_LNA_GAIN_NUM][MAX_ANTENNAS]; + struct cl_gain_report gain_tx[MAX_ANTENNAS]; + struct cl_gain_report gain_rx[MAX_ANTENNAS]; + struct cl_lolc_report lolc_report[MAX_ANTENNAS]; + struct cl_iq_report iq_tx[MAX_ANTENNAS]; + struct cl_iq_report iq_rx[MAX_ANTENNAS]; +}; + +struct calib_cfm { + u8 status; + __le16 raw_bits_data_0; + __le16 raw_bits_data_1; +}; + +struct cl_iq_dcoc_data { + struct cl_iq_dcoc_info iq_dcoc_db; + struct cl_iq_dcoc_report report; + struct calib_cfm dcoc_iq_cfm[CALIB_CFM_MAX]; +}; + +struct cl_iq_dcoc_data_info { + struct cl_iq_dcoc_data *iq_dcoc_data; + u32 dma_addr; +}; + +struct cl_calib_params { + u8 mode; + bool first_channel; + s8 sx_freq_offset_mhz; + u32 plan_bitmap; +}; + +struct cl_calib_work { + struct work_struct ws; + struct cl_hw *cl_hw; +}; + +struct cl_calib_chain { + u8 pair; + u8 initial_tx_gain; + u8 initial_rx_gain; +}; + +enum cl_calib_flags { + CALIB_FLAG_CREATE = 1 << 0, + CALIB_FLAG_VERSION = 1 << 1, + CALIB_FLAG_TITLE = 1 << 2, + CALIB_FLAG_HEADER_TCV0 = 1 << 3, + CALIB_FLAG_HEADER_TCV1 = 1 << 4, + + CALIB_FLAG_HEADER_TCV01 = (CALIB_FLAG_HEADER_TCV0 | + CALIB_FLAG_HEADER_TCV1), + CALIB_FLAG_ALL_REPORT = (CALIB_FLAG_CREATE | + CALIB_FLAG_VERSION | + CALIB_FLAG_TITLE), + CALIB_FLAG_ALL = (CALIB_FLAG_CREATE | + CALIB_FLAG_VERSION | + CALIB_FLAG_TITLE | + CALIB_FLAG_HEADER_TCV0 | + CALIB_FLAG_HEADER_TCV1) +}; + +struct cl_calib_file_flags { + u8 dcoc; + u8 dcoc_report; + u8 lolc; + u8 lolc_report; + u8 iq_tx; + u8 iq_tx_report; + u8 iq_rx; + u8 iq_rx_report; + u8 rx_gain_report; + bool iq_plan; +}; + +struct cl_calib_errors { + u16 dcoc; + u16 lolc; + u16 iq_tx; + u16 iq_rx; +}; + +struct cl_calib_db { + struct cl_dcoc_calib + dcoc[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS][DCOC_LNA_GAIN_NUM]; + u32 iq_tx_lolc[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS]; + struct cl_iq_calib iq_tx[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS]; + struct cl_iq_calib iq_rx[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS]; + struct cl_calib_file_flags file_flags; + struct cl_calib_errors errors[TCV_MAX]; + struct list_head plan[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX]; + bool is_plan_initialized; +}; + +#define SET_PHY_DATA_FLAGS_DCOC 0x1 /* Set DCOC calibration data.*/ +#define SET_PHY_DATA_FLAGS_IQ_TX 0x2 /* Set IQ Tx calibration data.*/ +#define SET_PHY_DATA_FLAGS_IQ_RX 0x4 /* Set IQ Rx calibration data.*/ +#define SET_PHY_DATA_FLAGS_IQ_TX_LOLC 0x8 /* Set IQ Tx LOLC calibration data.*/ +#define SET_PHY_DATA_FLAGS_ALL ( \ + SET_PHY_DATA_FLAGS_DCOC | \ + SET_PHY_DATA_FLAGS_IQ_TX | \ + SET_PHY_DATA_FLAGS_IQ_RX | \ + SET_PHY_DATA_FLAGS_IQ_TX_LOLC) +#define SET_PHY_DATA_FLAGS_LISTENER ( \ + SET_PHY_DATA_FLAGS_DCOC | \ + SET_PHY_DATA_FLAGS_IQ_RX) + +#define CL_CALIB_PARAMS_DEFAULT_STRUCT \ + ((struct cl_calib_params){SET_CHANNEL_MODE_OPERETIONAL, false, 0, 0}) + +#define CALIB_CHAN_5G_PLAN 6 +#define CALIB_CHAN_6G_PLAN 15 + +struct cl_chip; + +void cl_calib_dcoc_init_calibration(struct cl_hw *cl_hw); +u8 cl_calib_dcoc_channel_bw_to_idx(struct cl_hw *cl_hw, u8 channel, u8 bw); +void cl_calib_dcoc_fill_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db); +u8 cl_calib_dcoc_tcv_channel_to_idx(struct cl_chip *chip, u8 tcv_idx, u8 channel, u8 bw); +void cl_calib_dcoc_handle_set_channel_cfm(struct cl_hw *cl_hw, bool first_channel); +void cl_calib_common_start_work(struct cl_hw *cl_hw); +void cl_calib_common_fill_phy_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db, + u8 flags); +int cl_calib_common_tables_alloc(struct cl_hw *cl_hw); +void cl_calib_common_tables_free(struct cl_hw *cl_hw); +int cl_calib_common_handle_set_channel_cfm(struct cl_hw *cl_hw, + struct cl_calib_params calib_params); +int cl_calib_common_check_errors(struct cl_hw *cl_hw); +s16 cl_calib_common_get_temperature(struct cl_hw *cl_hw, u8 cfm_type); + +/* Calibration constants */ +#define CALIB_TX_GAIN_DEFAULT (0x75) +#define GAIN_SLEEVE_TRSHLD_DEFAULT (2) +#define CALIB_NCO_AMP_DEFAULT (-10) +#define CALIB_NCO_FREQ_DEFAULT (16) /* 5M/312.5K for LO & RGC */ +#define LO_P_THRESH (1000000) +#define N_SAMPLES_EXP_LOLC (13) +#define N_SAMPLES_EXP_IQC (13) +#define N_BIT_FIR_SCALE (11) +#define N_BIT_AMP_SCALE (10) +#define N_BIT_PHASE_SCALE (10) +#define GP_RAD_TRSHLD_DEFAULT (1144) /* Represents 1 degree in Q(16,16): 1*(pi/180) */ +#define GA_LIN_UPPER_TRSHLD_DEFAULT (66295) /* Represents 0.1 db in Q(16,16): 10^( 0.1/20)*2^16 */ +#define GA_LIN_LOWER_TRSHLD_DEFAULT (64786) /* Represents -0.1 db in Q(16,16): 10^(-0.1/20)*2^16 */ +#define COMP_FILTER_LEN_DEFAULT (9) +#define SINGLETONS_NUM_DEFAULT (10) /* Set to SINGLETONS_MAX_NUM for now */ +#define IQ_POST_IDX (LOOPS_MAX_NUM - 1) +#define RAMPUP_TIME (50) +#define LO_COARSE_STEP (20) +#define LO_FINE_STEP (1) + +#define DCOC_MAX_VGA 0x14 +#define CALIB_RX_GAIN_DEFAULT 0x83 +#define CALIB_RX_GAIN_UPPER_LIMIT 0x14 +#define CALIB_RX_GAIN_LOWER_LIMIT 0x0 +#define DCOC_MAX_VGA_ATHOS 0x1E +#define CALIB_RX_GAIN_DEFAULT_ATHOS 0x8D +#define CALIB_RX_GAIN_UPPER_LIMIT_ATHOS 0x1E +#define CALIB_RX_GAIN_LOWER_LIMIT_ATHOS 0x0A +#define DCOC_MAX_VGA_ATHOS_B 0x14 +#define CALIB_RX_GAIN_DEFAULT_ATHOS_B 0x81 +#define CALIB_RX_GAIN_UPPER_LIMIT_ATHOS_B 0x14 +#define CALIB_RX_GAIN_LOWER_LIMIT_ATHOS_B 0x0 + +struct cl_calib_iq_restore { + u8 bw; + u32 primary; + u32 center; + u8 channel; +}; + +bool cl_calib_iq_calibration_needed(struct cl_hw *cl_hw); +void cl_calib_iq_file_flags_clear(struct cl_chip *chip); +void cl_calib_iq_file_flags_set(struct cl_chip *chip); +int cl_calib_iq_post_read_actions(struct cl_chip *chip, char *buf); +void cl_calib_iq_init_calibration(struct cl_hw *cl_hw); +void cl_calib_iq_fill_data(struct cl_hw *cl_hw, struct cl_iq_calib *iq_data, + struct cl_iq_calib *iq_chip_data); +void cl_calib_iq_lolc_fill_data(struct cl_hw *cl_hw, __le32 *iq_lolc); +void cl_calib_iq_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap); +void cl_calib_iq_lolc_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap); +int cl_calib_iq_lolc_write_version(struct cl_hw *cl_hw); +int cl_calib_iq_lolc_report_write_version(struct cl_hw *cl_hw); +int cl_calib_iq_lolc_write_file(struct cl_hw *cl_hw, s32 *params); +int cl_calib_iq_lolc_report_write_file(struct cl_hw *cl_hw, s32 *params); +void cl_calib_iq_get_tone_vector(struct cl_hw *cl_hw, __le16 *tone_vector); +void cl_calib_iq_init_production(struct cl_hw *cl_hw); +int cl_calib_iq_set_idle(struct cl_hw *cl_hw, bool idle); +void cl_calib_restore_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore); +void cl_calib_save_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore); + +#define UNCALIBRATED_POWER 15 +#define UNCALIBRATED_POWER_OFFSET 0 +#define UNCALIBRATED_TEMPERATURE 35 + +struct point; +void cl_calib_power_read(struct cl_hw *cl_hw); +void cl_calib_power_offset_fill(struct cl_hw *cl_hw, u8 channel, + u8 bw, u8 offset[MAX_ANTENNAS]); +int cl_calib_runtime_and_switch_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u32 primary, + u32 center); +void cl_calib_runtime_work(struct cl_hw *cl_hw, u32 channel, u8 bw, u16 primary, u16 center); +bool cl_calib_runtime_is_allowed(struct cl_hw *cl_hw); + +#endif /* CL_CALIB_H */ From patchwork Tue May 24 11:33:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576867 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 F19D7C433EF for ; Tue, 24 May 2022 11:38:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236787AbiEXLiF (ORCPT ); Tue, 24 May 2022 07:38:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236773AbiEXLiD (ORCPT ); Tue, 24 May 2022 07:38:03 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A90D8CB3D for ; Tue, 24 May 2022 04:37:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TlYKdxQTfsFtCrMoPbhvuNIco4X0EOa3b3kKL6J2CqyE0JVmtMlst8omIrRrCmdy6rsT331qqLIRBRchGbNl9h9CUIZVaulRwLaF8FSx7jlApRVTimBSODFQob2geXP+rB2PbNh0j05bkj0T9kNPBnilJeim8Hf6N5yTafx73typvTNaMdoFCMJ56y9rUKC4d0Fd5hh95K0QBH2No/Faec6DxL+BA/GXEeubvTqhsn1dBWOeuKtDuiElbTqs4LMuridIcKFLxvmGxQXFl4qyBA1Z9LR7kYUgV2vdQdRbA662RbD3vfq+Yn646aI/4hTxvxhnv7Jv7XQVf8kYBH2wEg== 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=+GlnspchVv5AHBSQqu5yoZUXIRzjxSemY+DHvskgNa8=; b=K6z9MnhhBETXk1lWwr1Akve+ayZn/9bcSlcPQ0zPYKOzqnrdpBRw7VNWIuDs/CYxVVxr/hgsEt0Cl1ZvQMWkBBfosuBFKb+H2vSFS/yWsP0x0kSPUq+t9dEqOD7X8lFZ8mLFbZ2JgIOjtHTsMATXIbmfKn3UAmu+BmEyXUGmj2cl8kEM1oR4Cmzdn7tOz+j5pYbFKRsA23jF+B+BMtI6aAqL3No8t03SCpP5ggBiPyk1iqyKI3DqueDxyZUZweP8GL4qRO91EhIu3jfRgojZ4tIOF9DuLdrPBxQFONGV/ru9IDL6AJyWobKtJ8zX8TpKZjJq/RJgANn4YcD7i/tiGA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+GlnspchVv5AHBSQqu5yoZUXIRzjxSemY+DHvskgNa8=; b=aXMZEUhEBvcL8OPC4+R/4iwpkGADnjlRkZHCu4Rg1DMJtzUnSH0uabCdvemRDtx/qSGnRKEQsNRr/0juHV0EhhkpcSyfsr9zuS8TqxKOnEtfMl4ZbAN9RjnBn+B4IDw1mJjjP/c+JM4bjUsFbzA/bvB7SZxpbYp/mYYm5S8Em1s= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:50 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:50 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 11/96] cl8k: add channel.c Date: Tue, 24 May 2022 14:33:37 +0300 Message-Id: <20220524113502.1094459-12-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8f23b0ff-89b7-4550-637c-08da3d79d3dd X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: DpmwIsn2PcGDvV6cIwScEhKns9qIJCbzsJ+Tn0hlHmKKMt6/eMBozgGa3H1vi1Nle5pOcQOU37YhTD70ZyocGWNCNJ6PzNFwmwSFsSUO/UukCnflX8l8x6kH/pLUOyzEEGFY0wrhAgUBC/91tQXMSK+4HF1iU9nnrO2hwMrDkcZhMM3eOYCc8c649t2BFHPInGxDNUb/r/piV+mdk3piRgpVy9fMG/7ZblrbA/qaGryq/ErUg4lr+KYCdsyssuInXWKpTRku/Xa9tpnQIcF2Q37LvaGgIbHoykh7hoZPD5VPd7z8sLK/8ySll8r6SPQL8fsbZSDP9mw52q1jsmTDog9KteneLcD35aEdBTI9aLe/3zrePCLqLR5/4oRHlf594Pgw9MgcXqKCgcmvGsap9KnjhAcv6sw0wgmVurMJxrUNdtR3PuO4ecd9L0tvIaBzKBTIqPPaqQANz99HxQj3s8ZBrNZ6E9zWVgPz9T6JTVX/a91YDEYuFegTNUgDRBdRnf+4LSPs4QmuWIpgr6rCWRQsgws81RW5OUYgB73uMM5Td9bu/b0qqU72o9tCPrQV0RWWBYQQg3utFMq7pwpgpnhZdcnSv0Im1vaXjmbkdXNcw/hdZ51QuPg9SJLhryShHeLaoDBc+exUGaz5mTZdi/QbGCSziSswLFsoTeBhSaKh0sd4zu7rfTPrP0v40zPTwV7Lzm+Aw+YgNFGuWRkDM/uDW0l2/99IJMlUPeQS8vk= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(30864003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: WVWvwrJ0qGwG9ro0q61K9HqUG9lLcadMLVe/KhJ0eTfXhr3mL4pogfj4ipjnEMBJBqFn0U7iBhbe9+8PWxqK+wcztW0mlWcvUdxbglJVp5UuOWK2NwpH0n7NbPOTrLOReMhcloUXWRBIgeiA0vxpY4xm5yDoDnQG4TsSPOi2MHicJgwuNBjPY4Y5uMBLxq7H/TqBiqBHkcem9lMuIsR/etzs06EKpw+om5gSpFn4I16WOJNcE/YtRe06xFhs3DW8dYz11dq9yRuHYVEAcUsXauT4/+qDtv28oBMnHf28zJwxZ6c1adbkxE+yh4upGCjj4yCKqcFaQjsspIvju0aAFWQqsHJjPF6EOQN3sQ6VJLYd67z4bKaT1pk0jkQ8mXra3A6HcZ7Z846+Oil7QDU12NFdxF1luHzeiqbhRPpTjdao+b9Akvu6IPhbJSLNkUy7kyCKcDjhU4/2vh5965YxMER/BSeGXOJTBZLpuoafstwVC5JCYQ8G5Z85lIQ38lOz4CIeRRS2b0otIpuZ5wZ+wOw50IYIuMZKWfMKqtPX5hx0L0+eaolMnR130s7VeYdN3sCnwl+kBUCP9YkVVpmazDUsuvBe8EnjsG+8HldNbrbENRaL/c8PjxvDJrY0n9HAUA5HyBTpk8Rfos+eqav0dWN60um5bu6QNsb/PLIPjm2KicHXF16OBFCIZlvMMZlvmlQ0mgkJJHbi1nRo3z8zRi7aEFGOomJeDYgejaQsueuO9e7vtaZoFk8hBofDWzhYsWlNeSscBQAR+JFsFdXgY6/vqPsbptRFNK9DB8YKQ/XheM641N3JAN31evVX3Sn/2lxmToWnnpa7ehDToC4/7XUAHLUvHRryC+nmi+SWabCcI4i+SaeME6EjcRssgWbBy2L52EaPQsrabMs3k0fmUUVvafn7VXcAN/ojJZfjZXHht7saLK3jnmwz1/+DVJnA2NYVSGLEtr1Utrm4+QSc+Zp9n6LimNIi3BewkUx50OxgE+KbIve1FzycL97LeX4RhRXcnSqtvFGgJLv6dc5SoZLwGvqBDQ1TmHEC/gQXunV1qNFvGNlHZn6hvevK5vtkUQf148R/0l/4Qqozc0qryt4CG3NOewLb0sV1Onq0dJ8laQsHKxSvZOKu/Uy1W/7cAFhHN3A4/+F+UYSwcIyRFFWePV2l9y/WfpbliXb74JI0MP5ibo5Qz4mQe557ezrwn8QTmu23huIpVkYrYY2OJytQtMANxUjYI76Jj5FAKM5Bj/sCHIfxOs0EcNuO/PAJFrbPXti7wl1e6A7ZnWZYvum93lIsxddXJHSFidIfoFGQDNaiQfqaoqW9wlVesltGlIzgbfH3yMGDTNn5UgSAo07Ov7A8grbMqrgiUYwLCdBM9SFlR+urxqifjqe7ZlY3falv1WfwYRHgsFP+XmGFaPP8fN3QCkv519/4ipbhVvaGalTqa0Houz1x0OMrabs9/j8KsiYBw89LX+hNfPKXqhtbxGHdD8YP8cjUJgIdsK1nWL8I1JdPcWMujwQ4dnmuxwO7vSmQ+Gn9EhzTcqip1uAffAr3USVyec+9CqS7wQkUYfS2spC1fPFxs+AvfuCzciLZQ2Q+dWx+4RiqM18PKmzb1HIEgEUg3ZIJxAC7FneOaV9nLSUe4t4xoMUOeRYGt12n8YPt4Sv7KB6DfLutkMAfGZvP7n+SuiHp7b9MsfGeEx/l+0ylkLMUX7ZKUT/TBo7Qwh/1yLDyQ2YL5m1pzUTMYbPWPW21soiecBzM8dk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8f23b0ff-89b7-4550-637c-08da3d79d3dd X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:50.5557 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ew+2t3blf0KtpkmvKd299suhyQZl6+yKHDz4T/ViyzyjWTsILUAM3SLFv59KweHyHCWGmAHd0XEvy7z7Iwg2Rw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/channel.c | 1656 ++++++++++++++++++++ 1 file changed, 1656 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/channel.c diff --git a/drivers/net/wireless/celeno/cl8k/channel.c b/drivers/net/wireless/celeno/cl8k/channel.c new file mode 100644 index 000000000000..777c5f749059 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/channel.c @@ -0,0 +1,1656 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "vif.h" +#include "dfs.h" +#include "reg/reg_defs.h" +#include "hw.h" +#include "utils.h" +#include "channel.h" + +#define CASE_CHAN2BITMAP_IDX_6G(_chan) { case _chan: return (b6g_ch ## _chan); } +#define CASE_CHAN2EXT_IDX_6G(_chan) { case _chan: return (ext_b6g_ch ## _chan); } +#define CASE_CHAN2IDX_5G(_chan) { case _chan: return (b5g_ch ## _chan); } +#define CASE_CHAN2IDX_2G(_chan) { case _chan: return (b24g_ch ## _chan); } + +#define CASE_BITMAP_IDX2FREQ_6G(_chan) { case (b6g_ch ## _chan): return FREQ6G(_chan); } +#define CASE_EXT_IDX2FREQ_6G(_chan) { case (ext_b6g_ch ## _chan): return FREQ6G(_chan); } +#define CASE_IDX2FREQ_5G(_chan) { case (b5g_ch ## _chan): return FREQ5G(_chan); } +#define CASE_IDX2FREQ_2G(_chan) { case (b24g_ch ## _chan): return FREQ2G(_chan); } + +#define INVALID_FREQ 0xffff + +static u8 cl_channel_to_bitmap_index_6g(struct cl_hw *cl_hw, u32 channel) +{ + switch (channel) { + CASE_CHAN2BITMAP_IDX_6G(1); + CASE_CHAN2BITMAP_IDX_6G(2); + CASE_CHAN2BITMAP_IDX_6G(5); + CASE_CHAN2BITMAP_IDX_6G(9); + CASE_CHAN2BITMAP_IDX_6G(13); + CASE_CHAN2BITMAP_IDX_6G(17); + CASE_CHAN2BITMAP_IDX_6G(21); + CASE_CHAN2BITMAP_IDX_6G(25); + CASE_CHAN2BITMAP_IDX_6G(29); + CASE_CHAN2BITMAP_IDX_6G(33); + CASE_CHAN2BITMAP_IDX_6G(37); + CASE_CHAN2BITMAP_IDX_6G(41); + CASE_CHAN2BITMAP_IDX_6G(45); + CASE_CHAN2BITMAP_IDX_6G(49); + CASE_CHAN2BITMAP_IDX_6G(53); + CASE_CHAN2BITMAP_IDX_6G(57); + CASE_CHAN2BITMAP_IDX_6G(61); + CASE_CHAN2BITMAP_IDX_6G(65); + CASE_CHAN2BITMAP_IDX_6G(69); + CASE_CHAN2BITMAP_IDX_6G(73); + CASE_CHAN2BITMAP_IDX_6G(77); + CASE_CHAN2BITMAP_IDX_6G(81); + CASE_CHAN2BITMAP_IDX_6G(85); + CASE_CHAN2BITMAP_IDX_6G(89); + CASE_CHAN2BITMAP_IDX_6G(93); + CASE_CHAN2BITMAP_IDX_6G(97); + CASE_CHAN2BITMAP_IDX_6G(101); + CASE_CHAN2BITMAP_IDX_6G(105); + CASE_CHAN2BITMAP_IDX_6G(109); + CASE_CHAN2BITMAP_IDX_6G(113); + CASE_CHAN2BITMAP_IDX_6G(117); + CASE_CHAN2BITMAP_IDX_6G(121); + CASE_CHAN2BITMAP_IDX_6G(125); + CASE_CHAN2BITMAP_IDX_6G(129); + CASE_CHAN2BITMAP_IDX_6G(133); + CASE_CHAN2BITMAP_IDX_6G(137); + CASE_CHAN2BITMAP_IDX_6G(141); + CASE_CHAN2BITMAP_IDX_6G(145); + CASE_CHAN2BITMAP_IDX_6G(149); + CASE_CHAN2BITMAP_IDX_6G(153); + CASE_CHAN2BITMAP_IDX_6G(157); + CASE_CHAN2BITMAP_IDX_6G(161); + CASE_CHAN2BITMAP_IDX_6G(165); + CASE_CHAN2BITMAP_IDX_6G(169); + CASE_CHAN2BITMAP_IDX_6G(173); + CASE_CHAN2BITMAP_IDX_6G(177); + CASE_CHAN2BITMAP_IDX_6G(181); + CASE_CHAN2BITMAP_IDX_6G(185); + CASE_CHAN2BITMAP_IDX_6G(189); + CASE_CHAN2BITMAP_IDX_6G(193); + CASE_CHAN2BITMAP_IDX_6G(197); + CASE_CHAN2BITMAP_IDX_6G(201); + CASE_CHAN2BITMAP_IDX_6G(205); + CASE_CHAN2BITMAP_IDX_6G(209); + CASE_CHAN2BITMAP_IDX_6G(213); + CASE_CHAN2BITMAP_IDX_6G(217); + CASE_CHAN2BITMAP_IDX_6G(221); + CASE_CHAN2BITMAP_IDX_6G(225); + CASE_CHAN2BITMAP_IDX_6G(229); + CASE_CHAN2BITMAP_IDX_6G(233); + }; + + return INVALID_CHAN_IDX; +} + +u8 cl_channel_to_ext_index_6g(struct cl_hw *cl_hw, u32 channel) +{ + switch (channel) { + CASE_CHAN2EXT_IDX_6G(1); + CASE_CHAN2EXT_IDX_6G(2); + CASE_CHAN2EXT_IDX_6G(3); + CASE_CHAN2EXT_IDX_6G(5); + CASE_CHAN2EXT_IDX_6G(7); + CASE_CHAN2EXT_IDX_6G(9); + CASE_CHAN2EXT_IDX_6G(11); + CASE_CHAN2EXT_IDX_6G(13); + CASE_CHAN2EXT_IDX_6G(15); + CASE_CHAN2EXT_IDX_6G(17); + CASE_CHAN2EXT_IDX_6G(19); + CASE_CHAN2EXT_IDX_6G(21); + CASE_CHAN2EXT_IDX_6G(23); + CASE_CHAN2EXT_IDX_6G(25); + CASE_CHAN2EXT_IDX_6G(27); + CASE_CHAN2EXT_IDX_6G(29); + CASE_CHAN2EXT_IDX_6G(31); + CASE_CHAN2EXT_IDX_6G(33); + CASE_CHAN2EXT_IDX_6G(35); + CASE_CHAN2EXT_IDX_6G(37); + CASE_CHAN2EXT_IDX_6G(39); + CASE_CHAN2EXT_IDX_6G(41); + CASE_CHAN2EXT_IDX_6G(43); + CASE_CHAN2EXT_IDX_6G(45); + CASE_CHAN2EXT_IDX_6G(47); + CASE_CHAN2EXT_IDX_6G(49); + CASE_CHAN2EXT_IDX_6G(51); + CASE_CHAN2EXT_IDX_6G(53); + CASE_CHAN2EXT_IDX_6G(55); + CASE_CHAN2EXT_IDX_6G(57); + CASE_CHAN2EXT_IDX_6G(59); + CASE_CHAN2EXT_IDX_6G(61); + CASE_CHAN2EXT_IDX_6G(63); + CASE_CHAN2EXT_IDX_6G(65); + CASE_CHAN2EXT_IDX_6G(67); + CASE_CHAN2EXT_IDX_6G(69); + CASE_CHAN2EXT_IDX_6G(71); + CASE_CHAN2EXT_IDX_6G(73); + CASE_CHAN2EXT_IDX_6G(75); + CASE_CHAN2EXT_IDX_6G(77); + CASE_CHAN2EXT_IDX_6G(79); + CASE_CHAN2EXT_IDX_6G(81); + CASE_CHAN2EXT_IDX_6G(83); + CASE_CHAN2EXT_IDX_6G(85); + CASE_CHAN2EXT_IDX_6G(87); + CASE_CHAN2EXT_IDX_6G(89); + CASE_CHAN2EXT_IDX_6G(91); + CASE_CHAN2EXT_IDX_6G(93); + CASE_CHAN2EXT_IDX_6G(95); + CASE_CHAN2EXT_IDX_6G(97); + CASE_CHAN2EXT_IDX_6G(99); + CASE_CHAN2EXT_IDX_6G(101); + CASE_CHAN2EXT_IDX_6G(103); + CASE_CHAN2EXT_IDX_6G(105); + CASE_CHAN2EXT_IDX_6G(107); + CASE_CHAN2EXT_IDX_6G(109); + CASE_CHAN2EXT_IDX_6G(111); + CASE_CHAN2EXT_IDX_6G(113); + CASE_CHAN2EXT_IDX_6G(115); + CASE_CHAN2EXT_IDX_6G(117); + CASE_CHAN2EXT_IDX_6G(119); + CASE_CHAN2EXT_IDX_6G(121); + CASE_CHAN2EXT_IDX_6G(123); + CASE_CHAN2EXT_IDX_6G(125); + CASE_CHAN2EXT_IDX_6G(127); + CASE_CHAN2EXT_IDX_6G(129); + CASE_CHAN2EXT_IDX_6G(131); + CASE_CHAN2EXT_IDX_6G(133); + CASE_CHAN2EXT_IDX_6G(135); + CASE_CHAN2EXT_IDX_6G(137); + CASE_CHAN2EXT_IDX_6G(139); + CASE_CHAN2EXT_IDX_6G(141); + CASE_CHAN2EXT_IDX_6G(143); + CASE_CHAN2EXT_IDX_6G(145); + CASE_CHAN2EXT_IDX_6G(147); + CASE_CHAN2EXT_IDX_6G(149); + CASE_CHAN2EXT_IDX_6G(151); + CASE_CHAN2EXT_IDX_6G(153); + CASE_CHAN2EXT_IDX_6G(155); + CASE_CHAN2EXT_IDX_6G(157); + CASE_CHAN2EXT_IDX_6G(159); + CASE_CHAN2EXT_IDX_6G(161); + CASE_CHAN2EXT_IDX_6G(163); + CASE_CHAN2EXT_IDX_6G(165); + CASE_CHAN2EXT_IDX_6G(167); + CASE_CHAN2EXT_IDX_6G(169); + CASE_CHAN2EXT_IDX_6G(171); + CASE_CHAN2EXT_IDX_6G(173); + CASE_CHAN2EXT_IDX_6G(175); + CASE_CHAN2EXT_IDX_6G(177); + CASE_CHAN2EXT_IDX_6G(179); + CASE_CHAN2EXT_IDX_6G(181); + CASE_CHAN2EXT_IDX_6G(183); + CASE_CHAN2EXT_IDX_6G(185); + CASE_CHAN2EXT_IDX_6G(187); + CASE_CHAN2EXT_IDX_6G(189); + CASE_CHAN2EXT_IDX_6G(191); + CASE_CHAN2EXT_IDX_6G(193); + CASE_CHAN2EXT_IDX_6G(195); + CASE_CHAN2EXT_IDX_6G(197); + CASE_CHAN2EXT_IDX_6G(199); + CASE_CHAN2EXT_IDX_6G(201); + CASE_CHAN2EXT_IDX_6G(203); + CASE_CHAN2EXT_IDX_6G(205); + CASE_CHAN2EXT_IDX_6G(207); + CASE_CHAN2EXT_IDX_6G(209); + CASE_CHAN2EXT_IDX_6G(211); + CASE_CHAN2EXT_IDX_6G(213); + CASE_CHAN2EXT_IDX_6G(215); + CASE_CHAN2EXT_IDX_6G(217); + CASE_CHAN2EXT_IDX_6G(219); + CASE_CHAN2EXT_IDX_6G(221); + CASE_CHAN2EXT_IDX_6G(223); + CASE_CHAN2EXT_IDX_6G(225); + CASE_CHAN2EXT_IDX_6G(227); + CASE_CHAN2EXT_IDX_6G(229); + CASE_CHAN2EXT_IDX_6G(231); + CASE_CHAN2EXT_IDX_6G(233); + }; + + return INVALID_CHAN_IDX; +} + +static u8 cl_channel_to_index_5g(struct cl_hw *cl_hw, u32 channel) +{ + switch (channel) { + CASE_CHAN2IDX_5G(36); + CASE_CHAN2IDX_5G(38); + CASE_CHAN2IDX_5G(40); + CASE_CHAN2IDX_5G(42); + CASE_CHAN2IDX_5G(44); + CASE_CHAN2IDX_5G(46); + CASE_CHAN2IDX_5G(48); + CASE_CHAN2IDX_5G(50); + CASE_CHAN2IDX_5G(52); + CASE_CHAN2IDX_5G(54); + CASE_CHAN2IDX_5G(56); + CASE_CHAN2IDX_5G(58); + CASE_CHAN2IDX_5G(60); + CASE_CHAN2IDX_5G(62); + CASE_CHAN2IDX_5G(64); + CASE_CHAN2IDX_5G(100); + CASE_CHAN2IDX_5G(102); + CASE_CHAN2IDX_5G(104); + CASE_CHAN2IDX_5G(106); + CASE_CHAN2IDX_5G(108); + CASE_CHAN2IDX_5G(110); + CASE_CHAN2IDX_5G(112); + CASE_CHAN2IDX_5G(114); + CASE_CHAN2IDX_5G(116); + CASE_CHAN2IDX_5G(118); + CASE_CHAN2IDX_5G(120); + CASE_CHAN2IDX_5G(122); + CASE_CHAN2IDX_5G(124); + CASE_CHAN2IDX_5G(126); + CASE_CHAN2IDX_5G(128); + /* 130 - invalid */ + CASE_CHAN2IDX_5G(132); + CASE_CHAN2IDX_5G(134); + CASE_CHAN2IDX_5G(136); + CASE_CHAN2IDX_5G(138); + CASE_CHAN2IDX_5G(140); + CASE_CHAN2IDX_5G(142); + CASE_CHAN2IDX_5G(144); + CASE_CHAN2IDX_5G(149); + CASE_CHAN2IDX_5G(151); + CASE_CHAN2IDX_5G(153); + CASE_CHAN2IDX_5G(155); + CASE_CHAN2IDX_5G(157); + CASE_CHAN2IDX_5G(159); + CASE_CHAN2IDX_5G(161); + /* 163 - invalid */ + CASE_CHAN2IDX_5G(165); + }; + + return INVALID_CHAN_IDX; +} + +static u8 cl_channel_to_index_24g(struct cl_hw *cl_hw, u32 channel) +{ + switch (channel) { + CASE_CHAN2IDX_2G(1); + CASE_CHAN2IDX_2G(2); + CASE_CHAN2IDX_2G(3); + CASE_CHAN2IDX_2G(4); + CASE_CHAN2IDX_2G(5); + CASE_CHAN2IDX_2G(6); + CASE_CHAN2IDX_2G(7); + CASE_CHAN2IDX_2G(8); + CASE_CHAN2IDX_2G(9); + CASE_CHAN2IDX_2G(10); + CASE_CHAN2IDX_2G(11); + CASE_CHAN2IDX_2G(12); + CASE_CHAN2IDX_2G(13); + CASE_CHAN2IDX_2G(14); + }; + + return INVALID_CHAN_IDX; +} + +u8 cl_channel_to_index(struct cl_hw *cl_hw, u32 channel) +{ + /* Calculate index for a given channel */ + if (cl_band_is_6g(cl_hw)) + return cl_channel_to_ext_index_6g(cl_hw, channel); + else if (cl_band_is_5g(cl_hw)) + return cl_channel_to_index_5g(cl_hw, channel); + else + return cl_channel_to_index_24g(cl_hw, channel); +} + +u8 cl_channel_to_bitmap_index(struct cl_hw *cl_hw, u32 channel) +{ + /* Calculate index for a given channel */ + if (cl_band_is_6g(cl_hw)) + return cl_channel_to_bitmap_index_6g(cl_hw, channel); + else if (cl_band_is_5g(cl_hw)) + return cl_channel_to_index_5g(cl_hw, channel); + else + return cl_channel_to_index_24g(cl_hw, channel); +} + +static u16 cl_channel_bitmap_idx_to_freq_6g(struct cl_hw *cl_hw, u8 index) +{ + switch (index) { + CASE_BITMAP_IDX2FREQ_6G(1); + CASE_BITMAP_IDX2FREQ_6G(2); + CASE_BITMAP_IDX2FREQ_6G(5); + CASE_BITMAP_IDX2FREQ_6G(9); + CASE_BITMAP_IDX2FREQ_6G(13); + CASE_BITMAP_IDX2FREQ_6G(17); + CASE_BITMAP_IDX2FREQ_6G(21); + CASE_BITMAP_IDX2FREQ_6G(25); + CASE_BITMAP_IDX2FREQ_6G(29); + CASE_BITMAP_IDX2FREQ_6G(33); + CASE_BITMAP_IDX2FREQ_6G(37); + CASE_BITMAP_IDX2FREQ_6G(41); + CASE_BITMAP_IDX2FREQ_6G(45); + CASE_BITMAP_IDX2FREQ_6G(49); + CASE_BITMAP_IDX2FREQ_6G(53); + CASE_BITMAP_IDX2FREQ_6G(57); + CASE_BITMAP_IDX2FREQ_6G(61); + CASE_BITMAP_IDX2FREQ_6G(65); + CASE_BITMAP_IDX2FREQ_6G(69); + CASE_BITMAP_IDX2FREQ_6G(73); + CASE_BITMAP_IDX2FREQ_6G(77); + CASE_BITMAP_IDX2FREQ_6G(81); + CASE_BITMAP_IDX2FREQ_6G(85); + CASE_BITMAP_IDX2FREQ_6G(89); + CASE_BITMAP_IDX2FREQ_6G(93); + CASE_BITMAP_IDX2FREQ_6G(97); + CASE_BITMAP_IDX2FREQ_6G(101); + CASE_BITMAP_IDX2FREQ_6G(105); + CASE_BITMAP_IDX2FREQ_6G(109); + CASE_BITMAP_IDX2FREQ_6G(113); + CASE_BITMAP_IDX2FREQ_6G(117); + CASE_BITMAP_IDX2FREQ_6G(121); + CASE_BITMAP_IDX2FREQ_6G(125); + CASE_BITMAP_IDX2FREQ_6G(129); + CASE_BITMAP_IDX2FREQ_6G(133); + CASE_BITMAP_IDX2FREQ_6G(137); + CASE_BITMAP_IDX2FREQ_6G(141); + CASE_BITMAP_IDX2FREQ_6G(145); + CASE_BITMAP_IDX2FREQ_6G(149); + CASE_BITMAP_IDX2FREQ_6G(153); + CASE_BITMAP_IDX2FREQ_6G(157); + CASE_BITMAP_IDX2FREQ_6G(161); + CASE_BITMAP_IDX2FREQ_6G(165); + CASE_BITMAP_IDX2FREQ_6G(169); + CASE_BITMAP_IDX2FREQ_6G(173); + CASE_BITMAP_IDX2FREQ_6G(177); + CASE_BITMAP_IDX2FREQ_6G(181); + CASE_BITMAP_IDX2FREQ_6G(185); + CASE_BITMAP_IDX2FREQ_6G(189); + CASE_BITMAP_IDX2FREQ_6G(193); + CASE_BITMAP_IDX2FREQ_6G(197); + CASE_BITMAP_IDX2FREQ_6G(201); + CASE_BITMAP_IDX2FREQ_6G(205); + CASE_BITMAP_IDX2FREQ_6G(209); + CASE_BITMAP_IDX2FREQ_6G(213); + CASE_BITMAP_IDX2FREQ_6G(217); + CASE_BITMAP_IDX2FREQ_6G(221); + CASE_BITMAP_IDX2FREQ_6G(225); + CASE_BITMAP_IDX2FREQ_6G(229); + CASE_BITMAP_IDX2FREQ_6G(233); + }; + + return INVALID_FREQ; +} + +u16 cl_channel_ext_idx_to_freq_6g(struct cl_hw *cl_hw, u8 index) +{ + switch (index) { + CASE_EXT_IDX2FREQ_6G(1); + CASE_EXT_IDX2FREQ_6G(2); + CASE_EXT_IDX2FREQ_6G(3); + CASE_EXT_IDX2FREQ_6G(5); + CASE_EXT_IDX2FREQ_6G(7); + CASE_EXT_IDX2FREQ_6G(9); + CASE_EXT_IDX2FREQ_6G(11); + CASE_EXT_IDX2FREQ_6G(13); + CASE_EXT_IDX2FREQ_6G(15); + CASE_EXT_IDX2FREQ_6G(17); + CASE_EXT_IDX2FREQ_6G(19); + CASE_EXT_IDX2FREQ_6G(21); + CASE_EXT_IDX2FREQ_6G(23); + CASE_EXT_IDX2FREQ_6G(25); + CASE_EXT_IDX2FREQ_6G(27); + CASE_EXT_IDX2FREQ_6G(29); + CASE_EXT_IDX2FREQ_6G(31); + CASE_EXT_IDX2FREQ_6G(33); + CASE_EXT_IDX2FREQ_6G(35); + CASE_EXT_IDX2FREQ_6G(37); + CASE_EXT_IDX2FREQ_6G(39); + CASE_EXT_IDX2FREQ_6G(41); + CASE_EXT_IDX2FREQ_6G(43); + CASE_EXT_IDX2FREQ_6G(45); + CASE_EXT_IDX2FREQ_6G(47); + CASE_EXT_IDX2FREQ_6G(49); + CASE_EXT_IDX2FREQ_6G(51); + CASE_EXT_IDX2FREQ_6G(53); + CASE_EXT_IDX2FREQ_6G(55); + CASE_EXT_IDX2FREQ_6G(57); + CASE_EXT_IDX2FREQ_6G(59); + CASE_EXT_IDX2FREQ_6G(61); + CASE_EXT_IDX2FREQ_6G(63); + CASE_EXT_IDX2FREQ_6G(65); + CASE_EXT_IDX2FREQ_6G(67); + CASE_EXT_IDX2FREQ_6G(69); + CASE_EXT_IDX2FREQ_6G(71); + CASE_EXT_IDX2FREQ_6G(73); + CASE_EXT_IDX2FREQ_6G(75); + CASE_EXT_IDX2FREQ_6G(77); + CASE_EXT_IDX2FREQ_6G(79); + CASE_EXT_IDX2FREQ_6G(81); + CASE_EXT_IDX2FREQ_6G(83); + CASE_EXT_IDX2FREQ_6G(85); + CASE_EXT_IDX2FREQ_6G(87); + CASE_EXT_IDX2FREQ_6G(89); + CASE_EXT_IDX2FREQ_6G(91); + CASE_EXT_IDX2FREQ_6G(93); + CASE_EXT_IDX2FREQ_6G(95); + CASE_EXT_IDX2FREQ_6G(97); + CASE_EXT_IDX2FREQ_6G(99); + CASE_EXT_IDX2FREQ_6G(101); + CASE_EXT_IDX2FREQ_6G(103); + CASE_EXT_IDX2FREQ_6G(105); + CASE_EXT_IDX2FREQ_6G(107); + CASE_EXT_IDX2FREQ_6G(109); + CASE_EXT_IDX2FREQ_6G(111); + CASE_EXT_IDX2FREQ_6G(113); + CASE_EXT_IDX2FREQ_6G(115); + CASE_EXT_IDX2FREQ_6G(117); + CASE_EXT_IDX2FREQ_6G(119); + CASE_EXT_IDX2FREQ_6G(121); + CASE_EXT_IDX2FREQ_6G(123); + CASE_EXT_IDX2FREQ_6G(125); + CASE_EXT_IDX2FREQ_6G(127); + CASE_EXT_IDX2FREQ_6G(129); + CASE_EXT_IDX2FREQ_6G(131); + CASE_EXT_IDX2FREQ_6G(133); + CASE_EXT_IDX2FREQ_6G(135); + CASE_EXT_IDX2FREQ_6G(137); + CASE_EXT_IDX2FREQ_6G(139); + CASE_EXT_IDX2FREQ_6G(141); + CASE_EXT_IDX2FREQ_6G(143); + CASE_EXT_IDX2FREQ_6G(145); + CASE_EXT_IDX2FREQ_6G(147); + CASE_EXT_IDX2FREQ_6G(149); + CASE_EXT_IDX2FREQ_6G(151); + CASE_EXT_IDX2FREQ_6G(153); + CASE_EXT_IDX2FREQ_6G(155); + CASE_EXT_IDX2FREQ_6G(157); + CASE_EXT_IDX2FREQ_6G(159); + CASE_EXT_IDX2FREQ_6G(161); + CASE_EXT_IDX2FREQ_6G(163); + CASE_EXT_IDX2FREQ_6G(165); + CASE_EXT_IDX2FREQ_6G(167); + CASE_EXT_IDX2FREQ_6G(169); + CASE_EXT_IDX2FREQ_6G(171); + CASE_EXT_IDX2FREQ_6G(173); + CASE_EXT_IDX2FREQ_6G(175); + CASE_EXT_IDX2FREQ_6G(177); + CASE_EXT_IDX2FREQ_6G(179); + CASE_EXT_IDX2FREQ_6G(181); + CASE_EXT_IDX2FREQ_6G(183); + CASE_EXT_IDX2FREQ_6G(185); + CASE_EXT_IDX2FREQ_6G(187); + CASE_EXT_IDX2FREQ_6G(189); + CASE_EXT_IDX2FREQ_6G(191); + CASE_EXT_IDX2FREQ_6G(193); + CASE_EXT_IDX2FREQ_6G(195); + CASE_EXT_IDX2FREQ_6G(197); + CASE_EXT_IDX2FREQ_6G(199); + CASE_EXT_IDX2FREQ_6G(201); + CASE_EXT_IDX2FREQ_6G(203); + CASE_EXT_IDX2FREQ_6G(205); + CASE_EXT_IDX2FREQ_6G(207); + CASE_EXT_IDX2FREQ_6G(209); + CASE_EXT_IDX2FREQ_6G(211); + CASE_EXT_IDX2FREQ_6G(213); + CASE_EXT_IDX2FREQ_6G(215); + CASE_EXT_IDX2FREQ_6G(217); + CASE_EXT_IDX2FREQ_6G(219); + CASE_EXT_IDX2FREQ_6G(221); + CASE_EXT_IDX2FREQ_6G(223); + CASE_EXT_IDX2FREQ_6G(225); + CASE_EXT_IDX2FREQ_6G(227); + CASE_EXT_IDX2FREQ_6G(229); + CASE_EXT_IDX2FREQ_6G(231); + CASE_EXT_IDX2FREQ_6G(233); + }; + + return INVALID_FREQ; +} + +static u16 cl_channel_idx_to_freq_5g(struct cl_hw *cl_hw, u8 index) +{ + switch (index) { + CASE_IDX2FREQ_5G(36); + CASE_IDX2FREQ_5G(38); + CASE_IDX2FREQ_5G(40); + CASE_IDX2FREQ_5G(42); + CASE_IDX2FREQ_5G(44); + CASE_IDX2FREQ_5G(46); + CASE_IDX2FREQ_5G(48); + CASE_IDX2FREQ_5G(50); + CASE_IDX2FREQ_5G(52); + CASE_IDX2FREQ_5G(54); + CASE_IDX2FREQ_5G(56); + CASE_IDX2FREQ_5G(58); + CASE_IDX2FREQ_5G(60); + CASE_IDX2FREQ_5G(62); + CASE_IDX2FREQ_5G(64); + CASE_IDX2FREQ_5G(100); + CASE_IDX2FREQ_5G(102); + CASE_IDX2FREQ_5G(104); + CASE_IDX2FREQ_5G(106); + CASE_IDX2FREQ_5G(108); + CASE_IDX2FREQ_5G(110); + CASE_IDX2FREQ_5G(112); + CASE_IDX2FREQ_5G(114); + CASE_IDX2FREQ_5G(116); + CASE_IDX2FREQ_5G(118); + CASE_IDX2FREQ_5G(120); + CASE_IDX2FREQ_5G(122); + CASE_IDX2FREQ_5G(124); + CASE_IDX2FREQ_5G(126); + CASE_IDX2FREQ_5G(128); + CASE_IDX2FREQ_5G(132); + CASE_IDX2FREQ_5G(134); + CASE_IDX2FREQ_5G(136); + CASE_IDX2FREQ_5G(138); + CASE_IDX2FREQ_5G(140); + CASE_IDX2FREQ_5G(142); + CASE_IDX2FREQ_5G(144); + CASE_IDX2FREQ_5G(149); + CASE_IDX2FREQ_5G(151); + CASE_IDX2FREQ_5G(153); + CASE_IDX2FREQ_5G(155); + CASE_IDX2FREQ_5G(157); + CASE_IDX2FREQ_5G(159); + CASE_IDX2FREQ_5G(161); + CASE_IDX2FREQ_5G(165); + }; + + return INVALID_FREQ; +} + +static u16 cl_channel_idx_to_freq_24g(struct cl_hw *cl_hw, u8 index) +{ + switch (index) { + CASE_IDX2FREQ_2G(1); + CASE_IDX2FREQ_2G(2); + CASE_IDX2FREQ_2G(3); + CASE_IDX2FREQ_2G(4); + CASE_IDX2FREQ_2G(5); + CASE_IDX2FREQ_2G(6); + CASE_IDX2FREQ_2G(7); + CASE_IDX2FREQ_2G(8); + CASE_IDX2FREQ_2G(9); + CASE_IDX2FREQ_2G(10); + CASE_IDX2FREQ_2G(11); + CASE_IDX2FREQ_2G(12); + CASE_IDX2FREQ_2G(13); + CASE_IDX2FREQ_2G(14); + }; + + return INVALID_FREQ; +} + +u16 cl_channel_idx_to_freq(struct cl_hw *cl_hw, u8 index) +{ + /* Calculate frequency of a given idnex */ + if (cl_band_is_6g(cl_hw)) + return cl_channel_bitmap_idx_to_freq_6g(cl_hw, index); + else if (cl_band_is_5g(cl_hw)) + return cl_channel_idx_to_freq_5g(cl_hw, index); + else + return cl_channel_idx_to_freq_24g(cl_hw, index); +} + +bool cl_channel_is_valid(struct cl_hw *cl_hw, u8 channel) +{ + if (cl_band_is_24g(cl_hw)) { + return (channel > 0 && channel <= 14); + } else if (cl_band_is_5g(cl_hw)) { + if (channel >= 36 && channel <= 64) + return ((channel & 0x1) == 0x0); + + if (channel >= 100 && channel <= 144) + return ((channel & 0x1) == 0x0); + + if (channel >= 149 && channel <= 161) + return ((channel & 0x1) == 0x1); + + if (channel == 165) + return true; + } else { + if (channel == 2) + return true; + + if (channel >= 1 && channel <= 233) + if ((channel & 0x3) == 0x1) + return true; + } + + return false; +} + +u32 cl_channel_num(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_band_num == 6) + return NUM_BITMAP_CHANNELS_6G; + + if (cl_hw->conf->ci_band_num == 5) + return NUM_CHANNELS_5G; + + return NUM_CHANNELS_24G; +} + +bool cl_channel_is_dfs(struct cl_hw *cl_hw, u8 channel) +{ + if (!cl_band_is_5g(cl_hw)) + return false; + + return channel >= 36 && channel <= 144; +} + +u32 cl_channel_get_cac_time_ms(struct cl_hw *cl_hw, u8 channel) +{ + if (!cl_band_is_5g(cl_hw)) + return 0; + + if (!cl_channel_is_dfs(cl_hw, channel)) + return 0; + + /* FIXME: CAC time for weather channels may differ for some regions */ + if (channel >= 120 && channel <= 128) + return IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS; + + return IEEE80211_DFS_MIN_CAC_TIME_MS; +} + +static void _cl_fill_channel_info(struct cl_hw *cl_hw, u8 bw, u8 ch_idx, u8 channel, + u8 country_max_power_q2, u8 max_power_q2, + u32 flags, u32 dfs_cac_ms) +{ + struct cl_chan_info *chan_info = &cl_hw->channel_info.channels[bw][ch_idx]; + + chan_info->channel = channel; + chan_info->country_max_power_q2 = country_max_power_q2; + chan_info->max_power_q2 = max_power_q2; + chan_info->flags = flags; + chan_info->dfs_cac_ms = dfs_cac_ms; +} + +static void cl_fill_channel_info(struct cl_hw *cl_hw, u8 bw, u8 ch_idx, u8 channel, + u8 country_max_power_q2, u8 max_power_q2) +{ + _cl_fill_channel_info(cl_hw, bw, ch_idx, channel, country_max_power_q2, max_power_q2, 0, 0); +} + +static void cl_fill_channel_info_5g(struct cl_hw *cl_hw, u8 bw, u8 ch_idx, u8 channel, + u8 country_max_power_q2, u8 max_power_q2) +{ + u32 flags = 0; + u32 dfs_cac_ms = 0; + + if (cl_hw->conf->ci_ieee80211h && cl_channel_is_dfs(cl_hw, channel)) { + flags |= IEEE80211_CHAN_RADAR; + dfs_cac_ms = cl_channel_get_cac_time_ms(cl_hw, channel); + } + + _cl_fill_channel_info(cl_hw, bw, ch_idx, channel, country_max_power_q2, + max_power_q2, flags, dfs_cac_ms); +} + +static inline s32 cl_convert_str_int_q2(s8 *str) +{ + s32 x, y; + + if (!str) + return 0; + if (sscanf(str, "%d.%2d", &x, &y) != 2) + return 0; + if (!strstr(str, ".")) + return x * 4; + if (y < 10 && (*(strstr(str, ".") + 1) != '0')) + y *= 10; + return (x * 100 + y) * 4 / 100; +} + +static int cl_parse_reg_domain(struct cl_hw *cl_hw, char **str) +{ + /* Check if current line contains "FCC" or "ETSI" */ + char *token = strsep(str, "\n"); + + if (!token) + goto err; + + if (strstr(token, "FCC")) { + cl_hw->channel_info.standard = NL80211_DFS_FCC; + cl_dbg_info(cl_hw, "Standard = FCC\n"); + return 0; + } + + if (strstr(token, "ETSI")) { + cl_hw->channel_info.standard = NL80211_DFS_ETSI; + cl_dbg_info(cl_hw, "Standard = ETSI\n"); + return 0; + } + +err: + cl_dbg_err(cl_hw, "Illegal regulatory domain\n"); + cl_hw->channel_info.standard = NL80211_DFS_UNSET; + return -1; +} + +#define MAX_CC_STR 4 +#define MAX_BW_STR 8 + +static bool cl_parse_channel_info_txt(struct cl_hw *cl_hw) +{ + /* + * Example of country information in channel_info.txt: + * + * [EU (European Union)ETSI] + * 2.4GHz/20MHz: 2412(1,20) 2417(2,20) 2422(3,20) 2427(4,20) 2432(5,20) 2437(6,20) + * 2442(7,20) 2447(8,20) 2452(9,20) 2457(10,20) 2462(11,20) 2467(12,20) + * 2472(13,20) + * 2.4GHz/40MHz: 2422(1,20) 2427(2,20) 2432(3,20) 2437(4,20) 2442(5,20) 2447(6,20) + * 2452(7,20) 2457(8,20) 2462(9,20) 2467(10,20) 2472(11,20) + * 5.2GHz/20MHz: 5180(36,23) 5200(40,23) 5220(44,23) 5240(48,23) 5260(52,23) 5280(56,23) + * 5300(60,23) 5320(64,23) 5500(100,30) 5520(104,30) 5540(108,30) + * 5560(112,30)5580(116,30) 5600(120,30) 5620(124,30) 5640(128,30) + * 5660(132,30) 5680(136,30) 5700(140,30) + * 5.2GHz/40MHz: 5180(36,23) 5200(40,23) 5220(44,23) 5240(48,23) 5260(52,23) 5280(56,23) + * 5300(60,23) 5310(64,23) 5510(100,30) 5510(104,30) 5550(108,30) + * 5550(112,30) 5590(116,30) 5590(120,30) 5630(124,30) 5630(128,30) + * 5670(132,30) 5670(136,30) + * 5.2GHz/80MHz: 5180(36,23) 5200(40,23) 5220(44,23) 5240(48,23) 5260(52,23) 5280(56,23) + * 5300(60,23) 5310(64,23) 5510(100,30) 5510(104,30) 5550(108,30) + * 5550(112,30) 5590(116,30) 5590(120,30) 5630(124,30) 5630(128,30) + * 5.2GHz/160MHz: 5180(36,23) 5200(40,23) 5220(44,23) 5240(48,23) 5260(52,23) 5280(56,23) + * 5300(60,23) 5310(64,23) 5510(100,30) 5510(104,30) 5550(108,30) + * 5550(112,30) 5590(116,30) 5590(120,30) 5630(124,30) 5630(128,30) + */ + + char *buf = NULL, *ptr = NULL; + char cc_str[MAX_CC_STR] = {0}; + char bw_str[MAX_BW_STR] = {0}; + size_t size; + u8 bw, bw_mhz, bw_max, max_power, channel, i; + char file_name[CL_FILENAME_MAX] = {0}; + + snprintf(file_name, sizeof(file_name), "channel_info_chip%d.txt", cl_hw->chip->idx); + + /* Read channel_info.txt into buf */ + size = cl_file_open_and_read(cl_hw->chip, file_name, &buf); + + if (!buf) + return false; + + /* Jump to the correct country in the file */ + snprintf(cc_str, sizeof(cc_str), "[%s", cl_hw->chip->conf->ci_country_code); + ptr = strstr(buf, cc_str); + if (!ptr) + goto out; + + if (cl_parse_reg_domain(cl_hw, &ptr)) + goto out; + + /* Jump to the relevant band */ + if (cl_band_is_24g(cl_hw)) { + bw_max = CHNL_BW_40; + ptr = strstr(ptr, "2.4GHz"); + } else if (cl_band_is_5g(cl_hw)) { + ptr = strstr(ptr, "5.2GHz"); + bw_max = CHNL_BW_160; + } else { + ptr = strstr(ptr, "6GHz"); + bw_max = CHNL_BW_160; + } + + for (bw = 0; bw <= bw_max; bw++) { + if (!ptr) + goto out; + + i = 0; + + /* Jump to relevant bandwidth */ + bw_mhz = BW_TO_MHZ(bw); + snprintf(bw_str, sizeof(bw_str), "%uMHz:", bw_mhz); + ptr = strstr(ptr, bw_str); + + /* Iterate until end of line and parse (channel, max_power) */ + while (ptr && (ptr + 1) && (*(ptr + 1) != '\n')) { + u32 flags = 0, dfs_cac_ms = 0; + + ptr = strstr(ptr, "("); + if (!ptr) + goto out; + + if (sscanf(ptr, "(%hhu,%hhu)", &channel, &max_power) != 2) + goto out; + + if (!cl_channel_is_valid(cl_hw, channel) || + i == cl_channel_num(cl_hw)) + goto out; + + if (cl_hw->conf->ci_ieee80211h && cl_channel_is_dfs(cl_hw, channel)) { + flags |= IEEE80211_CHAN_RADAR; + dfs_cac_ms = cl_channel_get_cac_time_ms(cl_hw, channel); + } + + _cl_fill_channel_info(cl_hw, bw, i, channel, max_power << 2, + max_power << 2, flags, dfs_cac_ms); + + i++; + ptr = strstr(ptr, ")"); + } + } + + kfree(buf); + return true; + +out: + kfree(buf); + return false; +} + +static bool cl_is_parsing_success(struct cl_hw *cl_hw) +{ + /* Check that there is at least one channel in any bw */ + u8 bw; + u8 max_bw = BAND_IS_5G_6G(cl_hw) ? CHNL_BW_160 : CHNL_BW_40; + + for (bw = 0; bw <= max_bw; bw++) + if (!cl_hw->channel_info.channels[bw][0].channel) + return false; + + return true; +} + +static void cl_chan_info_set_max_bw_6g(struct cl_hw *cl_hw) +{ + u8 i, bw, bw_cnt, channel, channel_gap; + struct cl_chan_info *chan_info; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + chan_info = cl_hw->channel_info.channels[bw]; + bw_cnt = 0; + + for (i = 0; i < NUM_BITMAP_CHANNELS_6G; i++) { + channel = chan_info[i].channel; + + if (channel == 0) + break; + + channel_gap = channel - START_CHAN_IDX_6G; + + /* + * Verify that we don't combine together channels + * from different 80MHz sections + */ + if ((channel_gap % CL_160MHZ_CH_GAP) == 0) + bw_cnt = 0; + + if (i > 0) + bw_cnt++; + + /* Verify that we don't make illegal 80MHz combination */ + if ((channel_gap % CL_80MHZ_CH_GAP == 0) && bw_cnt == 3) + bw_cnt = 0; + + /* Verify that we don't make illegal 40MHz combination */ + if ((channel_gap % CL_40MHZ_CH_GAP == 0) && bw_cnt == 1) + bw_cnt = 0; + + if ((((bw_cnt + 1) % CL_160MHZ_HOP) == 0) && bw == CHNL_BW_160) { + chan_info[i].max_bw = CHNL_BW_160; + chan_info[i - 1].max_bw = CHNL_BW_160; + chan_info[i - 2].max_bw = CHNL_BW_160; + chan_info[i - 3].max_bw = CHNL_BW_160; + chan_info[i - 4].max_bw = CHNL_BW_160; + chan_info[i - 5].max_bw = CHNL_BW_160; + chan_info[i - 6].max_bw = CHNL_BW_160; + chan_info[i - 7].max_bw = CHNL_BW_160; + } else if ((((bw_cnt + 1) % CL_80MHZ_HOP) == 0) && (bw == CHNL_BW_80)) { + chan_info[i].max_bw = CHNL_BW_80; + chan_info[i - 1].max_bw = CHNL_BW_80; + chan_info[i - 2].max_bw = CHNL_BW_80; + chan_info[i - 3].max_bw = CHNL_BW_80; + } else if ((((bw_cnt + 1) % CL_40MHZ_HOP) == 0) && (bw >= CHNL_BW_40)) { + chan_info[i].max_bw = CHNL_BW_40; + chan_info[i - 1].max_bw = CHNL_BW_40; + } else { + chan_info[i].max_bw = CHNL_BW_20; + } + } + } +} + +static void cl_chan_info_set_max_bw_5g(struct cl_hw *cl_hw) +{ + u8 i, bw, bw_cnt, channel, channel_gap; + struct cl_chan_info *chan_info; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + chan_info = cl_hw->channel_info.channels[bw]; + bw_cnt = 0; + + for (i = 0; i < NUM_CHANNELS_5G; i++) { + channel = chan_info[i].channel; + + if (channel == 0) + break; + + if (channel < 149) + channel_gap = channel - 36; + else + channel_gap = channel - 149; + + /* + * Verify that we don't combine together channels from + * different 80MHz sections + * (i.e. 36-48 can be combined into 80MHz channels, unlike 40-52) + */ + if ((channel_gap % CL_160MHZ_CH_GAP) == 0) + bw_cnt = 0; + + /* Check if 20MHz channels can be combined into 40MHz or 80MHz channels */ + if (i > 0) { + /* + * Verify that we don't combine together unsecutive channels + * (like 36 and 44 when 40 is missing) + */ + if ((chan_info[i].channel - chan_info[i - 1].channel) > + CL_20MHZ_CH_GAP) + bw_cnt = 0; + else + bw_cnt++; + } + + /* Verify that we don't make illegal 80MHz combination (like 44-56) */ + if ((channel_gap % CL_80MHZ_CH_GAP == 0) && bw_cnt == 3) + bw_cnt = 0; + + /* Verify that we don't make illegal 40MHz combination (like 40-44) */ + if ((channel_gap % CL_40MHZ_CH_GAP == 0) && bw_cnt == 1) + bw_cnt = 0; + + if ((((bw_cnt + 1) % CL_160MHZ_HOP) == 0) && bw == CHNL_BW_160) { + chan_info[i].max_bw = CHNL_BW_160; + chan_info[i - 1].max_bw = CHNL_BW_160; + chan_info[i - 2].max_bw = CHNL_BW_160; + chan_info[i - 3].max_bw = CHNL_BW_160; + chan_info[i - 4].max_bw = CHNL_BW_160; + chan_info[i - 5].max_bw = CHNL_BW_160; + chan_info[i - 6].max_bw = CHNL_BW_160; + chan_info[i - 7].max_bw = CHNL_BW_160; + } else if ((((bw_cnt + 1) % CL_80MHZ_HOP) == 0) && bw == CHNL_BW_80) { + chan_info[i].max_bw = CHNL_BW_80; + chan_info[i - 1].max_bw = CHNL_BW_80; + chan_info[i - 2].max_bw = CHNL_BW_80; + chan_info[i - 3].max_bw = CHNL_BW_80; + } else if ((((bw_cnt + 1) % CL_40MHZ_HOP) == 0) && bw >= CHNL_BW_40) { + chan_info[i].max_bw = CHNL_BW_40; + chan_info[i - 1].max_bw = CHNL_BW_40; + } else { + chan_info[i].max_bw = CHNL_BW_20; + } + } + } +} + +static void cl_chan_info_set_max_bw_24g(struct cl_hw *cl_hw) +{ + u8 i, bw, channel; + struct cl_chan_info *chan_info; + + for (bw = 0; bw < CHNL_BW_80; bw++) { + chan_info = cl_hw->channel_info.channels[bw]; + + for (i = 0; i < NUM_CHANNELS_24G; i++) { + channel = chan_info[i].channel; + + if (channel == 0) + break; + + if (channel < 14) + chan_info[i].max_bw = CHNL_BW_40; + else + chan_info[i].max_bw = CHNL_BW_20; + } + } +} + +static void cl_chan_info_set_max_bw(struct cl_hw *cl_hw) +{ + if (cl_band_is_6g(cl_hw)) + cl_chan_info_set_max_bw_6g(cl_hw); + else if (cl_band_is_5g(cl_hw)) + cl_chan_info_set_max_bw_5g(cl_hw); + else + cl_chan_info_set_max_bw_24g(cl_hw); +} + +static void cl_chan_info_dbg(struct cl_hw *cl_hw) +{ + struct cl_chan_info *chan_info; + u32 max_power_integer, max_power_fraction; + u8 i, j; + + for (i = 0; i < CHNL_BW_MAX; i++) { + cl_dbg_info(cl_hw, "Bandwidth = %uMHz\n", BW_TO_MHZ(i)); + for (j = 0; j < cl_channel_num(cl_hw); j++) { + chan_info = &cl_hw->channel_info.channels[i][j]; + + if (chan_info->channel == 0) + continue; + + max_power_integer = (chan_info->max_power_q2 / 4); + max_power_fraction = + (100 * (chan_info->max_power_q2 - 4 * max_power_integer) / 4); + + cl_dbg_info(cl_hw, "Channel = %u, max EIRP = %3u.%02u, bw = %uMHz\n", + chan_info->channel, max_power_integer, + max_power_fraction, BW_TO_MHZ(chan_info->max_bw)); + } + } +} + +/* Band 6G - default power */ +#define UNII_5_POW_Q2 (27 << 2) +#define UNII_6_POW_Q2 (27 << 2) +#define UNII_7_POW_Q2 (27 << 2) +#define UNII_8_POW_Q2 (27 << 2) + +/* Band 5G - default power */ +/* Default regulatory domain: + * country US: DFS-FCC + * (2400 - 2472 @ 40), (N/A, 30), (N/A) + * (5150 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW + * (5250 - 5350 @ 80), (N/A, 23), (0 ms), DFS, AUTO-BW + * (5470 - 5730 @ 160), (N/A, 23), (0 ms), DFS + * (5730 - 5850 @ 80), (N/A, 30), (N/A), AUTO-BW + * (5850 - 5895 @ 40), (N/A, 27), (N/A), NO-OUTDOOR, AUTO-BW, PASSIVE-SCAN + * (57240 - 71000 @ 2160), (N/A, 40), (N/A) + */ +#define UNII_1_POW_Q2 (23 << 2) +#define UNII_2_POW_Q2 (23 << 2) +#define UNII_2_EXT_POW_Q2 (23 << 2) +#define UNII_3_POW_Q2 (30 << 2) + +/* Band 2.4G - default power */ +#define BAND_24G_POW_Q2 (30 << 2) + +static void cl_set_default_channel_info_6g(struct cl_hw *cl_hw) +{ + u8 i, j, k; + + for (i = 0; i < CHNL_BW_MAX; i++) { + k = 0; + + /* Ch2 is a special case */ + cl_fill_channel_info(cl_hw, i, k, 2, UNII_5_POW_Q2, UNII_5_POW_Q2); + k++; + + for (j = START_CHAN_IDX_UNII5; j <= END_CHAN_IDX_UNII5; j += 4) { + cl_fill_channel_info(cl_hw, i, k, j, UNII_5_POW_Q2, UNII_5_POW_Q2); + k++; + } + + for (j = START_CHAN_IDX_UNII6; j <= END_CHAN_IDX_UNII6; j += 4) { + cl_fill_channel_info(cl_hw, i, k, j, UNII_6_POW_Q2, UNII_6_POW_Q2); + k++; + } + + for (j = START_CHAN_IDX_UNII7; j <= END_CHAN_IDX_UNII7; j += 4) { + cl_fill_channel_info(cl_hw, i, k, j, UNII_7_POW_Q2, UNII_7_POW_Q2); + k++; + } + + for (j = START_CHAN_IDX_UNII8; j <= END_CHAN_IDX_UNII8; j += 4) { + /* Channel 233 is valid only in 20MHz */ + if (i != CHNL_BW_20 && j == END_CHAN_IDX_UNII8) + break; + + cl_fill_channel_info(cl_hw, i, k, j, UNII_8_POW_Q2, UNII_8_POW_Q2); + k++; + } + } +} + +static void cl_set_default_channel_info_5g(struct cl_hw *cl_hw) +{ + u8 i, j, k; + + for (i = 0; i < CHNL_BW_MAX; i++) { + k = 0; + + for (j = 36; j <= 48; j += 4) { + cl_fill_channel_info_5g(cl_hw, i, k, j, UNII_1_POW_Q2, UNII_1_POW_Q2); + k++; + } + + for (j = 52; j <= 64; j += 4) { + cl_fill_channel_info_5g(cl_hw, i, k, j, UNII_2_POW_Q2, UNII_2_POW_Q2); + k++; + } + + for (j = 100; j <= 144; j += 4) { + /* 160MHz is supported only in channel 36 - 64 and 100 - 128 */ + if (i == CHNL_BW_160 && j == 132) + return; + + cl_fill_channel_info_5g(cl_hw, i, k, j, + UNII_2_EXT_POW_Q2, UNII_2_EXT_POW_Q2); + k++; + } + + for (j = 149; j <= 165; j += 4) { + /* Channel 165 is valid only in 20MHz */ + if (i != CHNL_BW_20 && j == 165) + break; + + cl_fill_channel_info_5g(cl_hw, i, k, j, UNII_3_POW_Q2, UNII_3_POW_Q2); + k++; + } + } +} + +static void cl_set_default_channel_info_24g(struct cl_hw *cl_hw) +{ + u8 i, j; + + for (i = 0; i <= CHNL_BW_40; i++) + for (j = 0; j < 13; j++) + cl_fill_channel_info(cl_hw, i, j, j + 1, BAND_24G_POW_Q2, BAND_24G_POW_Q2); +} + +static void cl_set_default_channel_info(struct cl_hw *cl_hw) +{ + struct cl_channel_info *channel_info = &cl_hw->channel_info; + + memset(channel_info->channels, 0, sizeof(channel_info->channels)); + + channel_info->standard = NL80211_DFS_FCC; + + if (cl_band_is_6g(cl_hw)) + cl_set_default_channel_info_6g(cl_hw); + else if (cl_band_is_5g(cl_hw)) + cl_set_default_channel_info_5g(cl_hw); + else + cl_set_default_channel_info_24g(cl_hw); +} + +/* + * cl_hardware_power_table_update: Applies individual regulatory table entry + * Inputs: cl_hw - pointer to cl_hw + * bw_mhz - current bandwidth in MHz + * chan_start - match channels greater or equal to chan_start + * chan_end - match channels less than chan_end + * reg_pwr - ensure channel_info.channels[bw][ch_idx].max_power does not exceed this + * Output: updated channel_info.channels[bw][ch_idx].max_power + * and channel_info.channels[bw][ch_idx].max_total_power + * on all channels that match specified range + */ +static void cl_hardware_power_table_update(struct cl_hw *cl_hw, u8 bw_mhz, + u8 chan_start, u8 chan_end, u8 pwr_q2) +{ + struct cl_chan_info *chan_info = NULL; + u8 bw = 0; + u8 ch_idx = 0; + bool ch_found = false; + bool is_24g = cl_band_is_24g(cl_hw); + + if (bw_mhz == 20 || bw_mhz == 40 || (!is_24g && (bw_mhz == 80 || bw_mhz == 160))) { + bw = MHZ_TO_BW(bw_mhz); + } else { + cl_dbg_err(cl_hw, "Invalid bw %u\n", bw_mhz); + return; + } + + /* Iterate through all cl_channels[bw][ch_idx] - to find all matches */ + for (ch_idx = 0; ch_idx < cl_channel_num(cl_hw); ch_idx++) { + chan_info = &cl_hw->channel_info.channels[bw][ch_idx]; + + if (chan_start <= chan_info->channel && chan_info->channel < chan_end) { + ch_found = true; + + /* + * Max-Power = + * minimum beteen hardware_power_table and country code definition + */ + chan_info->max_power_q2 = min(pwr_q2, chan_info->max_power_q2); + chan_info->hardware_max_power_q2 = pwr_q2; + } + } + + if (!ch_found) + cl_dbg_info(cl_hw, "Skipping invalid channel range: %u - %u\n", + chan_start, chan_end); +} + +/* + * cl_hardware_power_table_parse(): + * Iterate through hardware power table entries and apply each one. + * Expected format: + * bw1(chan1=reg_pwr1;chan2=reg_pwr2;...)#bw2(chan3=reg_pwr3;chan4=reg_pwr4;...) ... + * Example: + * 20(36=22.0;40=22.75;149=21.75)#40(36=22.5;40=23.0;149=21.75)#80(36=21.75;40=21.5;149=22.25) + */ +static void cl_hardware_power_table_parse(struct cl_hw *cl_hw) +{ + char *table_str = NULL; + char *table_str_p = NULL; + char *channel_str = NULL; + char *channel_str_p = NULL; + char *bw_set = NULL; + char *out_tok = NULL; + s8 in_reg_pwr[16] = {0}; + u8 bw_mhz = 0; + u8 chan_start = 0; + u8 chan_end = 0; + u8 curr_pwr_q2 = 0; + u8 next_pwr_q2 = 0; + + if (strlen(cl_hw->conf->ce_hardware_power_table) == 0) + return; /* Not configured */ + + table_str_p = kzalloc(CL_MAX_STR_BUFFER_SIZE / 2, GFP_KERNEL); + if (!table_str_p) + return; + + channel_str_p = kzalloc(CL_MAX_STR_BUFFER_SIZE / 2, GFP_KERNEL); + if (!channel_str_p) { + kfree(table_str_p); + cl_dbg_err(cl_hw, "Failed to allocate channel_str\n"); + return; + } + + table_str = table_str_p; + + strncpy(table_str, + cl_hw->conf->ce_hardware_power_table, + (CL_MAX_STR_BUFFER_SIZE / 2) - 1); + + /* Iterate through all bandwidth sets included in table_str */ + bw_set = strsep(&table_str, "#"); + while (bw_set) { + channel_str = channel_str_p; + if (sscanf(bw_set, "%hhu(%s)", &bw_mhz, channel_str) != 2) { + bw_set = strsep(&table_str, "#"); + continue; + } + + /* Iterate through each channel in this bandwidth set */ + chan_start = 0; + chan_end = 0; + curr_pwr_q2 = 0; + next_pwr_q2 = 0; + out_tok = strsep(&channel_str, ";"); + + while (out_tok) { + if (sscanf(out_tok, "%hhu=%s", &chan_end, in_reg_pwr) == 2) { + next_pwr_q2 = cl_convert_str_int_q2(in_reg_pwr); + + /* Apply regulatory table rule. Skip initial case */ + if (curr_pwr_q2 != 0 && chan_start != 0) + cl_hardware_power_table_update(cl_hw, bw_mhz, chan_start, + chan_end, curr_pwr_q2); + + /* Prepare next iteration */ + chan_start = chan_end; + curr_pwr_q2 = next_pwr_q2; + } + out_tok = strsep(&channel_str, ";"); + } + + /* Handle last channel case */ + if (next_pwr_q2 != 0 && chan_start != 0) { + u8 chan_end; + + if (cl_band_is_6g(cl_hw)) + chan_end = 234; + else if (cl_band_is_5g(cl_hw)) + chan_end = 166; + else + chan_end = 15; + + cl_hardware_power_table_update(cl_hw, bw_mhz, chan_start, + chan_end, curr_pwr_q2); + } + + bw_set = strsep(&table_str, "#"); + } + + kfree(table_str_p); + kfree(channel_str_p); +} + +static void cl_chan_info_ieee80211_update_max_power(struct cl_hw *cl_hw) +{ + struct ieee80211_supported_band *sband = &cl_hw->sband; + struct ieee80211_channel *chan = NULL; + int i = 0, channel; + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; + channel = ieee80211_frequency_to_channel(chan->center_freq); + chan->max_power = cl_chan_info_get_max_power(cl_hw, channel); + } +} + +void cl_chan_info_init(struct cl_hw *cl_hw) +{ + struct cl_channel_info *channel_info = &cl_hw->channel_info; + + channel_info->use_channel_info = true; + + if (channel_info->use_channel_info) { + if (!cl_parse_channel_info_txt(cl_hw) || !cl_is_parsing_success(cl_hw)) { + CL_DBG_WARNING(cl_hw, "Error parsing channel_info.txt. Using default!\n"); + cl_set_default_channel_info(cl_hw); + } + + cl_chan_info_ieee80211_update_max_power(cl_hw); + cl_chan_info_set_max_bw(cl_hw); + cl_chan_info_dbg(cl_hw); + } else { + cl_set_default_channel_info(cl_hw); + } + + cl_hardware_power_table_parse(cl_hw); +} + +void cl_chan_info_deinit(struct cl_hw *cl_hw) +{ + if (cl_hw->channel_info.rd && + cl_hw->channel_info.use_channel_info) + kfree(cl_hw->channel_info.rd); +} + +struct cl_chan_info *cl_chan_info_get(struct cl_hw *cl_hw, u8 channel, u8 bw) +{ + int i = 0; + struct cl_chan_info *chan_info; + + for (i = 0; i < cl_channel_num(cl_hw); i++) { + chan_info = &cl_hw->channel_info.channels[bw][i]; + + if (chan_info->channel == channel) + return chan_info; + } + + return NULL; +} + +u8 cl_chan_info_get_max_bw(struct cl_hw *cl_hw, u8 channel) +{ + s8 bw = 0; + + for (bw = CHNL_BW_160; bw > CHNL_BW_20; bw--) + if (cl_chan_info_get(cl_hw, channel, bw)) + return (u8)bw; + + return CHNL_BW_20; +} + +s16 cl_chan_info_get_eirp_limit_q8(struct cl_hw *cl_hw, u8 bw) +{ + /* Eirp_limit = min(country_limit, hw_limit) */ + struct cl_chan_info *chan_info = cl_chan_info_get(cl_hw, cl_hw->channel, bw); + + return chan_info ? (chan_info->max_power_q2 << 6) : CL_DEFAULT_CHANNEL_POWER_Q8; +} + +u8 cl_chan_info_get_max_power(struct cl_hw *cl_hw, u8 channel) +{ + struct cl_chan_info *chan_info; + u8 bw = 0; + u8 max_power_q2 = 0; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + chan_info = cl_chan_info_get(cl_hw, channel, bw); + + if (!chan_info) + continue; + + if (chan_info->max_power_q2 > max_power_q2) + max_power_q2 = chan_info->max_power_q2; + } + + return max_power_q2 >> 2; +} + +static void cl_chan_update_channel_info(struct cl_hw *cl_hw, struct ieee80211_channel *channel) +{ + u8 bw; + u32 chan = ieee80211_frequency_to_channel(channel->center_freq); + struct cl_chan_info *chan_info; + + for (bw = CHNL_BW_20; bw < CHNL_BW_MAX; bw++) { + chan_info = cl_chan_info_get(cl_hw, chan, bw); + if (!chan_info || chan_info->channel == 0) + continue; + + chan_info->max_power_q2 = channel->max_power << 2; + chan_info->country_max_power_q2 = channel->max_reg_power << 2; + chan_info->flags = channel->flags; + chan_info->dfs_cac_ms = channel->dfs_cac_ms; + } +} + +void cl_chan_update_channels_info(struct cl_hw *cl_hw, + const struct ieee80211_supported_band *cfg_band) +{ + int i = 0; + + spin_lock_bh(&cl_hw->channel_info_lock); + for (i = 0; i < cfg_band->n_channels; ++i) + cl_chan_update_channel_info(cl_hw, &cfg_band->channels[i]); + spin_unlock_bh(&cl_hw->channel_info_lock); +} + +#define CENTER_FREQ_24G_BW_80MHZ 2442 +#define CENTER_FREQ_24G_BW_160MHZ 2482 + +static int cl_chandef_calc_6g(struct cl_hw *cl_hw, u16 freq, u32 bw, u32 offset, + u32 *primary, u32 *center) +{ + u32 bw_mhz = BW_TO_MHZ(bw); + u32 min_freq = 0; + + if (freq == FREQ6G(2)) { + min_freq = FREQ6G(2); + } else if (freq >= FREQ6G(1) && freq <= FREQ6G(233)) { + min_freq = FREQ6G(1); + } else { + cl_dbg_err(cl_hw, "Invalid frequecy - %u\n", freq); + return -EINVAL; + } + + *primary = freq - (freq - min_freq) % 20; + *center = *primary - (*primary - min_freq) % bw_mhz + offset; + + return 0; +} + +static int cl_chandef_calc_5g(struct cl_hw *cl_hw, u16 freq, u32 bw, u32 offset, + u32 *primary, u32 *center) +{ + u32 bw_mhz = BW_TO_MHZ(bw); + u32 min_freq = 0; + + if ((freq >= FREQ5G(36) && freq <= FREQ5G(64)) || + (freq >= FREQ5G(100) && freq <= FREQ5G(144))) { + min_freq = FREQ5G(36); + } else if (freq >= FREQ5G(149) && freq <= FREQ5G(165)) { + min_freq = FREQ5G(149); + } else { + cl_dbg_err(cl_hw, "Invalid frequecy - %u\n", freq); + return -EINVAL; + } + + *primary = freq - (freq - min_freq) % 20; + *center = *primary - (*primary - min_freq) % bw_mhz + offset; + + return 0; +} + +static int cl_chandef_calc_24g(struct cl_hw *cl_hw, u16 freq, u32 bw, u32 offset, + u32 *primary, u32 *center) +{ + u32 min_freq = 0; + + if (freq < FREQ2G(1) || freq > FREQ2G(14)) { + cl_dbg_err(cl_hw, "Invalid frequecy - %u\n", freq); + return -EINVAL; + } + + min_freq = freq < FREQ2G(14) ? FREQ2G(1) : FREQ2G(14); + *primary = freq - (freq - min_freq) % 5; + + if (bw == CHNL_BW_20) { + *center = *primary; + } else if (bw == CHNL_BW_40) { + if (freq <= FREQ2G(4)) { + /* Above extension channel */ + *center = *primary + offset; + } else if (freq >= FREQ2G(10)) { + /* Below extension channel */ + *center = *primary - offset; + } else { + /* Channels 8-9 must be below if channel 13 is not supported */ + if (freq >= FREQ2G(8) && !cl_chan_info_get(cl_hw, 13, CHNL_BW_20) && + /* For Calibration, when using 2.4GHz channels on TCV0 to set SX0. */ + !cl_chan_info_get(cl_hw->chip->cl_hw_tcv1, 13, CHNL_BW_20)) { + *center = *primary - offset; + } else { + /** + * Set below/above according to the current hapd configuration. + * If undefined, preffer above offset. + */ + if (cl_hw->ht40_preffered_ch_type == NL80211_CHAN_HT40MINUS) + *center = *primary - offset; + else + *center = *primary + offset; + } + } + } else if (bw == CHNL_BW_80) { + *center = CENTER_FREQ_24G_BW_80MHZ; + } else { + /* 160MHz */ + *center = CENTER_FREQ_24G_BW_160MHZ; + } + + return 0; +} + +int cl_chandef_calc(struct cl_hw *cl_hw, u32 channel, u32 bw, + enum nl80211_chan_width *width, u32 *primary, u32 *center) +{ + u16 freq = ieee80211_channel_to_frequency(channel, cl_hw->nl_band); + u32 offset = 0; + int ret = 0; + + switch (bw) { + case CHNL_BW_20: + offset = 0; + if (channel == 14) + *width = NL80211_CHAN_WIDTH_20_NOHT; + else + *width = NL80211_CHAN_WIDTH_20; + break; + case CHNL_BW_40: + offset = 10; + *width = NL80211_CHAN_WIDTH_40; + break; + case CHNL_BW_80: + if (!cl_hw->chip->conf->ce_production_mode && cl_band_is_24g(cl_hw)) { + cl_dbg_err(cl_hw, "Invalid bandwidth - %u\n", bw); + return -EINVAL; + } + + offset = 30; + *width = NL80211_CHAN_WIDTH_80; + break; + case CHNL_BW_160: + /* Verify 2.4G bandwidth validity only in operational mode */ + if (!cl_hw->chip->conf->ce_production_mode && cl_band_is_24g(cl_hw)) { + cl_dbg_err(cl_hw, "Invalid bandwidth - %u\n", bw); + return -EINVAL; + } + + offset = 70; + *width = NL80211_CHAN_WIDTH_160; + break; + default: + cl_dbg_err(cl_hw, "Invalid bandwidth - %u\n", bw); + return -EINVAL; + } + + if (cl_band_is_6g(cl_hw)) + ret = cl_chandef_calc_6g(cl_hw, freq, bw, offset, primary, center); + else if (cl_band_is_5g(cl_hw)) + ret = cl_chandef_calc_5g(cl_hw, freq, bw, offset, primary, center); + else + ret = cl_chandef_calc_24g(cl_hw, freq, bw, offset, primary, center); + + cl_dbg_trace(cl_hw, "primary=%u center=%u\n", *primary, *center); + + return ret; +} + +int cl_chandef_get_default(struct cl_hw *cl_hw, u32 *channel, u8 *bw, + enum nl80211_chan_width *width, + u32 *primary, u32 *center) +{ + *bw = cl_hw->conf->ci_chandef_bandwidth; + *channel = cl_hw->conf->ci_chandef_channel; + + return cl_chandef_calc(cl_hw, *channel, *bw, width, primary, center); +} + +int cl_init_channel_stats(struct cl_hw *cl_hw, + struct cl_channel_stats *ch_stats, u32 freq) +{ + memset(ch_stats, 0, sizeof(*ch_stats)); + + ch_stats->channel = ieee80211_frequency_to_channel(freq); + if (ch_stats->channel == INVALID_CHAN_IDX) { + cl_dbg_err(cl_hw, "Failed to get channel num for freq %u\n", freq); + return -EINVAL; + } + + return 0; +} + +void cl_get_final_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats) +{ + u32 tx_mine, rx_mine, edca_cca; + + /* + * Currently mac_hw_rx_mine_busy_get() doesn't work properly, + * so use mac_hw_edca_cca_busy_get() as workaround. + * After scan mac_hw_rx_mine_busy_get almost always returns zeros + * or some very small values. + * Use of EDCA CCA is less accurate, since it also includes non-wifi noise + */ + tx_mine = mac_hw_tx_mine_busy_get(cl_hw); + edca_cca = mac_hw_edca_cca_busy_get(cl_hw); + rx_mine = edca_cca; + + ch_stats->util_time_tx = max_t(s64, tx_mine - ch_stats->util_time_tx_total, 0); + ch_stats->util_time_rx = max_t(s64, rx_mine - ch_stats->util_time_rx_total, 0); + ch_stats->edca_cca_time = max_t(s64, edca_cca - ch_stats->edca_cca_time_total, 0); + + ch_stats->util_time_busy = ch_stats->edca_cca_time + ch_stats->util_time_tx; + + ch_stats->ch_noise = cl_calc_noise_floor(cl_hw, NULL); + + ch_stats->scan_time_ms = jiffies_to_msecs(get_jiffies_64() - ch_stats->scan_start_jiffies); +} + +void cl_get_initial_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats) +{ + ch_stats->util_time_tx = 0; + ch_stats->util_time_rx = 0; + ch_stats->edca_cca_time = 0; + ch_stats->util_time_busy = 0; + ch_stats->ch_noise = 0; + ch_stats->scan_time_ms = 0; + + ch_stats->util_time_tx_total = mac_hw_tx_mine_busy_get(cl_hw); + ch_stats->edca_cca_time_total = mac_hw_edca_cca_busy_get(cl_hw); + ch_stats->util_time_rx_total = ch_stats->edca_cca_time_total; + + ch_stats->scan_start_jiffies = get_jiffies_64(); +} From patchwork Tue May 24 11:33:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576868 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 16331C433FE for ; Tue, 24 May 2022 11:38:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236765AbiEXLh7 (ORCPT ); Tue, 24 May 2022 07:37:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236777AbiEXLh4 (ORCPT ); Tue, 24 May 2022 07:37:56 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2084.outbound.protection.outlook.com [40.107.21.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B7A250440 for ; Tue, 24 May 2022 04:37:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FAk7glnvtBaZFv4rUwV4dbiHK//TQWbehLFdzXmS+NgPL1nV+6YTHtB5nWs90cR4yK9jEkYvThkEfINqUETerHC2VNn6Mf/IWnBAn0VNTFaaL2sJ8BFuvyLUDblF1PDdt1wLKOQtxJZWJXOREY4os5rmHtbQ+b74ivAScTpesTa7l1c8upiHB5R6C3Hm0T2P9jc2f9b1siWgZv+NMZlrlgCxDRwkehMegqhSt47KlQnqmZNY3Tqb1dknki4sM2FAbHL9ODUZulZQEnhHIvwSDajLOBMh8DFElcnqNvFqAKUPh6kCYRM4UwprSVbvsL4ImNIk5RYnjEmsmm+ObrZK1g== 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=LPB501un7HifiDDO/x8nSGT3zwV7EsAaQmP87vBaum0=; b=Nw3o9skDu4rN+dpm09eGaa0IkW8SK9CLB5P1EWcM032rjKnBiQd7SzEeYZjn/jKREsAnN6TWOFRTnBHoS0++US1FHJ1U5qjTO4camkBWZBiIwbQTUsB4qFuqHJGb5ZaAGMWKBdfGi8/g4bbv4dQqbGA9/pHv2pXckT9X6IPGmNmeHpSzwYhcs9Abq76uni1h8p4otFtMkhcN1ZWTCrsyN6+5h1ch1zb/bBR4xthkCL+onSNrTjcv6BuCTn+jqlwYuw8nqeWuyZP+kmD4yKRZQ9FNuerWsmmEX71vtKHGq7innn7a7XJK7rX05xmvGQmFWCEI2iPmPh3Jc9a4P8Rmkw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LPB501un7HifiDDO/x8nSGT3zwV7EsAaQmP87vBaum0=; b=KT8DbOeDVUnkrT3AFqGYAkJ3KeGlvJb0BttMa9KCYzbvRuO7wkzJzP8nfPa9iUPIsm55zF+0O1fTkftAWCsLYkAjNcL0FLHJ4kmK7f18hEMNvs5igUeLbOVQJe2z6WX8GjfVAOdk/Q6me00SuTNFVgHhkwo4pk/yznNNkS9En1Q= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:37:51 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:51 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 12/96] cl8k: add channel.h Date: Tue, 24 May 2022 14:33:38 +0300 Message-Id: <20220524113502.1094459-13-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ac75a6e8-62da-422a-ff79-08da3d79d5b0 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 3gAAWPhj31W6T6Y7d+aXDweu8sgMX8xkMJ1crU1jvM6JeY11vqPK8ucayqQw20sa0xgDJ5GQHa921TLr3JrNXKnJSOe5dwtPvw5iXkVWqsI7xZ+bueXvapqotnyx5u8N/rKJkPbHYa8CgbcmhQOsAyb/tOhCU8/5ZDjwgkKlOOzw1Gz7Yf93Q+2d+b9ZeyWDJXVtyBQnxsO75AVpSdppBcKOjnl4tMN7EFWa6hWqf+j+9PgQ5Bm/Du5bZtEbFvmYr4iQDf3u+b62kZRhNzXhqN0DTKyqxIipll7erFx8PHCZHZCSJDIdeDnQ4VKYgVeO/FlTwtM8dYAGtXyZD8VSlZmIQexTKRIR6NVM0rM0sd1AUogCMnPvFHPe04EysTsXRcQegk5EaeZ3KkWoGPfWPpNthRiZbZER1PuTRqpN6q4w/9rKNkV+t3a2l84WxTMHfqcljWc3TV/Mq3ozN+Y91n/Q7NGmbZaOxYE2+3TDJVmEOp9VOFVG9FEEakoSRLtxK4Fmdf7j7dBSjEQQMTqwjOglOhNF3aZ/CxIXn/Qtuh/udlG4JxbcQm+fg9zdNM5lh3eHDamUBPGMdKBb0bs8xL4C/nluR+zpCKhiro4rdlCZQQ2Hc0rKnRFmpwp/oJl6GHSvkeE2AJpF/7am4XtGQyFb54FjZlpbQyAvnOJk2IpTj3IkJw0480NaCyhxL2NHiX3F1CP45ehVydmxMc0BFMXS6Nn7WbPlFQmuZTqtxWk= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: lZ+wozAJ6eJHAaKyKs+pvi6zs5WzAvRMudEOIHCv6W2pU2maBwdyI7yNCF8aq1+7EyIzanNk6L2udQie50d5RJd1Rl/Fa4rXcTztSA4MkXRHH2maObctXUIO7NIBqYGwU0DO29D7JjhvU8Pzd1R4Msian8zBIPd7tWV8YytATp8N49fu+Z6ACQbtHpQGt66dN0VG/24ojlHp6BlFtjul43QSWqQHlDXk44tVGMUhKXks/U5LNiIP3v0eG70+fR//Szf1w7SbiHjN1Amw5gbCZ4niT/j7U/Z+wY7PYM/Eq79pap288k0jcnVZa6CBnSCBhkiU0L+kJhiImCoaiaSCuuBCegM9f0ZQ9LhO2ek/RjlCYCFOPWhdBYwqOkwldtIlIb+AgrqF8c0D3sEWh7fWXKuu7ulKesLhtpT7ddSp+woFwBs7Dy9XxhP8nC1Lm3vORm3QxJW3tPsK117IV0ruuodedtif+f9Mcn341tgoCNKsOuvHF5+DRGjneZnnrJZs8AOga805ORaNITJA86L3+odFKrWj0j1ivl0b8ty5wruzRTgzwvzhtyfyvcYh5T58BWGVfysY8WAEVXK+AazwA20cdNO1AVemfvszYrTBU19O9hzsRtyq2ftxPrILwW3j7UHMCGCn0bbbwM8aV8jhEVafoF3a9mWAga5ICDJuQ2MzvnGNyojtkKb9Dus+Rw+TV/qJMHp84etyZY+kKELA5xytQcOnq0rGIXeuWIn9MygPbOgqj83UReiAqnGYezXl2gMUnJAg+TPjyLpsVaIONul1j3UYluZT3naJlJp/5BgHPO5hKTSFrqiDlMpdYyNV/G6nL3LwecTWE9SNxlZAOHK1vnkXfVxpRSjF7AjhSAk60VwUmmANl8Bm2uIkVsEbLzGS1y3khUF7hfXkzIhLdOh5HsLpkWl0WlUIt2yAN9ODlaInxn6+7hRm5tm27kC1ePSN/zqcFAFPBEDjZ34fKR6hb5OeBU6Ljkm1UZjsF5zli+0oAElWI1UHGlqSAVmd01/MV9+mTCKXjfvz6JXrhRGcM/mnwUIwAq1zK8ZdSgb55Wk+DKU47oMVfmhFO/y1XZvb9a8EkFFlnK+QPFHZc40AEmJQiWbbMPoArCxbne8aMhge+U026Uh8/VRwUCV0giUxi+8QnJQti0qv1IG0myt3rQUc7HONcUFrO1cx3RKFF5laUd4wBL9JuR7sewaEFfYKGvfX1zF52eAjK1WU7iVV2u8sRYJR6yx0VGaYmBhOJlbL24Kam0bWuvvoAg9ud2fi82R3EnGjjZLGdSryomFcCyT6EErH3f6ymlNUftxpIX6FOM4yEpGHBYumRkyB+10RtFJBP5ShsEfq6slMqJl7b15yPlX2B7WQWFCt3OpfxvxEthQfcILa8SsDhZY4pXgDrjHH1na/cuMTwQLkb4CFXcivxPjskrDYumaDBXQb9u9SGFOIDPfG9VX0z8ns++zUtqj+DMVhvRUdHivEiNyP2XUP226Iz4CWI3vvYcHh8NOVXNCn0TXbPyiwlWeV2MXqp1qe/ncgsst0xDF31SEkxYSDXcQZLOF/rKxaUX05Q/VVpMJOIoir20P71BP/VCyenmIDtw+nXBrec+o9KRVczgj1hR2WLkw/fQbyUx0AuhHLGMq4knEBxmtOGYWZm369fiijZRxmlNB36PjlTrK1zQ8AX8538vFA3kUNw9pZcwWViNGgzHvSIfB1/gm/iKIgp7L2kzx4pfrFXiqb1TSCmgngCyIYPKMY+h+LY7U= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ac75a6e8-62da-422a-ff79-08da3d79d5b0 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:51.3392 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: jBKh2/1WLVOiF26KfgWqZpV11OB80sIy4AYLUSNUqVDguV3EF75cDyzUJYJf5xGVoszUS9GVrm0+c1lMtYGHzA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/channel.h | 401 +++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/channel.h diff --git a/drivers/net/wireless/celeno/cl8k/channel.h b/drivers/net/wireless/celeno/cl8k/channel.h new file mode 100644 index 000000000000..aec65b2d1b19 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/channel.h @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_CHANNEL_H +#define CL_CHANNEL_H + +#include +#include +#include + +#include "def.h" + +enum bitmap_chan_idx_6g { + b6g_ch1, + b6g_ch2, + b6g_ch5, + b6g_ch9, + b6g_ch13, + b6g_ch17, + b6g_ch21, + b6g_ch25, + b6g_ch29, + b6g_ch33, + b6g_ch37, + b6g_ch41, + b6g_ch45, + b6g_ch49, + b6g_ch53, + b6g_ch57, + b6g_ch61, + b6g_ch65, + b6g_ch69, + b6g_ch73, + b6g_ch77, + b6g_ch81, + b6g_ch85, + b6g_ch89, + b6g_ch93, + b6g_ch97, + b6g_ch101, + b6g_ch105, + b6g_ch109, + b6g_ch113, + b6g_ch117, + b6g_ch121, + b6g_ch125, + b6g_ch129, + b6g_ch133, + b6g_ch137, + b6g_ch141, + b6g_ch145, + b6g_ch149, + b6g_ch153, + b6g_ch157, + b6g_ch161, + b6g_ch165, + b6g_ch169, + b6g_ch173, + b6g_ch177, + b6g_ch181, + b6g_ch185, + b6g_ch189, + b6g_ch193, + b6g_ch197, + b6g_ch201, + b6g_ch205, + b6g_ch209, + b6g_ch213, + b6g_ch217, + b6g_ch221, + b6g_ch225, + b6g_ch229, + b6g_ch233, + + NUM_BITMAP_CHANNELS_6G +}; + +enum ext_chan_idx_6g { + ext_b6g_ch1, + ext_b6g_ch2, + ext_b6g_ch3, + ext_b6g_ch5, + ext_b6g_ch7, + ext_b6g_ch9, + ext_b6g_ch11, + ext_b6g_ch13, + ext_b6g_ch15, + ext_b6g_ch17, + ext_b6g_ch19, + ext_b6g_ch21, + ext_b6g_ch23, + ext_b6g_ch25, + ext_b6g_ch27, + ext_b6g_ch29, + ext_b6g_ch31, + ext_b6g_ch33, + ext_b6g_ch35, + ext_b6g_ch37, + ext_b6g_ch39, + ext_b6g_ch41, + ext_b6g_ch43, + ext_b6g_ch45, + ext_b6g_ch47, + ext_b6g_ch49, + ext_b6g_ch51, + ext_b6g_ch53, + ext_b6g_ch55, + ext_b6g_ch57, + ext_b6g_ch59, + ext_b6g_ch61, + ext_b6g_ch63, + ext_b6g_ch65, + ext_b6g_ch67, + ext_b6g_ch69, + ext_b6g_ch71, + ext_b6g_ch73, + ext_b6g_ch75, + ext_b6g_ch77, + ext_b6g_ch79, + ext_b6g_ch81, + ext_b6g_ch83, + ext_b6g_ch85, + ext_b6g_ch87, + ext_b6g_ch89, + ext_b6g_ch91, + ext_b6g_ch93, + ext_b6g_ch95, + ext_b6g_ch97, + ext_b6g_ch99, + ext_b6g_ch101, + ext_b6g_ch103, + ext_b6g_ch105, + ext_b6g_ch107, + ext_b6g_ch109, + ext_b6g_ch111, + ext_b6g_ch113, + ext_b6g_ch115, + ext_b6g_ch117, + ext_b6g_ch119, + ext_b6g_ch121, + ext_b6g_ch123, + ext_b6g_ch125, + ext_b6g_ch127, + ext_b6g_ch129, + ext_b6g_ch131, + ext_b6g_ch133, + ext_b6g_ch135, + ext_b6g_ch137, + ext_b6g_ch139, + ext_b6g_ch141, + ext_b6g_ch143, + ext_b6g_ch145, + ext_b6g_ch147, + ext_b6g_ch149, + ext_b6g_ch151, + ext_b6g_ch153, + ext_b6g_ch155, + ext_b6g_ch157, + ext_b6g_ch159, + ext_b6g_ch161, + ext_b6g_ch163, + ext_b6g_ch165, + ext_b6g_ch167, + ext_b6g_ch169, + ext_b6g_ch171, + ext_b6g_ch173, + ext_b6g_ch175, + ext_b6g_ch177, + ext_b6g_ch179, + ext_b6g_ch181, + ext_b6g_ch183, + ext_b6g_ch185, + ext_b6g_ch187, + ext_b6g_ch189, + ext_b6g_ch191, + ext_b6g_ch193, + ext_b6g_ch195, + ext_b6g_ch197, + ext_b6g_ch199, + ext_b6g_ch201, + ext_b6g_ch203, + ext_b6g_ch205, + ext_b6g_ch207, + ext_b6g_ch209, + ext_b6g_ch211, + ext_b6g_ch213, + ext_b6g_ch215, + ext_b6g_ch217, + ext_b6g_ch219, + ext_b6g_ch221, + ext_b6g_ch223, + ext_b6g_ch225, + ext_b6g_ch227, + ext_b6g_ch229, + ext_b6g_ch231, + ext_b6g_ch233, + + NUM_EXT_CHANNELS_6G +}; + +enum chan_idx_5g { + b5g_ch36, + b5g_ch38, + b5g_ch40, + b5g_ch42, + b5g_ch44, + b5g_ch46, + b5g_ch48, + b5g_ch50, + b5g_ch52, + b5g_ch54, + b5g_ch56, + b5g_ch58, + b5g_ch60, + b5g_ch62, + b5g_ch64, + b5g_ch100, + b5g_ch102, + b5g_ch104, + b5g_ch106, + b5g_ch108, + b5g_ch110, + b5g_ch112, + b5g_ch114, + b5g_ch116, + b5g_ch118, + b5g_ch120, + b5g_ch122, + b5g_ch124, + b5g_ch126, + b5g_ch128, + b5g_ch132, + b5g_ch134, + b5g_ch136, + b5g_ch138, + b5g_ch140, + b5g_ch142, + b5g_ch144, + b5g_ch149, + b5g_ch151, + b5g_ch153, + b5g_ch155, + b5g_ch157, + b5g_ch159, + b5g_ch161, + b5g_ch165, + + NUM_CHANNELS_5G +}; + +enum chan_idx_24g { + b24g_ch1, + b24g_ch2, + b24g_ch3, + b24g_ch4, + b24g_ch5, + b24g_ch6, + b24g_ch7, + b24g_ch8, + b24g_ch9, + b24g_ch10, + b24g_ch11, + b24g_ch12, + b24g_ch13, + b24g_ch14, + + NUM_CHANNELS_24G +}; + +/* 6g band has the largest list */ +#define MAX_CHANNELS NUM_BITMAP_CHANNELS_6G +#define MAX_EXT_CHANNELS NUM_EXT_CHANNELS_6G +#define START_CHAN_IDX_6G 1 + +/* 1 ==> 5955 */ +#define FREQ6G(_chan) ((_chan) == 2 ? 5935 : 5950 + 5 * (_chan)) +/* 36 ==> 5180 */ +#define FREQ5G(_chan) (5000 + 5 * (_chan)) +/* 1 ==> 2412 */ +#define FREQ2G(_chan) ((_chan) == 14 ? 2484 : 2407 + (_chan) * 5) +#define CHAN_BITMAP_IDX_6G_2_EXT_IDX(_idx) ((_idx) ? ((_idx) << 1) - 1 : 0) +#define CHAN_EXT_IDX_6G_2_BITMAP_IDX(_ext_idx) (((_ext_idx) + 1) >> 1) + +/* 6G channels - UNII-5 */ +#define START_CHAN_IDX_UNII5 1 +#define END_CHAN_IDX_UNII5 85 +/* 6G channels - UNII-6 */ +#define START_CHAN_IDX_UNII6 89 +#define END_CHAN_IDX_UNII6 109 +/* 6G channels - UNII-7 */ +#define START_CHAN_IDX_UNII7 113 +#define END_CHAN_IDX_UNII7 165 +/* 6G channels - UNII-8 */ +#define START_CHAN_IDX_UNII8 169 +#define END_CHAN_IDX_UNII8 233 + +#define INVALID_CHAN_IDX 0xff + +#ifndef IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS +#define IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS 600000 +#endif + +struct cl_hw; + +u8 cl_channel_to_ext_index_6g(struct cl_hw *cl_hw, u32 channel); +u8 cl_channel_to_index(struct cl_hw *cl_hw, u32 channel); +u8 cl_channel_to_bitmap_index(struct cl_hw *cl_hw, u32 channel); +u16 cl_channel_ext_idx_to_freq_6g(struct cl_hw *cl_hw, u8 index); +u16 cl_channel_idx_to_freq(struct cl_hw *cl_hw, u8 index); +bool cl_channel_is_valid(struct cl_hw *cl_hw, u8 channel); +u32 cl_channel_num(struct cl_hw *cl_hw); +bool cl_channel_is_dfs(struct cl_hw *cl_hw, u8 channel); +u32 cl_channel_get_cac_time_ms(struct cl_hw *cl_hw, u8 channel); + +#define CL_MAX_STR_BUFFER_SIZE 1024 + +#define CL_DEFAULT_CHANNEL_POWER_Q8 (30 << 8) + +#define CL_20MHZ_CH_GAP 4 +#define CL_40MHZ_CH_GAP 8 +#define CL_80MHZ_CH_GAP 16 +#define CL_160MHZ_CH_GAP 32 +#define CL_40MHZ_HOP 2 +#define CL_80MHZ_HOP 4 +#define CL_160MHZ_HOP 8 + +struct cl_chan_info { + u8 channel; + u8 max_bw; + /* Resolution of 0.25dB */ + u8 max_power_q2; /* MIN(country_max_power_q2, hardware_max_power_q2) */ + u8 country_max_power_q2; + u8 hardware_max_power_q2; + u32 flags; /* channel flags from &enum ieee80211_channel_flags */ + unsigned int dfs_cac_ms; +}; + +struct cl_channel_info { + bool use_channel_info; + struct cl_chan_info channels[CHNL_BW_MAX][MAX_CHANNELS]; + enum nl80211_dfs_regions standard; + struct ieee80211_regdomain *rd; +}; + +void cl_chan_info_init(struct cl_hw *cl_hw); +void cl_chan_info_deinit(struct cl_hw *cl_hw); +struct cl_chan_info *cl_chan_info_get(struct cl_hw *cl_hw, u8 channel, u8 bw); +u8 cl_chan_info_get_max_bw(struct cl_hw *cl_hw, u8 channel); +s16 cl_chan_info_get_eirp_limit_q8(struct cl_hw *cl_hw, u8 bw); +u8 cl_chan_info_get_max_power(struct cl_hw *cl_hw, u8 channel); +void cl_chan_update_channels_info(struct cl_hw *cl_hw, + const struct ieee80211_supported_band *cfg_band); +int cl_chandef_calc(struct cl_hw *cl_hw, u32 channel, u32 bw, + enum nl80211_chan_width *width, u32 *primary, u32 *center); +int cl_chandef_get_default(struct cl_hw *cl_hw, u32 *channel, u8 *bw, + enum nl80211_chan_width *width, + u32 *primary, u32 *center); + +struct cl_channel_stats { + bool scan_enabled; + u8 channel; + enum cl_channel_bw scan_bw; + + s8 avg_snr; + s8 avg_non_wifi_noise; + u32 avg_channel_util; + u32 avg_retry_rate; + u32 total_frames; + u32 total_retries; + u32 vendor_specific; + + /* Time radio spent rx on channel + non wifi noise */ + u64 edca_cca_time; + u64 edca_cca_time_total; + + /* Time radio detected that channel was busy (Busy = Rx + Tx + Interference) */ + u64 util_time_busy; + + /* Time radio spent tx on channel */ + u64 util_time_tx; + u64 util_time_tx_total; + + /* Time radio spent rx on channel (Rx = Rx_obss + Rx_self + Rx_errr (self and obss errs) */ + u64 util_time_rx; + u64 util_time_rx_total; + + s8 ch_noise; + + u64 scan_start_jiffies; + u32 scan_time_ms; + + /* Currently this metric can't be calculated because fromat_mod in rxheader is always 0 */ + /* u64 util_time_self; */ +}; + +int cl_init_channel_stats(struct cl_hw *cl_hw, + struct cl_channel_stats *ch_stats, u32 freq); +void cl_get_final_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats); +void cl_get_initial_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats); + +#endif /* CL_CHANNEL_H */ From patchwork Tue May 24 11:33:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575986 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 60B28C433EF for ; Tue, 24 May 2022 11:38:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236780AbiEXLiA (ORCPT ); Tue, 24 May 2022 07:38:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236773AbiEXLh6 (ORCPT ); Tue, 24 May 2022 07:37:58 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC7B152E53 for ; Tue, 24 May 2022 04:37:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GOkpy6LcgJg78fTc+qs5tWekiEIHCml34tkMoV/4mEfZzgIlqMOYPnWnMreNMqJkdrFL56I3HjAbB3lfR7/xaXdspNrVD0v5WsVO8zH7Pre5y+DWcYXXew9n4nChWYHDwCDcYpIomf70aNLUyv1u9r4C1JpT6zqUt152PFHbQT9dixYDwIfSUKPAonSG2+fyixHqQaZAH9bI59WJJOvkhX6hDkFA4kiJmj76PH+Zh+xLG4eKekpA09HZPL/fK2T1AtLWfA1ytJevoeFrjcarwkxQgDMGciyv3XPH7wXZyG8WtheATxzBgl9nsiKBL5kL1eLIrem2opmiecQrjqMIyg== 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=2PHUAeh3NnhH1tt4Z80khQj4TXQ8emmo0Klqa2D/BEQ=; b=gW4OPbHtSJfPW6Y7oWpd9ZHjSgWgtl5KIspkkPnsDEuE3pGnM8DUqw34msHtdMog+rN6KHVKFFDADWa/CTafn/7lpGi8pgpLwTHJ62dk9JVDBi74oPLRepCdUu7hoDVmiKA1V5vYFcWyYWMWQ+yS/0qwwQ0NGBTJ/SZUd9R+gDT4mnIBsxuNZJZ0Vj9xKsEfsXge8VjMbNxCYs/6ecjQw/luY4YaD9QHm6x5TxYHvtT7PfYLMnmJINZkvadVa5LSXEKV7tDhcx7Y7a3rPK5PbbG4umnVbFX5Qz/VlJYFpNgDxE1CUw5ged085Ku6MKPzXRCARs/sx5utDnq1S+HI/A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2PHUAeh3NnhH1tt4Z80khQj4TXQ8emmo0Klqa2D/BEQ=; b=rQLmROF4XBeMMt0hEMfJCoJsq+TmDZga21sEZbVlvekqn1rVv8ukWq/vGuT7SwuojlYGLyFTE03Nlzbmc/duA855CxNNCGZtI6bFV8FjG4iKgnt/nlTkXlW1PzWqJ0Bsm9dI3N9y+1hOOrtSvmonYVvtgThND8iOv3C5INGiYsU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:52 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:52 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 13/96] cl8k: add chip.c Date: Tue, 24 May 2022 14:33:39 +0300 Message-Id: <20220524113502.1094459-14-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2d7db359-bb60-4a08-6acb-08da3d79d623 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: k+Bjbvsu4FS6rYhLljf6mGs6x0vwdvefwJ/9wQFQ4QpAvlMx+0CNvLdNK3mCz+OkWSJa64yvdzStgwzE3qGk0owfUarliEN7FYl8hhPqCeJrtkni5sRaqV69yTdcuucIs0EjUhnyRDjo7mu7/Lx97xaMMx+ps7UhEDmQa42dZz5bixoM/OlbmaTPjxa7usAO23vCLF97oZyDYY7y/L+hT/W72BkSBpgELfeXBYP4nDHSWZdqdqRQcRNZ+aORUY87ablt9H97uwtVGJ9637UbzK4AerQ+8RC7xG3U29Xha6U8TWgD1GNl8cnn2GFg0bYiO51kOHrOaoK1xuGk4KfCc4k5NZyYezkuc2wYZI/Rt0lqwzVXvGwCNdyHBcGSno7zVaiRyhFUlnFWqeOQZzsJHrHiICCLucijyv/UU4WhIiXkVDde5u35bE1UX0I3d44b6QRaZh/9gKRWJ0Qt0bzXwgPPqA82rP/lmeI3eDydUlRKRM+H64Sk95Iz/c0oF6nKYniUJrabA1YjI2g/KJNY5sCciFUZodenybLI4jv4CZ+7b9m4nyWH1xWamMaKXQOiJAHxLCIT2z+BlVEnPV2smNdkMuQnmJZpTFvGjeKMN44ULCp8h2BQy+JT/0LDsfNJ9ikB+H2gMVNFt4+V4D5HQJWeFH5rjEE8+U25LhFE2TsR7L9/LZ3sl3yPZnB1tRWRqNu1CzQ6cXcFvFE/Rv7O7lhM0rxivYH5YxW11IOigs8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GGgZRvZ9W36ldRYKLNeBJMQrzRIpZNF7MFw1VcmOA8afMrgcct8KXi7nuAK1shvb/1AMMMdAJuiO8blsM/86fYvDOLrnN1O4EKpccpcTPefWazcHSay4zW96EzHr7Kq0Yy5/VtMnVt1+CC5jjqVI/Ok5XPUDk6JBq/hdQvpOVMsGxCnp2noKanlRXFmK80jsCYVdeCw6Sq3Qc/4HEh8v99dYff6IaRZbsWrmQiAJlh8SdloIA8d+nA5jm4WRAMNk2tnIzV/dJTjMzb3GdUBluIc8E4BaFTNbTskiSSLkAq4N5R2qmbCVL4h1Ya4AYMORxqHKR1IPfM5t1jpfoFFMMWcIdV7ZJENQceO318RRQp75XdMNK+lo2ub5uCuCTILcSYGR4jsF+ElhlZ0Ox1pMyBKP54PD9c89+iTIOfZNxL1EYpbnnWYi0xxtuH3dzkPv6buOX4TaZumeuv3viTNsTM68OZBCa8a4i9JSXl0tSS7CRJVk+BvTqjujNrPKCExIeiBJWlXsSaPC1J3TSYbKlYP42/IBOa8hismwK1/cksLSo7wnJkjFHyIsnWIS9uXmC43uPEVxnfTb/rqozy2hHbDV1v1BbwIlDQmKPB7ONwCqcnGZSfpTL6xblIPa/PJ95FiJiF8vBPkLFC0y0m/7QnXciaBwnIi6p073DIdEyDS4QXGHzkFXBGPfGrAEwP3ghOKwWOa1i/mzGMTmhEbrR5imd7knaGA8zuQ6UBd5yE0Mkm/iEibNJbQQG8znHPA46I4ahtekCIH2LnDi4rwOC94wl1bZUfR4Nddk4cLvx/dJQXVbAOyGrD99VlhvuEr8Z2M+70wRY/wpI1WvG0PMADzMAuDiEz3tehKD7TsL1i+tsxIm3vmLCRVJrJW2PboMsEgN/iwQUqT1hPykof4rqWV2Yv1UkG4wtvbKAl1xaep5CRjQXuHxcxa6RelS6vDCKHRghpMXqocpu0WwhGJ+X1a57q8lnacVx59xEE/LmjQOkhuKAC0ATVWtRMdrt5yjFuPF34nN8qMiHcpgo6qDwED9ruOViiQXWevbezRRZTjofSpwdbiguTB8m89PFEnqG7IrTZJ+mzU8477oCkcjhV11Tdx+dHfaH6coZ3zPb0DGAcTVMczL7tKeHN2ro4oYKjS5fawYiEjZrAErl2zAKeyAzwIpqnkjOMbn06vFVlgoF7f7NtP5WJ7aPSEm9z1ULEiWP73SMGYm0tm5fR+RKwx/tqtOSLqi639ZvXHLkpTBwNmTKtqrUvOtuCf3Qvz8Tvx0EIGk9D/kq2gFM4WN+gZ8n89uRC1TPZJ5TLFFhFnjJ8IZGblH1qIkznebmkTf1qWGErnGNWTgmNe1BIcoZeRO85Mmzat0CWBKukukrZXY7z4OBU/kfuhrEly+/mGO+9u2gvLzmAiYxVFOZdMJ8/k1EdAm+Kq1amz/QUmMa3J5RwC5YiKLqnfh6Zv4v5WoRoWqYE+m4E0PwUh4nCEowcnULJT3dCHVK/Hu0zi+Y6XvGs+fVIXsjwiOPP+RrtrM6fwj8muV0NLvxCil0QrGVc1oz2xYuD20O15kMRKhhEwHl2Fiqysma4b2ZqWVPVhMH7YX0mZytjy40m2sZXiFRZgshhZXZRh6rAUUvwzudHBB8tI9b1tHlWeIsit2q9nC2vIduAWI/HPPQftbC6im42bmvP/eG/hhSziiRWCFlQ+hHmeSJ2E2VXOtMjEnK4mwNbhZ8S/QZKSzDI1+7HFowBfo+fHpHG9dyRFsLGj95hY= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2d7db359-bb60-4a08-6acb-08da3d79d623 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:52.0891 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: FvNkphhj+RIAu2poNYG3sMhyw1iZNIMkNViEZ6gwI2R3c1lCh5iuxjlax9oyEY8cUY2sKmzeEWxPqv8OwTixpA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/chip.c | 580 ++++++++++++++++++++++++ 1 file changed, 580 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/chip.c diff --git a/drivers/net/wireless/celeno/cl8k/chip.c b/drivers/net/wireless/celeno/cl8k/chip.c new file mode 100644 index 000000000000..67f65dffd804 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/chip.c @@ -0,0 +1,580 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "temperature.h" +#include "phy.h" +#include "e2p.h" +#include "main.h" +#include "rates.h" +#include "calib.h" +#include "config.h" +#include "utils.h" +#include "chip.h" + +#define CL_ALIGN_BOUND_64KB BIT(16) + +static void cl_chip_set_max_antennas(struct cl_chip *chip) +{ + u16 device_id = cl_chip_get_device_id(chip); + + switch (device_id) { + case 0x8040: + case 0x8046: + chip->max_antennas = MAX_ANTENNAS_CL804X; + break; + case 0x8060: + case 0x8066: + chip->max_antennas = MAX_ANTENNAS_CL806X; + break; + case 0x8080: + case 0x8086: + default: + chip->max_antennas = MAX_ANTENNAS_CL808X; + break; + } +} + +/* + * This function is necessary since now we can't determine the max antenna number by the + * device_id alone, since there is at least one case of device_id 8046 and max antenna of 3. + */ +static void cl_chip_update_max_antennas(struct cl_chip *chip) +{ + u8 wiring_id = chip->fem.wiring_id; + + if (wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1 || wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + chip->max_antennas = MAX_ANTENNAS_WIRING_ID_27_31; +} + +static int cl_chip_print_serial_number(struct cl_chip *chip) +{ + u8 serial_number[SIZE_GEN_SERIAL_NUMBER + 1] = {0}; + + if (!IS_REAL_PHY(chip)) + return 0; + + if (cl_e2p_read(chip, (u8 *)&serial_number, SIZE_GEN_SERIAL_NUMBER, ADDR_GEN_SERIAL_NUMBER)) + return -1; + + if (strlen(serial_number) == 0) + cl_dbg_chip_verbose(chip, "Serial-number in not set in EEPROM\n"); + else + cl_dbg_chip_verbose(chip, "Serial-number = %s\n", serial_number); + + return 0; +} + +static int cl_chip_ring_indices_init(struct cl_chip *chip) +{ + struct cl_ring_indices *ring_indices = &chip->ring_indices; + + ring_indices->pool = dma_pool_create("cl_ring_indices_pool", chip->dev, + (sizeof(struct cl_ipc_ring_indices) * TCV_MAX), + CL_ALIGN_BOUND_64KB, CL_ALIGN_BOUND_64KB); + + if (!ring_indices->pool) { + cl_dbg_chip_err(chip, "ring_indices pool create failed !!!\n"); + return -ENOMEM; + } + + ring_indices->params = dma_pool_alloc(ring_indices->pool, GFP_KERNEL, + &ring_indices->dma_addr); + if (!ring_indices->params) + return -ENOMEM; + + return 0; +} + +static void cl_chip_ring_indices_deinit(struct cl_chip *chip) +{ + if (chip->ring_indices.params) { + dma_pool_free(chip->ring_indices.pool, + chip->ring_indices.params, + chip->ring_indices.dma_addr); + chip->ring_indices.params = NULL; + } + + dma_pool_destroy(chip->ring_indices.pool); + chip->ring_indices.pool = NULL; +} + +struct cl_chip *cl_chip_alloc(u8 idx) +{ + struct cl_chip *chip = vzalloc(sizeof(*chip)); + + if (!chip) + return NULL; + + chip->idx = idx; + return chip; +} + +void cl_chip_dealloc(struct cl_chip *chip) +{ + cl_chip_config_dealloc(chip); + vfree(chip); +} + +static void cl_chip_workqueue_create(struct cl_chip *chip) +{ + if (!chip->chip_workqueue) + chip->chip_workqueue = create_singlethread_workqueue("chip_workqueue"); +} + +static void cl_chip_workqueue_destroy(struct cl_chip *chip) +{ + if (chip->chip_workqueue) { + destroy_workqueue(chip->chip_workqueue); + chip->chip_workqueue = NULL; + } +} + +int cl_chip_init(struct cl_chip *chip) +{ + int ret = 0; + + chip->ipc_host2xmac_trigger_set = ipc_host_2_umac_trigger_set; + + chip->platform.app = NULL; + chip->platform.app_size = 0; + chip->platform.idx = U8_MAX; + + spin_lock_init(&chip->isr_lock); + spin_lock_init(&chip->spi_lock); + mutex_init(&chip->start_msg_lock); + mutex_init(&chip->calib_runtime_mutex); + + rwlock_init(&chip->cl_hw_lock); + mutex_init(&chip->recovery_mutex); + mutex_init(&chip->set_idle_mutex); + + cl_chip_set_max_antennas(chip); + + ret = cl_irq_request(chip); + if (ret) + return ret; + + ipc_host_global_int_en_set(chip, 1); + + cl_temperature_init(chip); + + ret = cl_e2p_init(chip); + if (ret) { + cl_dbg_chip_err(chip, "cl_e2p_init failed %d\n", ret); + return ret; + } + + ret = cl_fem_init(chip); + if (ret) + return ret; + + /* + * Update chip->max_antennas according to wiring_id if needed. + * Should be called after cl_fem_init(), where wiring_id is read from eeprom. + */ + cl_chip_update_max_antennas(chip); + + ret = cl_chip_ring_indices_init(chip); + if (ret) + return ret; + + cl_chip_print_serial_number(chip); + + cl_wrs_tables_global_build(); + cl_data_rates_inverse_build(); + cl_chip_workqueue_create(chip); + + return ret; +} + +void cl_chip_deinit(struct cl_chip *chip) +{ + cl_chip_workqueue_destroy(chip); + + cl_chip_ring_indices_deinit(chip); + + cl_temperature_close(chip); + + cl_e2p_close(chip); + + ipc_host_global_int_en_set(chip, 0); + + cl_irq_free(chip); +} + +u16 cl_chip_get_device_id(struct cl_chip *chip) +{ + u16 device_id = chip->pci_dev->device; + + if (chip->conf->ci_sim_device_id) + return chip->conf->ci_sim_device_id; + + /* If device-id is default, set it accoridng to phy-dev. */ + if (device_id == 0x8000 || device_id == 0x8001) + device_id = (chip->conf->ci_phy_dev == PHY_DEV_ATHOS) ? 0x8086 : 0x8080; + + return device_id; +} + +bool cl_chip_is_enabled(struct cl_chip *chip) +{ + return cl_chip_is_tcv0_enabled(chip) || cl_chip_is_tcv1_enabled(chip); +} + +bool cl_chip_is_both_enabled(struct cl_chip *chip) +{ + return cl_chip_is_tcv0_enabled(chip) && cl_chip_is_tcv1_enabled(chip); +} + +bool cl_chip_is_tcv0_enabled(struct cl_chip *chip) +{ + return chip->conf->ce_tcv_enabled[TCV0]; +} + +bool cl_chip_is_tcv1_enabled(struct cl_chip *chip) +{ + return chip->conf->ce_tcv_enabled[TCV1]; +} + +bool cl_chip_is_only_tcv0_enabled(struct cl_chip *chip) +{ + return cl_chip_is_tcv0_enabled(chip) && !cl_chip_is_tcv1_enabled(chip); +} + +bool cl_chip_is_only_tcv1_enabled(struct cl_chip *chip) +{ + return !cl_chip_is_tcv0_enabled(chip) && cl_chip_is_tcv1_enabled(chip); +} + +void cl_chip_set_hw(struct cl_chip *chip, struct cl_hw *cl_hw) +{ + if (cl_hw_is_tcv0(cl_hw)) + chip->cl_hw_tcv0 = cl_hw; + else + chip->cl_hw_tcv1 = cl_hw; +} + +void cl_chip_unset_hw(struct cl_chip *chip, struct cl_hw *cl_hw) +{ + if (cl_hw_is_tcv0(cl_hw)) + chip->cl_hw_tcv0 = NULL; + else + chip->cl_hw_tcv1 = NULL; +} + +bool cl_chip_is_8ant(struct cl_chip *chip) +{ + return chip->max_antennas == MAX_ANTENNAS_CL808X; +} + +bool cl_chip_is_6ant(struct cl_chip *chip) +{ + return chip->max_antennas == MAX_ANTENNAS_CL806X; +} + +bool cl_chip_is_4ant(struct cl_chip *chip) +{ + return chip->max_antennas == MAX_ANTENNAS_CL804X; +} + +bool cl_chip_is_3ant(struct cl_chip *chip) +{ + return chip->max_antennas == MAX_ANTENNAS_WIRING_ID_27_31; +} + +bool cl_chip_is_6g(struct cl_chip *chip) +{ + u16 device_id = cl_chip_get_device_id(chip); + u8 band = device_id & 0xf; + + return (band == 6); +} + +#define MAX_FIRST_MASK_BIT ((ETH_ALEN * 8) - 1) + +static struct cl_chip_conf chip_conf = { + .ce_tcv_enabled = { + [TCV0] = false, + [TCV1] = false + }, + .ce_lmac = "lmacfw.bin", + .ce_smac = "smacfw.bin", + .ce_irq_smp_affinity = -1, + .ce_eeprom_mode = E2P_MODE_BIN, + .ce_production_mode = false, + .ci_pci_msi_enable = true, + .ci_dma_lli_max_chan = { + [TCV0] = 6, + [TCV1] = 3 + }, + .ci_regdom_mode = "self", + .ci_country_code = "US", + .ce_ela_mode = "default", + .ci_phy_dev = PHY_DEV_OLYMPUS, + .ce_debug_level = DBG_LVL_ERROR, + .ce_host_pci_gen_ver = 3, + .ci_scale_down_fw = 1, + .ce_temp_comp_en = true, + .ce_temp_protect_en = TEMP_PROTECT_EXTERNAL, + .ce_temp_protect_delta = 0, + .ce_temp_protect_th_max = 105, + .ce_temp_protect_th_min = 95, + .ce_temp_protect_tx_period_ms = 50, + .ce_temp_protect_radio_off_th = 110, + .ci_phy_load_bootdrv = false, + .ce_phys_mac_addr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .ce_lam_enable = true, + .ce_first_mask_bit = 0, + .ci_no_capture_noise_sleep = true, + .ci_afe_config_en = true, + .ci_afe_vc_ref = 0x77777777, + .ci_afe_vc_avd = 0x55555555, + .ci_afe_eoc_ctrl = 0xaaaa, + .ci_afe_ch_cml_sel = 0xff, + .ci_afe_vc_cml = 0, + .ci_afe_cml_sel = 7, + .ci_afe_loopback = false, + .ci_afe_hw_mode = true, + .ci_dcoc_mv_thr = { + [CHNL_BW_20] = 150, + [CHNL_BW_40] = 100, + [CHNL_BW_80] = 100, + [CHNL_BW_160] = 100 + }, + .ci_calib_check_errors = false, + .ci_lolc_db_thr = -40, + .ci_iq_db_thr = -46, + .ci_rx_resched_tasklet = false, + .ci_rx_skb_max = 10000, + .ci_tcv1_chains_sx0 = false, + .ci_sim_device_id = 0, + .ce_calib_runtime_en = false, + .ci_calib_eeprom_en = 0, + .ci_calib_runtime_force = false, + .ci_la_mirror_en = true, +}; + +static int cl_chip_update_config(struct cl_chip *chip, char *name, char *value) +{ + struct cl_chip_conf *conf = chip->conf; + int ret = -ENOENT; + + do { + READ_BOOL_ARR(ce_tcv_enabled, TCV_MAX); + READ_STR(ce_lmac); + READ_STR(ce_smac); + READ_S32(ce_irq_smp_affinity); + READ_U8(ce_eeprom_mode); + READ_BOOL(ce_production_mode); + READ_BOOL(ci_pci_msi_enable); + READ_U8_ARR(ci_dma_lli_max_chan, TCV_MAX, true); + READ_STR(ci_regdom_mode); + READ_STR(ci_country_code); + READ_STR(ce_ela_mode); + READ_U8(ci_phy_dev); + READ_S8(ce_debug_level); + READ_U8(ce_host_pci_gen_ver); + READ_S32(ci_scale_down_fw); + READ_BOOL(ce_temp_comp_en); + READ_U8(ce_temp_protect_en); + READ_S8(ce_temp_protect_delta); + READ_S16(ce_temp_protect_th_max); + READ_S16(ce_temp_protect_th_min); + READ_U16(ce_temp_protect_tx_period_ms); + READ_S16(ce_temp_protect_radio_off_th); + READ_BOOL(ci_phy_load_bootdrv); + READ_MAC(ce_phys_mac_addr); + READ_BOOL(ce_lam_enable); + READ_U8(ce_first_mask_bit); + READ_BOOL(ci_no_capture_noise_sleep); + READ_BOOL(ci_afe_config_en); + READ_U32(ci_afe_vc_ref); + READ_U8(ci_afe_cml_sel); + READ_BOOL(ci_afe_loopback); + READ_BOOL(ci_afe_hw_mode); + READ_U8_ARR(ci_dcoc_mv_thr, CHNL_BW_MAX, true); + READ_BOOL(ci_calib_check_errors); + READ_S8(ci_lolc_db_thr); + READ_S8(ci_iq_db_thr); + READ_BOOL(ci_rx_resched_tasklet); + READ_U32(ci_rx_skb_max); + READ_BOOL(ci_tcv1_chains_sx0); + READ_U16(ci_sim_device_id); + READ_BOOL(ce_calib_runtime_en); + READ_BOOL(ci_calib_eeprom_en); + READ_BOOL(ci_calib_runtime_force); + READ_BOOL(ci_la_mirror_en); + } while (0); + + if (ret == -ENOENT) { + if (cl_config_is_non_driver_param(name)) + ret = 0; + else + CL_DBG_ERROR_CHIP(chip, "No matching conf for nvram parameter %s\n", name); + } + + return ret; +} + +static bool cl_chip_is_valid_device_id(u16 device_id) +{ + switch (device_id) { + case 0x8000: + case 0x8001: + case 0x8080: + case 0x8086: + case 0x8060: + case 0x8040: + case 0x8066: + case 0x8046: + return true; + default: + pr_debug("Invalid device_id %u\n", device_id); + break; + } + + return false; +} + +static int cl_chip_post_configuration(struct cl_chip *chip) +{ + struct cl_chip_conf *conf = chip->conf; + + if (conf->ce_eeprom_mode >= E2P_MODE_MAX) { + CL_DBG_ERROR_CHIP(chip, + "Invalid ce_eeprom_mode [%u]. Must be 0 (file) or 1 (eeprom)\n", + conf->ce_eeprom_mode); + return -EINVAL; + } + + if (conf->ce_first_mask_bit > MAX_FIRST_MASK_BIT) { + CL_DBG_ERROR_CHIP(chip, "Invalid ce_first_mask_bit (%u). Must be <= %u\n", + conf->ce_first_mask_bit, MAX_FIRST_MASK_BIT); + return -EINVAL; + } + + if (conf->ci_tcv1_chains_sx0 && !conf->ce_production_mode) { + cl_dbg_chip_verbose(chip, "Force ci_tcv1_chains_sx0 to 0 for operational mode\n"); + conf->ci_tcv1_chains_sx0 = false; + } + + if (conf->ci_sim_device_id && !cl_chip_is_valid_device_id(conf->ci_sim_device_id)) { + CL_DBG_ERROR_CHIP(chip, "Invalid ci_sim_device_id (0x%x)\n", + conf->ci_sim_device_id); + return -1; + } + /* IQ and DCOC calibration data will be saved only if runtime feature is enable */ + if (chip->conf->ci_calib_eeprom_en && !chip->conf->ce_calib_runtime_en) { + chip->conf->ci_calib_eeprom_en = 0; + CL_DBG_ERROR_CHIP(chip, "Writing/reading calibration data from the EEPROM is " + "disabled because ce_calib_runtime_en nvram isn't set\n"); + } + + return 0; +} + +static int cl_chip_set_all_params_from_buf(struct cl_chip *chip, char *buf, loff_t size) +{ + char *line = buf; + char name[MAX_PARAM_NAME_LENGTH]; + char value[STR_LEN_256B]; + char *begin; + char *end; + int ret = 0; + int name_length = 0; + int value_length = 0; + + while (line && strlen(line) && (line != (buf + size))) { + if ((*line == '#') || (*line == '\n')) { + /* Skip comment or blank line */ + line = strstr(line, "\n") + 1; + } else if (*line) { + begin = line; + end = strstr(begin, "="); + + if (!end) { + ret = -EBADMSG; + goto exit; + } + + end++; + name_length = end - begin; + value_length = strstr(end, "\n") - end + 1; + + if (name_length >= MAX_PARAM_NAME_LENGTH) { + cl_dbg_chip_err(chip, "Name too long (%u)\n", name_length); + ret = -EBADMSG; + goto exit; + } + if (value_length >= STR_LEN_256B) { + cl_dbg_chip_err(chip, "Value too long (%u)\n", value_length); + ret = -EBADMSG; + goto exit; + } + + snprintf(name, name_length, "%s", begin); + snprintf(value, value_length, "%s", end); + + ret = cl_chip_update_config(chip, name, value); + if (ret) + goto exit; + + line = strstr(line, "\n") + 1; + } + } + +exit: + + return ret; +} + +int cl_chip_config_read(struct cl_chip *chip) +{ + char *buf = NULL; + loff_t size = 0; + int ret = 0; + char filename[CL_FILENAME_MAX] = {0}; + + /* Allocate cl_chip_conf */ + chip->conf = kzalloc(sizeof(*chip->conf), GFP_KERNEL); + if (!chip->conf) + return -ENOMEM; + + /* Copy default parameters */ + memcpy(chip->conf, &chip_conf, sizeof(*chip->conf)); + + snprintf(filename, sizeof(filename), "cl_chip%u.dat", chip->idx); + pr_debug("%s: %s\n", __func__, filename); + size = cl_file_open_and_read(chip, filename, &buf); + + if (!buf) { + pr_err("read %s failed !!!\n", filename); + return -ENODATA; + } + + ret = cl_chip_set_all_params_from_buf(chip, buf, size); + if (ret) { + kfree(buf); + return ret; + } + + kfree(buf); + + if (!cl_chip_is_enabled(chip)) { + cl_dbg_chip_verbose(chip, "Disabled\n"); + return -EOPNOTSUPP; + } + + ret = cl_chip_post_configuration(chip); + + return ret; +} + +void cl_chip_config_dealloc(struct cl_chip *chip) +{ + kfree(chip->conf); +} From patchwork Tue May 24 11:33:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576866 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 EA8DBC4332F for ; Tue, 24 May 2022 11:38:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236793AbiEXLiG (ORCPT ); Tue, 24 May 2022 07:38:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236786AbiEXLiF (ORCPT ); Tue, 24 May 2022 07:38:05 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D2BB8BD09 for ; Tue, 24 May 2022 04:37:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kOXnxCzDcAjNaKEwYtbV3dps/RNditZizRWyvM07ZmjpvZSEpie1qqNQ0kOBh6aVCB/eN/Hkbj6hNs+bx8SSPMMhzETKuDsbMcW7cIpQp5qEqoahJEwzHIBcrxTkPEMHEDMZ8THBwmkZ3cF/4ri6t8gIxOwoj2CAx/pAxjr7FRmqr7PNfok3EEKzizzHS695qWWQOz8vHhW9wStm7JXIuuu6rEWRmJcS/TaSHknBbi4O5IGmRpxxC4O203RS3DbkQn8UAjX54rh++8J9Jt3wH04hVKDua2sui3Io6PVYDyevcFhxA1wT4KVCumIJ1qvxkalOeRws67AS0Q0eXPcO4w== 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=n/yje7kGVUxMRVXinPBQpt7CEFdo5vm3t3XU8367uwc=; b=iy20+KlFAO1M1yf9+xidU/lmiPYALYxokVvphp+0doTJp5F7fv2b/WF2atLaJhXtNbQh3kRNeJqaC9MfmsAQrZi4mp+UsvKXgy8R3f9Em0v9eQF+aYFSfsxKvmiCEpjZq4o4uCiN5LqcKpvpuzdx5SfJjCwGlj0n0gEkI5GmgYxbE+grdZgFoZ0z0RxfoBYoCb+WhNvj+IkU2x/9ksE40ARdmUPp6gFusv+h/TDw8pxmyoi1d7/ZUxwAjji7OxXYK19wufNJBRW7RdfRosZccBsvX4tvmk44nTGJAy+8agHRvvQ4wr4Xvx6n3BU/5gBzMTG0GURn70Hif4U4lI2Pag== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=n/yje7kGVUxMRVXinPBQpt7CEFdo5vm3t3XU8367uwc=; b=SPxOxu8Hrp8dtLaj8mFrKOH9HvRpLTlfF7pItr1Z+LoEXBzLRw7bWwEtoBjGz7S+2NwnTxg810MKdZCWdmRxz8h/a1ExGiGTogPy2dNFdD1Hi7r6GF5O4NMwQS/rIzCZat4fO6GD0hzIj/CJOMDnbsSXPCcsOsMwmjaY0UGtnII= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:53 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:53 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 14/96] cl8k: add chip.h Date: Tue, 24 May 2022 14:33:40 +0300 Message-Id: <20220524113502.1094459-15-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8d2c010b-46bc-49e1-5f21-08da3d79d69f X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: f/z2CFkn0y5qlHHsWyEIUOH/bIXhRygIQgdSTiQ46HMmt5t7pC4+pwHjjHHwvzFDGmyF//K7fsCiUQ26SbPn+0YgSTQWafKeRQEMYBQx1+3I7dQVNtVp7iv+UDI+1yCblWMmVhUJdskSTsukE+eY4FPsfY4EmZgHXtlLoiUxLZs3ZKk3YD9DDfvBhxGtDmGy0nAJ+qcOX3PcLoUQmZ0LVJXlNdmxTRjTSYJUy1baUDm7/+z3JigTfh372waVINjM8efCTli6Sk8+y/NgI+dtnVZr50W3rBOOKWzSdoQ7ZSGKavMn/PpOCYgMVbi858jg2noNZj59NF4Zxz3ZUTF9/QT0cYyglmhKAwADSCtOgg0izs/xedcPJskzo4258B8G8q/kR+WsgNnSCyzuJUJUQwBqDI2HRL6jBcauZMmdBWu4AVLfQcPWqTKgBwfJKUoYYnYbaAmfkHMD9Y5ssKYx/m56m8VI40BTnUdYL8aZdjFqEKg3Z5w2fWFzUQw+EkK5qnkVfFxP8qKLXkBsupaYOLmcl1zmXaviWUFcSd5ZFOtxox7bD9Bxjm35dA2e3zcbWElj41S1hnWfJCUtMvBQEIOum3yBft3/CjgE/YZGKhTxPoeALCvqqUs8Lz0FIZNEP3Nhrvihk9i04moDGs0qp/IHMmI7sWqh1INHmumz5kTFF73jmw7XJYVsLStsSXB+DvshPT2jvQFC91OBxRNxUuU8JbMcgZ2iR/g3EMUSBx8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: FlyoC+fWvhKVE7dyuEy/F3b8FpPF0WFm9JCx0k52bDWe6odrTrR8zlbAMcxGlOo4wkJSaX+sjKBPzslYcmftjAVYDpQp8Ieh9Irp7CVqLVnb3HQbQg1kpZCpH3w40zA5JxojIRjDbypVbxYi3hyKycD7Ud8M2wpxcUzWDeDujyRursK/m331D4Dubix/PRDpQV/9MkF9ypMtSOFoTFG7srwXZPmV9c3jADdq2272sDdCTxz6I9HlAv5unXwIIIZoTz2hMA4V06iEyYiNB1Sfkee/ktP/YXPJrJHH0Kndm3gzodpNjksgngrpdPH3OoRLv9EpcnyYr7C6DoWi1NQe9n6w1QHCeAhIaszmh0zuCmTD37iguKYr3+q6rit/O0nn1mIPdJ74ONnSnk0eC7w2ExwB+i3JzO4IQhZH7U/PsZ4/QfG8MgNiX9dVGFG2GjWp97+ZlWcFX4Tbr4iaOvu7hmHHUI5ryDHXgxEpIYxJmsS6VdMw4T+vbf3vsPkEtNZAZxzc+gM4WnKDcRvj82bjeGyEPK4/rnGrhp+UlqogF3pQLYmFw2xYpT7gRg0gulE7YcVFq8Ao6iqY6dzwbuk8rWEov00257GSLksj42PtLhX/BagDzpFA9csLKUzsHFDmU2hfAtH4vdOvpFNc1erWLQ96fg43JDtumQJi68xDxmRcNX7PmRvKRLKR6mbyYRF1kR/us1NXOD7N1Z4nQbnj/7NfA3QIQ0q6uYno1eRrum6+mMvdbqtnCVSrLpoFlOW6tlxTWAR6ztOQf4oKD0JipTR9CGjDufNCEVeJycYBurp9L/SOc3h2iT5CDcQPzg2DMD3MYxVSjthT0Q9fqR5XrC3pvYBNAgQoRtw9aN2sBGl2FQg7s7jwiFXJpjJ8cgXs99DBKKekX3oe6VG4zW3ZogfjqF2ru7cGTr+N8vaXnGn+UkVYnarihm5UhRukEAdOu+1y4MA9cFoS4m3NEqcgPhNUlUo+DNHGBYtdodhp8juxdmOVbezRgwhRF19RFAKb5E/dDhrTMfmbZr3qX8ieLZIoZJ0ZXhk0zZaab5GZU4h8vKKig4yXZiQUlFunpZqQeyUN13QOtv4rXz9M955uPl0s+7Sob0LkBhsuJM/07F65CZUI6McEmhQyW33zgxQg375PlTAJZ+FELondf/i4Wiso8Tzfzyo4zgF4dQvLHbRStu9OdCNgBiyuX8O+3N+qZpZlp+Scc71lwzopEjU4U2McMgcRYOO50ykxyVMAvnV7M0CfqcirK1YCOMMvq9XboY/rXYRLLQQB8vtyAS2579X+ipSQcFA2LjNXSglM0G0QLHaZ5+VsVy4dtPOoX1NWfutZoAmKXbpzfbQm1Kb3VIEyLDW54Xd7HvZ0WdLSEOv+E3Hb3YPUUnZHf4+k4rKrwbTNQGy7b8D4YraF3XkzFfCNlgeEwCUwwPO9ppCey6ftZxyAFR3VnEMV+fm9VZk/OmrCNv5P6b4F1e1d1nPJMrfvWmKjLFaDWOaEi87OwXxBwsBbig1hd9B9YbTogCJZiqoA3eBVlSXr3dY0xHvKcGj/K/vssJZJEgPFQZtipGyi5HCm7F8hR11yDkcOQoHRXCNpJ+J4Mdqc+J9KGaVN7FZkrOyAgsKNmX0jM421Nq7f8bi8XaPRJDZ09YYVyA01khDUzNTPRcnHPUrRSA1bTNv+0il7hB3p2eyE/OEUYn7XM4VVHo02u7j9HFLFOTS3zhN8zll+tAwdPygEx58DHmmIvYing4ldm5h3RyvCJNQ= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8d2c010b-46bc-49e1-5f21-08da3d79d69f X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:53.0590 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: BNxgSnDZycQecMiBjoRI47ETF1rym5OtUo+kFroMTqpogzcZak9n8T9wWvOUuNea8hdNiOJCAtKJqsVxnT696w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/chip.h | 182 ++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/chip.h diff --git a/drivers/net/wireless/celeno/cl8k/chip.h b/drivers/net/wireless/celeno/cl8k/chip.h new file mode 100644 index 000000000000..29d02cb85fb4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/chip.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_CHIP_H +#define CL_CHIP_H + +#include +#include +#include + +#include "pci.h" +#include "calib.h" +#include "sounding.h" +#include "temperature.h" +#include "platform.h" +#include "phy.h" +#include "ela.h" + +/** + * DOC: Chip basics + * + * Each physical device of ours is a separate chip, that is being described by + * %cl_chip structure. Each chip may be several (%TCV_MAX) transceivers (bands), + * which are operating simultaneously and are described via own %ieee80211_hw + * unit (it refers to the private driver via specific pointer, described by + * %cl_hw). Totally, 3 types of bands are supported - 2.4G/5.2G/6G. Driver + * supports multiple chips (up to %CHIP_MAX). Since the driver can control up + * to %TCV_TOTAL entities, it is important to pass it's pointer to each + * function, that operates somehow with specific band/transceiver. + * + * Chip instance is being created during bus probing procedure and is being + * destroyed during bus removal procedure. + * + * Physically, 80xx chips family may have different amount of antennas (4/6/8), + * each of which may not be hardly bounded to the specific band (both bands are + * sharing them and may change antenna combinations in specific circumstances). + * + * Each band (transceiver) has own FW, that is being loaded by + * request_firmware() call during chip structure initialization procedure. At + * lower layer each band is associated with own HW die by LMAC and SMAC names + * (e.g: 5.2G and 2.4G). Celeno is using XMAC naming when we are referring to any + * of LMAC/SMAC components. + */ + +struct cl_ring_indices { + struct cl_ipc_ring_indices *params; + dma_addr_t dma_addr; + struct dma_pool *pool; +}; + +struct cl_chip { + u8 idx; + bool umac_active; + u8 max_antennas; + u8 rfic_version; + enum cl_bus_type bus_type; + struct pci_driver pci_drv; + struct pci_dev *pci_dev; + void __iomem *pci_bar0_virt_addr; + struct cl_irq_stats irq_stats; + struct cl_temperature temperature; + struct cl_chip_conf *conf; + struct device *dev; + struct cl_hw *cl_hw_lut[TCV_MAX]; + struct cl_hw *cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1; + u8 cdb_mode_maj; + spinlock_t isr_lock; + spinlock_t spi_lock; + struct mutex start_msg_lock; + bool first_start_sent; + rwlock_t cl_hw_lock; + void (*ipc_host2xmac_trigger_set)(struct cl_chip *chip, u32 value); + bool rf_reg_overwrite; + struct cl_fem_params fem; + struct eeprom *eeprom_cache; + size_t eeprom_bin_size; + int (*eeprom_read_block)(struct cl_chip *chip, u16 addr, u16 num_of_byte, u8 *data); + int (*eeprom_write_block)(struct cl_chip *chip, u16 addr, u16 num_of_byte, u8 *data); + struct cl_iq_dcoc_conf iq_dcoc_conf; + struct cl_afe_reg orig_afe_reg; + struct cl_calib_db calib_db; + struct cl_ela_db ela_db; + struct cl_ring_indices ring_indices; + u8 reg_dbg; + struct cl_xmem xmem_db; + bool is_calib_eeprom_loaded; + struct workqueue_struct *chip_workqueue; + struct mutex recovery_mutex; + struct mutex calib_runtime_mutex; + struct mutex set_idle_mutex; + struct cl_platform platform; +}; + +struct cl_controller_reg { + u32 breset; + u32 debug_enable; + u32 dreset; + u32 ocd_halt_on_reset; + u32 run_stall; +}; + +struct cl_chip *cl_chip_alloc(u8 idx); +void cl_chip_dealloc(struct cl_chip *chip); +int cl_chip_init(struct cl_chip *chip); +void cl_chip_deinit(struct cl_chip *chip); +bool cl_chip_is_enabled(struct cl_chip *chip); +bool cl_chip_is_both_enabled(struct cl_chip *chip); +bool cl_chip_is_tcv0_enabled(struct cl_chip *chip); +bool cl_chip_is_tcv1_enabled(struct cl_chip *chip); +bool cl_chip_is_only_tcv0_enabled(struct cl_chip *chip); +bool cl_chip_is_only_tcv1_enabled(struct cl_chip *chip); +void cl_chip_set_hw(struct cl_chip *chip, struct cl_hw *cl_hw); +void cl_chip_unset_hw(struct cl_chip *chip, struct cl_hw *cl_hw); +bool cl_chip_is_8ant(struct cl_chip *chip); +bool cl_chip_is_6ant(struct cl_chip *chip); +bool cl_chip_is_4ant(struct cl_chip *chip); +bool cl_chip_is_3ant(struct cl_chip *chip); +bool cl_chip_is_6g(struct cl_chip *chip); +u16 cl_chip_get_device_id(struct cl_chip *chip); + +#define CC_MAX_LEN 3 /* 2 characters + null */ +#define RM_MAX_LEN 5 /* 4 characters + null */ +#define FW_MAX_NAME 32 + +struct cl_chip_conf { + bool ce_tcv_enabled[TCV_MAX]; + s8 ce_lmac[FW_MAX_NAME]; + s8 ce_smac[FW_MAX_NAME]; + s32 ce_irq_smp_affinity; + u8 ce_eeprom_mode; + bool ce_production_mode; + bool ci_pci_msi_enable; + u8 ci_dma_lli_max_chan[TCV_MAX]; + s8 ci_country_code[CC_MAX_LEN]; + s8 ci_regdom_mode[RM_MAX_LEN]; + s8 ce_ela_mode[STR_LEN_64B]; + u8 ci_phy_dev; + s8 ce_debug_level; + u8 ce_host_pci_gen_ver; + s32 ci_scale_down_fw; + bool ce_temp_comp_en; + u8 ce_temp_protect_en; + s8 ce_temp_protect_delta; + s16 ce_temp_protect_th_max; + s16 ce_temp_protect_th_min; + u16 ce_temp_protect_tx_period_ms; + s16 ce_temp_protect_radio_off_th; + bool ci_phy_load_bootdrv; + u8 ce_phys_mac_addr[ETH_ALEN]; + bool ce_lam_enable; + u8 ce_first_mask_bit; + bool ci_no_capture_noise_sleep; + bool ci_afe_config_en; + u32 ci_afe_vc_ref; + u32 ci_afe_vc_avd; + u32 ci_afe_vc_cml; + u16 ci_afe_eoc_ctrl; + u8 ci_afe_ch_cml_sel; + u8 ci_afe_cml_sel; + bool ci_afe_loopback; + bool ci_afe_hw_mode; + u8 ci_dcoc_mv_thr[CHNL_BW_MAX]; + bool ci_calib_check_errors; + s8 ci_lolc_db_thr; + s8 ci_iq_db_thr; + bool ci_rx_resched_tasklet; + u32 ci_rx_skb_max; + bool ci_tcv1_chains_sx0; + u16 ci_sim_device_id; + bool ce_calib_runtime_en; + bool ci_calib_eeprom_en; + bool ci_calib_runtime_force; + bool ci_la_mirror_en; + + /* New NVRAM parameters must be added to cl_chip_config_print() */ +}; + +int cl_chip_config_read(struct cl_chip *chip); +void cl_chip_config_dealloc(struct cl_chip *chip); + +#endif /* CL_CHIP_H */ From patchwork Tue May 24 11:33:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575985 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 572B1C433FE for ; Tue, 24 May 2022 11:38:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236786AbiEXLiH (ORCPT ); Tue, 24 May 2022 07:38:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236773AbiEXLiG (ORCPT ); Tue, 24 May 2022 07:38:06 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70041.outbound.protection.outlook.com [40.107.7.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 731F68CCCF for ; Tue, 24 May 2022 04:38:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iK74rTsn1WRQVC2r5rRE7rpIo46/fRNfddVd8OQ3hMvD4H0PZd9Lm8c1RBmesVZf7NGm+dQ64j5dwi+PYb6otWJSBFLVdNCHeqRHNMPZErwk8iDULm//7wwjPoH1Zsm68/rUeP9YSGuhoWU831b6m52tJ+nhD11d0c8g8DGFRH7lnRjdCpSRwJmrYI+NOPevd1wbWhfObfH7ozorflTmIJ7t+aaDomXvw0d+rfwOeFvqePFR9fXoTGgyC2D1mk3ILxVfnvQf6iXCtprIABo7yys7InFkIrzXZqCffdLq4ox/vSkYenESFazqvG27ZwCoLkOtWsUaYN4XglYUYEr43w== 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=Co7LvVuHe8CONzs7QyYAq8Y2I8T5eAave9eAfyV0OEA=; b=nri3IsI6R2cthe6MU/PhXxoMtE3z1yyry97I8t+tAl8n9SSbhUGJ0/6QufyCkj3ViFNG2QG+BZMTbSD3rWNuMLYsZqbHkTAZGUf+AFucofpdiIW3gDdxJpI5Fzjr6sLHkLVm6wQ5kBIteWTsyWPSkr07AQuuezwazcRH/g1ICHPOOP41RbVYTSpFp6kH11g1aRcgg0BzK0BZ0NEUWDt7Of3zX6cIThYriInPHU78rR+dBZc22gEyeWQKrdCA4R5krCqE+lOKsHNgVY4O/s0DhDo9Ie8fkZieltxG0qgK6orYBqzsiyyOHQAFQJ11FROYj+Rv5HeH/EMGmWG0iVEekA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Co7LvVuHe8CONzs7QyYAq8Y2I8T5eAave9eAfyV0OEA=; b=3Ivzs3VH1kqHZcwWvWNVpWCcMAli1jEiiEPUJgxD1unGe37hl09T4Mk6k/jKtoYe2fnnSGNLGjpI712vXakyA2TBZaDLAuE7rx5j/feirsH7oxECQPWSVz5DPTejkxH7qwYOn04hFSiwzNd/av7lo8Ms/O5gNgKc/3NlYBC3bkk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:53 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:53 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 15/96] cl8k: add config.c Date: Tue, 24 May 2022 14:33:41 +0300 Message-Id: <20220524113502.1094459-16-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b16ff473-d815-4edc-369d-08da3d79d72c X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Q9Fa3nR5MAGvJdDLUpVVXHn0lf9R4oVzqYqXpkoLbBqKCthXzQvwmDXvMe4KqKe90LXwlF0pBs35++J3Q0I+QfZxLXrkc+WsQ4Qd1FxW2yg23HYP2K8JrTGXs2Px9rKHeRz5fiorWXo7005KnEU8lZX22GzG7F2t37JfzA7QABOcCvy+7XJ8y30trZ9oECxDGB1DmGOiNeOowwlhJff9dylpmLWtEtVK013P2x+3cRFThy0KkR+aA4lnQYvsJte2vtaqMVh0e+CotrVeaQE1YJhH4lqQFx09Ps7Lt+A1UyzOw1K+zRnRCou7u/rcagXxyu14cH2OhRPIFOMJtEo4oeoccUab45DrTMpE87KzuMAs1q+U0zry5bqpiHdwuaRLXCqH5PS3x/IHFbxbHLbva8uovJtxwWYO/mIjWkOa5iqiMbSvk+lXLtOPe5Hfk7X2UJc5FzS/qcwG9JK7iyJTAmGvk5GQ5Q7gWr6IpJtBAiN/WQFvj9614pifbcKxRarLCjHn9nFyr+Ce4Td7diIQl6VAR4MXaqzmN4dn6yXj9akr+JCvZwC/ypbVq5kX1snzWp6pSMz5lvAdsUhvCUMY+2pTzCl+c48Tl0R+Jj/pi1PBa6tMEWnXCqwokkeXmMkOllLIHb0d+FEerrX1rPO6yVMXty5hDRbju2qF9Anq2Blht+olk7TyiVJdpkyECoZfcbYVDwVE4AIxw31nQqiYKrsuFIOg3npQ50fohMUkE0o= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: rXdaXMHcSATpxgI4z4Lqk2Cd8qTXTLfruXZH3SlHZbXFYQE6fDvLQ/0NthBEi101ArrscKOLyWBszMLocH351dYYSwlAGhSsXEJH27x3pqfdvQ3n/KMJtSLbi7ge7g6nIGb5+x850defj69m+WK0ogy5uuEgQYTGUPg/jjvFuheJEXkHEp39Xv7pYO+j3eKZA02FdpIQrbygdPW9cSV4rFTCI6grPmyokB52w2uydPFugs3xxl/7aCs0MSq0LR4DaGTQeGXtDq06hwoZpEKgDr4s1/0OfxYLdeuG2O0X6EiF9XsgvQGQnGN+VdaB47LKAAhqoeLZr2rwUq9ng6mAlMRTFbPhAIqKrQ5PeKAz7htwyb2M2kRcDfG4omIe4Avf2492miG66DwEzegVOlyQ+a6FWTwzTVeGZ+1nT9PDI1ETa9bvuiTQbBYvW4VDE14CE3pjPhyTcuUQCAjYiatRl41lTRhhVspWnSruQrj3Fla/YYBXVs5GswNUEkZtJGjAwq+kleqvpEpaQJn55QPLrO86vMkKqWKGXpt+PWqm+9fVbet8k5qkt1m3IAAyPzdhi+RZCsI7RP9naVKaVqvEwJZaA60K8Lp23RshrudMOxFj/O6yQAkZ7ak/bilRluzX+xBZCCoufkunJ6EHYmnbpkXgSgw0vVZnWKNRuLDXD5KM/nDsKJBhZk95UEIoz1oynoLCfYGfIJcKs/izoFmt4hKYUzJGuuV79CJPprhrspYHcob2Ery5ycUOQi4BLnrL6149S8PSOlSoEPqABRXyE74C2a8/oxvTGBRdECFUwVh5RazBbtU1bAv+bAVav+RnaGL37rk1uV10GhZilMb7lc2OsyXLo13Q5b5haWasQA0n17xSx8x19zmF74MQLOLji/4py1F8FRllK+SmGP1nbwnlrgSpJWinfCCSQ4jxErM/AXIdJEcFCdlC2dp7cXJjUdhMelAJ5DzOiZQRSWbPQvlrxD8u6PTkHWvZfUDvnA0Vd5MOmM4PWEc1JtxsnUykjmMFDP8aso8YdEANE2TTMNJxdPaw7QS4JZ4iJ+IJMvxLyxfYzB40jT/43ogsTpeU2YQ/tGnh21aHy2O599/oP/fnZ4BW/Qnf3m3J2P03jBUfRXAZrPNhA5+ILo5LA05xWcHpQca1aSXT/Sk50tHOvhxdiLiqhJgDlvi2WLGXUngF3fVf21aIPrekxLBTEDr6i/T+fqo3+hlRhJyr1wnu5ctfGlI6LJpBzK4vj7hl7KcmYoKnLQjn1VRbsue4/P+MHpQ/EtP0OuRtzidPWhynCcslhORss/Rig58Rlx/SAzwIeVWLSr0N656j+DkQ/YoD/CJOYUHONpGfvwdXnRGs+4LGAjSXag3/ACVXnYDymmjPUn77Kn/bAsT0llueqwNkst0Wjd+wBfkD3mMn1DE1bzyKnDH3G3UE4nzmx27IgaI9Lc/k+w0ezPy7Z0pf/WY1Rxb1wqfJIytt0LFmGqfmVYlpKtjC6spVE0YaaofWwm7wLYehTy9preemTFEYcvdPF8ZqLiIY1YLh138hBSkYU4/7QtjTDgIDQMQwm1HcBBOcWMnMRsO0RycU3OuirUMfQZt6on6wPlokhmGgLUwQdVe1jvmvBfvRl+Vagu0w77VQDCA0ZNhlGaaEHkFYRLnJDyp78j92u+M2qBmyXsSQ6p8xQktUzSkoKv4WI5BaNXTLK4izQH7epN5D0Nf09c+LpbhWHevDE0seAvX4Kirz6uYa1rYUQqssriNCgmYqvU4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b16ff473-d815-4edc-369d-08da3d79d72c X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:53.8713 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: w2wB3x8prcasP/iAEX9C2mlbAgDKHzguRmb6u9fScyGlU9oq5fHNwVQMJx19IbT3VQ9suIc7GgwvCCfjdBVC9g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/config.c | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/config.c diff --git a/drivers/net/wireless/celeno/cl8k/config.c b/drivers/net/wireless/celeno/cl8k/config.c new file mode 100644 index 000000000000..dbf94060bfa4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/config.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "hw.h" +#include "debug.h" +#include "config.h" + +static char *non_driver_conf_params[] = { + "ws_", + "ha_", + "uuid1", + "ce_pci_id", + "ce_rst_gpio", + "ce_iface_eth", + "ce_iface_vlan", + "ce_iface_ip", + "ci_sim_chip_num", + "ci_lcu_dump_folder", + "ci_server_addr", + "ci_server_user", + "ci_pci_tune_en", + "ce_uapsd_en", + "ce_channel_bandwidth", + "ce_ht_rxldpc_en", + "ce_vht_rxldpc_en", + "ce_he_rxldpc_en", + "ce_bf_en", + "ce_bss_num", + "ce_iface_type", + "ce_mu_mimo_state", + "ce_wireless_mode", + "ce_extension_channel", + NULL +}; + +bool cl_config_is_non_driver_param(char *name) +{ + int i = 0; + + for (i = 0; non_driver_conf_params[i]; i++) + if (!strncmp(name, non_driver_conf_params[i], strlen(non_driver_conf_params[i]))) + return true; + + return false; +} + From patchwork Tue May 24 11:33:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575984 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 8772EC433EF for ; Tue, 24 May 2022 11:38:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236800AbiEXLiQ (ORCPT ); Tue, 24 May 2022 07:38:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236791AbiEXLiN (ORCPT ); Tue, 24 May 2022 07:38:13 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70052.outbound.protection.outlook.com [40.107.7.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D43D8CB3D for ; Tue, 24 May 2022 04:38:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fjUppEkIIWCuSdfDllOQCBMMjUWAQtVg64YUYFF9bPBLz2E+L3lHVgrOT2uIXEbu1aEl7kdNiTuyjEfCVyQfHH+jSh6H1bcBgvU39dFrUkjUS3zkE0x7qUq2gWyPyxhbrtJBnz5tKX0JB0xbf3rKSnS/Litb7M435hKsNmw1O2Jo2/d2vMmNJdBGN5Zkq+PHDu3JbrvfLKOQ0OY5qYNR1tK/B7JBt4T/+WI/+205Zic9IA86JR8f6q7c/Q7dIg9hH+7ZzOlQh9OY+dX9MtzG7zXf0IUEunF/1Q93C/PgReKcRnVEvYg2BKv+4rZ5cY5YIcd8uSFYPbHi4lsn8H7rJA== 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=N1buV6dRM3M0x/06R3qQp+ncFWo2ZXah0gGW/YWwdR4=; b=kSHECAfNY2ki5oDdPFlK3K+WC9nfyH4DDlcmGTLXgnsz9D5vmLMMZ6j21ADTopdEBagSTaDXSvwM2TTq24IN0PJzXbDZj+nDUWKd36ygxtA+PP6KtXjpK+QCJWzq2nXiOFU2d18pVoq2rOkVYRmh3+/Rc/3u19zZhLLIXdfhkefFkD7npbvksLdTW1deNSXQw/zEby9cXnmPmTORbTm3hLuXyjU0l5NnPoafO7IfOf2Eg+d7v2aLUSdzSM8pqbbXa67V9vsSVWGcHAQQ7jBnZGi5bp3ALG/JARWxjOmcV2R1Y07qwQ0ekTifMGm/CCywR52mkVTFxcVslc2oortz+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=N1buV6dRM3M0x/06R3qQp+ncFWo2ZXah0gGW/YWwdR4=; b=fzVjKd5JnXgzxAsAadfCQXJb6vPL+/Yj+raDHDizo3doNJnBSJjXxNL9AJkAbO4yTF6dfsX3XwbQ4kyaDRdwgges9p9kyPnEEoLc7O7PxpehaQXmZPs72DDaYKXdfRFR5uqIbpfAucLyHEnmHJjjFmjN+Y2ukPie08Pdd197i1I= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:54 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:54 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 16/96] cl8k: add config.h Date: Tue, 24 May 2022 14:33:42 +0300 Message-Id: <20220524113502.1094459-17-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9ec262ff-829c-49bb-fd30-08da3d79d7a7 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: iIGCDBu76DhBf3WHlRD3HdXs3PIHlAOM1FFH5ByNQhAbBBwzWuHGCBza1jEPSSBerVvp8NzHitcYfpDmaCJ0p0YiJYKAnrvAYB3Fh4sQytWBSm7Ius7ORuoHX/QmifEhJxTwHkvW44yZYfrOlpSJ+WdnYzMeVrNUCdG93LpKgiCzwZr69SPnjrs39CSSnVEt13X/CKoKA47lxr+ga+OS/aeKR6N2ur49CpHCt6Pvr0tcgmcHj9P7LRm+XG4UfozFWHVuAGlUo6txDIxtt8ScK4ZLcsrOuI3Xr9zkFJ6kbEgEWlnSaT9mOmC8GTrGOSihzPGi7upGYZ5VV0baLOkAl1D5Cmt3AgZakoGskfL2hmx0+BHvJxIqJkyfA86DI2q7OX8MnMdQYwH9JAiRlszfnyXO7/tQu1f48EF14g82hMBfNTKR5AHgfsU1GpnVI94kqhFBWDWjUToYuk1Nj/S3fueQlbjvhJR+Gjgiq0hPXtyGPj3ha83nV9lKbyFzmAmWNTyebmHG5vAzCsCv58F+29KUeXcxs2+SyE64775rW4/7TmkIAvBghnhAtK+8hACPtHBVOO0QoaufqjueHp/F8QSGrw9BYkIgSw2DKVrFePCgTjUNgOB6nQGasScmUTTXqMCdYKlYKUleOiw+SRq4OBSNp2nZZAX9h68bj5sp+Mqe2BPH4Rf/W1LeNElzNrqN3YZKEyk8z3uagJGCQTV8Ps2wihNo7glH2ErFky2jRu0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ysBiN3yk7yM2+ljtS5aaqip4jmZQAvgM3rzaaLiIWF++6FxvlMCvnJQRv/sRCqWtFfIqob22mUqBoZ06gPSAmqW6l8RoseEFQgq8qArbL+rM2bc/5dT+Y+MoI/2cGjhZeqWt1XrDU+dYSD5EhVjOG9M/NP4Hex8zb19iGXNzX/4/Kfm+rqEGha4SzBK7W9dOfvqVhR2iBHUlm6/lmrvmjtPhqkRadWwBMqAfcorHNQsUJlG9UVk1nBxbm4TNi0sMkCfWndi3D+LZUIPJQghPAtcxwASGyKjFLKQn5mFJMxPtW345FrDGJ3lM6b4Ky4U1LA6D54D63+7w9k5cgMZAQ0mIaymqiZ0IIr1T6gDGArMEd2DrOJaswgSs0sXqvvF8CwVAbdUUsff7/D3kYxMrYrszw5abgRCKXh+smkuePjpdBNY/EtxENyacuDyfrGn+8U8zqdpQ3F/johsMHnsw6aaRU/PpxGRHMoDS2LlChqZVnoxUr97wRRCiNlXjlnxmdt+91KrLDLUVYolHC7gQhPPoTRPfW3/vS8QrSEBHebXw8gHA8a8sQZcR8YZsEoq6vApS8sbeP/l3hFur+NJ05DREbnNTJn31QhlnVluIwZAz0K3M/4U4ZtQAYhE+Gdjw+fcYXWEnW7LMWH/8vQlX9xZ1IDIetXjMxSXbHnzMQTcQPjIIB0YsLtBgoWrNk6ukbzi5DzbGt5H/Qm4BmZ3XAwlCfU8RTJ7XZA5u4RahWYOMk9AtKz1W0wMQZpUYC4JndaatcVCJLW3/iu0xhkPjQBA8uqoO609bWuzQqf7NrrXC8oqsjlJNyHXqo9uX5Js7qAyHtXJKgkres0QdG9P6YuVarYDQZBV9TYnn91R8LzaTrteQguBzQmiVljkU4Lpf0cn6DdssgxxhYqeDXw1oaBP455KsdKYq6ygvKB17EuxD7TxiRyGVTZQ0Um9vQ9ze8hjFrsVo8nHviDSwrPrwr7DOBeFwQXLzgpGJrmJ3qRN5Ud8sJa1CgJaJk6vuSZCBRlZVO2Iv5Du/9ADe4nuVpYNCxwZSJ05p2pcJfYXq2U4cdcj3v8pkt7qRg9bjKP2coH4gKUE2TzvbzMYf1u3q4DUfzcG4GtObzJvaSH0z0rDuTw5mSwKwVO8YmcuQ3rJbEzZabbsyy7CiaZEb1matF5iw90d+w5FmommHXY6W7YYFAqNSjXD3pslBsv9hMqhk4gbXNwierSXytSDjzBer6pgL9iz4HPwyZx7GuIl+4EtU9wQR4o1T3N6nxySM8Jdlb8fTQpZjpcK+h6mT/HOTg9OE9Z0YN3I8hVxh/2QYtdvojIXJHECQoM5vduVKdYnDQYY655bAXqym/+Hw2MPNpqu7zYVuMaS5N1n49KbhgpnTUfVf0eVZFcpm+CY4nnBvDNWBirCXU5Ja35SfUWofPNCg4bi7/P5JTNksM9WNUrv49JxEd3UVRZCpP9qgCdaccfmozXRqYc56dhzN1fHeRjTsfOgmC6EFVyfAofTouqn8RcE36vAMtoeY0upic55p7JpY1QqEoBa8Ib61aLNHiAxMXk4n/2gA0sp7Bz3zaSs1raN5mWzRr9+vy1qEK4UJP55kX8AQwsR6IcrV8bGeXRQTmbB7SrqRECE6f5MkedZTTgjt+UuwjeiG4zCr14PSmffCddfgxrQzSwuSETN08lRpEHpT9xKyiLZ2WvODmwafcnsFy5jJj2kfpxJJVh8JOKWBqcg/Z33tWkPkCd5IbfGCuDRyYp62uTS386CLo7Y= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9ec262ff-829c-49bb-fd30-08da3d79d7a7 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:54.6356 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: nNCDFfzDIuoQpKXccJo3QYuWBzO81wGpwTj5bKqeHovKJ1ga5ORIXVBYZnB1kz9qkGuTilUfWw0GUXX3JhczbQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/config.h | 405 ++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/config.h diff --git a/drivers/net/wireless/celeno/cl8k/config.h b/drivers/net/wireless/celeno/cl8k/config.h new file mode 100644 index 000000000000..b918e4423efe --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/config.h @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_CONFIG_H +#define CL_CONFIG_H + +#include +#include +#include + +#define MAX_PARAM_NAME_LENGTH 64 + +#define PRINT_UNSIGNED_ARR(param, old_val, size, new_val) \ +do { \ + u8 i; \ + char buf[STR_LEN_256B]; \ + int len = 0; \ + len += snprintf(buf, sizeof(buf), "%s: old value ", #param); \ + for (i = 0; i < (size) - 1; i++) \ + len += snprintf(buf + len, sizeof(buf) - len, \ + "%u,", old_val[i]); \ + len += snprintf(buf + len, sizeof(buf) - len, \ + "%u --> new value %s\n", old_val[(size) - 1], new_val); \ + pr_debug("%s", buf); \ +} while (0) + +#define READ_BOOL(param) \ +{ \ + if (!strcmp(name, #param)) { \ + bool new_val = false; \ + ret = kstrtobool(value, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %u -> new value %u\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_U8(param) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 new_val = 0; \ + ret = kstrtou8(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %u -> new value %u\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_U16(param) \ +{ \ + if (!strcmp(name, #param)) { \ + u16 new_val = 0; \ + ret = kstrtou16(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %u -> new value %u\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_U32(param) \ +{ \ + if (!strcmp(name, #param)) { \ + u32 new_val = 0; \ + ret = kstrtou32(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %u -> new value %u\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_S8(param) \ +{ \ + if (!strcmp(name, #param)) { \ + s8 new_val = 0; \ + ret = kstrtos8(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %d -> new value %d\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_S16(param) \ +{ \ + if (!strcmp(name, #param)) { \ + s16 new_val = 0; \ + ret = kstrtos16(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %d -> new value %d\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_S32(param) \ +{ \ + if (!strcmp(name, #param)) { \ + s32 new_val = 0; \ + ret = kstrtos32(value, 0, &new_val); \ + if (ret) { \ + pr_err("%s: invalid value [%s]\n", #param, value); \ + break; \ + } \ + if (conf->param != new_val) { \ + pr_debug("%s: old value %d -> new value %d\n", \ + #param, conf->param, new_val); \ + conf->param = new_val; \ + } \ + break; \ + } \ +} + +#define READ_BOOL_ARR(param, size) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 i = 0; \ + char *buf = NULL; \ + char vector[STR_LEN_256B] = {0}; \ + char *vector_p = &vector[i]; \ + bool old_val[size] = {false}; \ + memcpy(old_val, conf->param, sizeof(old_val)); \ + if (strlen(value) >= sizeof(vector)) { \ + pr_err("%s: value [%s] too big [%zu]\n", #param, value, strlen(value)); \ + ret = -E2BIG; \ + break; \ + } \ + strscpy(vector_p, value, sizeof(vector)); \ + buf = strsep(&vector_p, ","); \ + if (!buf) { \ + pr_err("%s: delimiter ',' not found\n", #param); \ + ret = -EIO; \ + break; \ + } \ + if (kstrtobool(buf, &conf->param[0]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + ret = -EINVAL; \ + break; \ + } \ + for (i = 1; i < (size); i++) { \ + buf = strsep(&vector_p, ","); \ + if (!buf) \ + break; \ + if (kstrtobool(buf, &conf->param[i]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + break; \ + } \ + } \ + if (i < size) { \ + pr_err("%s: value [%s] doesn't have %u elements\n", #param, value, size); \ + ret = -ENODATA; \ + break; \ + } \ + ret = 0; \ + if (memcmp(old_val, conf->param, sizeof(old_val))) \ + PRINT_UNSIGNED_ARR(param, old_val, size, value); \ + break; \ + } \ +} + +#define READ_U8_ARR(param, size, is_array_fix_size) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 i = 0; \ + char *buf = NULL; \ + char vector[STR_LEN_256B] = {0}; \ + char *vector_p = &vector[0]; \ + u8 old_val[size] = {false}; \ + memcpy(old_val, conf->param, sizeof(old_val)); \ + if (strlen(value) >= sizeof(vector)) { \ + pr_err("%s: value [%s] too big [%zu]\n", #param, value, strlen(value)); \ + ret = -E2BIG; \ + break; \ + } \ + strscpy(vector_p, value, sizeof(vector)); \ + buf = strsep(&vector_p, ","); \ + if (!buf) { \ + pr_err("%s: delimiter ',' not found\n", #param); \ + ret = -EIO; \ + break; \ + } \ + if (kstrtou8(buf, 0, &conf->param[0]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + ret = -EINVAL; \ + break; \ + } \ + for (i = 1; i < (size); i++) { \ + buf = strsep(&vector_p, ","); \ + if (!buf) \ + break; \ + if (kstrtou8(buf, 0, &conf->param[i]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + break; \ + } \ + } \ + if ((is_array_fix_size) && i < (size)) { \ + pr_err("%s: value [%s] doesn't have %u elements\n", #param, value, size); \ + ret = -ENODATA; \ + break; \ + } \ + ret = 0; \ + if (memcmp(old_val, conf->param, sizeof(old_val))) \ + PRINT_UNSIGNED_ARR(param, old_val, size, value); \ + break; \ + } \ +} + +#define READ_U16_ARR(param, size, is_array_fix_size) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 i = 0; \ + char *buf = NULL; \ + char vector[STR_LEN_256B] = {0}; \ + char *vector_p = &vector[0]; \ + u16 old_val[size] = {false}; \ + memcpy(old_val, conf->param, sizeof(old_val)); \ + if (strlen(value) >= sizeof(vector)) { \ + pr_err("%s: value [%s] too big [%zu]\n", #param, value, strlen(value)); \ + ret = -E2BIG; \ + break; \ + } \ + strscpy(vector_p, value, sizeof(vector)); \ + buf = strsep(&vector_p, ","); \ + if (!buf) { \ + pr_err("%s: delimiter ',' not found\n", #param); \ + ret = -EIO; \ + break; \ + } \ + if (kstrtou16(buf, 0, &conf->param[0]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + ret = -EINVAL; \ + break; \ + } \ + for (i = 1; i < (size); i++) { \ + buf = strsep(&vector_p, ","); \ + if (!buf) \ + break; \ + if (kstrtou16(buf, 0, &conf->param[i]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + break; \ + } \ + } \ + if ((is_array_fix_size) && i < (size)) { \ + pr_err("%s: value [%s] doesn't have %u elements\n", #param, value, size); \ + ret = -ENODATA; \ + break; \ + } \ + ret = 0; \ + if (memcmp(old_val, conf->param, sizeof(old_val))) \ + PRINT_UNSIGNED_ARR(param, old_val, size, value); \ + break; \ + } \ +} + +#define READ_S8_ARR(param, size) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 i = 0; \ + char *buf = NULL; \ + char vector[STR_LEN_256B] = {0}; \ + char *vector_p = &vector[0]; \ + s8 old_val[size] = {false}; \ + memcpy(old_val, conf->param, sizeof(old_val)); \ + if (strlen(value) >= sizeof(vector)) { \ + pr_err("%s: value [%s] too big [%zu]\n", #param, value, strlen(value)); \ + ret = -E2BIG; \ + break; \ + } \ + strscpy(vector_p, value, sizeof(vector)); \ + buf = strsep(&vector_p, ","); \ + if (!buf) { \ + pr_err("%s: delimiter ',' not found\n", #param); \ + ret = -EIO; \ + break; \ + } \ + if (kstrtos8(buf, 0, &conf->param[0]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + ret = -EINVAL; \ + break; \ + } \ + for (i = 1; i < (size); i++) { \ + buf = strsep(&vector_p, ","); \ + if (!buf) \ + break; \ + if (kstrtos8(buf, 0, &conf->param[i]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + break; \ + } \ + } \ + if (i < (size)) { \ + pr_err("%s: value [%s] doesn't have %u elements\n", #param, value, size); \ + ret = -ENODATA; \ + break; \ + } \ + ret = 0; \ + if (memcmp(old_val, conf->param, sizeof(old_val))) \ + PRINT_UNSIGNED_ARR(param, old_val, size, value); \ + break; \ + } \ +} + +#define READ_STR(param) \ +{ \ + if (!strcmp(name, #param)) { \ + if (strcmp(value, conf->param)) { \ + pr_debug("%s: old value %s -> new value %s\n", \ + #param, conf->param, value); \ + strncpy(conf->param, value, sizeof(conf->param) - 1); \ + } \ + ret = 0; \ + break; \ + } \ +} + +#define READ_MAC(param) \ +{ \ + if (!strcmp(name, #param)) { \ + u8 i = 0; \ + char *buf = NULL; \ + char vector[STR_LEN_32B] = {0}; \ + char *vector_p = &vector[0]; \ + u8 old_val[ETH_ALEN] = {false}; \ + memcpy(old_val, conf->param, ETH_ALEN); \ + if (strlen(value) >= sizeof(vector)) { \ + pr_err("%s: value [%s] too big [%zu]\n", #param, value, strlen(value)); \ + ret = -E2BIG; \ + break; \ + } \ + strscpy(vector_p, value, sizeof(vector)); \ + buf = strsep(&vector_p, ":"); \ + if (!buf) { \ + pr_err("%s: delimiter ':' not found\n", #param); \ + ret = -EIO; \ + break; \ + } \ + if (kstrtou8(buf, 16, &conf->param[0]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + ret = -EINVAL; \ + break; \ + } \ + for (i = 1; i < ETH_ALEN; i++) { \ + buf = strsep(&vector_p, ":"); \ + if (!buf) \ + break; \ + if (kstrtou8(buf, 16, &conf->param[i]) != 0) { \ + pr_err("%s: invalid argument [%s]\n", #param, value); \ + break; \ + } \ + } \ + if (i < ETH_ALEN) { \ + pr_err("%s: value [%s] doesn't have %u elements\n", #param, value, \ + ETH_ALEN); \ + ret = -ENODATA; \ + break; \ + } \ + ret = 0; \ + if (memcmp(old_val, conf->param, sizeof(old_val))) \ + pr_debug("%s: old value %pM -> new value %pM\n", \ + #param, old_val, conf->param); \ + break; \ + } \ +} + +bool cl_config_is_non_driver_param(char *name); + +#endif /* CL_CONFIG_H */ From patchwork Tue May 24 11:33:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576865 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 37338C433F5 for ; Tue, 24 May 2022 11:38:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236794AbiEXLiR (ORCPT ); Tue, 24 May 2022 07:38:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236788AbiEXLiN (ORCPT ); Tue, 24 May 2022 07:38:13 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2763E43382 for ; Tue, 24 May 2022 04:38:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XCAWeHbxzNadOVaUquWkUi2/N1F/pvcz0h1qGBAhi46R42QzpR3mOHxtUb6EWlepvVf2AG7NEEZ+4cKnpMlaUAvxROq4PrjXppD2oV0IGRFgdTsGJ/tgazBmcLg547Fs1/ljgAYjkscErwYXSLgqpmT3SYhyTLyJt2vvr0L8p9DQ5jy9w4gabRAQeLwU6dJMhSk7o3LiIHGvATSuJqrHhszNdNbIYF+SzrTyhcsg/HxVryKxQJR/PIhhT6055fOKXQQLAXRj/kUR02e/m+BaiYL0QgilQckOSj5ZOHBvOeDL0NT14sqLVr0e5P1nRAE8rfKemZSgYuflT4fSiS5T+w== 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=7NS5yavrzXglgWZOKCg1jKxmVi8wSp7Y3hV4xwwv6mg=; b=DHNMRRkzBHLUmeXxUNbagzg2OXimqi+6saeUl54rTi4fcg3CPz4xib4eQ7uXq84kJilZ+aIyuylAFfl5ZCbVWJOzPBrnn1PT0eiRfd2IPQ9hZ2rReo6NrxdI7Acv22h9qI9UZwigUCo45vFgN+2aUucPQL20e1qxu7WGfsLUc32SSt4xuUWHw88CnwVR+2CvUViq160SC2FYixI1z1xdu7KCOm/eaiwd6tHmI4/9LCX30XERowiOeHLMUC2LWkswT50ShMuooGhd+LXN4SayXfUzdLO7610tc7CEoIskVXdUVOLZgHCqq61+s4mNitLIz1J+MpKJh6EtLcnztD5ypQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7NS5yavrzXglgWZOKCg1jKxmVi8wSp7Y3hV4xwwv6mg=; b=cIsaf+cBiNtRwZ1omRhtXYK+NRO6GvRhPRH4j7oKVVB4jIKCs8jJJow6uLGKQWlgQPPPTMuSbwlOA9I8pabgO9ThDMTQQsLT9Q3E3UDJWdat7lyviN/PZGxST3JatVM/l7i7LZBL114KBijf0KzY2s0+6YlIP94Klr7zlT9Hn8g= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:55 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:55 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 17/96] cl8k: add debug.c Date: Tue, 24 May 2022 14:33:43 +0300 Message-Id: <20220524113502.1094459-18-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3d4a8757-da98-426e-c3e4-08da3d79d821 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oR028BBuprapjVpEO47BT7Nl6joAbUgTS5MERqY+d95MZHJYm/sDLlBgiU4dfcRPOV2SyJXz5LBgFSjHmnk7VfhQNQyoVs6nB0RVn9tsXlwqGNty0xUmPQ1cUUz6rLKP742pTmMzmEIQYXJSyL3qRG4mdKnHzEl+C7KnLVb2fATsbncFPk+dl5DFsEdwhQiYBbUBK5jFyVZTVFP4eLcl7NDVtbdkYh3ScbTBkVgxZu/J4zfSofhaHJBCcRRB5ANgY5HsgL+f4mI8/+Onn7H3zfznYXKU52SNnTYQal6U9kwlhOBpYvkypDjtWwRy4MSrXICE5LNhnMyi5YKrDbXQtCayLWhR1OY2JYz4aWDuDlV1noTKgI1XpVX3l/NKkmKGXDMWjkCVdWhaa5sUbU4cElPNU9quf82UPoEqnbfew31/Zrj6wvkML2QC1064lXfnlJGiOfadOtVnt8DSDQdiE1i1kEMK154YNt5ELZEjBqi8SZk461Ml3HnjtIgVbaTgwrR5soTHMC2xj6gS2zLr8oihq1GC92hJyRDrXPHW/wAClFz0zcDTsHW07/oft/ZRMrB9dEDgrFUeBi3e2JjZDavvs9CYMlieePxCnTyZcq5/QlXi68S+Ou2hEImRUk0b3tr5Z6S4BUK16uvtX7vc1KGvOUjfbL94jn9rfVNFF/hP3U5kLKT+DGpwIVLK2pQiDJea4l+H1hu0Wo6VyCgRe/HVsk88NtSMFIcesHzPtzQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 1PFgkOq2styQXbj+6b7o76X9caDtRcGrymbK2pICxvQWEKT0RNX2A/oCBLjWxcuYA2jOVRW0TMjW4dTbqa3evRZi/Vg/a5+mWE6oiwckyQd+PIErmCPI8TnPVl2PeHNM6X3CK2xjTwevNO17GbiEXLyjORXaVv+yS5erfyR+K1fPoKRfn4Uxvs2uDvxSwyYeInosoYxm4WydMWQdleCXpFf0hkeVgV9v/Xk+L8ngFL2N5TSq+mMTuCzK+dRX2f5iuNrm6L6uF27A9G+nuocttvIM3kFjxet7qH6dgENuBb/OP5wGpLUcIz4mXGO1hyDojPi0rc4ZRnLsfOY+JOesAUQvAHUouQnVw/0Zm5DT87XAApSgMS3M8ZdzanHgGqw0K0lv02wR3pO7A936nVsMI+zKODWhAvy+AAI2rP4hfDbcUUsbNVtkk0xTm9N+4hirfj2Bj/7ZGrtYELRQXaT6WdXR+YeUZvLEGG5hPrzvPSm6fdlf06IzGsxCV7LkiYi53tq5OdaiGyhaI4XGVfjGfI8Vzi0rwsbjJj4jg7nQ5A6GX9pFq2jAb3YjpBboVbs3vrhP/35IYM56q+1aOTMPp3dcB9NnESr+sPFbU6wEzyN7xE5D8zKyewOqyA8C2/m206c+AwVd+PJFHYqokaxbM5lzpiJv/7j8ftHKDUZcPsXob8s1FmTWJ74rFpAyqv7qiS3kXAuDIFmyLSITGWh+WvFygyCt6WfiF+33lJNNiDEMPNaRjIZBHdrzWIH+q2WR/2/fRFEtRkNemL1T5z2Cp2lDtKWs2cqLVousFtw5dzow1BE1Ho+fahvXXUfWdgrqr+CmyhhZTQAcfJh17TStoJOkHINe2a23/fSxXeg8UY3rSq5RMjhRzWV/MZPm1okGxDSC/hqZuyzvGz66x1ztCl6ZrJMeGvOIDDBOfJGP3Ft1xU2duro0f4ZIcvdKk8wQGQwa7xcDG7+49ml3nZRjv1bYC/UINKjHB5Q4V8fPzOqmERmxEYFqDzlxeUDpRBlXxNLCpju7CXdew9wOYf2IS8tAUCBB2KGsAYmyT0A/NQ71X1pBZeTE/j4ocIZ1lw1SGJVdyhBL//abuxua+DP85lFGvvCJNOBaZSDL6v2cHgU0G5VemSsZjKFYxzVUopR2CUSwQ5g626TPAj8hgYrR9Kui6iXPcug4PqlT2h8Sl0TweVPWOOlzFI3kjVibCdFG6TxsSPzYdGjQTvJsVIRJu94rxuyHlegk+A0mPpGYUVuPLBB9xj58BQDfzcm11YhselOH5UY4QOnKHDbckYKsVn1t+XysifGN5jXz1G8QM2cnb9iOJyH12wfILA9P2PobECZUrew8YnkwOslBldJQYc9PuRnxZNDmQ90xnG0g3EuACh3q/FhNHBY6fkrLON2Dj/Gf1YcuxDrNK0fw1mziEdV2NWaYGXXaqZD2G8E5CszDOT2p0OoN6HTD/fp1ujo2duT5uZznp8PRQRJJD0SslAKSo4i122IzBJ0c0BGGsw5JKkUxETmpppbBUe2EHDmqPJL/dQWwNjePw2p24xNt0tFZcSrLIJc579rDCpeT42hl9Tf2cIIYF57jF87Uyt7v7DmEpjDwcHZC9v/arH2kbbWJU5WzyC1s+CeGWUUiKUObdhez99umjBqbonuuXu3KWY6GQo8DiNz3HO/FomyxR3uH61zsYPgRrodBfPrbPTslmftC3BvUmAwzpXQoaQUGOAZApx+w9FZ56szwEOT+l24MxzGojZn3WCrCIJaqCD4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3d4a8757-da98-426e-c3e4-08da3d79d821 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:55.4181 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hmuhaYMSxXuOjomiFhi1UHzOv0JwiMR11NkXyf913ZEwO9i+ukem1TyuDRLAUy1UgQSrJcOLt0VTGcQ2/QoWWg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/debug.c | 442 +++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/debug.c diff --git a/drivers/net/wireless/celeno/cl8k/debug.c b/drivers/net/wireless/celeno/cl8k/debug.c new file mode 100644 index 000000000000..f8a438747ac3 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/debug.c @@ -0,0 +1,442 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "hw.h" +#include "utils.h" +#include "debug.h" + +const char *cl_dbgfile_get_msg_txt(struct cl_dbg_data *dbg_data, u16 file_id, u16 line) +{ + /* Get the message text from the .dbg file by file_id & line number */ + int remaining_bytes = dbg_data->size; + const char *str = dbg_data->str; + char id_str[32]; + int idstr_len; + + if (!str || 0 == remaining_bytes) + return NULL; + + idstr_len = snprintf(id_str, sizeof(id_str), "%u:%u:", file_id, line); + + /* Skip hash */ + while (*str++ != '\n') + ; + + remaining_bytes -= (str - (char *)dbg_data->str); + + while (remaining_bytes > 0) { + if (strncmp(id_str, str, idstr_len) == 0) { + str += idstr_len; + while (*str == ' ') + ++str; + return (const char *)str; + } + + str += strnlen(str, 512) + 1; + remaining_bytes = dbg_data->size - (str - (char *)dbg_data->str); + } + + /* No match found */ + pr_err("error: file_id=%d line=%d not found in debug print file\n", file_id, line); + return NULL; +} + +void cl_dbgfile_parse(struct cl_hw *cl_hw, void *edata, u32 esize) +{ + /* Parse & store the firmware debug file */ + struct cl_dbg_data *dbg_data = &cl_hw->dbg_data; + + dbg_data->size = esize; + dbg_data->str = edata; +} + +void cl_dbgfile_release_mem(struct cl_dbg_data *dbg_data, + struct cl_str_offload_env *str_offload_env) +{ + dbg_data->str = NULL; + + str_offload_env->enabled = false; + str_offload_env->block1 = NULL; + str_offload_env->block2 = NULL; +} + +/* + * Store debug print offload data + * - part 1: offloaded block that does not exist on target + * - part 2: resident block that remains on target [optional] + */ +int cl_dbgfile_store_offload_data(struct cl_chip *chip, struct cl_hw *cl_hw, + void *data1, u32 size1, u32 base1, + void *data2, u32 size2, u32 base2, + void *data3, u32 size3, u32 base3) +{ + u32 u = size1; + struct cl_str_offload_env *str_offload_env = &cl_hw->str_offload_env; + + if (u > 200000) + goto err_too_big; + + /* TODO we modify offload data! if caller checks integrity, make a copy? */ + str_offload_env->block1 = data1; + str_offload_env->size1 = size1; + str_offload_env->base1 = base1; + + str_offload_env->block2 = data2; + str_offload_env->size2 = size2; + str_offload_env->base2 = base2; + + str_offload_env->block3 = data3; + str_offload_env->size3 = size3; + str_offload_env->base3 = base3; + + str_offload_env->enabled = true; + + cl_dbg_info(cl_hw, "%cmac%u: FW prints offload memory use = %uK\n", + cl_hw->fw_prefix, chip->idx, (size1 + size2 + 1023) / 1024); + + return 0; + +err_too_big: + pr_err("%s: size too big: %u\n", __func__, u); + return 1; +} + +static void cl_fw_do_print_n(struct cl_hw *cl_hw, const char *str, int n) +{ + /* Print formatted string with "band" prefix */ + if (n < 0 || n > 256) { + cl_dbg_err(cl_hw, "%cmac%u: *** FW PRINT - BAD SIZE: %d\n", + cl_hw->fw_prefix, cl_hw->chip->idx, n); + return; + } + + cl_dbg_verbose(cl_hw, "%cmac%u: %.*s\n", cl_hw->fw_prefix, cl_hw->chip->idx, n, str); +} + +static void cl_fw_do_hex_dump_bytes(struct cl_hw *cl_hw, u32 addr, void *data, u32 count) +{ + cl_dbg_verbose(cl_hw, "%cmac%u: hex dump:\n", cl_hw->fw_prefix, cl_hw->chip->idx); + cl_hex_dump(NULL, data, count, addr, true); +} + +#define MAGIC_PRINT_OFFLOAD 0xFA /* 1st (low) byte of signature */ +/* 2nd signature byte */ +#define MAGIC_PRINT_OFF_XDUMP 0xD0 /* Hex dump, by bytes */ +#define MAGIC_PRINT_OFF_LIT 0x01 /* Literal/preformatted string */ +#define MAGIC_PRINT_OFF_PRINT 0x02 /* Print with 'virtual' format string */ + +static int cl_fw_offload_print(struct cl_str_offload_env *str_offload_env, + char *fmt, const char *params) +{ + static char buf[1024] = {0}; + const char *cur_prm = params; + char tmp; + char *fmt_end = fmt; + size_t size = sizeof(int); + int len = 0; + + union v { + u32 val32; + u64 val64; + ptrdiff_t str; + } v; + + while ((fmt_end = strchr(fmt_end, '%'))) { + fmt_end++; + + /* Skip '%%'. */ + if (*fmt_end == '%') { + fmt_end++; + continue; + } + + /* Skip flags. */ + while (strchr("-+ 0#", *fmt_end)) + fmt_end++; + + /* Skip width. */ + while (isdigit(*fmt_end)) + fmt_end++; + + /* Skip precision. */ + if (*fmt_end == '.') { + while (*fmt_end == '-' || *fmt_end == '+') + fmt_end++; + + while (isdigit(*fmt_end)) + fmt_end++; + } + + /* Get size. */ + if (*fmt_end == 'z') { + /* Remove 'z' from %zu, %zd, %zx and %zX, + * because sizeof(size_t) == 4 in the firmware. + * 'z' can only appear in front of 'd', 'u', 'x' or 'X'. + */ + if (!strchr("duxX", *(fmt_end + 1))) + return -1; + + fmt_end++; + size = 4; + } else if (*fmt_end == 'l') { + fmt_end++; + + if (*fmt_end == 'l') { + fmt_end++; + size = sizeof(long long); + } else { + size = sizeof(long); + } + + if (*fmt_end == 'p') /* %p can't get 'l' or 'll' modifiers. */ + return -1; + } else { + size = 4; + } + + /* Get parameter. */ + switch (*fmt_end) { + case 'p': /* Replace %p with %x, because the firmware's pointers are 32 bit wide */ + *fmt_end = 'x'; + fallthrough; + case 'd': + case 'u': + case 'x': + case 'X': + if (size == 4) + v.val32 = __le32_to_cpu(*(__le32 *)cur_prm); + else + v.val64 = __le64_to_cpu(*(__le64 *)cur_prm); + cur_prm += size; + break; + case 's': + v.str = __le32_to_cpu(*(__le32 *)cur_prm); + cur_prm += 4; + size = sizeof(ptrdiff_t); + + if (v.str >= str_offload_env->base3 && + v.str < str_offload_env->base3 + str_offload_env->size3) { + v.str -= str_offload_env->base3; + v.str += (ptrdiff_t)str_offload_env->block3; + } else if (v.str >= str_offload_env->base2 && + v.str < str_offload_env->base2 + str_offload_env->size2) { + v.str -= str_offload_env->base2; + v.str += (ptrdiff_t)str_offload_env->block2; + } else { + return -1; + } + + break; + default: + return -1; + } + + /* Print into buffer. */ + fmt_end++; + tmp = *fmt_end; /* Truncate the format to the current point and then restore. */ + *fmt_end = 0; + len += snprintf(buf + len, sizeof(buf) - len, fmt, size == 4 ? v.val32 : v.val64); + *fmt_end = tmp; + fmt = fmt_end; + } + + snprintf(buf + len, sizeof(buf) - len, "%s", fmt); + + pr_debug("%s", buf); + + return 0; +} + +struct cl_pr_off_desc { + u8 file_id; + u8 flag; + __le16 line_num; + char fmt[]; +}; + +char *cl_fw_print_normalize(char *s, char old, char new) +{ + for (; *s; ++s) + if (*s == old) + *s = new; + return s; +} + +static int cl_fw_do_dprint(struct cl_hw *cl_hw, u32 fmtaddr, u32 nparams, u32 *params) +{ + /* + * fmtaddr - virtual address of format descriptor in firmware, + * must be in the offloaded segment + * nparams - size of parameters array in u32; min=0, max=MAX_PRINT_OFF_PARAMS + * params - array of parameters[nparams] + */ + struct cl_str_offload_env *str_offload_env = &cl_hw->str_offload_env; + struct cl_pr_off_desc *pfmt = NULL; + + if (!str_offload_env->enabled) + return -1; + + if (fmtaddr & 0x3) + cl_dbg_warn(cl_hw, "FW PRINT - format not aligned on 4? %8.8X\n", fmtaddr); + + if (fmtaddr > str_offload_env->base1 && + fmtaddr < (str_offload_env->base1 + str_offload_env->size1)) { + pfmt = (void *)((fmtaddr - str_offload_env->base1) + str_offload_env->block1); + } else { + cl_dbg_err(cl_hw, "FW PRINT - format not in allowed area %8.8X\n", fmtaddr); + return -1; + } + + /* + * Current string sent by firmware is #mac@ where # is '253' and @ is '254' + * Replace '253' with 'l' or 's' according to the fw_prefix. + * Replace '254' with '0' or '1' according to chip index. + */ + cl_fw_print_normalize(pfmt->fmt, (char)253, cl_hw->fw_prefix); + cl_fw_print_normalize(pfmt->fmt, (char)254, (cl_hw->chip->idx == CHIP0) ? '0' : '1'); + + if (cl_fw_offload_print(str_offload_env, pfmt->fmt, (char *)params) < 0) { + cl_dbg_err(cl_hw, "FW PRINT - ERROR in format! (file %u:%u)\n", + pfmt->file_id, pfmt->line_num); + cl_hex_dump(NULL, (void *)pfmt, 48, fmtaddr, true); /* $$$ dbg dump the struct */ + return -EINVAL; + } + + return 0; +} + +static int cl_fw_do_offload(struct cl_hw *cl_hw, u8 *data, int bytes_remaining) +{ + u8 magic2 = data[1]; + u32 nb = data[2] + (data[3] << 8); /* Following size in bytes */ + /* DATA IS UNALIGNED! REVISE if alignment required or BIG ENDIAN! */ + __le32 *dp = (__le32 *)data; + int bytes_consumed = 4; /* 1 + 1 + 2 */ + + /* Data: [0] u8 magic1, u8 magic2, u16 following size in bytes */ + if (bytes_remaining < 8) { + cl_dbg_err(cl_hw, "*** FW PRINT - OFFLOAD PACKET TOO SHORT: %d\n", + bytes_remaining); + return bytes_remaining; + } + + if (bytes_remaining < (nb + bytes_consumed)) { + cl_dbg_err(cl_hw, "*** FW PRINT - OFFLOAD PACKET %u > remainder %d??\n", + nb, bytes_remaining); + return bytes_remaining; + } + + switch (magic2) { + case MAGIC_PRINT_OFF_PRINT: { + /* + * [1] u32 format descriptor ptr + * [2] u32[] parameters + */ + u32 fmtp = le32_to_cpu(dp[1]); + u32 np = (nb - 4) / 4; /* Number of printf parameters */ + + if (nb < 4 || nb & 3) { + cl_dbg_err(cl_hw, "*** FW PRINT - bad pkt size: %u\n", nb); + goto err; + } + + cl_fw_do_dprint(cl_hw, fmtp, np, (u32 *)&dp[2]); + + bytes_consumed += nb; /* Already padded to 4 bytes */ + } + break; + + case MAGIC_PRINT_OFF_LIT: { + /* [1] Remaining bytes: literal string */ + cl_fw_do_print_n(cl_hw, (char *)&dp[1], nb); + bytes_consumed += ((nb + 3) / 4) * 4; /* Padding to 4 bytes */ + } + break; + + case MAGIC_PRINT_OFF_XDUMP: + /* [1] bytes[nb] */ + if (nb >= 1) + cl_fw_do_hex_dump_bytes(cl_hw, 0, &dp[1], nb); + + bytes_consumed += ((nb + 3) / 4) * 4; /* Padding to 4 bytes */ + break; + + default: + cl_dbg_err(cl_hw, "*** FW PRINT - BAD TYPE: %4.4X\n", magic2); + goto err; + } + + return bytes_consumed; + +err: + return bytes_remaining; /* Skip all */ +} + +void cl_dbgfile_print_fw_str(struct cl_hw *cl_hw, u8 *str, int max_size) +{ + /* Handler for firmware debug prints */ + int bytes_remaining = max_size; + int i; + u8 delim = 0; + + while (bytes_remaining > 0) { + /* Scan for normal print data: */ + for (i = 0; i < bytes_remaining; i++) { + if (str[i] < ' ' || str[i] >= 0x7F) { + if (str[i] == '\t') + continue; + delim = str[i]; + break; + } + } + + if (i > 0) { + if (delim == '\n') { + bytes_remaining -= i + 1; + cl_fw_do_print_n(cl_hw, str, i); + str += i + 1; + continue; + } + + if (delim != MAGIC_PRINT_OFFLOAD) { + cl_fw_do_print_n(cl_hw, str, i); + bytes_remaining -= i; + return; /* Better stop parsing this */ + } + /* Found offload packet but previous string not terminated: */ + cl_fw_do_print_n(cl_hw, str, i); + cl_dbg_err(cl_hw, "*** FW PRINT - NO LINE END2\n"); + bytes_remaining -= i; + str += i; + continue; + } + + /* Delimiter at offset 0 */ + switch (delim) { + case '\n': + cl_fw_do_print_n(cl_hw, " ", 1); /* Print empty line */ + str++; + bytes_remaining--; + continue; + case 0: + return; + case MAGIC_PRINT_OFFLOAD: + i = cl_fw_do_offload(cl_hw, str, bytes_remaining); + bytes_remaining -= i; + str += i; + break; + default: + cl_dbg_err(cl_hw, "*** FW PRINT - BAD BYTE=%2.2X ! rem=%d\n", + delim, bytes_remaining); + return; /* Better stop parsing this */ + } + } +} From patchwork Tue May 24 11:33:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576864 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 D5884C433FE for ; Tue, 24 May 2022 11:38:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236788AbiEXLiV (ORCPT ); Tue, 24 May 2022 07:38:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236798AbiEXLiP (ORCPT ); Tue, 24 May 2022 07:38:15 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70041.outbound.protection.outlook.com [40.107.7.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF2B78CCEA for ; Tue, 24 May 2022 04:38:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HTCO/saUBNWZ+8UKqF9r6jxuv5rNcylBCz59bYiSzo5rWwLE6k5/K4FSKJiLglAYyAzLI7IAjLLr1tcczuUsIUWoiBT2jDeVsofGaX3po95GGLx8aVO59HmkLSwzH8T7LnF1hfCzwAK3P0l8oZlvDJcINCaxb+1XnRjjA5ciFHnrjh9qfRDz41djh1Jim3dzZGNngC7KTRzzYzMt0wAUNGNf1lCusRthJ3dsa2mNDVmGVn4Tl+xtW8BOQrZWj+vsZ7laHe7YGlQRZgyD9PYf0BGDyu8Di6F8c8ApW6S6Y/Kro5LqHeR92rIVYVoDJcldGrtl1S7KA9gFdceq3DLSvg== 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=HdJKGhv1awtpSLfprCHArHA5yR4oRhIZpC2DNsxNoXw=; b=Ms4hAZWp0m2u4URunuz+nAMKdrQslXVQJzEfWJvLfWIut8Fj7XHMP31UG9PV+A9mxh65fAjj1zC7RsezYo9lFa02acQi7/3ApjurRM/BhZWf0RTV94oGFj6xyx36Oc+VwtprOC+8hY0MIhc969yAmzsfJYxXek3Tumg0tWryTkoYXsVkhp67ekfaou1YKVF1Y+xHLsbMogmH+saVlEK7s12bSrxTXaAn6AfRnrpI6LnNTApp0icTL2Q1ytuMKEGhDBMDXfKUQlURKYhwRwxcnYZAErKMoNt2tjqCGOi3vMRoMKKiuFm8JDiUEoLwIAshPokcOVPFdBpKmE/vzUitmQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=HdJKGhv1awtpSLfprCHArHA5yR4oRhIZpC2DNsxNoXw=; b=lMVku6bU+mjBcu4Ku3u2ePUi/GrXM6dKxEVsMC1JIBP+Ec/izljzwuQJMo8Je+p+07jgnpm1yWCI/G31C4KILSqAJFNERD9xtswdbTHC7puxtl9UdTWplomwnNFhXJgOs18xpmlsSbpq5tEm+m11U9loOBFmd5bmfqAHoVO8RsE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:56 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:56 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 18/96] cl8k: add debug.h Date: Tue, 24 May 2022 14:33:44 +0300 Message-Id: <20220524113502.1094459-19-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1f6b95a3-6f2c-41ba-2f3e-08da3d79d894 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 3hDs4+1PUkwO21V1syEVwhagl4w89NdDh/3d/jHlH3UP5GHI5Jhhy7u/KDdrMf6AGS9LR4A5tPBeqECiXeF5oPbj5L0F3jp5+vN7yGgXrRPhQ3437TRKgtiqpRHswlhsH+6BW3ssZ9ZbinrjjukLmUky6lzlGNGa6y5INYHrUHDtWd1+pBdEyR8sSc+0XMzBpm2LmoLmJ4rMLOrZbzQxU9SAGU8rOOBKpzsvfHcflNU0VyfQnU+pEQEmQ89QE2ljNNcM5k8z9eXWancDzFjf49ypSD0xZTCchm74LRUjm69NBadIUD4Vt1dujynTyPUSSq6hmPeHSl91fBOTMWSCNzEy4RqfW7plFp9zlnje1XrIxrn0XtNQs8c50QvKxfeHlGI+acoe/NJhZgtQZ4SsOTj3QyolPhjJKJ5G3CslFO5xq9nROqfOo1do6rvASCwiQjpAGp0FlzfAscwhPiUif4+9cjCmwQmKH4yjtvM+UXR/vm3C+kh7qaeXHOkNJqeLw4AfjZ31CInOBfJpGq7l9LmqWaQcnyDiymmNjHb+U3bCo8Hd0Kq2ShZzt9wiUnxVDqSD6ACPjCg7sipyqTubd5mhK/Jd1fZnv8R7i5HuLAcjKlyEotsRKdWg77mvZQIgoYffWqWK0jhQ7R0znPA5YhYvbktnqur5f3TL4gawtaEmKQQHi90tmpyiRgS4k3EMURd2Kvu2TtS6qVYPz3+0uJmVKwTGhQR9pMvMwK4gptg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 4LzfykFqoJfIfrdXHvAwKpmrJrrAnQu0eWLfIz5VGsOlPBYLGlff3hEVXPiKgN4MzJVuBeS6O026f6oNfkIVTd7QN4GezVjc2I9OjxZbIxsh2cY3vht98nnB98qgYdpd/Gn9o3ndyWlwgnjDYrq/ttxqg24JQSw4UNiinfgK6Y9NJF6o+9m1waYStMY0co3LQX1SclsM8Nc0AmlvkoXjEk7pd4+DlTh2WygPKvJSkGY2ZRAXoSxrrEnE46Np+M1hr/m6WVhtlQzqJzHnzxQVdECUMRiuRVC8F12fNe6K8KTkcarVfuLvdFZntRbQxrwP77CNAmq92LOU9mqpaEm8yfnMKJxC8OcRRfVeOzTvyTYMJvfqpgxRWc+Yr4mp+9H0R2hKfV45EU6deWhae3v9l+xxxHNzgSqsJp3IsLLQdDQoHfv/NwVSuLcMuZJFkdvvlF4YbkjlLqGxAnmehDfkMr8JYAXt4VGe8uTzmPAqNF/AdUicTTqtSbp16nr96Ftc89Bt8VQ6UMcleOSee9sGeqbIIYDpPWRF93haNTqy80GLXPTDwQqzxSntuJn9BSNiNBvpTLlSE3LWM86y4jHA2+jUvVMCttnQAJ2YC4l8NG/tKHuZ2gdb2l09H5eizlyIZ9vYZP6QkEOV4mxiuUqXUmSfZj4QWxmWBbVbrqks9mb3EuXKrrEscwtlv0Ggapteoa7QpArA4wF6XmoJhqkQ//7O2lNEtgBRJ70adL1VzHQtSJ/cEfPu/UuaUx12HenXfsqC2J6U3WR1F3ctAUX0WwDksUIrNt91j+yCJY8vJcKHJFJiX5P09h05uBSR9Qjwa5Uf5nfZoAo90kY+kZOpU0VYcZv2x1OinwZ92nyaoaawEdxvLF0LdiGsaZaEdn2MqzgX3hmvUUcRtzSavf7Xp+HI5Nz7MYxUIrwBEivQPMj1dBqFjgXgDvG7TZgW7EsopeLvMvdai1zhxnRggMqB8WIBrBlGNR0P8H8vOMfyGPoKO8GZGfznZjJsBNb3Y1KvhrBynvtMUYpC2RXScq8ENklrK245wOaubWUGz71zvo2FK7mA8QunxVXTURhpzxT6pK5awaogE5pi+PvxidEq9KVSZYpWHDJPCj6hKl/OTEpTuDGTMfLey/6aP6cluNbwt8GnXsGZhBYRtbIIfCD6sssyxAaENzj3owkjPlb3nt4Jca0n37cpenO5jYVZP/q13JLup7yBdGJUf0M4yDejYEBohyRB4YWORlq9bOvTjVWMGs3Ep3osdxbaGYA24Pcoe4wJ4CkubvdPAP774c/U5UcSoYOc0g1oqnwjjBPZRIZhiYOil7QqSvk+POUk/lY1sXSLryj7HgRifwSvUvHodWxPDUlypZf5dBB/b/VccTQKMXtJnPohYyZpD2iVx6PScGjUF2nEYZFlD1S7hvVCljCcPNrKlgz+xVd5FQKurcDMDWm8wAFGXvVNX54bpjVJtrmMYgmJ97Nt3L10J5UnaW8m5xEGLEFAp4NtxnJb/fbbvPZCZQS/Dygfxf76dp2fAFlwWGa4QgB2YVgTMTv1ppgTKIZpKhJ/BzAqz+vYhn776GSYACH/s3CM8nQrfCDEXM/UH8JUff6JsqQjdYkA4Fdqw39/CnP/4jId5PMjSHZ8BoKNdtlvaYaKRDRoTKkgh0p+rlZv/TaD9sw/lBLp7WQrf1DulCdROL1NuAJCwXYx16kSqnak2mVQuNSNBk1/aQ9qCwbUTbyBXHlYk0YUKkovBTxrXTfkrUqqbxOKVaU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1f6b95a3-6f2c-41ba-2f3e-08da3d79d894 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:56.1679 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: JfbR+4Bij978MI3niqJxat9HDBIW3/bc4fwwRB8YEIky0ZCJrSVnJWBe+LboNeYF0215caElXme8wnbvJuI3uA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/debug.h | 160 +++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/debug.h diff --git a/drivers/net/wireless/celeno/cl8k/debug.h b/drivers/net/wireless/celeno/cl8k/debug.h new file mode 100644 index 000000000000..dffee2125903 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/debug.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_DEBUG_H +#define CL_DEBUG_H + +#include + +enum cl_dbg_level { + DBG_LVL_VERBOSE, + DBG_LVL_ERROR, + DBG_LVL_WARNING, + DBG_LVL_TRACE, + DBG_LVL_INFO, + + DBG_LVL_MAX, +}; + +#define CL_DBG(cl_hw, lvl, fmt, ...) \ +do { \ + if ((lvl) <= (cl_hw)->conf->ce_debug_level) \ + pr_debug("[tcv%u][%s][%d] " fmt, (cl_hw)->idx, __func__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#define CL_DBG_CHIP(chip, lvl, fmt, ...) \ +do { \ + if ((lvl) <= (chip)->conf->ce_debug_level) \ + pr_debug("[chip%u][%s][%d] " fmt, (chip)->idx, __func__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#define cl_dbg_verbose(cl_hw, ...) CL_DBG((cl_hw), DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define cl_dbg_err(cl_hw, ...) CL_DBG((cl_hw), DBG_LVL_ERROR, ##__VA_ARGS__) +#define cl_dbg_warn(cl_hw, ...) CL_DBG((cl_hw), DBG_LVL_WARNING, ##__VA_ARGS__) +#define cl_dbg_trace(cl_hw, ...) CL_DBG((cl_hw), DBG_LVL_TRACE, ##__VA_ARGS__) +#define cl_dbg_info(cl_hw, ...) CL_DBG((cl_hw), DBG_LVL_INFO, ##__VA_ARGS__) + +#define cl_dbg_chip_verbose(chip, ...) CL_DBG_CHIP((chip), DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define cl_dbg_chip_err(chip, ...) CL_DBG_CHIP((chip), DBG_LVL_ERROR, ##__VA_ARGS__) +#define cl_dbg_chip_warn(chip, ...) CL_DBG_CHIP((chip), DBG_LVL_WARNING, ##__VA_ARGS__) +#define cl_dbg_chip_trace(chip, ...) CL_DBG_CHIP((chip), DBG_LVL_TRACE, ##__VA_ARGS__) +#define cl_dbg_chip_info(chip, ...) CL_DBG_CHIP((chip), DBG_LVL_INFO, ##__VA_ARGS__) + +static inline char *cl_code_basename(const char *filename) +{ + char *p = strrchr(filename, '/'); + + return p ? p + 1 : (char *)filename; +} + +#define TXT_ERROR \ + do { \ + pr_debug("\n"); \ + pr_debug("####### ##### ##### ##### #####\n"); \ + pr_debug("# # # # # # # # #\n"); \ + pr_debug("# # # # # # # # #\n"); \ + pr_debug("####### ##### ##### # # #####\n"); \ + pr_debug("# # # # # # # # #\n"); \ + pr_debug("# # # # # # # # #\n"); \ + pr_debug("####### # # # # ##### # #\n"); \ + } while (0) + +#define TXT_WARNING \ + do { \ + pr_debug("\n"); \ + pr_debug("# # ##### ##### # # ### # # #####\n"); \ + pr_debug("# # # # # # ## # # ## # # #\n"); \ + pr_debug("# # # # # # # # # # # # # #\n"); \ + pr_debug("# # # ####### ##### # # # # # # # # ###\n"); \ + pr_debug("# # # # # # # # # # # # # # # # #\n"); \ + pr_debug("# # # # # # # # # ## # # ## # #\n"); \ + pr_debug(" # # # # # # # # ### # # #####\n"); \ + } while (0) + +#define INFO_CL_HW(cl_hw, ...) \ + do { \ + pr_debug("\n"); \ + pr_debug("CHIP: %u\n", (cl_hw)->chip->idx); \ + pr_debug("TCV: %u\n", (cl_hw)->idx); \ + pr_debug("FILE: %s\n", cl_code_basename(__FILE__)); \ + pr_debug("FUNCTION: %s\n", __func__); \ + pr_debug("LINE: %u\n", __LINE__); \ + pr_debug("DESCRIPTION: " __VA_ARGS__); \ + pr_debug("\n"); \ + } while (0) + +#define INFO_CHIP(chip, ...) \ + do { \ + pr_debug("\n"); \ + pr_debug("CHIP: %u\n", (chip)->idx); \ + pr_debug("FILE: %s\n", cl_code_basename(__FILE__)); \ + pr_debug("FUNCTION: %s\n", __func__); \ + pr_debug("LINE: %u\n", __LINE__); \ + pr_debug("DESCRIPTION: " __VA_ARGS__); \ + pr_debug("\n"); \ + } while (0) + +#define CL_DBG_ERROR(cl_hw, ...) \ + do { \ + TXT_ERROR; \ + INFO_CL_HW(cl_hw, __VA_ARGS__); \ + } while (0) + +#define CL_DBG_ERROR_CHIP(chip, ...) \ + do { \ + TXT_ERROR; \ + INFO_CHIP(chip, __VA_ARGS__); \ + } while (0) + +#define CL_DBG_WARNING(cl_hw, ...) \ + do { \ + TXT_WARNING; \ + INFO_CL_HW(cl_hw, __VA_ARGS__); \ + } while (0) + +#define CL_DBG_WARNING_CHIP(chip, ...) \ + do { \ + TXT_WARNING; \ + INFO_CHIP(chip, __VA_ARGS__); \ + } while (0) + +/* Min HW assert before testing asserts time-stamp */ +#define CL_MIN_ASSERT_CNT 10 + +/* Define max time between hw asserts in msec */ +#define CL_HW_ASSERT_TIME_MAX 5000 + +struct cl_dbg_data { + char *str; /* Pointer to debug strings start address */ + int size; /* Size of debug strings pool */ +}; + +/* String offloading to minimize FW size */ +struct cl_str_offload_env { + char *block1; + u32 size1; + u32 base1; + char *block2; + u32 size2; + u32 base2; + char *block3; + u32 size3; + u32 base3; + bool enabled; + char buf[512]; +}; + +struct cl_hw; +struct cl_chip; + +void cl_dbgfile_parse(struct cl_hw *cl_hw, void *edata, u32 esize); +void cl_dbgfile_release_mem(struct cl_dbg_data *dbg_data, + struct cl_str_offload_env *str_offload_env); +void cl_dbgfile_print_fw_str(struct cl_hw *cl_hw, u8 *str, int max_size); +int cl_dbgfile_store_offload_data(struct cl_chip *chip, struct cl_hw *cl_hw, + void *data1, u32 size1, u32 base1, + void *data2, u32 size2, u32 base2, + void *data3, u32 size3, u32 base3); +const char *cl_dbgfile_get_msg_txt(struct cl_dbg_data *dbg_data, u16 file_id, u16 line); + +#endif /* CL_DEBUG_H */ From patchwork Tue May 24 11:33:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575982 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 71580C433EF for ; Tue, 24 May 2022 11:38:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236798AbiEXLiX (ORCPT ); Tue, 24 May 2022 07:38:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40590 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiEXLiW (ORCPT ); Tue, 24 May 2022 07:38:22 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E393A8CCFA for ; Tue, 24 May 2022 04:38:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PD8jMwQNzL9+2gtbjbhbivYtQc7yQ0rfinnmBuYi0SNq2vxH/hU7xlo4WYqo0efVxx/5WstyfZvqRzJ6XHN+TrmoB2tVndtxV5CgLM3k9nev1cALylmcf8coqO6gdk1bx3v6aordPBEvSS1sadgwWr9cCbxrahSlpPM1ICRSNSkuDP5fIMldZGMXWNFjVBU3xJVTJJ4Vu/MDHHDaRU4r/i8TPefN2/RQULb0EJYT24kUUyczXilD/IP/yGMme87q0a2cuC3YrrHVJvfOL8Zo3+Rdg6yz5AgS+G0b9c6tM4Jw2TZbwtJBMTcyOZh7F63VQtQMN5/W0nb8kxkvlV5NLQ== 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=rBCIt1tSUmwdibKNmYe31vXFjwWKkqpJIcJ9Q5hqVYg=; b=QmHQ5EkXIDJou8Ej8N/1KrZq6jkjQonSj9qgT3mJ+lgkdB8zi7+FHhhgi4a6wYvDowXfSy2/HXsfOQ8zEeWk1MYA1UsJQESTWx6wWhd6FqpFnweu/2u2bOjudw77IJEUg4cq/y7D1LvPTiq4JUTvs4WNyP1imbmY/FH3rSQit6hF8CDXmHWu+9mTlmcZi73MQZTcrdqMNbrszG7jr0H9GS12QKnABENEwNh/O8rjWMKeHMmjpeiTLtRUIYS8U7gJ06mSQIyj3ig/Opf2UCoUWJ9+iv0xjP/brdlIYC39gnHkB6cJMscWVdS5OXKFJPomDTmdXFv+x0kyumqMXly1oA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rBCIt1tSUmwdibKNmYe31vXFjwWKkqpJIcJ9Q5hqVYg=; b=3GfyLPrgwe4JUqAQMFvAryWg7u420aXG8AwjzoLs/cdBB++eXoCj8cHTO4IsmVc5cKl8YEuY5AvKIB65NRGexeA1BxRBfJ5Wi1FLkK3MVvZI+xhdUxTm4Cu8MD0mIvVZjDHk0XWEItl90iFREvJiEFt5w7RehZHC4WQxkZsODcw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:57 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:56 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 19/96] cl8k: add def.h Date: Tue, 24 May 2022 14:33:45 +0300 Message-Id: <20220524113502.1094459-20-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4962d2fe-72ab-4973-11a3-08da3d79d8fd X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: qGo9LJm8i6JI2L8fAvwTwCrb9DNUObMOt6JwRey24LEjz/RJz7WwSuJ6LG13a/in8i4TSk705iCXqTX9tGlDLuSd6JGU88J564PzWn5S2sdTOlWf9i3RHDiDwJPe4HQ37ifPJMpWG3U16fGgxsFU4AIyElEpbMM+pJ5+2PI3dLuIDC/SAY5wUg+XWu9y/cZgDRJ8lO409JWz0JtHj+tukto03MhkBTNnSMgco+GZBbnrZSe/XkIo8OvoGmEum35RVSCQOm89wHFnxqbg9MSW1GDrjokMy1/G3j7ZojqIArI/SdWli7Oza1bgNZt/4b5RlPuYy00C8aMqyBwGI1euXvxLGJZUnZErsIRfPAXStFB1jl4UVJ9DLzN0zcRArHZAYG6ZLJyenoGBVqDz4CKhVFcb6uAM/Rhsc1n3NE493tcOW4sV+g8s+Rb9eqGJEMJoDoz/x0hca3R15HxIiUWYvso/MqzAwKFOHjr2nV5rphovS9JSXYGQAPT3lH79p+x34OtK6d2SIwauUcyrMZIlzjWVlG8KIud3ca5LXhZJjAYsh4y2vmGeG7wToF2DkYNCq4p1/RujgmBQv1WIUrLjp1rUjk+0sV2I3CcMkpriOm21mW7L84Vnd5UKWEo7nEKM9tgDnxMFtK//mfG2ujvg5vBenCB2Dz7cD5TbK4JFt7ICWu5FUPnm8qiQvgBvxWkmvThvRrbshhPhx7G4y0p4Da4kS5hIvbc/9v60Lda9ZGw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VMaobklahK43RYwgLXHMjNIHhObFR6CTYWVL/L+1od725zzuymqyzs+OKe+hFATx2+IRuc4rkrjhtAMeFn+niQ6bStYwSWPCcdFaXNOgAu2CZuXVXOnCnzWRhUrQVolZlVuPQ3l8PErnwkXR3awYKaTiSMRxUvNMXO8nS5zodi80Uco26QTT8n15BJnfXwPfqK59TGg60Xkq4YV/y1fp7PyhejJO4Q2Tw6rCzrIT8nMuILzSwoKlPysCaSjrwolBuUR5PSkCxASKBPWSULAUPDPTHe5hhI2MnQ3fs2cuoRrS2XkQbujCsbADQONQCmP7r8Wr4AmIOHlJiI9gYMAiMEXbPeMp67LG200Z10Xgj/hMIhfcItwRLyAKSf8coO2UN8j6ZTs1ha5gkmr1Rv7q0e77tjXnsIFvEOtWMk868leEjgVtqT6XQ6fXmCeTMjCOr+d+gxjOdKC2j0/8h0wj4f24fpyHYuptVhSXdBwAAie0E+2zmmPzDI6BGVI7ronD8zZoGQzowukrmD1i9z4odLli9ofF/ulHgNJhPvxd5CYSSR1Ya6spL65oXu6pRNKKZEAqST15huzI8i/KGA7wXg82XZ8K5MT93gDq/WZsAfPOM3kHBI7WhC59sZVsU/h3/8f00m9XV5mgUMsBY3xgeA/wJwMtbyF2bg3BKhCCH1bEi/r2KaRCKdcQE+7n+kh50+DTNYuoHSYgaPq+aY1lzYrvx4VzXzmlfawY9mgtLLLo0Udc64rBCO49YwItLnZxwOZhMJM8JrUQwiOJCL3pMUokX20Da6eb2ICtQKehAjz7JIID0ineWNkIZIlheiUoG8NoR+fzSM7vuo+Z0col+WhIMnA8LPhlYR7vYbGT0JQHWCWZAFGpA73Kl5Fo0tGsYaU7kdsqSy0/8JeJl9XV+EUiahG8iXh+unQVOm2Iw7o2bj/c6mAQlru/n6yw2bi/vNPYtZWsIcLrmNvh6Jb1YPSkqO2DmtcRm/W2I3v+OPnjzx+GYJGnr7ObnS3SowbWkgr8XEuQNUdSXIKFmdy/ZZhwRXSQQ/QyUTQYsSKEDmZIP0DFu5nSxdncZzV7IXZTufuhw18YPL5gluKZCH4YA+914egn7XHX/EXSmJPK2ZHzWle4uMrQaK4Q6MVoPA25aDtYsVmH/IDroEiLRPKurtx4eJ82crwESFzLruQfSxCVYkwfHOgXoWH86xVnZOR5tcNwBR0IurxZOdNO0kxEPsfiT/fbyfGCspUWwW/jbFOcH7HhleAjPLXtF9sbgEwNXqtD4Fi6EwiP04UIVhi9KA7s1VHCEzUxZiZdiHQA5S1zpAta4hlGk+d58FlEMyX/S6D+gBAHMhI74rF0Iepwj2NFWJSiq5T3uhJ/u8pU4AZ/UAUQMdQV33OvK+++/GHv7/FBbx+vJHdPd2t1ZI+MKqRhHCbAB1RoEVjHo4ZWj9HrWgXCbMGEBWgjITs7YlgUBXJGs1zgSfbb1XXBSOhVVO4tXY7Wt+DitDPVIvcsD22XnJ5WqO52QmSlDXPxJjM3x951e8y06e2vrocKtTrvHmOYZVAchsmQSYAbpmvX5nQqxv3LBNWbgDH3gXVAnNrcH3qtgA25Kch92dlu5KdK8zcXPa/5SdjlDQXGbRnTHKiYPZlwjUUF4ZxUG0TKFxllX3p87e3nH8/TRo6jNJlVzB2NRnLsg2YCRBfyGWGGkIjntdzJwLWwJ7SikmFJVHUWh8SSNe5eYJqJqGHJVr6jhWi/iuQGl3Dcp3yqqPkc+Rg= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4962d2fe-72ab-4973-11a3-08da3d79d8fd X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:56.9035 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 96Mdj1T8DX0kD/C3W08ZWLc8NUO/2EP5pZVYQ8OopfuWWkDlpMaKLApZEVDHc5i7ZElJxSVEuuKykjAEXGb7Bw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/def.h | 235 +++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/def.h diff --git a/drivers/net/wireless/celeno/cl8k/def.h b/drivers/net/wireless/celeno/cl8k/def.h new file mode 100644 index 000000000000..24613836d263 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/def.h @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_DEF_H +#define CL_DEF_H + +#include +#include + +#ifndef CONFIG_CL8K_VERSION +#define CONFIG_CL8K_VERSION "8.0.0.0.0.0" +#endif /* CONFIG_CL8K_VERSION */ + +#define ASSERT_ERR(condition) \ + do { \ + if (unlikely(!(condition))) \ + cl_dbg_err(cl_hw, ":ASSERT_ERR(" #condition ")\n"); \ + } while (0) + +#define ASSERT_ERR_CHIP(condition) \ + do { \ + if (unlikely(!(condition))) \ + cl_dbg_chip_err(chip, ":ASSERT_ERR(" #condition ")\n"); \ + } while (0) + +#define msecs_round(ms) jiffies_to_msecs(msecs_to_jiffies(ms)) + +/* Each chip supports two TCVs */ +#define TCV0 0 +#define TCV1 1 +#define TCV_MAX 2 + +#define CHIP0 0 +#define CHIP1 1 +#define CHIP_MAX 2 + +#define TCV_TOTAL (CHIP_MAX * TCV_MAX) + +enum cl_fw_band { + FW_BAND_2GHZ, + FW_BAND_5GHZ, + FW_BAND_6GHZ, + + FW_BAND_MAX, +}; + +#define BAND_6G 6 +#define BAND_5G 5 +#define BAND_24G 24 + +#define CL_VENDOR_ID 0x1d69 + +#define CPU_MAX_NUM 8 + +/* We support 128 stations and last station is assigned for high priority */ +#define CL_MAX_NUM_STA 128 +#define FW_MAX_NUM_STA (CL_MAX_NUM_STA + 1) + +#define MAX_SINGLE_QUEUES (AC_MAX * FW_MAX_NUM_STA) +#define HIGH_PRIORITY_QUEUE (MAX_SINGLE_QUEUES - 1) + +/* Must be aligned to NX_VIRT_DEV_MAX definition in rwnx_config.h */ +#define MAX_BSS_NUM 8 +#define BSS_INVALID_IDX 0xFF + +#define MAX_TX_SW_AMSDU_PACKET 15 + +#define RX_MAX_MSDU_IN_AMSDU 128 + +#define CL_PATH_MAX 200 +#define CL_FILENAME_MAX 100 + +/* MAX/MIN number of antennas supported */ +#define MIN_ANTENNAS 1 +#define MAX_ANTENNAS 6 +#define MAX_ANTENNAS_OFDM_HT_VHT 4 +#define MAX_ANTENNAS_CCK 4 +#define MAX_ANTENNAS_CHIP 8 + +#define MAX_ANTENNAS_CL808X 8 +#define MAX_ANTENNAS_CL806X 6 +#define MAX_ANTENNAS_CL804X 4 +#define MAX_ANTENNAS_WIRING_ID_27_31 3 + +#define ANT_MASK(ant) (BIT(ant) - 1) + +/* 6GHz defines */ +#define HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_OFFSET 3 +#define HE_6GHZ_CAP_MAX_MPDU_LEN_OFFSET 6 +#define HE_6GHZ_CAP_MAX_AMPDU_LEN_FACTOR 13 +#define HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_MASK 0x38 + +#define MHZ_TO_BW(mhz) ilog2((mhz) / 20) +#define BW_TO_MHZ(bw) ((1 << (bw)) * 20) +#define BW_TO_KHZ(bw) ((1 << (bw)) * 20000) + +#define CL_HWQ_BK 0 +#define CL_HWQ_BE 1 +#define CL_HWQ_VI 2 +#define CL_HWQ_VO 3 +#define CL_HWQ_BCN 4 + +/* Traffic ID enumeration */ +enum { + TID_0, + TID_1, + TID_2, + TID_3, + TID_4, + TID_5, + TID_6, + TID_7, + TID_MAX +}; + +/* Access Category enumeration */ +enum { + AC_BK = 0, + AC_BE, + AC_VI, + AC_VO, + AC_MAX +}; + +enum cl_dev_flag { + CL_DEV_HW_RESTART, + CL_DEV_SW_RESTART, + CL_DEV_STOP_HW, + CL_DEV_STARTED, + CL_DEV_AP_STARTED, + CL_DEV_INIT, + CL_DEV_FW_SYNC, + CL_DEV_FW_ERROR, + CL_DEV_REPEATER, + CL_DEV_MESH_AP, + CL_DEV_RADAR_LISTEN +}; + +enum cl_hw_mode { + HW_MODE_A, + HW_MODE_B, + HW_MODE_G, + HW_MODE_BG, + + HW_MODE_MAX, +}; + +enum cl_channel_bw { + CHNL_BW_20, + CHNL_BW_40, + CHNL_BW_80, + CHNL_BW_160, + + CHNL_BW_MAX, +}; + +#define MU_UL_MAX 4 + +#define CHNL_BW_MAX_HE CHNL_BW_MAX +#define CHNL_BW_MAX_VHT CHNL_BW_MAX +#define CHNL_BW_MAX_HT CHNL_BW_80 + +#define CHNL_BW_2_5 4 +#define CHNL_BW_5 5 +#define CHNL_BW_10 6 + +#define MESH_BASIC_RATE_MAX 12 + +enum cl_wireless_mode { + WIRELESS_MODE_LEGACY, + WIRELESS_MODE_HT, + WIRELESS_MODE_HT_VHT, + WIRELESS_MODE_HT_VHT_HE, + WIRELESS_MODE_HE +}; + +enum cl_ndp_tx_chains { + NDP_TX_PHY0 = 0x1, + NDP_TX_PHY1 = 0x2, + NDP_TX_PHY01 = 0x3, +}; + +#define Q2_TO_FREQ(x) ((x) >> 2) +#define FREQ_TO_Q2(freq) ((freq) << 2) + +/* Values of the firmware FORMATMOD fields */ +enum format_mode { + FORMATMOD_NON_HT = 0, + FORMATMOD_NON_HT_DUP_OFDM = 1, + FORMATMOD_HT_MF = 2, + FORMATMOD_HT_GF = 3, + FORMATMOD_VHT = 4, + FORMATMOD_HE_SU = 5, + FORMATMOD_HE_MU = 6, + FORMATMOD_HE_EXT = 7, + FORMATMOD_HE_TRIG = 8, + FORMATMOD_MAX = 9 +}; + +/* PHY device options */ +enum { + PHY_DEV_OLYMPUS, /* Olympus - 5g/24g */ + PHY_DEV_ATHOS, /* Athos - 6g , AthosB - 6g/5g */ + PHY_DEV_DUMMY, /* Dummy */ + PHY_DEV_FRU, /* Fake RF Unit */ + PHY_DEV_LOOPBACK, /* RICU loopback mode */ + PHY_DEV_MAX, +}; + +#define IS_REAL_PHY(chip) ((chip)->conf->ci_phy_dev <= PHY_DEV_ATHOS) + +#define riu_chain_for_each(_chain) \ + for (_chain = cl_hw->first_riu_chain; _chain <= cl_hw->last_riu_chain; _chain++) + +#define CL_MU_OFDMA_MAX_STA_PER_GRP 8 +#define CL_MU_MIMO_MAX_STA_PER_GRP 4 + +#if CL_MU_MIMO_MAX_STA_PER_GRP > CL_MU_OFDMA_MAX_STA_PER_GRP +#define CL_MU_MAX_STA_PER_GROUP CL_MU_MIMO_MAX_STA_PER_GRP +#else +#define CL_MU_MAX_STA_PER_GROUP CL_MU_OFDMA_MAX_STA_PER_GRP +#endif + +/* Max flags for driver status description is defined as 32 * MAX_CFM_FLAGS */ +#define MAX_CFM_FLAGS 2 +#define DELAY_HIST_SIZE 32 + +#define STR_LEN_32B 32 +#define STR_LEN_64B 64 +#define STR_LEN_256B 256 + +#define STA_HASH_SIZE 256 +#define STA_IDX_INVALID U8_MAX + +#endif /* CL_DEF_H */ From patchwork Tue May 24 11:33:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576863 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 95C7BC433EF for ; Tue, 24 May 2022 11:38:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236807AbiEXLiZ (ORCPT ); Tue, 24 May 2022 07:38:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236801AbiEXLiY (ORCPT ); Tue, 24 May 2022 07:38:24 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70052.outbound.protection.outlook.com [40.107.7.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 048188CCFB for ; Tue, 24 May 2022 04:38:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MuhcbAlsLT8tMUTZmAjc37kJ1CX3vubtp0hsbFa7l/Gei4DCpTFOeKREAdUFWKCCCj4RECkScQSzpIrkE06sOpCP3cR8lXGJeTYt9raXEWZlc/nu9fMM/ddtu2ktZ+glkKxfmP1e577+a2Zgc+5i94fEEyAAB3XV+rDr17KoPTasokWhBMOHFT1nKILMmy6moSE8zIRiv4NXW4YGEztX9amMVkZF25t7PqTkgOtFl2+24TTyfPQKbj79gg5yr66rBpERXTir1QCJ8wClLy5OH3nupt7NLaY0zl4S4RcaJFO42l+Dh7Cm2TcIKI6mIaSG80TPv/ZwFMyQXwOrZbhQHw== 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=XR1alug55Mo1W1eIVpnKL1Y70kdnT36BzL+K+24WZus=; b=OCvm1x/l+Jjb0OIe2hxWcJYuTp90CrHH9ZYx+eUnRdQedPPa1NLQ3VTURVk9ZAocXUxTVCK+cAY1+VGzqsjJ2b42tH9YNq9ErtI9OWEspel79AH6bryQDoA8nYMTZo6KJWWel8NJ/tgkmF8r2oggUEz9n2EQl2DPTxnySar6sRx8L4ZDJONL69LGD76najBrAIxOJ+d95JHCJF9L4I620l6EnoOsP9KXdvpc8XHhB8hDTxfKHza+rugn0qC75VvjsKVfj3ajUPl+l78mCDPpZ3mOSQN7l+PfdtExXbr6gnmmyuzJFAkusIzU1R2WMCASHPNrEXkvp/b2qC1c8Ob0nA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XR1alug55Mo1W1eIVpnKL1Y70kdnT36BzL+K+24WZus=; b=dqdvKruC/9jCfJksJXFgGz/xebtEEgmt3KIqMvv1OfTPoWzzciw1LgQ5BkKTKvbc894f9qk8mQ9FgWGo5zYfitOPU75kqlL+W1CPw8vjJZZ/huLF4DxkHxrnayzyo1eJN8PUvFNIK80B7HTo3zLANV0/U3P/+dT0uPVP2m1ZqFQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:58 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:58 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 20/96] cl8k: add dfs.c Date: Tue, 24 May 2022 14:33:46 +0300 Message-Id: <20220524113502.1094459-21-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b91881ac-7b9d-4358-d860-08da3d79d976 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 8AtQY4qtd8aPZTVDl3gdJtoWiWpURsl3BHOcHTEld6fSbj4HtE390iMjxNUasgZYUOb3YAPIkPRUdx5dhXNAFLgM1uyB54dWIP7P+NeQ/YHsvYmRUl+QDdV3IorGKDDcEKMYEqd+f8aTjZPkbt7g2j36gzKr00yXMNepKBrikQbp9s8WmyPVLUF3VWf6LSha/v/4U3B7+D6upGDbLJW7mi9NBf/PAGRVD/LiTSWmxJ++KDl74wbIxCUNApOWRpvq7rt2PIXFlItpmjZrk3hW9U/iOwX3CF1DfE2Cs9SVCzjMsoOGZvt4mnYqZ8imRGtI0YurMQ47dS64Tlnb2OPCSq7Fketpiz7L3JO22a4bfR4nDyW6V5+mGJsIEs4wmTpm95asTnc6x5SnqMaHE6NB7iBcMTBLftVCJDYPzJuMe2q8hxrXjKYkap7mAVjFIVakxlCFvWgZP05lqvHrQuu8muG3G/vEGRJ4ykcMkudNN3SZ6GzwCIFFZoGnqtUtDrUew3t/UmwJdNzVa2rzLgp+XE8Bh2/BvmEaHkNiR/xll6VhT/TsYg1mrFKWXHPGozs5C4n6tj5p061qDRpLwIbG4OQ2UvOIKX1dqrRrq2PQ2fsuJtfJ30j2ufT6MIMl5dBsoZeH8bLemxmfFOPioDmiagg7Yna2mprBQav8uAeGeflQoYa3PFmXtpwPvFkac29dhkyqzEvZWea9HsweSpvV6rE1k+7vrya+cEHJ30sfR64= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Jkp91JE8YM0kYEaG3yhmkr7xt2A5tU6YLg8QACZLT7UI+oiBOy7Jpp2xdnYPM47PmMJM/J/Gb0WtWrdb1IeluTi/9J2AfoUo32PFpBdb1Sjd0Fgp4BfeQyDKWopaKAd6KBEoSUKRIGkcdPg96ssG02f2xzAbLrv5vsj9wJiN6vVfvdNVn8gngZx0Hd52cqipyYwS30SX/G/ED4H+Uw6nQ3ij1PxuroKmzBnabOslV1MnFm6miWJS8bjrxrrHlzZNg+YBr2BhBpmE7LNvhnHC+SAzRaDGJlwT0QspTenXuRgPvi/bdE+gL/MUmDMTRSH0qM0wh/drwh38VznUcyXQLcRhu5KbyXRFdEQfJv0tlMmlOersct3gpBdJbWrYX2z+FJ7f9qXxSXtnpwfZRoZZGGfsriw/GLZtm3bUHs6/cBKcq6oAZkcTYb0x0yUZrBVv+E8fLBshJXRl0S07K8hnn3/k05aT8ETcLUW0lEEWLk5pm01Krlc0trFoK6z/8weFFFUtaiCTLHUhyQ5CmU3z4D62tVgE0kC8yAGzkV3bte03g0shAlLCK0KrcX2TotseyaqkDm+vVVqY2eyfDnkZKVVLsrfKwNQksbLsEN0jkEI0kPHxo3wc5yutN6CVS+leiORyDSni/fmMLzbCgBZYQ2t8TWmEtJ4G7Sv9KLvQZwUWgTpFMT2cbA3mB4fHZUVXssREMiawlpKtjdP0w0BUidxTmAIIcLddNKwDpTz3P9NvJHpE3Y0fOQpCg99JmGSDHGTQvm+hwuPo1FyKHUKBGTUk8+LmWyt2i2psniFZjju4OA3QKwjsf/OJ9/tV3h4ewzXygL7PemgP8QXNcJUPnMyFQdLrnmlWZFydGPqNt2WaTAGC+Ez7LGg0Gf8uPHScrEj/BX9teFFPOqkNMCPn6qh2HgTM26/bbvF8b709EtNyJzub9PMcs8m29nMabOeRIbKepCQ64K2yeJk6ZDJhubCs9ZsnRllfgC5zE34xe+gKmwaDttURP+HNVQrvENn8EfqraBUKEj/rJpWyrfDd7yQKQ4ag+/HDFSZdtEmNErMTKF4EPayvlonIfhuUXbIuwnrFPRqUgT0TjEvZqjWBzX5eZjQ/Lds0E21oCsy2ctWH65IxK6q8WZAENxzwPurZ69qxQ7T1eTT+Y2Rm+Cf0fw5hN1puehiozf8H1CzoslDnGAwur3AdyID8KBHTAoiM6i5ZHS487stgEoLcBsTHo2AMw1w654i57/g3T8P1lHf5Xhfsu4RYo4HKkLG+oT4McUdkmYHqTgg7WF57dOFKKg/hRItIByu2qTCYFfZJlnpFcu1tp5CczBgxh3O0OWGFygUoRxAZgWy/tBLN1ZlzbK4+/LYIvGc8Uql8DLHjY1DCwsGJWOVVFKc6OGzqNlwVCgdd2qHqAatgf2Yo/6I1t0NmpDX7l3q0DkAwjp19bK9hctmLwOyyaQ5SsvBg72YCKVOSCeYt04fKNvggZBgY3KGRExI6L4Vk+vJDW766An3R/VcCdzKLRrX0inFYD0fyMaAvJraf5RNCKff+YWZ9cWvx8gRlCUswN9+SS6Soc2jONErquZWisNBRpFO83sDDmNTvbIW63eL6YyObCA7jUa+v0+yH8FpSlwhcyZ5g+FkZFjEBG0Bl9Dsiy8KHSSA7k35jh9PB6x8F0u8fx76wtTcaofiUTDDGIWhmwC1HFHxmzqYJjQ/DKTbUUo+DpudCkYZPP6FNZhIoYxvha0Pr8AAJiW2h4xEHOLHcwk59Bcc= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b91881ac-7b9d-4358-d860-08da3d79d976 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:57.9971 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: UaeftMgk4Lfe0EQSRhdU79u3sYTNqRLSBX5Ognikcj7Hxn9nmms1etPAgDQTEqcA8bJa9ejHXQzUgKolFE9Low== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/dfs.c | 768 +++++++++++++++++++++++++ 1 file changed, 768 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/dfs.c diff --git a/drivers/net/wireless/celeno/cl8k/dfs.c b/drivers/net/wireless/celeno/cl8k/dfs.c new file mode 100644 index 000000000000..f320e5885a58 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/dfs.c @@ -0,0 +1,768 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "utils.h" +#include "debug.h" +#include "temperature.h" +#include "traffic.h" +#include "reg/reg_defs.h" +#include "config.h" +#include "debug.h" +#include "dfs.h" + +#define dfs_pr(cl_hw, level, ...) \ + do { \ + if ((level) <= (cl_hw)->dfs_db.dbg_lvl) \ + pr_debug(__VA_ARGS__); \ + } while (0) + +#define dfs_pr_verbose(cl_hw, ...) dfs_pr((cl_hw), DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define dfs_pr_err(cl_hw, ...) dfs_pr((cl_hw), DBG_LVL_ERROR, ##__VA_ARGS__) +#define dfs_pr_warn(cl_hw, ...) dfs_pr((cl_hw), DBG_LVL_WARNING, ##__VA_ARGS__) +#define dfs_pr_trace(cl_hw, ...) dfs_pr((cl_hw), DBG_LVL_TRACE, ##__VA_ARGS__) +#define dfs_pr_info(cl_hw, ...) dfs_pr((cl_hw), DBG_LVL_INFO, ##__VA_ARGS__) + +/* + * ID Min Max Tol Min Max Tol Tol MIN PPB Trig Type + * Width Width Width PRI PRI PRI FREQ Burst Count + */ + +/* ETSI Radar Types v1.8.2 */ +static struct cl_radar_type radar_type_etsi[] = { + {0, 1, 10, 2, 1428, 1428, 2, 1, 1, 18, 10, RADAR_WAVEFORM_SHORT}, + {1, 1, 10, 2, 1000, 5000, 2, 1, 1, 10, 5, RADAR_WAVEFORM_SHORT}, + {2, 1, 15, 2, 625, 5000, 2, 1, 1, 15, 8, RADAR_WAVEFORM_SHORT}, + {3, 1, 15, 2, 250, 435, 2, 1, 1, 25, 9, RADAR_WAVEFORM_SHORT}, + {4, 10, 30, 2, 250, 500, 2, 1, 1, 20, 9, RADAR_WAVEFORM_SHORT}, + {5, 1, 10, 2, 2500, 3334, 2, 1, 2, 10, 5, RADAR_WAVEFORM_STAGGERED}, + {6, 1, 10, 2, 833, 2500, 2, 1, 2, 15, 8, RADAR_WAVEFORM_STAGGERED}, +}; + +/* FCC Radar Types 8/14 */ +static struct cl_radar_type radar_type_fcc[] = { + {0, 1, 10, 0, 1428, 1428, 1, 1, 1, 18, 10, RADAR_WAVEFORM_SHORT}, + {1, 1, 10, 3, 518, 3066, 3, 1, 1, 18, 10, RADAR_WAVEFORM_SHORT}, + {2, 1, 10, 3, 150, 230, 3, 1, 1, 23, 10, RADAR_WAVEFORM_SHORT}, + {3, 3, 10, 3, 200, 500, 3, 1, 1, 16, 6, RADAR_WAVEFORM_SHORT}, + {4, 6, 20, 3, 200, 500, 3, 1, 1, 12, 6, RADAR_WAVEFORM_SHORT}, + {5, 50, 100, 50, 1000, 2000, 1, 1, 2, 10, 5, RADAR_WAVEFORM_LONG}, + {6, 1, 10, 0, 333, 333, 1, 1, 2, 30, 10, RADAR_WAVEFORM_LONG}, +}; + +static void cl_dfs_en(struct cl_hw *cl_hw, u8 dfs_en) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + struct cl_tcv_conf *conf = cl_hw->conf; + + cl_msg_tx_set_dfs(cl_hw, dfs_en, dfs_db->dfs_standard, + conf->ci_dfs_initial_gain, conf->ci_dfs_agc_cd_th); + dfs_pr_verbose(cl_hw, "DFS: %s\n", dfs_en ? "Enable" : "Disable"); +} + +static bool cl_dfs_create_detection_buffer(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, + struct cl_dfs_pulse *pulse_buffer, u8 *samples_cnt, + unsigned long time) +{ + u8 i; + u8 pulse_idx; + /* Init First index to last */ + u8 first_pulse_idx = (dfs_db->buf_idx - 1 + CL_DFS_PULSE_BUF_SIZE) & CL_DFS_PULSE_BUF_MASK; + + /* Find Start Pulse indexes */ + for (i = 0; i < CL_DFS_PULSE_BUF_SIZE; i++) { + pulse_idx = (i + dfs_db->buf_idx) & CL_DFS_PULSE_BUF_MASK; + + if ((time - dfs_db->dfs_pulse[pulse_idx].time) < dfs_db->search_window) { + first_pulse_idx = pulse_idx; + break; + } + } + + dfs_pr_info(cl_hw, "DFS: First pulse idx = %u, Last pulse idx = %u\n", + first_pulse_idx, (dfs_db->buf_idx - 1 + CL_DFS_PULSE_BUF_SIZE) + & CL_DFS_PULSE_BUF_MASK); + + if (dfs_db->buf_idx >= first_pulse_idx + 1) { + if ((dfs_db->buf_idx - first_pulse_idx) < dfs_db->min_pulse_eeq) + goto not_enough_pulses; + } else { + if ((dfs_db->buf_idx + CL_DFS_PULSE_BUF_SIZE - first_pulse_idx) < + dfs_db->min_pulse_eeq) + goto not_enough_pulses; + } + + /* Copy the processed samples to local Buf to avoid index castings */ + for (i = 0; pulse_idx != ((dfs_db->buf_idx - 1 + CL_DFS_PULSE_BUF_SIZE) + & CL_DFS_PULSE_BUF_MASK); i++) { + pulse_idx = (i + first_pulse_idx) & CL_DFS_PULSE_BUF_MASK; + memcpy(&pulse_buffer[i], &dfs_db->dfs_pulse[pulse_idx], sizeof(pulse_buffer[i])); + } + *samples_cnt = i + 1; + + return true; +not_enough_pulses: + /* Return if buffer don't hold enough valid samples */ + dfs_pr_warn(cl_hw, "DFS: Not enough pulses in buffer\n"); + + return false; +} + +static bool cl_dfs_is_valid_dfs_freq(struct cl_hw *cl_hw, u32 freq_off) +{ + u16 freq = cl_hw->center_freq + freq_off; + u16 freq_min = max((u16)(cl_hw->center_freq - cl_center_freq_offset(cl_hw->bw) - 10), + (u16)CL_DFS_MIN_FREQ); + u16 freq_max = min((u16)(cl_hw->center_freq + cl_center_freq_offset(cl_hw->bw) + 10), + (u16)CL_DFS_MAX_FREQ); + + if (freq > freq_min && freq < freq_max) + return true; + + return false; +} + +static void cl_dfs_add_pulses_to_global_buffer(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, + struct cl_radar_pulse *pulse, u8 pulse_cnt, + unsigned long time) +{ + int i; + + for (i = 0; i < pulse_cnt; i++) + dfs_pr_info(cl_hw, "Pulse=%d, Width=%u, PRI=%u, FREQ=%d, Time=%lu, FOM=%x\n", + i, pulse[i].len, pulse[i].rep, pulse[i].freq, time, pulse[i].fom); + + /* Maintain cyclic pulse buffer */ + for (i = 0; i < pulse_cnt; i++) { + if (!cl_dfs_is_valid_dfs_freq(cl_hw, (u32)pulse[i].freq)) + continue; + + dfs_db->dfs_pulse[dfs_db->buf_idx].freq = pulse[i].freq; + dfs_db->dfs_pulse[dfs_db->buf_idx].width = pulse[i].len; + dfs_db->dfs_pulse[dfs_db->buf_idx].pri = pulse[i].rep; + dfs_db->dfs_pulse[dfs_db->buf_idx].fom = pulse[i].fom; + dfs_db->dfs_pulse[dfs_db->buf_idx].occ = 0; /* occ temp disabled. */ + dfs_db->dfs_pulse[dfs_db->buf_idx].time = time; + + dfs_db->buf_idx++; + dfs_db->buf_idx &= CL_DFS_PULSE_BUF_MASK; + } +} + +static bool cl_dfs_buf_maintain(struct cl_hw *cl_hw, struct cl_radar_pulse *pulse, + struct cl_dfs_pulse *pulse_buffer, u8 pulse_cnt, + unsigned long time, u8 *samples_cnt, struct cl_dfs_db *dfs_db) +{ + int i; + + cl_dfs_add_pulses_to_global_buffer(cl_hw, dfs_db, pulse, pulse_cnt, time); + if (!cl_dfs_create_detection_buffer(cl_hw, dfs_db, pulse_buffer, samples_cnt, time)) + return false; + + for (i = 0; i < *samples_cnt; i++) + dfs_pr_info(cl_hw, "DFS: pulse[%d]: width=%u, pri=%u, freq=%d\n", + i, pulse_buffer[i].width, pulse_buffer[i].pri, pulse_buffer[i].freq); + + return true; +} + +static inline bool cl_dfs_pulse_match(s32 pulse_val, s32 spec_min_val, + s32 spec_max_val, s32 spec_tol) +{ + return ((pulse_val >= (spec_min_val - spec_tol)) && + (pulse_val <= (spec_max_val + spec_tol))); +} + +static u8 cl_dfs_is_stag_pulse(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, + struct cl_dfs_pulse *pulse) +{ + int i; + struct cl_radar_type *radar_type; + + for (i = 0; i < dfs_db->radar_type_cnt; i++) { + radar_type = &dfs_db->radar_type[i]; + + if (radar_type->waveform != RADAR_WAVEFORM_STAGGERED) + continue; + + if (cl_dfs_pulse_match((s32)pulse->width, radar_type->min_width, + radar_type->max_width, radar_type->tol_width) && + cl_dfs_pulse_match((s32)pulse->pri, radar_type->min_pri, + radar_type->max_pri, radar_type->tol_pri)) { + /* Search for the second burst */ + if (abs(pulse[0].pri - pulse[2].pri) <= dfs_db->radar_type[i].tol_pri && + abs(pulse[1].pri - pulse[3].pri) <= radar_type->tol_pri && + abs(pulse[0].pri - pulse[1].pri) > radar_type->tol_pri && + abs(pulse[2].pri - pulse[3].pri) > radar_type->tol_pri) { + dfs_pr_info(cl_hw, "DFS: Found match type %d\n", i); + return (i + 1); + } else if (abs(pulse[0].pri - pulse[3].pri) <= radar_type->tol_pri && + abs(pulse[1].pri - pulse[4].pri) <= radar_type->tol_pri && + abs(pulse[0].pri - pulse[1].pri) > radar_type->tol_pri && + abs(pulse[3].pri - pulse[4].pri) > radar_type->tol_pri) { + dfs_pr_info(cl_hw, "DFS: Found match radar %d\n", i); + return (i + 1); + } + } + } + + return 0; +} + +static u8 cl_dfs_is_non_stag_pulse(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, + struct cl_dfs_pulse *pulse) +{ + int i; + struct cl_radar_type *radar_type; + + for (i = 0; i < dfs_db->radar_type_cnt; i++) { + radar_type = &dfs_db->radar_type[i]; + + if (radar_type->waveform == RADAR_WAVEFORM_STAGGERED) + continue; + + if (cl_dfs_pulse_match((s32)pulse->width, radar_type->min_width, + radar_type->max_width, radar_type->tol_width) && + cl_dfs_pulse_match((s32)pulse->pri, radar_type->min_pri, + radar_type->max_pri, radar_type->tol_pri)) { + dfs_pr_info(cl_hw, "DFS: Found match type %d\n", i); + return (i + 1); + } + } + + dfs_pr_warn(cl_hw, "DFS: Match not found\n"); + + return 0; +} + +static u8 cl_dfs_get_pulse_type(struct cl_hw *cl_hw, struct cl_dfs_pulse *pulse, + bool stag_candidate) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + if (stag_candidate) { + u8 pulse_type = cl_dfs_is_stag_pulse(cl_hw, dfs_db, pulse); + + if (pulse_type) + return pulse_type; + } + + return cl_dfs_is_non_stag_pulse(cl_hw, dfs_db, pulse); +} + +static bool cl_dfs_compare_cand(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, u8 pulse_type, + struct cl_dfs_pulse radar_cand, u8 *match, int idx, + u8 *occ_ch_cand) +{ + int i; + + if (!(abs(dfs_db->pulse_buffer[idx].width - radar_cand.width) <= + dfs_db->radar_type[pulse_type].tol_width)) + goto end; + + if (!(abs(dfs_db->pulse_buffer[idx].freq - radar_cand.freq) <= + dfs_db->radar_type[pulse_type].tol_freq)) + goto end; + + for (i = 1; i < CL_DFS_CONCEAL_CNT; i++) + if (abs(dfs_db->pulse_buffer[idx].pri - i * radar_cand.pri) <= + dfs_db->radar_type[pulse_type].tol_pri) + break; + + if (i == CL_DFS_CONCEAL_CNT) + goto end; + + (*match)++; + (*occ_ch_cand) += dfs_db->pulse_buffer[i].occ; + +end: + dfs_pr_info(cl_hw, "DFS: compared pulse - width=%u, pri=%u, freq=%u match: %u " + "trig cnt: %u\n", + dfs_db->pulse_buffer[idx].width, dfs_db->pulse_buffer[idx].pri, + dfs_db->pulse_buffer[idx].freq, *match, + dfs_db->radar_type[pulse_type].trig_count); + + if (*match < dfs_db->radar_type[pulse_type].trig_count) + return false; + + return true; +} + +static bool cl_dfs_check_cand(struct cl_hw *cl_hw, struct cl_dfs_db *dfs_db, u8 pulse_type, + struct cl_dfs_pulse radar_cand, u8 samples_cnt) +{ + u8 occ_ch_cand = 0; + u8 match = 0; + int i; + + dfs_pr_info(cl_hw, "DFS: candidate pulse - width=%u, pri=%u, freq=%u\n", + radar_cand.width, radar_cand.pri, radar_cand.freq); + + for (i = 0; i < samples_cnt; i++) { + if (!cl_dfs_compare_cand(cl_hw, dfs_db, pulse_type, radar_cand, &match, i, + &occ_ch_cand)) + continue; + + dfs_pr_verbose(cl_hw, "DFS: Radar detected - type %u\n", pulse_type); + + return true; + } + + return false; +} + +static bool cl_dfs_short_pulse_search(struct cl_hw *cl_hw, struct cl_radar_pulse *pulse, + u8 pulse_cnt, unsigned long time, struct cl_dfs_db *dfs_db) +{ + int i; + bool stag_candidate; + u8 samples_cnt = 0; + u8 pulse_type; + + /* Return if not enough pulses in the buffer */ + if (!cl_dfs_buf_maintain(cl_hw, pulse, dfs_db->pulse_buffer, pulse_cnt, time, + &samples_cnt, dfs_db)) + return false; + + for (i = 0; i < samples_cnt; i++) { + struct cl_dfs_pulse radar_cand; + + stag_candidate = false; + + /* Make sure there is enough samples to staggered check */ + if (dfs_db->dfs_standard == NL80211_DFS_ETSI && + (samples_cnt - i) > CL_DFS_STAGGERED_CHEC_LEN) + stag_candidate = true; + + pulse_type = cl_dfs_get_pulse_type(cl_hw, &dfs_db->pulse_buffer[i], stag_candidate); + + if (!pulse_type) + continue; + + radar_cand.width = dfs_db->pulse_buffer[i].width; + radar_cand.pri = dfs_db->pulse_buffer[i].pri; + radar_cand.freq = dfs_db->pulse_buffer[i].freq; + + if (cl_dfs_check_cand(cl_hw, dfs_db, pulse_type - 1, radar_cand, samples_cnt)) + return true; + } + + return false; +} + +static bool cl_dfs_long_pulse_search(struct cl_hw *cl_hw, struct cl_radar_pulse *pulse, + u8 pulse_cnt, unsigned long time) +{ + u32 prev_pulse_time_diff; + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + struct cl_tcv_conf *conf = cl_hw->conf; + int i; + + for (i = 0; i < pulse_cnt; i++) { + if (pulse[i].len > CL_DFS_LONG_MIN_WIDTH) { + prev_pulse_time_diff = time - dfs_db->last_long_pulse_ts; + + if (pulse[i].rep >= dfs_db->radar_type[5].min_pri && + pulse[i].rep <= dfs_db->radar_type[5].max_pri) + dfs_db->long_pri_match_count += 1; + + dfs_pr_info(cl_hw, "DFS: Long pulse search: width = %u, delta_time = %u\n", + pulse[i].len, prev_pulse_time_diff); + + if (dfs_db->long_pulse_count == 0 || + (prev_pulse_time_diff >= conf->ci_dfs_long_pulse_min && + prev_pulse_time_diff <= conf->ci_dfs_long_pulse_max)) { + dfs_db->long_pulse_count += 1; + } else if (prev_pulse_time_diff > min(dfs_db->max_interrupt_diff, + conf->ci_dfs_long_pulse_min)) { + dfs_db->long_pulse_count = 0; + dfs_db->short_pulse_count = 0; + dfs_db->long_pri_match_count = 0; + } + dfs_db->last_long_pulse_ts = time; + } else if (pulse[i].len < CL_DFS_LONG_FALSE_WIDTH) { + dfs_db->short_pulse_count++; + + if (dfs_db->short_pulse_count > CL_DFS_LONG_FALSE_IND) { + dfs_db->long_pulse_count = 0; + dfs_db->short_pulse_count = 0; + dfs_db->long_pri_match_count = 0; + + dfs_pr_warn(cl_hw, "DFS: Restart long sequence search\n"); + } + } + } + + if (dfs_db->long_pulse_count >= dfs_db->radar_type[5].trig_count && + dfs_db->long_pri_match_count >= (dfs_db->radar_type[5].trig_count - 1)) { + dfs_db->short_pulse_count = 0; + dfs_db->long_pulse_count = 0; + dfs_db->long_pri_match_count = 0; + return true; + } else { + return false; + } +} + +static bool cl_dfs_post_detection(struct cl_hw *cl_hw) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + /* Make sure firmware sets the DFS registers */ + cl_radar_flush(cl_hw); + cl_msg_tx_set_dfs(cl_hw, false, dfs_db->dfs_standard, + cl_hw->conf->ci_dfs_initial_gain, cl_hw->conf->ci_dfs_agc_cd_th); + + ieee80211_radar_detected(cl_hw->hw); + + return true; +} + +bool cl_dfs_pulse_process(struct cl_hw *cl_hw, struct cl_radar_pulse *pulse, u8 pulse_cnt, + unsigned long time) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + dfs_db->pulse_cnt += pulse_cnt; + + if (dfs_db->dfs_standard == NL80211_DFS_FCC && + cl_dfs_long_pulse_search(cl_hw, pulse, pulse_cnt, time)) { + dfs_pr_verbose(cl_hw, "DFS: Radar detected - long\n"); + return cl_dfs_post_detection(cl_hw); + } else if (cl_dfs_short_pulse_search(cl_hw, pulse, pulse_cnt, time, dfs_db)) { + return cl_dfs_post_detection(cl_hw); + } + + return false; +} + +static void cl_dfs_set_min_pulse(struct cl_hw *cl_hw) +{ + int i; + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + dfs_db->min_pulse_eeq = U8_MAX; + + for (i = 0; i < dfs_db->radar_type_cnt; i++) { + if (dfs_db->radar_type[i].trig_count < dfs_db->min_pulse_eeq) + dfs_db->min_pulse_eeq = dfs_db->radar_type[i].trig_count; + } + dfs_db->min_pulse_eeq = max(dfs_db->min_pulse_eeq, (u8)CL_DFS_MIN_PULSE_TRIG); +} + +static void cl_dfs_set_region(struct cl_hw *cl_hw, enum nl80211_dfs_regions std) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + dfs_db->dfs_standard = std; + + if (dfs_db->dfs_standard == NL80211_DFS_FCC) { + dfs_db->radar_type = radar_type_fcc; + dfs_db->radar_type_cnt = sizeof(radar_type_fcc) / sizeof(struct cl_radar_type); + } else { + dfs_db->radar_type = radar_type_etsi; + dfs_db->radar_type_cnt = sizeof(radar_type_etsi) / sizeof(struct cl_radar_type); + } +} + +static void cl_dfs_start_cac(struct cl_dfs_db *db) +{ + db->cac.started = true; +} + +static void cl_dfs_end_cac(struct cl_dfs_db *db) +{ + db->cac.started = false; +} + +void cl_dfs_radar_listen_start(struct cl_hw *cl_hw) +{ + set_bit(CL_DEV_RADAR_LISTEN, &cl_hw->drv_flags); + + cl_dfs_en(cl_hw, true); + + dfs_pr_verbose(cl_hw, "DFS: Started radar listening\n"); +} + +void cl_dfs_radar_listen_end(struct cl_hw *cl_hw) +{ + clear_bit(CL_DEV_RADAR_LISTEN, &cl_hw->drv_flags); + + cl_dfs_en(cl_hw, false); + + dfs_pr_verbose(cl_hw, "DFS: Ended radar listening\n"); +} + +void cl_dfs_force_cac_start(struct cl_hw *cl_hw) +{ + bool is_listening = test_bit(CL_DEV_RADAR_LISTEN, &cl_hw->drv_flags); + + cl_dfs_start_cac(&cl_hw->dfs_db); + + /* Reset request state upon completion */ + cl_dfs_request_cac(cl_hw, false); + + /* Disable all the TX flow - be silent */ + cl_tx_en(cl_hw, CL_TX_EN_DFS, false); + + /* If for some reason we are still not listening radar, do it */ + if (unlikely(!is_listening && cl_hw->hw->conf.radar_enabled)) + cl_dfs_radar_listen_start(cl_hw); + + dfs_pr_verbose(cl_hw, "DFS: CAC started\n"); +} + +void cl_dfs_force_cac_end(struct cl_hw *cl_hw) +{ + bool is_listening = test_bit(CL_DEV_RADAR_LISTEN, &cl_hw->drv_flags); + + /* Enable all the TX flow */ + cl_tx_en(cl_hw, CL_TX_EN_DFS, true); + + /* + * If for some reason we are still listening and mac80211 does not + * require to listen radar - disable it + */ + if (unlikely(is_listening && !cl_hw->hw->conf.radar_enabled)) + cl_dfs_radar_listen_end(cl_hw); + + cl_dfs_end_cac(&cl_hw->dfs_db); + + dfs_pr_verbose(cl_hw, "DFS: CAC ended\n"); +} + +bool __must_check cl_dfs_is_in_cac(struct cl_hw *cl_hw) +{ + return cl_hw->dfs_db.cac.started; +} + +bool __must_check cl_dfs_radar_listening(struct cl_hw *cl_hw) +{ + return test_bit(CL_DEV_RADAR_LISTEN, &cl_hw->drv_flags); +} + +bool __must_check cl_dfs_requested_cac(struct cl_hw *cl_hw) +{ + return cl_hw->dfs_db.cac.requested; +} + +void cl_dfs_request_cac(struct cl_hw *cl_hw, bool should_do) +{ + cl_hw->dfs_db.cac.requested = should_do; +} + +static void cl_dfs_edit_tbl(struct cl_hw *cl_hw, u8 row, u8 line, s16 val) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + + if (row > dfs_db->radar_type_cnt) { + dfs_pr_err(cl_hw, "Invalid row number (%u) [0 - %u]\n", line, + dfs_db->radar_type_cnt - 1); + return; + } + + if (line == 0 || line > CL_DFS_MAX_TBL_LINE) { + dfs_pr_err(cl_hw, "Invalid line number (%u) [1 - %u]\n", line, + CL_DFS_MAX_TBL_LINE - 1); + return; + } + + if (line == 1) + dfs_db->radar_type[row].min_width = (s32)val; + else if (line == 2) + dfs_db->radar_type[row].max_width = (s32)val; + else if (line == 3) + dfs_db->radar_type[row].tol_width = (s32)val; + else if (line == 4) + dfs_db->radar_type[row].min_pri = (s32)val; + else if (line == 5) + dfs_db->radar_type[row].max_pri = (s32)val; + else if (line == 6) + dfs_db->radar_type[row].tol_pri = (s32)val; + else if (line == 7) + dfs_db->radar_type[row].tol_freq = (s32)val; + else if (line == 8) + dfs_db->radar_type[row].min_burst = (u8)val; + else if (line == 9) + dfs_db->radar_type[row].ppb = (u8)val; + else if (line == 10) + dfs_db->radar_type[row].trig_count = (u8)val; + else if (line == 11) + dfs_db->radar_type[row].waveform = (enum cl_radar_waveform)val; + + /* Verify if min_pulse_eeq was changed */ + cl_dfs_set_min_pulse(cl_hw); +} + +static void cl_dfs_tbl_overwrite_set(struct cl_hw *cl_hw) +{ + char *tok = NULL; + u8 param1 = 0; + u8 param2 = 0; + s16 param3 = 0; + char str[64]; + char *strp = str; + + if (strlen(cl_hw->conf->ce_dfs_tbl_overwrite) == 0) + return; + + snprintf(str, sizeof(str), cl_hw->conf->ce_dfs_tbl_overwrite); + + tok = strsep(&strp, ";"); + while (tok) { + if (sscanf(tok, "%hhd,%hhd,%hd", ¶m1, ¶m2, ¶m3) == 3) + cl_dfs_edit_tbl(cl_hw, param1, param2, param3); + tok = strsep(&strp, ";"); + } +} + +void cl_dfs_init(struct cl_hw *cl_hw) +{ + struct cl_dfs_db *dfs_db = &cl_hw->dfs_db; + struct cl_tcv_conf *conf = cl_hw->conf; + + if (!cl_band_is_5g(cl_hw)) + return; + + dfs_db->en = conf->ci_ieee80211h; + + cl_hw->dfs_db.dbg_lvl = DBG_LVL_ERROR; + + /* + * Setting min window size to avoid the case where the second interrupt + * within the burst is setting the counter to 0. the max is between jiffies + * unit and max PRI in ms. + */ + dfs_db->max_interrupt_diff = max(1000 / HZ, 2); + + cl_dfs_set_region(cl_hw, cl_hw->channel_info.standard); + dfs_db->search_window = CL_DFS_PULSE_WINDOW; + + cl_dfs_set_min_pulse(cl_hw); + cl_dfs_tbl_overwrite_set(cl_hw); +} + +void cl_dfs_reinit(struct cl_hw *cl_hw) +{ + cl_dfs_init(cl_hw); +} + +void cl_dfs_recovery(struct cl_hw *cl_hw) +{ + /* Re-enable DFS after recovery */ + if (cl_dfs_is_in_cac(cl_hw)) { + cl_dfs_en(cl_hw, true); + + /* If recovery happened during CAC make sure to disable beacon backup */ + cl_tx_en(cl_hw, CL_TX_EN_DFS, false); + } +} + +static bool cl_radar_handler(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem, + unsigned long time) +{ + /* Retrieve the radar pulses structure */ + struct cl_radar_pulse_array *pulses = radar_elem->radarbuf_ptr; + + cl_dfs_pulse_process(cl_hw, (struct cl_radar_pulse *)pulses->pulse, pulses->cnt, time); + + return false; +} + +static void cl_radar_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct cl_radar_queue_elem *radar_elem = NULL; + unsigned long flags = 0; + bool radar_stat = false; + + while (!list_empty(&cl_hw->radar_queue.head)) { + spin_lock_irqsave(&cl_hw->radar_queue.lock, flags); + radar_elem = list_first_entry(&cl_hw->radar_queue.head, + struct cl_radar_queue_elem, list); + list_del(&radar_elem->list); + spin_unlock_irqrestore(&cl_hw->radar_queue.lock, flags); + + radar_stat = cl_radar_handler(radar_elem->cl_hw, &radar_elem->radar_elem, + radar_elem->time); + + kfree(radar_elem->radar_elem.radarbuf_ptr); + kfree(radar_elem); + } + + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + if (!radar_stat) + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.radar); +} + +void cl_radar_init(struct cl_hw *cl_hw) +{ + INIT_LIST_HEAD(&cl_hw->radar_queue.head); + + tasklet_init(&cl_hw->radar_tasklet, cl_radar_tasklet, (unsigned long)cl_hw); + + spin_lock_init(&cl_hw->radar_queue.lock); +} + +void cl_radar_push(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem) +{ + struct cl_radar_queue_elem *new_queue_elem = NULL; + u32 i; + + new_queue_elem = kmalloc(sizeof(*new_queue_elem), GFP_ATOMIC); + + if (new_queue_elem) { + new_queue_elem->radar_elem.radarbuf_ptr = + kmalloc(sizeof(*new_queue_elem->radar_elem.radarbuf_ptr), GFP_ATOMIC); + + if (new_queue_elem->radar_elem.radarbuf_ptr) { + new_queue_elem->radar_elem.dma_addr = radar_elem->dma_addr; + new_queue_elem->radar_elem.radarbuf_ptr->cnt = + radar_elem->radarbuf_ptr->cnt; + + /* Copy into local list */ + for (i = 0; i < RADAR_PULSE_MAX; i++) + new_queue_elem->radar_elem.radarbuf_ptr->pulse[i] = + radar_elem->radarbuf_ptr->pulse[i]; + + new_queue_elem->time = jiffies_to_msecs(jiffies); + new_queue_elem->cl_hw = cl_hw; + + spin_lock(&cl_hw->radar_queue.lock); + list_add_tail(&new_queue_elem->list, &cl_hw->radar_queue.head); + spin_unlock(&cl_hw->radar_queue.lock); + } else { + kfree(new_queue_elem); + } + } +} + +void cl_radar_tasklet_schedule(struct cl_hw *cl_hw) +{ + tasklet_schedule(&cl_hw->radar_tasklet); +} + +void cl_radar_flush(struct cl_hw *cl_hw) +{ + struct cl_radar_queue_elem *radar_elem = NULL; + unsigned long flags = 0; + + spin_lock_irqsave(&cl_hw->radar_queue.lock, flags); + + while (!list_empty(&cl_hw->radar_queue.head)) { + radar_elem = list_first_entry(&cl_hw->radar_queue.head, + struct cl_radar_queue_elem, list); + list_del(&radar_elem->list); + kfree(radar_elem->radar_elem.radarbuf_ptr); + kfree(radar_elem); + } + + spin_unlock_irqrestore(&cl_hw->radar_queue.lock, flags); +} + +void cl_radar_close(struct cl_hw *cl_hw) +{ + cl_radar_flush(cl_hw); + tasklet_kill(&cl_hw->radar_tasklet); +} + From patchwork Tue May 24 11:33:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576862 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 2F7ACC433FE for ; Tue, 24 May 2022 11:38:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236815AbiEXLib (ORCPT ); Tue, 24 May 2022 07:38:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236804AbiEXLiY (ORCPT ); Tue, 24 May 2022 07:38:24 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70041.outbound.protection.outlook.com [40.107.7.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56D0943382 for ; Tue, 24 May 2022 04:38:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XlhZbCQidTg2Gv9SlfndBBW6UoGqQMVlfjitFtevR1O4bmb6yZMKN2OYt9oUG4kxByMlVjTjbnKmT88MsFhnEgJB2q8QZI1H0kDsj1dzOPXfRRQa3iG3RbUU9jShkHuM9tmuDqxj8rIAXDzW8TTz802Vl9rMkrvA0imy7HVANdtaazmkXaXRlCaHJ2/c684lXQEDiacMxjbRcqawAFa7SHGrrHF8ang8fjJ1XEhpksv+OoKFj8OpTdXeYCN5w3w3O5mNBzxY5r5rK84izsvZmGIBTpl9sCMOJXRI4K4Djuct+lkLbePAyWsVK5FboasJR4LqUO06CVBvNCbSIYNLAg== 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=c3gmp2I8EFIRQV6cQXkdIAEWEsx6BvYYfAHOsMuDkDM=; b=LVjRBdWj/OrS/UjOH3jYKMu2uyEYe+wdMiRXrygqHZrgzV2oed5GVhrSRGUjSD9rm0byLQ55fGoXh0brSMGsa7mucr5LY04PdG1W26PyjvG3BoULNkAWdeby35RwEmqqN59oRgG9h53K/DR4uwqV2mOSYfVU7gFmx58Ib1VKTRD+LMTElpcqBkOOpSJeApnApEh2cOORPXyfT+L4jSk6zE9H91uqXyTFaTaI5PFRjXzXoW7bstYF0pWQ0DkSza4+W0sVJKTK7En530l4Ti0cWYl8Td0NQ456v7LPlxcmrd+nBcTKcC3CW0lPMKVxIaYn9S91XJVw/HsZ6m9BS7kFwQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=c3gmp2I8EFIRQV6cQXkdIAEWEsx6BvYYfAHOsMuDkDM=; b=sAcNIFLFfy4638abCIHd/i4G0hJsG33wZceYT9P9WXKusarMVxbLCOkDsknynGtpcCphV9b6SliaQlnMICZqqBrxxEuRTLBXzW1g9ZvQZqnOd0218MSVzGXELnUsZ6aHSZhwUatCtM0SYi/lgSCfD7uygZzoJsXXeCNZmEhXEzo= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:58 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:58 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 21/96] cl8k: add dfs.h Date: Tue, 24 May 2022 14:33:47 +0300 Message-Id: <20220524113502.1094459-22-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d6d5ea6e-b5fd-43aa-f066-08da3d79da18 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: S+5jgv8TJtncifOpmdgvLXj6fLeXU1wPD7O1zb1cR4Ka8tLX5zUyso6RyPmv/Q/4eHjJTz3vKMWrYtffAFct8Try1nEtAy2YABYyfnbcm0TtcfnpD0lbyKa1qgKpayXZ986T34iNFLlI601wce749ISMK4bAdnorHf6zD+//0qvaHK95KAKnU4FxaD11wsO/ENf/ywFsH3D9S7DWpAA6wbRyukm9IK7t6HzQ6qpiaKStAD2GMyliS5GUsynJDxCUupbdlL1azZ8IlH3dHngrgVfcLaXAOgE03IznUOSFzl7Nsi09RBzqK8ZjZP8OPRqNfuWKzCCjdi9hkeHb2eJVTiFBDpPeHTN0hEtMGOOhqK40BPpZh0FeXs/3GRPnM6IuLCr2pYyTqqy2p3OpnBT9PD6+vYx/NBQzrhSXUNTTMHzYmWTsIe0soCjRcttF60Lny1vQTzTjrcz2hJHPUoX0RLesc2dpeHRI/3q6mUlALgBkZ3F4/NsmmHmvv13hTwagEsbQ8ecrtzFxagpeJ7GgsIjzC6JUTGZTDVI9rTumHO6H3aS1ba39tpHjUh5C1PDVvpuBtc+ClPXp/LKrpKXek6bx69FqsaQV0rsRd5zKRjUPFdZ3Dx6iVnHAXLVoEf3TpxNWuoqFLvPfdZyGvq/19yap+8oPpWqQnrYynrUMLQ2chvUgFs/G8K8MZbm8QuJWR02VvkLHRKRyHxyzr2xHPHpdp6oLJKUevqs6E7Ob3UU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: wQCckivdpmDdbIrul31FQxd2ofRngLy1UB+13v23K6NCVb3gVyVPH49oo/MyzfAKvQ8ry/VU4TMNhlVnMw2IuF1pYqxng+1bFC/QqpWNEWAcv7wfHDFrs7dIm4YMWZ5MhuSBZIUa7/Jmwtq5J6FdidgaUA2WhOR6TI6PxhzCYMgLeChyZVZ3QmKmGeRl7Got3B0z/Ing74XrBaM18ytcHMVSkhCz8/GZkBr35FXIbFSQvR0d3+4okO1DBdEZNzu+e2NYcoy31yXsgkrH+R2qQ345bu27i169G2jeC4Ujy7ZNSOh+7AyuGwGSuTsS5n8NJrK2GDueTnO6OAvRPSWP9fy2WbMTy1P0UYCV0Lz/Vr/XoT6pHXqmw55PoZpe6MZArOyMfpPNmNvvOpP1memTrjyc21j6Vf8ew0fWom1ems1fRC6LmuiwJQ2h2OKcQ3cWgpmZX7y3tAFgW5E040LjVOuNVrhIqy8gARAVH0eYh6q+k57hIHSV1RNQxmuvvQ784ZP/yICzuBfdN75ugZfXC72v2LzvrapuBNFqJzUh+HMvffPc1BEAdxjYU6UIG1aWsBwd8/HJTturW1PBSAgPaqGBtKFrYDVaDM4QsZQQqMmsWEToDkKYEJq9eDPXID5KMKnvqUHQyPS+tAIyzS/6edl9hx/VsmWSpYTQAzcW/1vczPxMEdQgDkeDkFL2CgrwXsPWk2sfKR+8DxHXEFXifrlXthpQKo3L/NloUBYdi7vqaua+tCUqgoivoL2Lnkrxk/zb8k/nvkd7sSLjwGFH1Mua2o3YHsjsRCdulQXNNu4LR6jU1AKA1hoH1xlIdyy5UUejBLtfEPNuHnFnyof3z0ojEi0E7vXOVWgis4wpA5ZoeI0VkOYEKOV9Xc/9SB3DdCODjDM9e86EgvmcYhjPMN9lMFCMLMPzTnU8P090qdx3SE9USXrErCnApbJ9AvNy3HFjwrZAAQUipEkBQM5TyobWXEgeoip0vbNZZEIrUzmap8W2vMIK1EthY1M8MKqvJ6S+MeXnWYkMLEAVHQParUJsaqvoJ16bF4goYojJfkPM9UlqaEfgOXSue68HIbYpS0rW/q8BFs1JP0iTw3WY49PbB1O2KTYmxArGUZKG+G9AXzpLQMoSGhOS65ctnDRSkmVhfZxOA+JpJeGw4EJquzJQcJ+7dzYpojKlZM9XmHJ7PSbTRt2zMT4ItybpdN64H8bhi9H54lIBP58FUIu/PQHWY/AV3gaeefvBq41ShLkLo8b8+qVFP2FefSyEj9UQpv1/pgGMbKO85lBrwXqP1YC4fGPioVumVFgI2q59fa8KwyWpOdBaQMWi/+7FBAokYRtQn769aMNLAORQ5qtYVraM3JJRo4Gqe9bhhnkADU9XYH6wZb5p56Gi6wsbFTA/NQs73ItUDYII4LqjDhSED1HLvuzwejq4VEc9qpHorXyGjUYQblr7qTqVoolUaORIUAHgYiRGQXTi2SI6hNMiy3LlnojOjFcTHKJXtMQuy2BD/7WFb2nfJVfSGCH5Y0KNztbBwI8CvA/NB6FVqZmg0cPbRjGW26eZ+ey5FNAdhkRppqVQ8rBinxqkpQmGRwapHbhjToy2izT3esviKFkFdL174B4fx72Y7b8zDJoPk2pn8RdLrrDRQt9QDvfphw3OGWmFSS/RVUhxRjb0MGm8TZt9Za/xTxB5f/rWLgNrjmguLqgcDCFTVYTGbca13iqbwCYIZaHV4KNAIq0mLDNnzY0tHnPZAjyjJaEId6WF1Uk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d6d5ea6e-b5fd-43aa-f066-08da3d79da18 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:58.7157 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: QyTi2fZVZ9NHhjQvg+I5zQnr5RONMe1XLXLqGcnFy4mmqrguvs3+YwItycA5AsLvur3D7+PeC17BXZLL4YvYbw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/dfs.h | 146 +++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/dfs.h diff --git a/drivers/net/wireless/celeno/cl8k/dfs.h b/drivers/net/wireless/celeno/cl8k/dfs.h new file mode 100644 index 000000000000..a252844f854b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/dfs.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_DFS_H +#define CL_DFS_H + +#include +#include + +#include "debug.h" + +#define CL_DFS_MAX_TBL_LINE 11 /* Radar Table Max Line */ +#define CL_DFS_PULSE_BUF_SIZE 64 /* Radar Pulse buffer size */ +#define CL_DFS_PULSE_BUF_MASK 0x03F /* Radar Pulse buffer cyclic mask */ +#define CL_DFS_PULSE_WINDOW 100 /* Radar Pulse search window [ms] */ +#define CL_DFS_MIN_PULSE_TRIG 1 /* Minimum Pulse trigger num */ +#define CL_DFS_LONG_MIN_WIDTH 20 /* Min Long Pulse Width */ +#define CL_DFS_LONG_FALSE_WIDTH 10 /* Low width signals indicates of false detections */ +#define CL_DFS_LONG_FALSE_IND 6 /* False indication while searching for long sequence */ +#define CL_DFS_STAGGERED_CHEC_LEN 4 /* Staggered check length */ +#define CL_DFS_CONCEAL_CNT 10 /* Maximum concealed pulses search */ +#define CL_DFS_MIN_FREQ 5250 /* Min DFS frequency */ +#define CL_DFS_MAX_FREQ 5725 /* Max DFS frequency */ + +enum cl_radar_waveform { + RADAR_WAVEFORM_SHORT, + RADAR_WAVEFORM_LONG, + RADAR_WAVEFORM_STAGGERED, + RADAR_WAVEFORM_SEVERE +}; + +struct cl_radar_type { + u8 id; + s32 min_width; + s32 max_width; + s32 tol_width; + s32 min_pri; + s32 max_pri; + s32 tol_pri; + s32 tol_freq; + u8 min_burst; + u8 ppb; + u8 trig_count; + enum cl_radar_waveform waveform; +}; + +/* Number of pulses in a radar event structure */ +#define RADAR_PULSE_MAX 4 + +/* + * Structure used to store information regarding + * E2A radar events in the driver + */ +struct cl_radar_elem { + struct cl_radar_pulse_array *radarbuf_ptr; + dma_addr_t dma_addr; +}; + +/* Bit mapping inside a radar pulse element */ +struct cl_radar_pulse { + u64 freq : 8; + u64 fom : 8; + u64 len : 8; /* Pulse length timer */ + u64 measure_cnt : 2; /* Measure count */ + u64 rsv1 : 6; /* Reserve1 */ + u64 rep : 16; /* PRI */ + u64 rsv2 : 16; /* Reserve2 */ +}; + +/* Definition of an array of radar pulses */ +struct cl_radar_pulse_array { + /* Buffer containing the radar pulses */ + u64 pulse[RADAR_PULSE_MAX]; + /* Number of valid pulses in the buffer */ + u32 cnt; +}; + +struct cl_radar_queue_elem { + struct list_head list; + struct cl_hw *cl_hw; + struct cl_radar_elem radar_elem; + unsigned long time; +}; + +struct cl_radar_queue { + struct list_head head; + spinlock_t lock; +}; + +struct cl_dfs_pulse { + s32 freq : 8; /* Radar Frequency offset [units of 4MHz] */ + u32 fom : 8; /* Figure of Merit */ + u32 width : 8; /* Pulse Width [units of 2 micro sec] */ + u32 occ : 1; /* OCC indication for Primary/Secondary channel */ + u32 res1 : 7; /* Reserve */ + u32 pri : 16; /* Pulse Repetition Frequency */ + u32 res2 : 16; + unsigned long time; /* Pulse Receive Time */ +}; + +struct cl_dfs_db { + bool en; + enum cl_dbg_level dbg_lvl; + enum nl80211_dfs_regions dfs_standard; + struct { + bool started; + bool requested; + } cac; + u8 long_pulse_count; + u32 last_long_pulse_ts; + u8 short_pulse_count; + u8 long_pri_match_count; + u8 min_pulse_eeq; + u8 buf_idx; + u8 radar_type_cnt; + u16 search_window; + u16 max_interrupt_diff; + u16 remain_cac_time; + u32 pulse_cnt; + struct cl_radar_type *radar_type; + struct cl_dfs_pulse dfs_pulse[CL_DFS_PULSE_BUF_SIZE]; + struct cl_dfs_pulse pulse_buffer[CL_DFS_PULSE_BUF_SIZE]; +}; + +void cl_dfs_init(struct cl_hw *cl_hw); +void cl_dfs_reinit(struct cl_hw *cl_hw); +void cl_dfs_start(struct cl_hw *cl_hw); +void cl_dfs_recovery(struct cl_hw *cl_hw); +bool cl_dfs_pulse_process(struct cl_hw *cl_hw, struct cl_radar_pulse *pulse, u8 pulse_cnt, + unsigned long time); +bool __must_check cl_dfs_is_in_cac(struct cl_hw *cl_hw); +bool __must_check cl_dfs_requested_cac(struct cl_hw *cl_hw); +bool __must_check cl_dfs_radar_listening(struct cl_hw *cl_hw); +void cl_dfs_request_cac(struct cl_hw *cl_hw, bool should_do); +void cl_dfs_force_cac_start(struct cl_hw *cl_hw); +void cl_dfs_force_cac_end(struct cl_hw *cl_hw); +void cl_dfs_radar_listen_start(struct cl_hw *cl_hw); +void cl_dfs_radar_listen_end(struct cl_hw *cl_hw); + +void cl_radar_init(struct cl_hw *cl_hw); +void cl_radar_push(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem); +void cl_radar_tasklet_schedule(struct cl_hw *cl_hw); +void cl_radar_flush(struct cl_hw *cl_hw); +void cl_radar_close(struct cl_hw *cl_hw); + +#endif /* CL_DFS_H */ From patchwork Tue May 24 11:33:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575980 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 21CAFC433FE for ; Tue, 24 May 2022 11:38:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236809AbiEXLie (ORCPT ); Tue, 24 May 2022 07:38:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiEXLid (ORCPT ); Tue, 24 May 2022 07:38:33 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 950AA4AE15 for ; Tue, 24 May 2022 04:38:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Zj4GM5jIa55p6Dh6+hWfpST8Sz2/8qpxlYdd+bkxzeypxoWyNbMPvXJGTkV3wh0nU/ePCRtEaASGz6YxUUYbvDkupGdZnV7vMlItZWdPBWNtk/5WEKeBII81QPh9PzAJ2Rfzrs7iJHBSYNxSaQQ96vI89vTW5VFQ+TbvB/274kMk3maizkzmjPTCTnDuuMQLPtbeC1koSpBVMJtxDt8V5TMy3LtjS+zda+0aWPLhQMfidt/ftUGejiefk2ZsfPvWjuP/fcOmLTbCULeGrwJq40W6W8CTFnZ9NrvTR/gHV0fcb9m2CJlvq5K7a291QtWCF+MxLD1QK9Vu/oLFQp7piA== 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=f7owtQBxsysZXPucQNcHSWkqO6F18itCYViwPFZa3PI=; b=UcRwfwRxy4GM35f1KWVLBga+FiwQub+ZhiAB+SGMd+1QE6S0LxhbT54PcpeYsclC1xeso9avTXO5qfHZ8szD29GTOgnXKNq02POexxZ5de+o+K+NnfksLjfFP6MX0NPJzzXxgDmk0o1+QF0JZge92QqtVV5vOCHDWV0fA+TCRifOTctj0w9ei+SCDFKyUcXvZKAH58HfAIdV9whR3mCVqPbl1FMOoHAQnFvkA8Vb+xpXliNbT7Wz68ZjQokxDyM/9T6mxeGdRMMltYVo0A0owR6HuhAC/g6L1thQAEHp4Zu0qLSGUfb/3gLNvgDONsqAeZxSZqRPQW73cUSBZJu2fA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=f7owtQBxsysZXPucQNcHSWkqO6F18itCYViwPFZa3PI=; b=JfBDoqajLmhydrOp9i1YKw9IV/HpovhiyueB0xpjD6PT+IjWU3ESQytyVvJ1ql2YI9AnLU9DPZMcTCGyYIxC4bgwvCDf3xv0rGLnOtZaIE8VokfuFeEXW94PDIH1gXyMekYhyvs+bMz6MaY8XzhwfBUo7SHgzrDRtq4gUuvAE3I= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:37:59 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:37:59 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 22/96] cl8k: add dsp.c Date: Tue, 24 May 2022 14:33:48 +0300 Message-Id: <20220524113502.1094459-23-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9e154caa-1dc3-40a3-a216-08da3d79da86 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 12eVieqGCSPQAboHsf/D55dBoWhbkJRwyu5GoQymhFFJz5jhwIIXAXFEq3pgZ5NFpxH6UsoBvihZq7l/bqNS101UjrKm25hyYpkGvShh67YtuZeVRXWQiop8Aq8fR+6DnpK30tGbVzIGhmmSHIG0ujHZ8g0ZJbyTCfbFCPRsWkRJsTkOVj2lIQLVUbhevoKja8Te6J9wtv1N1OGJaVSp221CawnliP3ZwNCPQ9fusD7K5rm81pGWEFtAxVwEdKtFYlDZWU6AS811PXE0KGld+adp7O7u0LiDK103B48/SktxYofIcVfX/AnyZSbxRneMY1kvkYKlm9JcXtdxzDm4RrOI8suoMzPN9/djc0HV9g2APmxX/E8doO7TsT3LnPBPzKRRAN+qIoacvwyyCsdRtaA2iLfa0DIq+bMpeudKps1FguS66YXoZ857L3ox+9O9BPFYL/H/DjE4lrdaDqBpPLi7aUupb+/LUew3oETny/ArBBDb2duxhz4vGeD4v+pxzMbfJZfzf8NRsGmAjt9uGDBXqzD+eVw1v0D5n4ZZ+spOwTLtmdU0KQ3uC6ia49bwtYCESdOGRo2wR2QqW2JFQN0Lwhs/7sszDeLoweZ8rVwParIxAe76m2wDAwODtUxT/8vS6hBPoW3RsQk3jWsMysQH9ziu5iJnklYP7cqXz0OlDfrl3QBONP6j4tIJJ6S7MsvUN0h0IvqWLkgvd2j7u+Nl66hOhpJpE7W1FZud+kM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: g1J3a2HgVcrAnAM63Ilj8a/HaHKL1ITOm++Ou99lQHrPs9Qo1J0a2x+HGrL1GmwVSTb2tt0oXFkQm4NKJtaQSuSnwaq3OTP8g/00TwgcoAJrfD/2reorpT/bhsT6dny14NgMqCBRchT6OX0Vfw2qu4eDgMc4sfIEfxNVoRZd2lQ6qkSsfx48mNjUwC0FB/GvXTV9BzkjdsZP7NmOOvwHQcPnrkqcuJgdNC1PmbrOcp4aAapdwCeyFmYO4nYtPZA6UFqoRmH351Bm6IwU8+eVWS2JWQM4yutXMS+LUyCI/YXx7UOmYTVib+hXL9hrjvV2gfX37/miT3j/Q1etuD5TnislDpuZA3GqE7DVamGiRORoEJXvycGSv/OaVCDTmpD4vfhTA6/4XSX1HqgllIvJ1YonVLrRPiozD6ZP4hdFk17PkVo2SL5n8+8shOV099hevnKbP9gAGHRxz7ERTzU5KALMFhZ/cwaqEethYX12rSJUDCiM8FzJKNg81KazPzxptZx4n9qgLR7yclc8YoaBLL90/RwxYnfIEvFAElDe/PV/jey5byrCSbW36CJmd2D43luHH96Nz3O4bWeNxfcugsoYBX2Y+LC4+wroObD+N2GYkhx9ETkFL34bg+ESjfwHUP5RjCd01qcHUfGpSSj7NM+nAuk8TAfS1SKvEHxicr2EtYVTDIMpBmy5T4VIRSixb5BMhA6FJzYtPiZtTRlBNXouFAoLH8PrIsTfWCGTEI53Gzi5JEw8EuXax/EWSEe21UoU08iFKdRjj5AyysTi1ak4jj6WsMrRK8JFfHyoPUE6Lok0rtHhyZijZdpILEK5HAdkhw4mAQ87rfP3iP+KJlQRWuIH7v6sKgEBqXh7Ux7Yn+GvlMhILM7fCOJA9aRE0AR9zqBTwG9srAMdfwjaB1NcWakfoA5fSeuOJOjkCJBWUoGjPQY0LSK9GvXdvhLJ4fHwzuHkm9g1RtJh0yZ+pURQl8Qz4c2szDBov25i+XBqpW7CxugmOo99x4VSmnGglqUa3Sb70/54mgSP48FCERgaWm35awJ/AWr8XYfgMNXveizwO23Q3gkvFKDbnmgQQuIZvToIBsG4Q0dvCf5Tq6Z8BKGAUkjal4vGVFCzLUpQHOgMwwn430+bbTmXbzKS32mG57/mRLvep4HlZaHUkbd8mN5CNvp0tqLbICC8PfAVjWTSEpVt7SSgPZ2lpGkxBL82znlIwCJIQ51Qcrh9Dk18F4AGTXn6G0uwwBg9qUmn5MCzLf5AqJ2kbwuAWJjdDEm4QupRPJbF6QQ/HfRGh6DyZ5R66Gbxw656U3asFH52S6DkEfVQY1gprdQR9kWg/k9W36mkYMgf5jiNKIx88nmJTGHJCWvbJ0wCW95KvdoAiatzTIov3iEOWg1kUmzG7NffVBtTlajQk/7LJ/akmopDlPKfSezN4hbNnBSta/6Kjvfy6XrKNvUX6aHr5XnmmpJQYiGbBfoqZxZ93BTO80PTBLNsEhNFGQC/+ZfM7Mk3g+JaAAzhDTMbzkPJT9mFPqysvKzQxaKMvXLILf9TWOnPSHEL1VQkRtNIPidepT6mhg6ba5wOophjZwP8gF9HaZBAAErl9c/KT7twHnWpWnHR7QJEINPXNeN5rChOmckWR1zdZwRzkox6j8/NaIrV0HXfxSgmr2jF7rhk4BF1gJ+FM8vGiH05ayMs553qwxCNkst0lwcj1wnVLIWibQ0R3jjIoCMO5rVsbsOAb6KTVjAkQrN3U6LFqzIdZPRvrr0= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9e154caa-1dc3-40a3-a216-08da3d79da86 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:37:59.4345 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: I0J51Ll5LuOaStSGV+Cymy3gpjBGEBevNVK0p3IlB6KcdEPQmYCguV922W3hVkw1iwEANAzH8t1VhQGg4vER0g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/dsp.c | 627 +++++++++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/dsp.c diff --git a/drivers/net/wireless/celeno/cl8k/dsp.c b/drivers/net/wireless/celeno/cl8k/dsp.c new file mode 100644 index 000000000000..fbc8b29b9257 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/dsp.c @@ -0,0 +1,627 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "dsp.h" +#include "hw.h" + +#define BUSY_WAIT_LIMIT 10000 + +static int cl_dsp_busy_wait(struct cl_hw *cl_hw, u32 control_reg) +{ + int i; + + for (i = 0; i < BUSY_WAIT_LIMIT; i++) { + /* Poll Bit29 to verify DMA transfer has ended. */ + if ((cl_reg_read(cl_hw, control_reg) & 0x20000000) == 0) + return 0; + + cpu_relax(); + } + + return -EIO; +} + +static void cl_dsp_boot(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_hw_is_tcv0(cl_hw)) { + /* Disable ceva_free_clk */ + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 0); + /* Assert Ceva reset */ + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 0); + } else { + /* Disable ceva_free_clk */ + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 0); + /* Assert Ceva reset */ + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 0); + } + + /* Set Ceva boot=1 */ + modem_gcu_ceva_ctrl_boot_setf(cl_hw, 1); + /* Set Ceva vector */ + modem_gcu_ceva_vec_set(cl_hw, 0); + + if (cl_hw_is_tcv0(cl_hw)) { + /* Enable ceva_clk */ + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 1); + /* Disabel ceva_clk */ + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 0); + /* De-Assert Ceva reset - Reset Release */ + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 1); + /* Enable ceva_clk */ + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 1); + } else { + /* Enable ceva_clk */ + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 1); + /* Disabel ceva_clk */ + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 0); + /* De-Assert Ceva reset - Reset Release */ + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 1); + /* Enable ceva_clk */ + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 1); + } + + /* Release Ceva external_wait */ + modem_gcu_ceva_ctrl_external_wait_setf(cl_hw, 0); + /* Set Ceva boot=0 */ + modem_gcu_ceva_ctrl_boot_setf(cl_hw, 0); +} + +static void cl_dsp_config_dma_for_code_copy(struct cl_hw *cl_hw, u32 page, u32 page_size) +{ + /* Configure Program DMA to copy FW code from Shared PMEM to internal PMEM. */ + + /* External address to read from. */ + cl_reg_write(cl_hw, CEVA_CPM_PDEA_REG, CEVA_SHARED_PMEM_BASE_ADDR_INTERNAL); + /* Internal address to write to. */ + cl_reg_write(cl_hw, CEVA_CPM_PDIA_REG, CEVA_SHARED_PMEM_SIZE * page); + /* Page size */ + cl_reg_write(cl_hw, CEVA_CPM_PDTC_REG, page_size); +} + +static void cl_dsp_config_dma_for_external_data_copy(struct cl_hw *cl_hw) +{ + /* Configure Program DMA to copy FW code from Shared XMEM to internal XMEM. */ + + /* External address to read from. */ + cl_reg_write(cl_hw, CEVA_CPM_DDEA_REG, CEVA_SHARED_XMEM_BASE_ADDR_INTERNAL); + /* Internal address to write to. */ + cl_reg_write(cl_hw, CEVA_CPM_DDIA_REG, 0); + /* Page size + DMA direction is write */ + cl_reg_write(cl_hw, CEVA_CPM_DDTC_REG, + CEVA_SHARED_XMEM_SIZE | CEVA_CPM_DDTC_WRITE_COMMAND); +} + +static int cl_dsp_hex_load(struct cl_hw *cl_hw, const u8 *buf, + off_t offset, size_t size, size_t buf_size) +{ + u8 single_buf[4] = {0}; + u32 bin_data = 0; + u8 next_byte; + u8 byte_num = 0; + int ret = 0; + ssize_t oft = 0; + size_t real_size = min(size * 3, buf_size); + /* + * CEVA_SHARED_PMEM_BASE_ADDR_FROM_HOST is global and we don't + * want to add TCV reg offset. + */ + bool chip_reg = (offset == CEVA_SHARED_PMEM_BASE_ADDR_FROM_HOST); + + if (buf_size % 3) { + cl_dbg_err(cl_hw, "DSP size %zu must be divided by 3 !!!\n", + buf_size); + return -EINVAL; + } + + while (oft < real_size) { + memcpy(single_buf, buf + oft, 3); + /* Each line contains 2 hex digits + a line feed, i.e. 3 bytes */ + ret = kstrtou8(single_buf, 16, &next_byte); + if (ret < 0) { + cl_dbg_err(cl_hw, + "ret = %d, oft = %zu," + "single_buf = 0x%x 0x%x 0x%x 0x%x\n", + ret, oft, single_buf[0], single_buf[1], + single_buf[2], single_buf[3]); + return ret; + } + + /* Little-endian order. */ + bin_data += next_byte << (8 * byte_num); + byte_num = (byte_num + 1) % 4; + + /* Read 4 lines from the file, and then write. */ + if (byte_num == 0) { + if (chip_reg) + cl_reg_write_chip(cl_hw->chip, offset, bin_data); + else + cl_reg_write_direct(cl_hw, offset, bin_data); + offset += 4; + bin_data = 0; + } + + memset(&single_buf, 0, sizeof(single_buf)); + oft += 3; + } + + return 0; +} + +static int cl_dsp_load_code(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + u32 real_size; + u32 page; + u32 page_size = CEVA_SHARED_PMEM_SIZE; + const struct firmware *fw; + size_t size = 0; + u8 *buf = NULL; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", + cl_hw->conf->ce_dsp_code); + + cl_dbg_verbose(cl_hw, "from %s\n", cl_hw->conf->ce_dsp_code); + + ret = request_firmware(&fw, path_name, chip->dev); + + if (ret) { + cl_dbg_err(cl_hw, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + buf = (u8 *)fw->data; + + /* Load all pages + 1 extra cache page */ + for (page = 0; page < CEVA_MAX_PAGES + 1; page++) { + if (page >= CEVA_MAX_PAGES) + page_size = CEVA_SHARED_PMEM_CACHE_SIZE; + + real_size = min_t(u32, page_size * 3, size); + + if (!real_size) + break; + + /* Copy DSP code (one page each time) */ + ret = cl_dsp_hex_load(cl_hw, buf, + CEVA_SHARED_PMEM_BASE_ADDR_FROM_HOST, + page_size, size); + if (ret != 0) { + cl_dbg_err(cl_hw, "Failed to load pmem page 0x%x!\n", page); + break; + } + + cl_dsp_config_dma_for_code_copy(cl_hw, page, page_size); + ret = cl_dsp_busy_wait(cl_hw, CEVA_CPM_PDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw, "cl_dsp_busy_wait failed!\n"); + goto out; + } + + buf += real_size; + size -= real_size; + } + +out: + release_firmware(fw); + + return ret; +} + +static int cl_dsp_load_data(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + const struct firmware *fw; + size_t size = 0; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", + cl_hw->conf->ce_dsp_data); + + cl_dbg_verbose(cl_hw, "from %s\n", cl_hw->conf->ce_dsp_data); + + ret = request_firmware(&fw, path_name, chip->dev); + if (ret) { + cl_dbg_err(cl_hw, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + + ret = cl_dsp_hex_load(cl_hw, fw->data, REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_DATA_SIZE, size); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load HEX file\n"); + goto out; + } +out: + release_firmware(fw); + + return ret; +} + +static int cl_dsp_load_external_data(struct cl_hw *cl_hw) +{ + /* + * Shared XMEM is not accessible by host. + * Copy the XMEM section to DRAM first and then use CEVA internal DMA to copy to + * SHARED XMEM. + */ + struct cl_chip *chip = cl_hw->chip; + const struct firmware *fw; + size_t size = 0; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", + cl_hw->conf->ce_dsp_external_data); + + cl_dbg_verbose(cl_hw, "from %s\n", cl_hw->conf->ce_dsp_external_data); + + ret = request_firmware(&fw, path_name, chip->dev); + if (ret) { + cl_dbg_err(cl_hw, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + + ret = cl_dsp_hex_load(cl_hw, fw->data, REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_EXT_DATA_SIZE, size); + + if (ret) { + cl_dbg_err(cl_hw, "Failed to load HEX file\n"); + goto out; + } + + cl_dsp_config_dma_for_external_data_copy(cl_hw); + ret = cl_dsp_busy_wait(cl_hw, CEVA_CPM_DDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw, "cl_dsp_busy_wait failed!\n"); + goto out; + } + +out: + release_firmware(fw); + + return ret; +} + +static bool cl_dsp_is_universal_file(struct cl_chip *chip) +{ + return (cl_chip_is_tcv0_enabled(chip) && + cl_chip_is_tcv1_enabled(chip) && + !strcmp(chip->cl_hw_tcv0->conf->ce_dsp_code, + chip->cl_hw_tcv1->conf->ce_dsp_code)); +} + +static int cl_dsp_load_code_dual(struct cl_chip *chip, const char *filename) +{ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + u32 real_size; + u32 page; + u32 page_size = CEVA_SHARED_PMEM_SIZE; + const struct firmware *fw; + size_t size = 0; + u8 *buf = NULL; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", filename); + cl_dbg_chip_verbose(chip, "from %s\n", filename); + ret = request_firmware(&fw, path_name, chip->dev); + + if (ret) { + cl_dbg_chip_err(chip, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + buf = (u8 *)fw->data; + + /* Load all pages + 1 extra cache page */ + for (page = 0; page < CEVA_MAX_PAGES + 1; page++) { + if (page >= CEVA_MAX_PAGES) + page_size = CEVA_SHARED_PMEM_CACHE_SIZE; + + real_size = min_t(u32, page_size * 3, size); + + if (!real_size) + break; + + /* Copy DSP code (one page each time) */ + ret = cl_dsp_hex_load(chip->cl_hw_tcv0, buf, + CEVA_SHARED_PMEM_BASE_ADDR_FROM_HOST, + page_size, size); + if (ret) { + cl_dbg_chip_err(chip, "Failed to load pmem page 0x%x!\n", page); + break; + } + + cl_dsp_config_dma_for_code_copy(cl_hw_tcv0, page, page_size); + ret = cl_dsp_busy_wait(cl_hw_tcv0, CEVA_CPM_PDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw_tcv0, "cl_dsp_busy_wait failed\n"); + goto out; + } + + cl_dsp_config_dma_for_code_copy(cl_hw_tcv1, page, page_size); + ret = cl_dsp_busy_wait(cl_hw_tcv1, CEVA_CPM_PDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw_tcv1, "cl_dsp_busy_wait failed\n"); + goto out; + } + + buf += real_size; + size -= real_size; + } + +out: + release_firmware(fw); + + return ret; +} + +static int cl_dsp_load_external_data_dual(struct cl_chip *chip, const char *filename) +{ + /* + * Shared XMEM is not accessible by host. + * Copy the XMEM section to DRAM first and then use CEVA internal DMA to copy to + * SHARED XMEM. + */ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + const struct firmware *fw; + size_t size = 0; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", filename); + cl_dbg_chip_verbose(chip, "from %s\n", filename); + ret = request_firmware(&fw, path_name, chip->dev); + + if (ret) { + cl_dbg_chip_err(chip, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + + /* TCV0 */ + ret = cl_dsp_hex_load(cl_hw_tcv0, fw->data, REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_EXT_DATA_SIZE, size); + + if (ret) { + cl_dbg_err(cl_hw_tcv0, "Failed to load HEX file\n"); + goto out; + } + + cl_dsp_config_dma_for_external_data_copy(cl_hw_tcv0); + ret = cl_dsp_busy_wait(cl_hw_tcv0, CEVA_CPM_DDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw_tcv0, "dsp_busy_wait failed!\n"); + goto out; + } + + /* TCV1 */ + ret = cl_dsp_hex_load(cl_hw_tcv1, fw->data, REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_EXT_DATA_SIZE, size); + + if (ret) { + cl_dbg_err(cl_hw_tcv1, "Failed to load HEX file\n"); + goto out; + } + + cl_dsp_config_dma_for_external_data_copy(cl_hw_tcv1); + ret = cl_dsp_busy_wait(cl_hw_tcv1, CEVA_CPM_DDTC_REG); + + if (ret) { + cl_dbg_err(cl_hw_tcv1, "cl_dsp_busy_wait failed!\n"); + goto out; + } + +out: + release_firmware(fw); + + return ret; +} + +static int cl_dsp_load_data_dual(struct cl_chip *chip, const char *filename) +{ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + const struct firmware *fw; + size_t size = 0; + char path_name[CL_PATH_MAX] = {0}; + int ret; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", filename); + cl_dbg_chip_verbose(chip, "from %s\n", filename); + ret = request_firmware(&fw, path_name, chip->dev); + + if (ret) { + cl_dbg_chip_err(chip, "Failed to get %s, with error: %x!\n", + path_name, ret); + goto out; + } + + size = fw->size; + + ret = cl_dsp_hex_load(cl_hw_tcv0, fw->data, + REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_DATA_SIZE, size); + + if (ret != 0) { + cl_dbg_err(cl_hw_tcv0, "Failed to load HEX file\n"); + goto out; + } + + ret = cl_dsp_hex_load(cl_hw_tcv1, fw->data, + REG_MACDSP_API_BASE_ADDR, + CEVA_DSP_DATA_SIZE, size); + + if (ret != 0) { + cl_dbg_err(cl_hw_tcv1, "Failed to load HEX file\n"); + goto out; + } + +out: + release_firmware(fw); + + return ret; +} + +static void cl_dsp_print_ceva_core_info(struct cl_hw *cl_hw) +{ + cl_dbg_trace(cl_hw, "CEVA_CORE_VERSION_ADDR=0x%X.\n", + cl_reg_read(cl_hw, CEVA_CORE_VERSION_ADDR)); + cl_dbg_trace(cl_hw, "CEVA_CORE_ID_ADDR=0x%X.\n", + cl_reg_read(cl_hw, CEVA_CORE_ID_ADDR)); +} + +static int cl_dsp_load_dual(struct cl_chip *chip) +{ + int ret = 0; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + struct cl_tcv_conf *tcv0_conf = cl_hw_tcv0->conf; + + modem_gcu_ceva_ctrl_external_wait_setf(cl_hw_tcv0, 0x1); + modem_gcu_ceva_ctrl_external_wait_setf(cl_hw_tcv1, 0x1); + + cl_dsp_print_ceva_core_info(cl_hw_tcv0); + cl_dsp_print_ceva_core_info(cl_hw_tcv1); + + ret = cl_dsp_load_code_dual(chip, tcv0_conf->ce_dsp_code); + if (ret != 0) { + cl_dbg_chip_err(chip, + "Failed to load DSP code. Error code %d.\n", + ret); + return ret; + } + + ret = cl_dsp_load_external_data_dual(chip, tcv0_conf->ce_dsp_external_data); + if (ret != 0) { + cl_dbg_chip_err(chip, + "Failed to load DSP external data. Error code %d.\n", + ret); + return ret; + } + + ret = cl_dsp_load_data_dual(chip, tcv0_conf->ce_dsp_data); + if (ret != 0) { + cl_dbg_chip_err(chip, + "Failed to load DSP data. Error code %d.\n", + ret); + return ret; + } + + macdsp_api_config_space_set(cl_hw_tcv0, 0); + /* Release DSP wait. */ + cl_dsp_boot(cl_hw_tcv0); + + macdsp_api_config_space_set(cl_hw_tcv1, 0); + /* Release DSP wait. */ + cl_dsp_boot(cl_hw_tcv1); + + return ret; +} + +static int _cl_dsp_load(struct cl_hw *cl_hw) +{ + int ret = 0; + + modem_gcu_ceva_ctrl_external_wait_setf(cl_hw, 0x1); + cl_dsp_print_ceva_core_info(cl_hw); + + ret = cl_dsp_load_code(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load DSP code %d\n", ret); + return ret; + } + + ret = cl_dsp_load_external_data(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load DSP external data %d\n", ret); + return ret; + } + + ret = cl_dsp_load_data(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load DSP data %d\n", ret); + return ret; + } + + macdsp_api_config_space_set(cl_hw, 0); + /* Release DSP wait */ + cl_dsp_boot(cl_hw); + + return ret; +} + +int cl_dsp_load_regular(struct cl_chip *chip) +{ + int ret = 0; + + if (cl_dsp_is_universal_file(chip)) + return cl_dsp_load_dual(chip); + + if (cl_chip_is_tcv0_enabled(chip)) { + ret = _cl_dsp_load(chip->cl_hw_tcv0); + if (ret) + return ret; + } + + if (cl_chip_is_tcv1_enabled(chip)) { + ret = _cl_dsp_load(chip->cl_hw_tcv1); + if (ret) + return ret; + } + + return ret; +} + +int cl_dsp_load_recovery(struct cl_hw *cl_hw) +{ + int ret = 0; + + modem_gcu_ceva_ctrl_external_wait_setf(cl_hw, 0x1); + + ret = cl_dsp_load_external_data(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load DSP external data %d\n", ret); + return ret; + } + + ret = cl_dsp_load_data(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "Failed to load DSP data %d\n", ret); + return ret; + } + + macdsp_api_config_space_set(cl_hw, 0); + /* Release DSP wait. */ + cl_dsp_boot(cl_hw); + + return ret; +} From patchwork Tue May 24 11:33:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575979 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 2D350C433EF for ; Tue, 24 May 2022 11:38:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236811AbiEXLii (ORCPT ); Tue, 24 May 2022 07:38:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235569AbiEXLie (ORCPT ); Tue, 24 May 2022 07:38:34 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70052.outbound.protection.outlook.com [40.107.7.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F2758CCF2 for ; Tue, 24 May 2022 04:38:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eBG6cYLDHigOjaBNUi2HdoeFoX/FwtVFbGfctYO+NndpNZ6A7bp/bAjxFyAnYVaT+mciB58PVji5o0XpUHr1K5+DdCDBcrNpMa3ImDYsjpqUhquDQvrB7CEvlxqnfPZ6lOAVvq0ug3m5VvGw2p3qYWbbbp2OT6liJI6GwCcVNhS1NUlMUwKDpAgltW5MQqKTnH5Bva1nMN1XxNfPb+pBhveHRUHZnsO5wvYfG3psBqtx4VDI9KoedJ8ijxp0SkIgAMVTqIA6npiS19Fc8nxgrUP+3Sd3diXo3Y6qXidAZLB/2D6SRcD33WGq4iHgCGBKZtvdnjYh5fbfTJqq7Z8hZw== 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=WAuHuTD9exojMeoaBmIf6+CD7o/d9qZ39+eHWH6bNJs=; b=GTzEBWdPF9jDQEgaOv5YKQfmV99a6IJppbCRHcPrcE3p2L7Jn2Zuug5tAXq9MY3FjHZ3kBrjz7xRH1Wz1CtutoaLlpEDK3iGTvsyc9MekNu1qo7FTmWhWqiKeRW2VqGw2DIfT0lo115nUzHnAEYQT45HGsHMzVGhclvyZ/VggaKVsqKujm6FmW4j/WnweQ22R1NiHgNazJcSOMQwrMDcccq7Z5gyTUXNxvIMMNmpxhCaqWRAKaZIgYFrc0V4z1oUsoQW7IGql2njD0dicxMm65QBeasdZyQi29mXQxcNdz37wd9gQLxY7x75XBEpo+q5vOeGAyiJQyf7EhdVBFGfgQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WAuHuTD9exojMeoaBmIf6+CD7o/d9qZ39+eHWH6bNJs=; b=W/8g5U5EEWswOWhSEjMqOVbFlTTy2V9LD1Sytc1FvySnKCs/ppRzEBbasYsfpGNsKRj3zU5Js8gBU2rprS36cgkOo1DoTsISxMzq7iH7n7s3AxOwjO3J2WpCiS4KXKE6YNi12ie1k5DDoG1x+4jwkEuUzz3+jPXaTcY6d/V2Bl0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:38:00 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:00 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 23/96] cl8k: add dsp.h Date: Tue, 24 May 2022 14:33:49 +0300 Message-Id: <20220524113502.1094459-24-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7956de99-f04b-465a-f6bd-08da3d79db04 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: I0mxGXZJOmpu5Bv19h5SAhRRqQaI0jd5FHjdBHHnUUxi6/1yA1qZ0yRjly/x7EJOnt4rIN4R2JaBTmi4UN3CYfnwFCSQZag5Z/1k4SH6bYzPzi7jPpU+sLZZcUEqWS44totUr5zrxC2UNFJH1nQGWDRQ5jgsUcVhZRiRY8KJ0NrjX/frKyyz/6sSR/g32p7zvsUwgzylUIEkVZjHmXQ+/6dN/vXvqiVZLQnkdnyGb7QbBdm//IwjN8V7A8isvoA40op35RCSvhAecBsD6eDPthBjIrMB+d+DBDyJAnVBAqNENqjfyWVus03XeiTYhryoc5+Uwn78pq9P9j0mMOb10OQtTditmDGk5A9t4xT1kDRBcmvgg0krK5lOw61gE+pdASFF+mh0s0PG3zA2xcEkoY/l7TFaO0hUJU1gMR/fu1Pu/YfBodtVaFfuc8jIZi/Wr6YxvDJAhxgqSytFfVUtXk/JTiyfyN4P2EACxgp3xbOnmhuinDv4eArjgZLu65ZsE2gp21ynBiBDg6zAPhlkZc3EEkse8Emjg6zOj3pisO8q07iJMrKQgSzVSaXzWMIjSn3QXRWMImdTF4GNchDFTdrUUjILtY3JRWWq1huz+faMrPVNMhPoit87Tx9WRAincFn18aYXg3FX2MQeVcp0Y+nZu7k8swVU+NwmU/WFyfmeJkbuX55tIIF9+otRFrX/eOTdlSVGB7QGDafMzkQOsQl3MVoMzDMLGsJh/24k5d8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: e6k6SP40eIJvmz5XwccrC9y5F6Bs4oG3Ct7TDHZvFuFFbVIXhxcteB9uq4gIG1ikzfxSWioZXemd4NEgzxYZevQ63DmZrUDUJdNRBhVltTrVjhgVD5todTglpKXIsmY65y7xyfUY/lH/69MWnK7mZUu+mcExnuS0mrbxED7NggToOJGXLNzxqTxkoAyuGY/0DgKpYn22X8w6Uf9cV0TCnWs2CUpSQfoq2BxDks85zmpZZIsSkiXsR7Mg7U6KqYhrGNo+Y+mvSrGBxwI4HtxU0ioQAWlyxifqFGnUZ3Po1xoMeASQUleW7p72xtKxIgunz6DAhN6kxsBUNt7oJuN1QfHEFvBr0l8fPumLJ55a+rVRtUMZqWQepVp/cbZAD+as3PwtWO2fC1OXCdLkKILm5gdM/3MIERP5859Zdp1d6SwxlhRA1Aj+YZkNvAy6ri+VYscEe7LGxh1aNxL8sBM72kqUrNvJ/yNp1mTFMyqppl6010Rjh/3kqVLEQco+6Snf2PyKE80M33gUVaSVciBpeE+FDZI9MWPCqs5wa/6P4jBlSA3/GfAb7v2splhYozTOMGDZtKXsGI9/+vFEk+8H7AvubUrfmVaEC8TGDKNP3Mj4nXKH7YFOJ9bjW2rAi3PQrVTtmi1LkCUz6DcdjXgjkDWk2lXCAqQ8mFI+fDfZXoABMyn9SFs39sDaw/2ltN31Y3Y535sjJzXwo6hUywxPdkAgP3fRqViFf/rTglx4B2jSSAg1oekCTbwenJ4aAMJpLmUlTPQZXzU8vbD7mCWb+hI/pRo7mN/J0B4PgAuekLDeOvjm0y7ZixvMwzUBIX9o3BhpXCMiaE3M0fQUxVZpHdTe20WQTgwQvP2E5UJgEpATcgIApCknBIDmypHhQnITj38YF4UIEZuQJSQve7BSvljENhHRqCYApdLnAmrn1UGeMfgHKBvqpJkSN47EzB7oijhX3t7Eo5GNgSc+mxp/Q6k2ySc4Iw+1tP7NETVfOymVoCQb3qEsUFT0K4vizNUEPtZaNYGsBRSqH6TD3pyuA3fSwvYTlffaqrvBB9+ZXueqyjuCPIyK7it4TitwVGNbNMHNuoDu+zTbK2pWKiS0I2mGxWw2LGOn/sTHN87encx6kLZhnB6sHp+eucFNKiZcacbjTyINGLdzgq/IIxhU/934Y9bCSXkKdwzLjl/070i14Kao0lp8YKVaggIawMS9fwpyrYGvzOOgL3pduWb21gG2xbk7+biFpqkZFL1uG3so0x96DaWCtD+282S5JVKEfN3BxCrf4wFy2j/d09eNtPZCNgM2pVRYeb0TsCuIHaBH0kZWU+9nt2I1lWt4qGzl+OzNsaApCO50KMuF0Rx80pWWtYq/1wBkZc/y8sx733kpdUfm8VONjNPQcEB1e8GgyTXbB+cHZTtjA1naDat4JNNRKvI4IaCg8GMUPPE1qcwwERu7+l09/0xbh+UeoTxh+tEvfymVwN1BtZ6VEG1f85O0nrENkGRC8HbOG5h+4YbatA43A8UfAN0Z/uYUKxecGSMRnt1tZqTgkqy7u3PV2DjoiGIEy09l8hXAj8gZ80vqaa1t2MoInGo3jd1Hd9a8kn3vwb05LEtdMag8kZMcJoavBgcQiVMdjsup5tE/4ew4KAZjVneMPP9yLguigpPiCXiZN13CtHLxnZ/Cgi6Ixg+kvHedCAKLVi3wqzZCxA1otzUsAsCHiimy0psjqEoussQfBaisNvcLuJMCo6xOFm9nj6ZaBNeGAHk9yPUJQLo= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7956de99-f04b-465a-f6bd-08da3d79db04 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:00.2625 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: b0/RJPa5OHvLqRnIP64PbFfcLXah5vjsK47DToGA8YeGEXNUycr5JQRPm+Chp7yg5SopIj8Zq+OWrgokDBRzOg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/dsp.h | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/dsp.h diff --git a/drivers/net/wireless/celeno/cl8k/dsp.h b/drivers/net/wireless/celeno/cl8k/dsp.h new file mode 100644 index 000000000000..006043983ae3 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/dsp.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_DSP_H +#define CL_DSP_H + +#include "chip.h" + +/* + * cl_dsp_load_regular - Load DSP firmware for both TCV's. + * + * @chip - chip pointer. + * + * Return value: 0 upon success, negative errno code upon failure. + */ +int cl_dsp_load_regular(struct cl_chip *chip); + +/* + * cl_dsp_load_recovery - Load only DSP data for single TCV. + * + * @chip - chip pointer. + * + * Return value: 0 upon success, negative errno code upon failure. + */ +int cl_dsp_load_recovery(struct cl_hw *cl_hw); + +#endif /* CL_DSP_H */ From patchwork Tue May 24 11:33:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576860 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 8967DC433FE for ; Tue, 24 May 2022 11:38:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236821AbiEXLik (ORCPT ); Tue, 24 May 2022 07:38:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiEXLig (ORCPT ); Tue, 24 May 2022 07:38:36 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70041.outbound.protection.outlook.com [40.107.7.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18A6E8CCFA for ; Tue, 24 May 2022 04:38:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ioabgpmgwprepml+osQ8dfFMRtWZ4nAUwgcJA9s9v0c/R+vycrwPkVLVPDCskOXmnqBlhJSc1fcc+5T/fmbrnq8YY7JeBc4TVTliTHaxp/gTNdOYgHqa5PgTG6SXpEPMSAtWomF9L1wT6nc9pozG70oAcZ+z/7JVHSAAOMrrB+67IPDFRT/wI2To1gAKUbtLqUHYafQaCEeR5X1t7oiUW+iw3quBfqBi21pk6VVKNDc5x/wR3JIzM0W5osgAcmdSpEg5GpoCLwmVygZuYZkQF/IJ9U1P3t9EPBlgCpNHd0enHddK4LOpIj7QeUY9q9fWhjUYa99vuBPqJ8RsZC2/vA== 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=XfbmPiTrH4/U98i0UYCMO8hVcb76Iw3EXn0/n2QLyGY=; b=V77/NxSqyJEx9Gkhw7NnJ4tuDev7jMpBLH+zWpf9pI95V0dhGLeg0V7jdaGDB9exNBOgRP9lJ1acrKt1OxkxlocVsnkEiUCpj2b3zOMUD7D5cNDvycXBdOqa99+JnORmIhOLT837QobaywttwDL6SM+g5lTE2qX4eA6AmP43DDzvX3g/bhnajqqQKzyfHdhDFj7bWBVlktnY8NId4QH3ZoZ+ohtkJ9sin0jIpFIRDZ9U/vV4EM56btz7P7TRTuUdKzg7QXm50co8cd+IIpM+qqolzZqzADcFHSqdJTY8EuU4+Y7w4phI5egDH7JfajKPyybizYLl5VXylezSZiK/FQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XfbmPiTrH4/U98i0UYCMO8hVcb76Iw3EXn0/n2QLyGY=; b=gj1AgNe9JT4xjwkwMg0Ca7Ff/HrRnF855Ja+Y3E5vueVXvMglKria8OgKAx8FCVAVY3Sm0Mx44U4ddMmft83eEQiqHNkKIsPSW6N3hX1khxvfSQ0ShzaJ2hMehTK7UkWVJNU23yADBAP/d/d6J8f4hNbh8V+5cIeVXz3SGfNm6o= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:38:01 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:01 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 24/96] cl8k: add e2p.c Date: Tue, 24 May 2022 14:33:50 +0300 Message-Id: <20220524113502.1094459-25-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0f8bd0bf-f879-4582-6e17-08da3d79db70 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oAFNHOtHsDz52mHwRhOfI82k9dRPOhab9mMcrL5H+xDk0RaN1cGsTrK0oXaGwREBes8NAnKBngjvpMDDeYiTXubAOWJkjlYzl1NnPvVMbKsKAtUZFFWfIX5nGKyfJoNbviRz8ueEQz7EYxoT5gQ3l04zmAKTTU+xlhjelVHXy5cj11HKP6Txx/LBH6u1VMitQuGa6MONQe/tHFJjCZbuUglOmrWn94lmFtKpQhPTyF6xSNVWPCEETM3bZNcAQ/Rn5jqNpv3l8JXrLHWVB/zYA1bejQ1ZO/H864PO9vb4WCZVhj8W3rEntX7Y9Lp1dLG0TSJfahNKw62kVcQlvQVdiyWZiGKzRddOuadS/EHWb14+kOf39B1RsGhLDe2FuRu0OvVKlLcwxGA9uG23g0DlhsYdpkwTokUsv103E33+zYUKrjl+kvDpH9Qz0mV5HEUwTypBzUinVW2hZf0rJ6SplxzrOMUBFrA4RZqhIY3kX1GWLQXLjAHvcmIRpUx9eY8dxyptz9W/2lcIGHlBrGMLFLIJ72Tji7yChtI5QM6srrcxcXLHvxxe4NJSrrBmyhfH2t2pvjXqlIChjCxbHyUCXFT2cFMMDOtAyI0ibeXsXEo04vXW+L2Aq1ZNH8hUzghMiRE/tAXnGLW0Y7PseCclxQ57VSInBNSOyKNLYUQugFdB5s83IQDDu/WsXx+d3pAH5nfdDOgICuOZFt9YZ6pUjwBJjdyqdQHqwlHHo0KRBC4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?/VwaSIxLxEPnB7Sm8OSQcx4zHWw9?= =?utf-8?q?H72LxAe8v57Po7bod+dMfi/HAYOJ/c+U0fDVA46ukjFH7wo1vfuUnDuCx6dyzgslJ?= =?utf-8?q?AJuKv3phvueQ4F1wyX3cbnfP5J1vCJIKNR0kFENfG/V5SdjkLESEkEsCmM1IXDuXz?= =?utf-8?q?4wp9WQNBLZfYJmNrUAhPNYALwjsB3SBPmFVJ2EzBIRptaiA+Lvb1/FzGYoiaRbq2H?= =?utf-8?q?hfFBZNd3sS5p7HP473ahsj09xGpqxHXR/IIQEW7CNlem8M82yu4vxAt18ojkeAQ53?= =?utf-8?q?Jc1KRdAB/+58HwdNGROTy+rmaZPJ1ZXZU5W7HGkdGHWtlYdaU0vyH+WCgJg54iuSe?= =?utf-8?q?przEqwurwlm5yMSdUUjKGQ5o0QlpiZJ8ss6dGjHj0bb0nZn5+xFwBDHRlLjtq2q0y?= =?utf-8?q?/7uxOuMzpcVZgIuWne0fc70JtrBxf2lE9byKRvcjdLQYiiB/A3WazGx9Q/VHfZaRH?= =?utf-8?q?n1/mSMg+e37RLzq95mgD5bZ2B83ejqDp3rGlZMKaHOqinzUYkKAl80C7rV0Ifup/7?= =?utf-8?q?Jjleu+paCTXFSjiPB+++qQDnNvsWB60MxznGLrK1HQzQ7f+it776CId8jF68fUNGF?= =?utf-8?q?ZuzJEa2u8zHdkmyswyN0vshjAc4uFds/yCGniO/Sop9dyDoNeipLzBA283QcU1ELK?= =?utf-8?q?PIMq4banYG2CT3BKgs4NHPtNqLu23qArmjPC+jjkqCvyYTAa40AdYmGDaxZuz+nbg?= =?utf-8?q?tDVpnguhDnnLeP1KhqUFl3WKwLuU7E5+z6dPGdINXS7w2faE7MDxEdyIsvrHTpQxj?= =?utf-8?q?N3wvQeHnzfW9EDd4tT5mRFXQwx/lE+FHctw984qh1fFwbaNyEu5r4RhlT4cc0elmU?= =?utf-8?q?T80YqTIc+KxZhcZZaP1Tz3KkVQLJ1PfYwZbGI8T5Gs5DYGEedooyZ32Jv4iJXx3CG?= =?utf-8?q?UaDW+KJt+oOzUCrYVmvsdYUfZEbMat3NroZyskW5oTAWCJN0V7gFY3/s7ub86yRBj?= =?utf-8?q?VPcMMySLy1pMU6B9KZFJgGIoXe215gCwXyX8m9j9ndN3GCyYVs2bj77iHn6Lbkuqa?= =?utf-8?q?waELcyPDeLpb8NTOkokx5kGrSO7UognOj02hbgxLs32KY8d2tMNc3fpfMoi8VWCo0?= =?utf-8?q?jQA96Rx6KPtWodqH/0nsVb6s/2/3z1GRB00TbMuooK/gk/iqlxW+MM8ifxB5J5zCs?= =?utf-8?q?rE2ZEB3oBkIKZsFYV56/QG3P8IM2TDqTbMkMFSoBi0L1E5+oI7akngkSvSMWuNBwe?= =?utf-8?q?d62cSXjts6C1xUzqsNonGAA7WzM2H2HSFfp1pN1UkFC5/T0lmDDKt0cmMJtSoVRNr?= =?utf-8?q?vCXLQyqT1+q9b0f1bDo/oEc1+8ZpkOU+lbulqBdFGR80bJR06cby4V8wMm+cqpd0a?= =?utf-8?q?/jtXdb2ocWuRCxJebZmwcrYNL9wHNbyk56frxdxhKdFZSnhO2bXzAGa7ZJTSvuh9h?= =?utf-8?q?8hnMcGdmc4LvzKU8H3yofvHy4FU1W2nNTN8kzN0ksDvLKq95e2aNgO3y3fO/l/O7U?= =?utf-8?q?gLYkdijuDa0UG5kmURWxtEKFyzIpT65FamyfmRgKWPe49BpZCBbmclY5YiZ/+kmdf?= =?utf-8?q?vAjclUmwpfpBs+HCyuQRHRrO527X97ouLX890VBRZaHL3tC6IAuqcQcwbxqfjh1T1?= =?utf-8?q?5FyMimQGBSaNIDBWEyxS/qpVQW8ZdKtFp8dlWngKYc4/eYX6nJMTWdHjwKIwhJGWM?= =?utf-8?q?CCvkJ+SFUwO4tNhnkUJ9HSL8DNg0GbcuyPa/352MV8hoqZrWo55Ys=3D?= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0f8bd0bf-f879-4582-6e17-08da3d79db70 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:01.0618 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: zXqX6eCCIYGSZp5HRbGRmOVMapegB8gSrY/3NSVKK6SehiaqHXvHXw6sJNASdQjizs+vzsprWlddKAarIuBxfg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/e2p.c | 771 +++++++++++++++++++++++++ 1 file changed, 771 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/e2p.c diff --git a/drivers/net/wireless/celeno/cl8k/e2p.c b/drivers/net/wireless/celeno/cl8k/e2p.c new file mode 100644 index 000000000000..14e9a4498046 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/e2p.c @@ -0,0 +1,771 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include + +#include "chip.h" +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "config.h" +#include "utils.h" +#include "e2p.h" +#include "calib.h" +#include "debug.h" + +#define EEPROM_VERSION 3 + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +/* EEPROM Parameters - Suitable for ST-M24256 */ +#define E2P_SIZE 0x8000 /* 32KB = 256Kbit */ +#define E2P_PAGE_SIZE 0x40 /* 64 Bytes */ +#define E2P_PAGE_MASK (E2P_PAGE_SIZE - 1) /* 0x3F */ +#define E2P_PAGE_SHIFT 0x6 +#else +/* EEPROM Parameters - Suitable for ATMEL AT24C16BN */ +#define E2P_SIZE 0x800 /* 2KB = 16Kbit */ +#define E2P_PAGE_SIZE 0x10 /* 16 Bytes */ +#define E2P_PAGE_MASK (E2P_PAGE_SIZE - 1) /* 0xF */ +#define E2P_PAGE_SHIFT 0x4 +#endif + +#define PAGE_NUM(addr) ((addr) >> E2P_PAGE_SHIFT) +#define PAGE_OFF(addr) ((addr) & E2P_PAGE_MASK) + +#define CH_LIST_SIZE_CL80X0 59 +#define CH_LIST_SIZE_CL80X6 105 + +static const u8 chan_list_cl80x0[CH_LIST_SIZE_CL80X0] = { + 36, 38, 40, 42, 44, 46, 48, 50, + 52, 54, 56, 58, 60, 62, 64, 100, + 102, 104, 106, 108, 110, 112, 114, 116, + 118, 120, 122, 124, 126, 128, 132, 134, + 136, 138, 140, 142, 144, 149, 151, 153, + 155, 157, 159, 161, 165, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14 +}; + +static const u16 chan_list_cl80x6[CH_LIST_SIZE_CL80X6] = { + 1, 2, 5, 9, 13, 17, 21, 25, + 29, 33, 37, 41, 45, 49, 53, 57, + 61, 65, 69, 73, 77, 81, 85, 89, + 93, 97, 101, 105, 109, 113, 117, 121, + 125, 129, 133, 137, 141, 145, 149, 153, + 157, 161, 165, 169, 173, 177, 181, 185, + 189, 193, 197, 201, 205, 209, 213, 217, + 221, 225, 229, 233, 36, 38, 40, 42, + 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, + 110, 112, 114, 116, 118, 120, 122, 124, + 126, 128, 132, 134, 136, 138, 140, 142, + 144, 149, 151, 153, 155, 157, 159, 161, + 165 +}; + +enum bit_num { + BIT0, + BIT1, + BIT2, + BIT3, + BIT4, + BIT5, + BIT6, + BIT7, +}; + +struct cl_e2p_work { + struct work_struct ws; + struct cl_chip *chip; +}; + +/* + * MACSYS_I2C:: PRERLO (0x0) - Clock Prescale register lo-byte + * Width: 8, Access: RW, Reset: 0xff. + */ +#define I2C_PRERLO (I2C_REG_BASE_ADDR + 0x0) + +/* + * MACSYS_I2C:: PRERHI (0x4) - Clock Prescale register lo-byte + * Width: 8, Access: RW, Reset: 0xff. + */ +#define I2C_PRERHI (I2C_REG_BASE_ADDR + 0x4) + +/* + * MACSYS_I2C:: CTR (0x8) - Control Register + * Width: 8, Access: RW, Reset: 0x00. + */ +#define I2C_CTR (I2C_REG_BASE_ADDR + 0x8) + +#define EN (BIT7) /* ‘1’ the core is enabled. */ + +/* + * MACSYS_I2C:: TXR_RXR (0xC) - Transmit Register - Data + * Width: 8, Access: W, Reset: 0x00. + */ +#define I2C_TXD (I2C_REG_BASE_ADDR + 0xC) + +/* 7:0 TXD */ +#define TXD (BIT0) /* Next byte to transmit via I2C */ + +#define TXD_MASK (0xFF << TXD) + +/* + * MACSYS_I2C:: TXR_RXR (0xC) - Transmit Register - Address + * Width: 8, Access: W, Reset: 0x00. + */ +#define I2C_TXADDR (I2C_REG_BASE_ADDR + 0xC) + +/* + * 7:1 TXADDR + * 0 RDWR + */ +#define TXADDR (BIT1) /* I2C Slave Address */ +#define RDWR (BIT0) /* ‘1’ = reading from slave. ‘0’ = writing to slave. */ + +#define TXADDR_MASK (0x7F << TXADDR) + +/* + * MACSYS_I2C:: TXR_RXR (0xC) - Receive Register + * Width: 8, Access: R, Reset: 0x00. + */ +#define I2C_RXD (I2C_REG_BASE_ADDR + 0xC) + +/* 7:0 RXD */ +#define RXD (BIT0) /* Last byte received via I2C. */ +#define RXD_MASK (0xFF << RXD) + +/* + * MACSYS_I2C:: CR_SR (0x10) - Command Register + * Width: 8, Access: WC, Reset: 0x00. + */ +#define I2C_CR (I2C_REG_BASE_ADDR + 0x10) + +/* + * 7 STA + * 6 STO + * 5 RD + * 4 WR + * 3 ACK + * 2:1 RES + * 0 IACK + */ +#define STA (BIT7) /* Generate (repeated) start condition. */ +#define STO (BIT6) /* Generate stop condition. */ +#define RD (BIT5) /* Read from slave. */ +#define WR (BIT4) /* Write to slave. */ +#define ACK (BIT3) /* When a receiver, sent ACK (ACK = ‘0’) or NACK (NACK = ‘1’). */ +#define IACK (BIT0) /* Interrupt acknowledge, When set, clears a pending interrupt. */ + +/* + * MACSYS_I2C:: CR_SR (0x10) - Status Register + * Width: 8, Access: R, Reset: 0x00. + */ +#define I2C_SR (I2C_REG_BASE_ADDR + 0x10) + +/* + * 7 RX_ACK - Received acknowledge from slave - ‘1’ = No acknowledge received. + * 6 BUSY - I2C bus busy - ‘1’ after START signal detected. ‘0’ after STOP signal detected. + * 5 AL - Arbitration lost - This bit is set when the core lost arbitration. + * 4:2 RES + * 1 TIP - Transfer in progress. ‘1’ when transferring data. ‘0’ when transfer complete. + * 0 IF - Set when interrupt is pending, cause a processor interrupt if the IEN bit is set. + */ +#define RX_ACK (BIT7) +#define BUSY (BIT6) +#define AL (BIT5) +#define TIP (BIT1) +#define IF (BIT0) + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +#define I2C_EEPROM_ADDR(page) (0xA0 | (((page) >> 8) & 0xE)) /* [1-0-1-0-P2-P1-P0-0] */ +#else +#define I2C_EEPROM_ADDR(page) (0xA0 | (((page) >> 3) & 0xE)) /* [1-0-1-0-P2-P1-P0-0] */ +#endif + +/* E2P_MAX_POLLS should not exceed 12 iterations (attemts) */ +#define E2P_MAX_POLLS 500 +#define E2P_INITIAL_DELAY 32 + +static int i2c_poll_xfer_acked(struct cl_chip *chip) +{ + u32 val = cl_reg_read_chip(chip, I2C_SR); + int cnt = E2P_MAX_POLLS; + unsigned long delay = E2P_INITIAL_DELAY; + + while ((val & BIT(TIP)) && cnt--) { + udelay(delay); + val = cl_reg_read_chip(chip, I2C_SR); + delay <<= 1; + } + ++cnt; + + while ((val & BIT(RX_ACK)) && cnt--) { + udelay(delay); + val = cl_reg_read_chip(chip, I2C_SR); + delay <<= 1; + } + + if (cnt >= 0) + return 0; + + cl_dbg_chip_err(chip, "ACK FAILED\n"); + cl_dbg_chip_trace(chip, "I2C_POLL_XFER_ACKED: val=%Xh, cnt=%d.\n", val, cnt); + + return -EBADE; +} + +static int i2c_poll_xfer_no_acked(struct cl_chip *chip) +{ + u32 val = cl_reg_read_chip(chip, I2C_SR); + int cnt = E2P_MAX_POLLS; + unsigned long delay = E2P_INITIAL_DELAY; + + while ((val & BIT(TIP)) && cnt--) { + udelay(delay); + val = cl_reg_read_chip(chip, I2C_SR); + delay <<= 1; + } + + ++cnt; + + while (!(val & BIT(RX_ACK)) && cnt--) { + udelay(delay); + val = cl_reg_read_chip(chip, I2C_SR); + delay <<= 1; + } + + if (cnt >= 0) + return 0; + + cl_dbg_chip_err(chip, "NO ACK FAILED\n"); + cl_dbg_chip_trace(chip, "I2C_POLL_XFER_NO_ACKED: val=%Xh, cnt=%d.\n", val, cnt); + + return -EBADE; +} + +static void i2c_write_start(struct cl_chip *chip, u16 page) +{ + u32 addr = I2C_EEPROM_ADDR(page) & TXADDR_MASK; + + cl_reg_write_chip(chip, I2C_TXADDR, addr); + cl_reg_write_chip(chip, I2C_CR, BIT(STA) | BIT(WR)); +} + +static void i2c_write(struct cl_chip *chip, u8 data) +{ + cl_reg_write_chip(chip, I2C_TXD, data & TXD_MASK); + cl_reg_write_chip(chip, I2C_CR, BIT(WR)); +} + +static void i2c_write_stop(struct cl_chip *chip, u8 data) +{ + cl_reg_write_chip(chip, I2C_TXD, data & TXD_MASK); + cl_reg_write_chip(chip, I2C_CR, BIT(STO) | BIT(WR)); +} + +static void i2c_read_start(struct cl_chip *chip, u16 page) +{ + u32 addr = (I2C_EEPROM_ADDR(page) & TXADDR_MASK) | BIT(RDWR); + + cl_reg_write_chip(chip, I2C_TXADDR, addr); + cl_reg_write_chip(chip, I2C_CR, BIT(STA) | BIT(WR)); +} + +static int i2c_read_stop(struct cl_chip *chip, u8 *data) +{ + int ret = 0; + + cl_reg_write_chip(chip, I2C_CR, BIT(STO) | BIT(RD) | BIT(ACK)); + ret = i2c_poll_xfer_no_acked(chip); + if (ret < 0) + return ret; + *data = cl_reg_read_chip(chip, I2C_RXD) & RXD_MASK; + return 0; +} + +static void e2p_reg_set_bit(struct cl_chip *chip, u32 reg, u32 bit) +{ + u32 regval = cl_reg_read_chip(chip, reg); + + regval |= bit; + cl_reg_write_chip(chip, reg, regval); +} + +static void e2p_reg_clear_bit(struct cl_chip *chip, u32 reg, u32 bit) +{ + u32 regval = cl_reg_read_chip(chip, reg); + + regval &= ~bit; + cl_reg_write_chip(chip, reg, regval); +} + +/* + * helpers for cl_e2p_write_addr_bytes() + */ +static inline u16 cl_e2p_addrbyte_lo(u16 v) +{ + return v & 0xff; +} + +static inline u16 cl_e2p_addrbyte_hi(u16 v) +{ + return (v >> 8) & 0xff; +} + +/* + * Helper writing address byte(s) to the eeprom, some eeprom need two + * byte address cycles, some need only one. + */ +static int cl_e2p_write_addr_bytes(struct cl_chip *chip, u16 addr) +{ +#ifdef CONFIG_CL8K_EEPROM_STM24256 + int ret = 0; + + /* Addr 8 msbits are 8 bits msb page */ + i2c_write(chip, cl_e2p_addrbyte_hi(addr)); + + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; +#endif + /* Addr 8 lsbits are 4 bits page lsbits or`ed with 4 bits page offset */ + i2c_write(chip, cl_e2p_addrbyte_lo(addr)); + + return i2c_poll_xfer_acked(chip); +} + +static void e2p_enable(struct cl_chip *chip) +{ + /* Disable I2C Core */ + e2p_reg_clear_bit(chip, I2C_CTR, BIT(EN)); + + /* + * Set Pre-Scaler LO + * pclk = 240MHz, desired SCL = 400KHz. + * Prescale = [240e6 / (5*400e3) ] – 1 = 120 -1 = 119 = 77h + */ + cl_reg_write_chip(chip, I2C_PRERLO, 0x77); + + /* Set Pre-Scaler HI */ + cl_reg_write_chip(chip, I2C_PRERHI, 0x0); + + /* Enable I2C Core */ + e2p_reg_set_bit(chip, I2C_CTR, BIT(EN)); +} + +static int e2p_read_byte(struct cl_chip *chip, u16 addr, u8 *pbyte) +{ + int ret = 0; + + if (addr > E2P_SIZE) { + cl_dbg_chip_err(chip, "Wrong addr or len\n"); + return -EFAULT; + } + + /* Clock in the address to read from. */ + i2c_write_start(chip, PAGE_NUM(addr)); + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; + + ret = cl_e2p_write_addr_bytes(chip, addr); + if (ret) + return ret; + + /* Read single byte */ + i2c_read_start(chip, PAGE_NUM(addr)); + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; + + return i2c_read_stop(chip, pbyte); +} + +static int e2p_write_page(struct cl_chip *chip, u16 addr, u8 *val, u16 num_of_bytes) +{ + /* + * This is a write page (up to E2P_PAGE_SIZE bytes) operation indicating the offset + * to write to. + */ + int i; + int ret = 0; + + if (num_of_bytes > E2P_PAGE_SIZE) + return -EMSGSIZE; + + /* Clock in the address to write to. */ + i2c_write_start(chip, PAGE_NUM(addr)); + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; + + ret = cl_e2p_write_addr_bytes(chip, addr); + if (ret) + return ret; + + /* Clock in the data to write. */ + for (i = 0; i < (num_of_bytes - 1); i++, val++) { + i2c_write(chip, *val); + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; + } + + /* Clock in the last data byte to write */ + i2c_write_stop(chip, *val); + ret = i2c_poll_xfer_acked(chip); + if (ret) + return ret; + + /* Wait for the write to finish */ + mdelay(6); + + return ret; +} + +static int e2p_write_block(struct cl_chip *chip, u16 addr, u16 num_of_bytes, u8 *val) +{ + u16 bytes_on_curr_page = 0, bytes_left_to_write = num_of_bytes; + int ret = 0; + + do { + bytes_on_curr_page = E2P_PAGE_SIZE - PAGE_OFF(addr); + bytes_on_curr_page = min(bytes_left_to_write, bytes_on_curr_page); + bytes_left_to_write -= bytes_on_curr_page; + + ret = e2p_write_page(chip, addr, val, bytes_on_curr_page); + if (ret) { + cl_dbg_chip_err(chip, + "Error writing page %u offset %u, ret %d\n", + PAGE_NUM(addr), PAGE_OFF(addr), ret); + /* Written less bytes than num_of_bytes */ + return 0; + } + + addr += bytes_on_curr_page; + val += bytes_on_curr_page; + } while (bytes_left_to_write); + + return num_of_bytes - bytes_left_to_write; +} + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +static void cl_e2p_init_calib_ch_bmp_per_bw(struct cl_hw *cl_hw, int data_elem_num, + u16 channel_list[], int bw, int bmp_size, + int bmp_addr, int eeprom_data_size, int data_addr) +{ + u8 chan_idx; + u8 chan_bmp[SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV0] = {0}; + u8 chan_bmp_prev[SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV0] = {0}; + struct eeprom_calib_data zero_calib = {0}; + int i; + + for (i = 0; i < data_elem_num; i++) { + chan_idx = cl_calib_dcoc_channel_bw_to_idx(cl_hw, channel_list[i], bw); + if (channel_list[i] && chan_idx != INVALID_CHAN_IDX) + chan_bmp[chan_idx / BITS_PER_BYTE] |= (BIT(chan_idx % BITS_PER_BYTE)); + } + + cl_e2p_read(cl_hw->chip, chan_bmp_prev, bmp_size, bmp_addr); + if (memcmp(chan_bmp, chan_bmp_prev, bmp_size)) + for (i = 0; i < data_elem_num; i++) + cl_e2p_write(cl_hw->chip, (u8 *)&zero_calib, + (u16)sizeof(struct eeprom_calib_data), + data_addr + (i * + (u16)sizeof(struct eeprom_calib_data))); + + cl_e2p_write(cl_hw->chip, chan_bmp, bmp_size, + bmp_addr); +} + +static void cl_e2p_init_calib_ch_bmp(struct cl_hw *cl_hw) +{ + if (cl_hw->tcv_idx == 0) { + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0, + cl_hw->conf->ci_calib_eeprom_channels_20mhz, + CHNL_BW_20, SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV0, + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_20MHZ_TCV0, + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV0); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0, + cl_hw->conf->ci_calib_eeprom_channels_40mhz, + CHNL_BW_40, SIZE_CALIB_IQ_DCOC_40MHZ_BMP_TCV0, + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_40MHZ_TCV0, + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV0); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0, + cl_hw->conf->ci_calib_eeprom_channels_80mhz, + CHNL_BW_80, SIZE_CALIB_IQ_DCOC_80MHZ_BMP_TCV0, + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_80MHZ_TCV0, + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV0, + cl_hw->conf->ci_calib_eeprom_channels_160mhz, + CHNL_BW_160, SIZE_CALIB_IQ_DCOC_160MHZ_BMP_TCV0, + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_160MHZ_TCV0, + ADDR_CALIB_IQ_DCOC_DATA_160MHZ_TCV0); + } else { + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1, + cl_hw->conf->ci_calib_eeprom_channels_20mhz, + CHNL_BW_20, SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV1, + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_20MHZ_TCV1, + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV1); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV1, + cl_hw->conf->ci_calib_eeprom_channels_40mhz, + CHNL_BW_40, SIZE_CALIB_IQ_DCOC_40MHZ_BMP_TCV1, + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_40MHZ_TCV1, + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV1); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1, + cl_hw->conf->ci_calib_eeprom_channels_80mhz, + CHNL_BW_80, SIZE_CALIB_IQ_DCOC_80MHZ_BMP_TCV1, + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_80MHZ_TCV1, + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1); + + cl_e2p_init_calib_ch_bmp_per_bw(cl_hw, EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV1, + cl_hw->conf->ci_calib_eeprom_channels_160mhz, + CHNL_BW_160, SIZE_CALIB_IQ_DCOC_160MHZ_BMP_TCV1, + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_160MHZ_TCV1, + ADDR_CALIB_IQ_DCOC_DATA_160MHZ_TCV1); + } +} + +static void e2p_read_eeprom_handler(struct work_struct *ws) +{ + struct cl_e2p_work *e2p_work = container_of(ws, struct cl_e2p_work, ws); + struct cl_chip *chip = e2p_work->chip; + u8 *cache = (u8 *)chip->eeprom_cache; + u16 i; + + if (chip->conf->ce_eeprom_mode == E2P_MODE_EEPROM) + for (i = EEPROM_BASIC_NUM_BYTES; i < EEPROM_NUM_BYTES; i++) + if (e2p_read_byte(chip, i, &cache[i]) < 0) + return; + + if (chip->cl_hw_tcv0) + cl_e2p_init_calib_ch_bmp(chip->cl_hw_tcv0); + if (chip->cl_hw_tcv1) + cl_e2p_init_calib_ch_bmp(chip->cl_hw_tcv1); + + chip->is_calib_eeprom_loaded = 1; +} + +void cl_e2p_read_eeprom_start_work(struct cl_chip *chip) +{ + struct cl_e2p_work *e2p_work = kzalloc(sizeof(*e2p_work), GFP_ATOMIC); + + if (!e2p_work) + return; + + e2p_work->chip = chip; + INIT_WORK(&e2p_work->ws, e2p_read_eeprom_handler); + queue_work(chip->chip_workqueue, &e2p_work->ws); +} +#endif + +static int e2p_load_from_eeprom(struct cl_chip *chip) +{ + u8 *cache = (u8 *)chip->eeprom_cache; + u16 i; + int ret = 0; +#ifdef CONFIG_CL8K_EEPROM_STM24256 + u16 eeprom_load_len = EEPROM_BASIC_NUM_BYTES; +#else + u16 eeprom_load_len = EEPROM_NUM_BYTES; +#endif + + for (i = 0; i < eeprom_load_len; i++) { + ret = e2p_read_byte(chip, i, &cache[i]); + if (ret) + return ret; + } + + return ret; +} + +static int e2p_eeprom_read_block(struct cl_chip *chip, u16 addr, u16 num_of_bytes, u8 *val) +{ + void *read_block = NULL; + + if (!val) + return -EFAULT; + + if (addr + num_of_bytes > EEPROM_NUM_BYTES) + return -ENXIO; + + read_block = (u8 *)chip->eeprom_cache + addr; + memcpy(val, read_block, num_of_bytes); + + return num_of_bytes; +} + +static int e2p_eeprom_write_block(struct cl_chip *chip, u16 addr, u16 num_of_bytes, u8 *val) +{ + int bytes_written = -EIO; + void *write_block = NULL; + + if (!val) + return -EFAULT; + + if (addr + num_of_bytes > EEPROM_NUM_BYTES) + return -ENXIO; + + bytes_written = e2p_write_block(chip, addr, num_of_bytes, val); + write_block = (u8 *)chip->eeprom_cache + addr; + memcpy(write_block, val, num_of_bytes); + + return bytes_written; +} + +static int e2p_load_from_bin(struct cl_chip *chip) +{ + char filename[CL_FILENAME_MAX]; + size_t size = 0; + char *buf = NULL; + int ret = 0; + + if (cl_chip_is_6g(chip)) + snprintf(filename, sizeof(filename), + "eeprom%u_cl80x6.bin", chip->idx); + else + snprintf(filename, sizeof(filename), + "eeprom%u_cl80x0.bin", chip->idx); + + size = cl_file_open_and_read(chip, filename, + (char **)&buf); + + if (size < EEPROM_BASIC_NUM_BYTES) { + cl_dbg_chip_err(chip, + "Invalid EEPROM size - %s (actual %zu) (min size %d)\n", + filename, size, EEPROM_BASIC_NUM_BYTES); + ret = -EINVAL; + goto err; + } + + if (size > EEPROM_NUM_BYTES) { + cl_dbg_chip_err(chip, + "Invalid EEPROM size - %s (actual %zu) (max size %d)\n", + filename, size, EEPROM_NUM_BYTES); + ret = -EFBIG; + goto err; + } + + if (!buf) { + cl_dbg_chip_err(chip, "EEPROM data buffer is empty\n"); + + ret = -ENODATA; + goto err; + } + + chip->eeprom_bin_size = size; + memcpy(chip->eeprom_cache, buf, size); + +err: + kfree(buf); + + return ret; +} + +static int e2p_bin_write_block(struct cl_chip *chip, u16 addr, u16 num_of_bytes, u8 *val) +{ + return -EOPNOTSUPP; +} + +static int e2p_bin_read_block(struct cl_chip *chip, u16 addr, u16 num_of_bytes, u8 *val) +{ + u8 *base; + u16 *offset_addr; + + if (!val) + return -EFAULT; + + if (addr + num_of_bytes > chip->eeprom_bin_size) + return -ENXIO; + + base = (u8 *)chip->eeprom_cache; + offset_addr = (u16 *)(base + addr); + memmove(val, offset_addr, num_of_bytes); + + return num_of_bytes; +} + +static int cl_e2p_init_bin(struct cl_chip *chip) +{ + int ret = 0; + + ret = e2p_load_from_bin(chip); + if (ret) + return ret; + + chip->eeprom_read_block = e2p_bin_read_block; + chip->eeprom_write_block = e2p_bin_write_block; + + return ret; +} + +static int cl_e2p_init_eeprom(struct cl_chip *chip) +{ + int ret = 0; + + e2p_enable(chip); + + ret = e2p_load_from_eeprom(chip); + if (ret) + return ret; + + chip->eeprom_read_block = e2p_eeprom_read_block; + chip->eeprom_write_block = e2p_eeprom_write_block; + + return ret; +} + +int cl_e2p_init(struct cl_chip *chip) +{ + u8 eeprom_mode = chip->conf->ce_eeprom_mode; + + chip->eeprom_cache = kzalloc(EEPROM_NUM_BYTES, GFP_KERNEL); + if (!chip->eeprom_cache) + return -ENOMEM; + + if (eeprom_mode == E2P_MODE_BIN) + return cl_e2p_init_bin(chip); + else if (eeprom_mode == E2P_MODE_EEPROM) + return cl_e2p_init_eeprom(chip); + + return -EINVAL; +} + +void cl_e2p_close(struct cl_chip *chip) +{ + kfree(chip->eeprom_cache); +} + +int cl_e2p_write(struct cl_chip *chip, u8 *data, u16 size, u16 addr) +{ + if (size != chip->eeprom_write_block(chip, addr, size, data)) { + cl_dbg_chip_err(chip, "Error writing eeprom addr 0x%x\n", addr); + return -EBADE; + } + + return 0; +} + +int cl_e2p_read(struct cl_chip *chip, u8 *data, u16 size, u16 addr) +{ + if (size != chip->eeprom_read_block(chip, addr, size, data)) { + cl_dbg_chip_err(chip, "Error reading eeprom addr 0x%x\n", addr); + return -EBADE; + } + + return 0; +} From patchwork Tue May 24 11:33:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575978 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 24BA4C433EF for ; Tue, 24 May 2022 11:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236804AbiEXLiu (ORCPT ); Tue, 24 May 2022 07:38:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236813AbiEXLit (ORCPT ); Tue, 24 May 2022 07:38:49 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60084.outbound.protection.outlook.com [40.107.6.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9A708CB3D for ; Tue, 24 May 2022 04:38:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=enEAV2yUHwrNa5S7nU/PSwbcGtZZXUZC0N8NyRYsgGRqTEVWK3n6qnYwA2b+sWC/BkzgFBploYkEWYD5c3LRB3WwuWoaw5NxsUYFcU8n0QCbRIodO6x7m07LzK1kYosMUBnkUJt6KzewMAYtx0bF0NjPqpRrov7W0bYW1gLlOBr3BFGoaKJ16NXsb+Ayl961e/KgvjVKkqBqSLRH2i4h/vFno4E5WJojB6l2TPJMVoUiyGc1vZYsEFbKZxuffa8ESJvyeLbZLyupBU2uCeOk3vVlXnq8EQKkRYFJmBenL4mPJAxdk+8Kg3NvVe0SWz8cxk1KgeRsM3W+Bs9F/GP1EA== 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=XpDkQhgmR2figWUIoKaEzozOhSDXVZziNtRpXzlq6xE=; b=CkOA66ZKHfRq+2+7guGZUOdztD6kBWrG2oG2Pcyof+vkXJ2MmTHo/6mSov3W4b/pEQ0Z2vHGdoqRXV2k61FVnlFlWjovdRDZzEDCBlqqcxorFgxyWf0Qftpn/Evy9hInAFINDACcqrWaX35gk9ltLkjjpG/WAfenUko7DIV0YV5KESeeTFX9gRwqlOQH0sxdddIe3dR3Ucty8aLqEkmKESlF+C3+dfo2/3L4o4WUzrNeLSpxb9e+dca7YGzwfqz51C1bbaVKtTLMAlMY294g99NShCvH+P7gpfQyr1YRhJquckUSe2RLd5l4/bGxLV/vCrWAAFdDIpjg/xdOIHa3HA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XpDkQhgmR2figWUIoKaEzozOhSDXVZziNtRpXzlq6xE=; b=R2n0SyUPDNe0nkkLsSDqawFHseIO3KYgFWh54cYCOLwSG+iGE9kBehbVlDwio5ZUG1I7ieTwtIsHeFwmmqG/mcQDe4nmR2FdYRlYbmhZPfXZvsfCG6ttcLsFLCtA0zXAbNPQWJUPQ5E1QUaeVNs9QMHv0buSb0mcRGKLAl9+KaA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:38:01 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:01 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 25/96] cl8k: add e2p.h Date: Tue, 24 May 2022 14:33:51 +0300 Message-Id: <20220524113502.1094459-26-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 448de6f5-10f1-4636-d15f-08da3d79dbe7 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Fyl+2leJqlRLA5h0kZXKrFJGE8oKwMR+GBgsNRElCFqcBHloEXg//hPIWD/kEZulG4Wu2TLGmtmJg8KH4t5JAkC8ZtWE2wBTNbJr5IHVwam+YFAQr6gNiOc8L33U5oPoLx3ZLuvz/SBuMzUi61IZKSRt0JqQjz3piSmzz+MJglBLFfrcvwFKKdut68jGP6NvwUp4zEsEb+sGcaYtIBfdTBeUyVRaAQmG0YEtg0xjdRw5pZoBSHrcxxzgtiJJXw4t34ilu7ct7fFoixKN96IZ7ltOwtKPUYHhDHH9ffhyMWDVhcG1ThnGo4y93FgL1xFdRcRtkSEG6NEKxfaBXam21pCZ8SXlyKD+3vn9Tvln3Ip4XfjVWc//1CduRtjxZDfDzWpzkvy5sp9PQucGSZ0lL/AYjtsk7Saizq/LdhVghkwnmq1nasjhM+urEDrSmhmiPNKCstm/aKAeZs4u41oJWYO6gSJ8cB94YRKVqVG3RXF4PUwo1u+BNXtvsTMYWbEyBpC13IZObijWrWWkdBbvmhnLOnCcDYrcEIbTDxzaNAztoRKDNyQlqUwgWW72ImXrC42JJOadDc9VxQXPVyOl+7VJjvBgriKvt/16ngmG/3BbyhNCUmPy3OnPPYR0aiEFqsn4jwqY5nH9xaZrXgD2ZKgd0MF2dGrnbycjeMQgKVswkoNHCtPQoSLrdFrTM8E4VgRh92Xe7srJhgRyt0g15hQXZ5PUyBRNErKkYGsvN+E= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: gagFCHHbAyCzRNZDsFRIm+Y/C/P+hznjOUAV+Fgn9eUuWCikAE3zHbUXc/BNfcuNkwo9EyilpPC7HHENoaBA7UPTzyNWcvpgiGOZAklzPgTX1TyGA/kNzo8JCc0mTTo5ku61nyySKqnuooa7kChRfDFE5t2WaME3ywnuxvm5+e2RtMklFeoQVNjqWnP3kH9nBvL1Wb8z+MR+1aFnhqLeuc7FCaAc0+w2Bqpswd4pH5P65S+Z1tef7jX52+qtCmMgs2GseeQTiU8xunO4CMfUdrdj9NFO/vCKHQQ7FwuZP9V8XGPKvP8L4s7pksKZZkm3BhSRRXotvqgiQSnAImjKHTZ+4UR5iahWOTajstkapQEg3iLIdMTYs4HkfYjpBDoUNK5ZHFEgChyitkYvkX0uHhTpbvdU6tYquebhalxtOnh3wMHjE7j3b2RyhYf01ZBYIc3PAdSwQmzhlmNMZDJhjYx5SSx9BYtsWH6nybnxYLHt5N7wleS610UwH8876dlEq2Ax7yRB1X1lHtC3WuINHtGW5deiA9kdp1C02bivJfZmCNrldGsJnw/x4SdcwFM6s6QT5Ps5rt11o2UjBCP6LOB+EfF+kMWZ+Qx74jIprMxcR3NaZ1V0nREmtUHgfR7VTZRLuGH360t5P668nB8BXkxgeEtuGO/1rfJHmlQvNB+TTISmDMxubzWRAsE1NJ3ZlsDXhn7EPYp7xfzeBzehWAtnMXbLMdb0PgoXDXGmw34OVIJQswBiz04b+B01ur7UtIGY0xRxMSWyLa3XLgMFsPggCw7UAOxiAT2WQq84z96y+joHnssJKbl1lp3BMusit2T71vI6ViwJ52Rgi0XPzVWx2kyML0bnmMh5LGxD9D+tgt0YcN/CyVLEbHIlcriiBhLhXnYwDaAKgWylQR2PBbE6ZP2P5AmzsBGoiUIB/RIAWJwGnlU+BKCLEwM/L3wYviB7OP4wUJ6olYzjELBQge8mPEUpd0YMYmhAg7Ju1BCQyiN9jJaThVzjqq0lwWCr60XROO8weeZAwYpkIUqLWJ4W0O0/QR7ZU8LRB0cYnQZiUeV1ojZro7n3bQxGJPzh0JnP/XtBw/Q9uROw7uKHqfqPox51AbziJo8bZx3yLAUJ7Vv8pTXKCEoumS5dLiHWcOKnTEYMqj1sRDg5j1KKqKVb6S3FW299a3qldPYGPOAF3jsnesSqHgCgNkQyML0BjNZ1ncTF9twhYoZNnF59mwGMGfmMArj74SVCN42bME4n5RY/LI1MA/Iui9mmWY55OSwfYUZtaWF7IGwKhZlSkh7oShG2/fMBi+Xky6RgDmKxFNn/VC120mXNOeyDzS0tX4/nlDoNSXkWrNeyEnlMTys5wPsfpGDJMjYBD38phU3OhezVmQ7hrDTftN3WrDnB1l2C0cBTzEsXwteR8AFBLzS6XQyYNzOq6FOeyf/NSjx/+HdWBliHqJXOTLf89gHJ9Qe6BmRxgifz7bzX66IszwL2IgcwO4tmVlRhbLEmh9CxcLbTRQeNz1SxpJNfIj6vw4RHzqwDszKfiZT8PmNYxsjHaQiqcFGcPeVQjBVHM/GlgMHxcPy69ICG6bes1rQUxJc6pogIjMasmw2nEdI9BeZYJkrtJjCDkXl6y+sRo1Q/TyCsfuD+4f8U1e5WYPT3b+5N6e9j7obfeCkx70/2IRlh2alxMNb65nP8KaNfDTh9ANgWVB4wZJL7QJggX4hiQoTSjGDozwshDwVsM3GyoA2VExbSWp7lNfJBB+4xuOA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 448de6f5-10f1-4636-d15f-08da3d79dbe7 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:01.7648 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: naDBATcsKmpkJF0bsZ8AFfJEg1UpLVvY8cgj+wdgjqnwokFJ+uS4+gAI3YUi8acMP9kM4fyJZ+yiK4Y+ItfnxA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/e2p.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/e2p.h diff --git a/drivers/net/wireless/celeno/cl8k/e2p.h b/drivers/net/wireless/celeno/cl8k/e2p.h new file mode 100644 index 000000000000..3545e1d110f1 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/e2p.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_E2P_H +#define CL_E2P_H + +#include + +#include "chip.h" +#include "eeprom.h" + +enum { + E2P_MODE_BIN, + E2P_MODE_EEPROM, + + E2P_MODE_MAX +}; + +int cl_e2p_init(struct cl_chip *chip); +void cl_e2p_close(struct cl_chip *chip); +int cl_e2p_write(struct cl_chip *chip, u8 *data, u16 size, u16 addr); +int cl_e2p_read(struct cl_chip *chip, u8 *data, u16 size, u16 addr); +void cl_e2p_read_eeprom_start_work(struct cl_chip *chip); + +#endif /* CL_E2P_H */ From patchwork Tue May 24 11:33:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576859 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 2AD18C433EF for ; Tue, 24 May 2022 11:38:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236824AbiEXLiw (ORCPT ); Tue, 24 May 2022 07:38:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235816AbiEXLit (ORCPT ); Tue, 24 May 2022 07:38:49 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70052.outbound.protection.outlook.com [40.107.7.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E15654130C for ; Tue, 24 May 2022 04:38:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=C/oiYRUj+7CTbeqh3LZ5KQ3r/3sPTUhRcRkkub1QeEpv/H4HUPIqioAikjxnYcdivOpbrInKB2BIUoPajYGs5QoiDq4Yb4D5T86uD9+hrUoHCmoyeNAbFmlpzydzBU7DiOUtfy8yj5hXatuOaX02o+lSXg4GrWwe1yVEwVEDAN1O+oEjB6ly4JODm+JczpUYUwHdr82pmhoJhdQKE3gt/pT7q2IsV16MLK9KHLqJmbWszc/KTOpNSxpu4fuXb+ucijsZmSRo57s7sXH+Slh0bqvJc6/W619CM3Ga6lK5n7sl2jY4Cx+8u8HRVTi0uJSSn3Rrb6411Jmf9CmpbQqhWQ== 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=34gWxQjNsWnRqnKnL7hgF8K8oGx292n9Ds70+XyAb1E=; b=nQaWaju465OqlpEw6ZwAFX9bCj/0Uo6NgbmDfUSYmcz3nJlH/QZAfFSoZLWiKAbLURh4da9uudiosh5N1xgfg7jGeulKdrpB7v5AVKG4DyuQG2sj1VehdoiRhx+FVYjbpKf68UNRaqgCZQIdnVsSqWntcHio3G9lg8D1iAUuflohJOF53Vm1Y90KIZI6M9IJqyqelmW8oLhyO97WJ+27Ac72qfo/tjqn2oNKNluFQmZ0H5bbynmIJ2nb+//TFywBBdxjoXHH5K3CSXQ6LW0QuioJ+MAQFNixjh3fjL+PB5uT4g5c9U9/AYdAnkp951GgwP7cRJAmOL6YUdcIqIvhGg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=34gWxQjNsWnRqnKnL7hgF8K8oGx292n9Ds70+XyAb1E=; b=OuBM0aZNZkZbE2Pff++OhQEjma/SN81/krdICa/AUo9hvhnL65dEejgygMTNnokWX3q8/j29HwD5kox/ZC1E6OuZdw+nhxBZMKOr3Ljl/mIK89vxIFN42gdjbrHfURVsYiyYhORSxdV2JfUOHiZOw+ZpHogjXKwu40qodfBJ5zA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:38:02 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:02 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 26/96] cl8k: add eeprom.h Date: Tue, 24 May 2022 14:33:52 +0300 Message-Id: <20220524113502.1094459-27-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d5094714-0b42-40e3-3d00-08da3d79dc5a X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: iXXmCPnNL/cpt0ShRn+5LWf/znLSWuikuHhTUaGs0cjm5ddsvQO1HmmwLRS7sIaI4vtBHy5++iqJKKJP8o86+kSH9dqj6r7vsfNTe3olVXztw5bwVUfhmms00ZS8GteawsPg39tmhSSIqIDDmCyE2wUpBG19sWLLGVtuCE+5elHGg1DiBzvx2CaZTLZVz6jC6evhqpCvT+uM/kYvjv4yeP92NNygujAprHJxFaA7Z1YzO4sAFhqe0jVlzbrIa2+RIjzzMVPuUpl6VIIfqpSc1+SjSONhravCBgs9iGdf4fHMXzdB/AUIjQ4gVwTpHEhvgYv21LaORSAV9bMjlLZgbbtkPEh2QZIOGkF+kyQRe3UDBqaZvPwoNpTDHk1IvgFYqPUPKPSGbqcmXEHnC05y3VchkmfpT1dl7uTwgWzCwGWwGriea7tdB5NiA1BU6+fYrYQUmR/80fHdP2h51V34e9LDLA0EeKW9QVzRbNiIm2SlJnMlUzI25jwHhGG8GpUCGd11d5FuKSmaPz+XToWSHL9OJw8rGzyBhofNlsruhkW2iWTAHHpShaiJ6ocMMUlTIjHTFhcw5vqGNnO2S8Rh4dPlDYFWfGAz8E0xIenwweQLBakptTnidHAx7BUa3M9dWEQgCP2btCJ20XLR1jl4JdSQMLWZ3bkJtCEn17JqHfByJHljVXOOJFcrnMccsHAG0+SIjrKZ09cbDhAgm1IrgCp+TZf0uKX/m7ro2YRcJVQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(30864003)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 3V18H+xqz+L4cq38/KtkIlN2VjJqBBxAGl401hnfuFSo9IC+ry+GRdJI8LXt4rwGAY83fi/0zD2dzNhW50W7pNHcZfFABt84j8nFkITdfMoThmllAjrbTH+4BMz0AO8sCSdsJyE6oFKOG155NEmqPjMl1D/C8JwCM64WjTesgZjhSdMoP6r/dT8wH0rW4/qzVkaT7UVsH1ysVpf2MYVwJAzu8RH+/NjghFwDfYaYJLQjItiN4vC31T3pvatYakLkPMqVUtvUgvNueaRDSLFHgllTn7ZGjVc7/Dly4R7suSosRBiBD1VqdGlflBEd+14B2kDbkLSAiMhMs0qHpmNeyhieogOFhA+sqkwsVzIpVgzIDgI8iqy7kG+QN0StmfzYuqTsjYk06mKYlGe4x8dUhz4OzPC+OM7K5xZYvq9akBPOOMj0NJVegSgNkQzj7dzK59NiXmu0BDTWV5TWoGASANztTH6a/8e0QI/QNhBahLONeJFNCUi/E8auQJ8u4ZNsePca4v137Z6KZuYEPBtsjH4XI5jZlP8V+lhRTDv4d+hDotE6SWlyODh7rWjyeAlxyIm8a3noswImcT/HuDPoCDI3PXIk3MEcWUSrKJTHmIbRxwKmJvaHKCsJJaLsl2CI9FBKPj8jGi1rd/VV9ld1/mjFv07p/WxO8u58eEorJTIJZ/kQMmyw34Hm4QYS09JnGst08Pvl9r0DqH1p9WHqilx2ZvF4djEfBeuW7BW6ic0y8+S2mJpSOL6cYX9ABeMbmxFmLHoNTjAk6XOBPnlobiM7pEfFrUTJ+Deh+SsFVvFlB1vQyipNKrGgSAJV0vgmjtRFqXMmPCNTnUCuxZL5zsiXkI+DODc4wJTKwg6zZItsuKCPK8ZrkYd7T5D3eyIOaAlLdksmoEWsTqYDsqkwhB1hKM4l9digIIQ5tGLuFsodDb/ChYFAKKmrKDdWG+2e6PSSRWApiam1NhWjOQMy3fZ1v+NiPrz1/L/mvA8UqaiiWBzuw+j/9D41XJdVYsz/s/EF+/UGGIxkSAmp8fMuXOw0sm3fKlqul7EtsH6mhvsN3o8JQYeElrvaprRd4n6uU/iJKoSWWTYBaGqnQlywA2hWVXomxIR5ynw/xdVNUBTFvMXuW1otLTHonxp8SbRbk9Z8QfTBJJqAe5d2eMXCY/dXHcRrNIE6CJJPzcgNkneujcZC+lFOI9rOrFjZip07pZVk8EFKETC1xvl6LzCWf9415gtF8LZIswDszfVXPdtHrnaoZaGNCdXq/J+wDHHBSUYSeHigajXcX5WIzpOwGQCsR6lgQXm86LcUGT4/Rbvf+9oG4qSLJuPbvNpFWAX7jZGrTgUFWgJbsfw+PNwWvnIWPhoVEu8obF9IxQ7b5q+v4VAUkoajz12FzyYz0+eyR8Nhhsg6QTQB/Ktw29gQCwBOul4AIbYjKphKbVx1GRtiXcJxNGfOAiG0sR211g9Szi7caXsm06u2PJwYRG+D+yBQKy1eQQ9stl1U3l+r6jwxnvIhaWyHfHx5htrSnTuh/iLjnYLpZO+t7uitCc9rbRTAEvrX0WmvgfE5uqcgtDJLAvx+nojqKnW2ZQ+03XYVO1PVqh4lAUxRN1jzY+c/jeLg1/6xkRl1IpDzb6vCuAlr4Lncy2TpNJyc61XA2hGb/WGgZn8crTw9L/9cOKliMfL/mojGwLDIiXgH9Xt7ulCs+q1z0FleRfbrb1uC9Scx7kAmtHSYfmkw178XBMSmb5UdDd9aJNS+sL/pgb9/mJI= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d5094714-0b42-40e3-3d00-08da3d79dc5a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:02.5303 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: AzBeuHoCbDT7EC8tRBPOxDT1NxIxeGKb/2wbKw0lHpR34v+A7ZPyA8kGFep0jXLoVpZiD6q9EQCcFV641DYJHw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/eeprom.h | 283 ++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/eeprom.h diff --git a/drivers/net/wireless/celeno/cl8k/eeprom.h b/drivers/net/wireless/celeno/cl8k/eeprom.h new file mode 100644 index 000000000000..2680af90484b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/eeprom.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_EEPROM_H +#define CL_EEPROM_H + +#include + +#include "def.h" +#include "phy.h" +#include "calib.h" + +#define SERIAL_NUMBER_SIZE 32 +#define BIT_MAP_SIZE 20 +#define EXT_BIT_MAP_SIZE (BIT_MAP_SIZE * 2) +#define NUM_OF_PIVOTS 20 +#define NUM_PIVOT_PHYS (MAX_ANTENNAS * NUM_OF_PIVOTS) + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +#define BIT_MAP_SIZE_20MHZ_TCV0 9 +#define BIT_MAP_SIZE_20MHZ_TCV1 6 +#define BIT_MAP_SIZE_40MHZ_TCV0 4 +#define BIT_MAP_SIZE_40MHZ_TCV1 4 +#define BIT_MAP_SIZE_80MHZ_TCV0 2 +#define BIT_MAP_SIZE_80MHZ_TCV1 2 +#define BIT_MAP_SIZE_160MHZ_TCV0 1 +#define BIT_MAP_SIZE_160MHZ_TCV1 3 + +#define EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0 10 +#define EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1 7 +#define EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0 9 +#define EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV1 7 +#define EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0 8 +#define EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1 6 +#define EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV0 6 +#define EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV1 2 +#endif + +struct eeprom_hw { + u8 reserved[96]; +} __packed; + +struct eeprom_general { + u8 version; + u8 flavor; + u8 mac_address[6]; + u8 temp_diff; /* Default value TEMP_DIFF_INVALID = 0x7F */ + u8 serial_number[SERIAL_NUMBER_SIZE]; + u8 pwr_table_id[2]; + u8 reserved[53]; +} __packed; + +struct eeprom_fem { + u8 wiring_id; + u16 fem_lut[FEM_TYPE_MAX]; + u32 platform_id; + u8 reserved[19]; +} __packed; + +struct eeprom_phy_calib { + s8 pow; + s8 offset; + s8 tmp; +} __packed; + +struct point { + u8 chan; + u8 phy; + u8 idx; + u16 addr; + struct eeprom_phy_calib calib; +} __packed; + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +struct iq { + __le32 coef0; + __le32 coef1; + __le32 coef2; + __le32 gain; +} __packed; + +struct score { + s8 iq_tx_score; + s8 iq_tx_worst_score; + s8 iq_rx_score; + s8 iq_rx_worst_score; + s16 dcoc_i_mv[DCOC_LNA_GAIN_NUM]; + s16 dcoc_q_mv[DCOC_LNA_GAIN_NUM]; + s32 lolc_score; +} __packed; + +struct eeprom_calib_data { + u8 valid; + u8 temperature; + u32 lolc[MAX_ANTENNAS]; + struct cl_dcoc_calib dcoc[MAX_ANTENNAS][DCOC_LNA_GAIN_NUM]; + struct iq iq_tx[MAX_ANTENNAS]; + struct iq iq_rx[MAX_ANTENNAS]; + struct score score[MAX_ANTENNAS]; +} __packed; +#endif + +struct eeprom_calib_power { + u16 freq_offset; + u8 chan_bmp[BIT_MAP_SIZE]; + struct eeprom_phy_calib phy_calib[NUM_PIVOT_PHYS]; +} __packed; + +#ifdef CONFIG_CL8K_EEPROM_STM24256 +struct eeprom_calib_iq_dcoc { + u8 calib_version; + u8 chan_20mhz_bmp_tcv0[BIT_MAP_SIZE_20MHZ_TCV0]; + u8 chan_20mhz_bmp_tcv1[BIT_MAP_SIZE_20MHZ_TCV1]; + u8 chan_40mhz_bmp_tcv0[BIT_MAP_SIZE_40MHZ_TCV0]; + u8 chan_40mhz_bmp_tcv1[BIT_MAP_SIZE_40MHZ_TCV1]; + u8 chan_80mhz_bmp_tcv0[BIT_MAP_SIZE_80MHZ_TCV0]; + u8 chan_80mhz_bmp_tcv1[BIT_MAP_SIZE_80MHZ_TCV1]; + u8 chan_160mhz_bmp_tcv0[BIT_MAP_SIZE_160MHZ_TCV0]; + u8 chan_160mhz_bmp_tcv1[BIT_MAP_SIZE_160MHZ_TCV1]; + struct eeprom_calib_data + calib_20_data_tcv0[EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0]; + struct eeprom_calib_data + calib_20_data_tcv1[EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1]; + struct eeprom_calib_data + calib_40_data_tcv0[EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0]; + struct eeprom_calib_data + calib_40_data_tcv1[EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV1]; + struct eeprom_calib_data + calib_80_data_tcv0[EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0]; + struct eeprom_calib_data + calib_80_data_tcv1[EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1]; + struct eeprom_calib_data + calib_160_data_tcv0[EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV0]; + struct eeprom_calib_data + calib_160_data_tcv1[EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV1]; +} __packed; +#endif + +struct eeprom { + struct eeprom_hw hw; + struct eeprom_general general; + struct eeprom_fem fem; + struct eeprom_calib_power calib_power; +#ifdef CONFIG_CL8K_EEPROM_STM24256 + struct eeprom_calib_iq_dcoc calib_iq_dcoc; +#endif +} __packed; + +enum { + ADDR_HW = offsetof(struct eeprom, hw), + ADDR_HW_RESERVED = ADDR_HW + offsetof(struct eeprom_hw, reserved), + + ADDR_GEN = offsetof(struct eeprom, general), + ADDR_GEN_VERSION = ADDR_GEN + offsetof(struct eeprom_general, version), + ADDR_GEN_FLAVOR = ADDR_GEN + offsetof(struct eeprom_general, flavor), + ADDR_GEN_MAC_ADDR = ADDR_GEN + offsetof(struct eeprom_general, mac_address), + ADDR_GEN_TEMP_DIFF = ADDR_GEN + offsetof(struct eeprom_general, temp_diff), + ADDR_GEN_SERIAL_NUMBER = ADDR_GEN + offsetof(struct eeprom_general, serial_number), + ADDR_GEN_PWR_TABLE_ID = ADDR_GEN + offsetof(struct eeprom_general, pwr_table_id), + ADDR_GEN_RESERVED = ADDR_GEN + offsetof(struct eeprom_general, reserved), + + ADDR_FEM = offsetof(struct eeprom, fem), + ADDR_FEM_WIRING_ID = ADDR_FEM + offsetof(struct eeprom_fem, wiring_id), + ADDR_FEM_LUT = ADDR_FEM + offsetof(struct eeprom_fem, fem_lut), + ADDR_FEM_PLATFORM_ID = ADDR_FEM + offsetof(struct eeprom_fem, platform_id), + ADDR_FEM_RESERVED = ADDR_FEM + offsetof(struct eeprom_fem, reserved), + + ADDR_CALIB_POWER = offsetof(struct eeprom, calib_power), + ADDR_CALIB_POWER_FREQ_OFFSET = ADDR_CALIB_POWER + + offsetof(struct eeprom_calib_power, freq_offset), + ADDR_CALIB_POWER_CHAN_BMP = ADDR_CALIB_POWER + + offsetof(struct eeprom_calib_power, chan_bmp), + ADDR_CALIB_POWER_PHY = ADDR_CALIB_POWER + + offsetof(struct eeprom_calib_power, phy_calib), + +#ifdef CONFIG_CL8K_EEPROM_STM24256 + ADDR_CALIB_IQ_DCOC = offsetof(struct eeprom, calib_iq_dcoc), + ADDR_CALIB_IQ_DCOC_VERSION = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_version), + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_20mhz_bmp_tcv0), + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_20mhz_bmp_tcv1), + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_40mhz_bmp_tcv0), + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_40mhz_bmp_tcv1), + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_80mhz_bmp_tcv0), + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_80mhz_bmp_tcv1), + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_160mhz_bmp_tcv0), + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, chan_160mhz_bmp_tcv1), + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_20_data_tcv0), + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_20_data_tcv1), + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_40_data_tcv0), + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_40_data_tcv1), + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_80_data_tcv0), + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_80_data_tcv1), + ADDR_CALIB_IQ_DCOC_DATA_160MHZ_TCV0 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_160_data_tcv0), + ADDR_CALIB_IQ_DCOC_DATA_160MHZ_TCV1 = ADDR_CALIB_IQ_DCOC + + offsetof(struct eeprom_calib_iq_dcoc, calib_160_data_tcv1), +#endif + SIZE_HW = sizeof(struct eeprom_hw), + SIZE_HW_RESERVED = ADDR_GEN - ADDR_HW_RESERVED, + + SIZE_GEN = sizeof(struct eeprom_general), + SIZE_GEN_VERSION = ADDR_GEN_FLAVOR - ADDR_GEN_VERSION, + SIZE_GEN_FLAVOR = ADDR_GEN_MAC_ADDR - ADDR_GEN_FLAVOR, + SIZE_GEN_MAC_ADDR = ADDR_GEN_TEMP_DIFF - ADDR_GEN_MAC_ADDR, + SIZE_GEN_TEMP_DIFF = ADDR_GEN_SERIAL_NUMBER - ADDR_GEN_TEMP_DIFF, + SIZE_GEN_SERIAL_NUMBER = ADDR_GEN_PWR_TABLE_ID - ADDR_GEN_SERIAL_NUMBER, + SIZE_GEN_PWR_TABLE_ID = ADDR_GEN_RESERVED - ADDR_GEN_PWR_TABLE_ID, + SIZE_GEN_RESERVED = ADDR_FEM - ADDR_GEN_RESERVED, + + SIZE_FEM = sizeof(struct eeprom_fem), + SIZE_FEM_WIRING_ID = ADDR_FEM_LUT - ADDR_FEM_WIRING_ID, + SIZE_FEM_LUT = ADDR_FEM_PLATFORM_ID - ADDR_FEM_LUT, + SIZE_FEM_PLATFORM_ID = ADDR_FEM_RESERVED - ADDR_FEM_PLATFORM_ID, + + SIZE_CALIB_POWER = sizeof(struct eeprom_calib_power), + SIZE_CALIB_POWER_FREQ_OFFSET = ADDR_CALIB_POWER_CHAN_BMP - ADDR_CALIB_POWER_FREQ_OFFSET, + SIZE_CALIB_POWER_CHAN_BMP = ADDR_CALIB_POWER_PHY - ADDR_CALIB_POWER_CHAN_BMP, +#ifdef CONFIG_CL8K_EEPROM_STM24256 + SIZE_CALIB_POWER_PHY = ADDR_CALIB_IQ_DCOC_VERSION - ADDR_CALIB_POWER_PHY, +#else + SIZE_CALIB_POWER_PHY = sizeof(struct eeprom_phy_calib) * NUM_PIVOT_PHYS, +#endif + +#ifdef CONFIG_CL8K_EEPROM_STM24256 + SIZE_CALIB_IQ_DCOC_VERSION = ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV0 - + ADDR_CALIB_IQ_DCOC_VERSION, + SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV1 - + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_20MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV0 - + ADDR_CALIB_IQ_DCOC_CHANNEL_20MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_40MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV1 - + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_40MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV0 - + ADDR_CALIB_IQ_DCOC_CHANNEL_40MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_80MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV1 - + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_80MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0 - + ADDR_CALIB_IQ_DCOC_CHANNEL_80MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_160MHZ_BMP_TCV0 = ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1 - + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_160MHZ_BMP_TCV1 = ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV0 - + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_20MHZ_TCV0 = ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV1 - + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_20MHZ_TCV1 = ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV0 - + ADDR_CALIB_IQ_DCOC_DATA_20MHZ_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_40MHZ_TCV0 = ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV1 - + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_40MHZ_TCV1 = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0 - + ADDR_CALIB_IQ_DCOC_DATA_40MHZ_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_80MHZ_TCV0 = ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1 - + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_80MHZ_TCV1 = ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0 - + ADDR_CALIB_IQ_DCOC_DATA_80MHZ_TCV1, + SIZE_CALIB_IQ_DCOC_DATA_160MHZ_TCV0 = ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1 - + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV0, + SIZE_CALIB_IQ_DCOC_DATA_160MHZ_TCV1 = sizeof(struct eeprom_calib_data) * + ADDR_CALIB_IQ_DCOC_CHANNEL_160MHZ_BMP_TCV1, + EEPROM_BASIC_NUM_BYTES = sizeof(struct eeprom) - sizeof(struct eeprom_calib_iq_dcoc), +#else + EEPROM_BASIC_NUM_BYTES = sizeof(struct eeprom), +#endif + EEPROM_NUM_BYTES = sizeof(struct eeprom), + + EEPROM_LAST_BYTE = EEPROM_NUM_BYTES - 1, +}; + +#endif /* CL_EEPROM_H */ From patchwork Tue May 24 11:33:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575977 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 F288FC433FE for ; Tue, 24 May 2022 11:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236828AbiEXLiy (ORCPT ); Tue, 24 May 2022 07:38:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236819AbiEXLiu (ORCPT ); Tue, 24 May 2022 07:38:50 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70041.outbound.protection.outlook.com [40.107.7.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7484279828 for ; Tue, 24 May 2022 04:38:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=i6ZJsfEfy9B7z88h1pbP7dvUjGAwFVhNjHkn66e8yy11mjtLJWM+Ouc/Qe7gVDhzrz8Uho6r2nuCBOYV3+ssN+t62n5g7alknmX4Otocz4vFSBEHKDN26TsyiVLUp2Z8Ybj1bnlBkSP9F55zP/eu5kKtXmLvgMKBZCCgyeRRfqBAhp8VeJFZILakn4BPqLAnrdhjA60UwVs6Z4jPGu5wwtLHMDiRBcjALCCXgU1guU45AJK8uTI5fe48VFsW5UJxAl8CXVZ6XMuGPSDhMyruhin/mb/KeKLhrB2RRmp7WhLXLJf9mMcMt2ORc/YycrkNSx6ue/waoa2zJQrrRZwE1A== 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=daaN8cov8RRoxAdX/xwqo1j8Z7No5bLADTD+H4jsGms=; b=ZtwVaqyAdOP03YpHnL1A+5a0tdHKGKxqxgHM+E1u4mxyLbZQLuK8sN9dKSvBcosySxZDMsP8AmPmh4vEDEmlWebuJh7XgK+RhJVaN74MswYUHHoNqQwE+J5IPA/egit17bz2EzSsa/biqmPC8ACDtEsj8NpeiKfjoo35yX5jqhpSqDZP1r3rNnl7q4Dyunj5uRHg+uc6qbE38usdfQBTTMMgm5ldvyaqNcZQF3YtVOP/luKhl9DupGe9OgW/nsW7UIdOKPVeTQwKHi1rVGf3UBdRMWp6MrbPEMi61YVYsNmxClLCWuziuD4L0U50TOD6ozzb4eX/CPNFP7cOcruZ5A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=daaN8cov8RRoxAdX/xwqo1j8Z7No5bLADTD+H4jsGms=; b=n+ftqe7bnidfQYqWlPhqqNyjfvU+/F8HDgg91NlCAK9tHVq8NOLJeh7jAJkHVXULo84v0IzIfRCfSkIJerVsKOMBrQpYtYUOXxgCW1XtXjQI32LonKV0mhJm5XtamdsdXyIxiQ3fDyvKWBhw2jvDiNpCwhxd7ma3ocrEVq0oyCI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM6P192MB0469.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:32::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:38:03 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:03 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 27/96] cl8k: add ela.c Date: Tue, 24 May 2022 14:33:53 +0300 Message-Id: <20220524113502.1094459-28-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7d0adce3-d62a-47ac-ffed-08da3d79dcd3 X-MS-TrafficTypeDiagnostic: AM6P192MB0469:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yiaoEEeJwgzvULvx36d04fNE3bjnFZ+oU554uGX7iMFq0YTOqW29laAB6NPy0r5eE4M6sMhkUV6SwiMtwnHgKaj3pOtsMbcPXl3gpTCBY5HwixX2aABNs0EmyUQvt2g5twa7gcRkLPQC0OfkA9CEvJXO4HTRlNhe72bpfPN/VaBBtdmaRj3Eb2zWGq04eVk298qld3FHeZLjRJblZsiA4kdT2vcZBXi8vPrCG2XEhAmVqPDLPh9Bx9R5de1Fzi8V8DtSDSM/mYw7MqtIYVa8TrUNpWYDaCJ5HNF+/MwyW1l+SNRCXoSUYBpF1jS0i1kSOLdshuWTlwaYd9BnJM7WlkF/sx8CGPRx8F1EnKnXJnQzTfcdIYj1Bbb2WX9fwWg4Kwy7ukwTE0GxdRLsPJ5SErPxkVlHpKei8ttx7Kuek1B2eGgswL3fHxdfUh9/HNHbiS2pWCgGhxcDrMSKdt3BgwMlh3NAs9vtDBwu9ZpHWyBHsx2nqBVE00oYBs2+dwJClvS8CoNrdP3hJlMNSp4LHrlUzkh50PkjNMIi+Nl6ReGS4JXutQHD5BRNi/0X48w0zhGjob3PJiVAUO3Ba86K0akf4yorVgG4Va/Zgd+G3Afr9XFNJ9GrRpMlW0VABsO5nIEBvlEd4F+9XLJrE3BdLnQaYSHzrn3rK+G7nZKJQ54bxc1WdZroEulu2Z7c+FhyobNBeVxXBTHvQnCX6OayT4yPM/XXNWBhIlFdS4bWkqaWUCfsCojRrcmyXTaj7zqkmw+9ThrtV48Z8jwI0wMYVA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(346002)(376002)(136003)(366004)(39850400004)(6486002)(6916009)(508600001)(8936002)(86362001)(2906002)(5660300002)(4326008)(1076003)(83380400001)(36756003)(38100700002)(41300700001)(52116002)(186003)(66556008)(2616005)(6506007)(6512007)(26005)(316002)(54906003)(107886003)(8676002)(9686003)(66476007)(38350700002)(66946007)(6666004)(32563001)(309714004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: uZPq8H0a5CCngy0j6j4wMLHPoDIYvMX2PK+7kn/0Fbj8Nch3sYvJxV6Ol07/cAvG/14Rmqr5rOQdSQnmML2x+km2eG1XpdZmux1deX/udxbOfaWpqYSCUULNqAUBDCwRpW0y9LljCmuKadu6gbQ4niNfrmO/jGhub6rIKMfqpOCo1f7EtBrotCwzkQBfuSf/lx4nC4R/Qx9FmQ0PIlbk7W1Wa75yZ+73m/3fzk/YUY4vuWSfnJoWNt3pOx6GRg4GvODXE0lIcg4W6QqgdferQvx8iOzBtC92b+bbbqU+fgEYM8/IFECpu2tWnfcHu9QS4Ng0OVg02Oc40vTOndm14MV0STKojNbew6KvOlNe4ggn3hm5YiSkluFkhQb5cjWPZQgo8DcYoVcBczsDfbIAN6HKZlDjZDy8HXGkh+6Fn2a3Q/aANnCm8u/tuDXy4LyK42Ts5ETPSglYOaODQqiJMnGEVNs5TLLAgdfvKQfFpiMiZHfB7MkiPu4nQ07bmvL25D0VEpc46D+JnI5tA4Q7iRTTlDl69wsdnqCkgWODza1T1ejjFJCD+XR+QyUfr8PKNpgjdPkJQGQyC36zbqJwX4tv43Q06cuZRyhTV5hVJGlD7ZuUgaQSph/ES7u3xG4Ng+076sq8pQ0lX+yp43pFXuvY1JP+MX346EvPQISJKkDv802Yyqs9zf3haxapb4NrzNvPzIsQ6+0QFjjokiYWKCCZYnZvnxRkF43PBMNxmVGOYjrLaMje56fH1durfogXJDlWvFhCOENj3uHUynvNFq+6uiZLH/Vlc7VWz/HWv0Wd/ge+qjLmKa+G77peOwzwuVKtTCOR6RMG3ylbZSGl4+vGb9rhotKtn06JqMs0MUnXkAe2kf//3IPmwrt1EWdN733fSx+H0+ek7O8h55WHw3+NRHXyVocjZA9hImA5exHesxbbsNgbGO6OrDmUwhtyVnse/GKDPDkoMTz1No7XsZHYaLgiSF3Mjo6R1Flgd4CmZ0LirijScpJKxKbzZcnN69PkK8Vjkq5wQdUzBAuB+N0TY47JZefK2AGu4o1uNtur5YXdgz16a29btTDZ5NO1dye5gNRoqrAA51LYcqESbifSR/zA0WtZz+oiLbyR3qagvkeQdCjQ7F5VbeuufpJ/0uNTqhlFXib8IwLNKo6iF7CrWfgvSf37kcGKFVGqdgmmBfI74HSEKELpXFKgUtmLBU7aIQhOd46rak2k9ALLuKApgNnMBtZKptZPosiK0xBRLdDwUNt27/Wnde+MYuNe78g6XT14tn5YYT3IxDK3YRXR+p7Hl4KD4kP7W+04dtPiL/xh1g2boWwjV5sYmZEke2tidCYgUqwcXWnR+lLfPbCEp0liougispqbQkkIVv6RD1nHmmhi14MgrhI6TDXumkv+puMwYTfMgc4GF6aL5jvVlpRa3ObPXVPlnUVM79u/uhRnt5kSu1XZMWhrtpOHsXTDwjgRxL/Kq3NcelOy2UEQUFacy8YGArrPxtT+H+3OaDLkyMb40qYLDbbmoH2yFiHayRLlZOcM1bLT56jUC46M7CYFuW8bsiWT/2iwf5hWb4MbJBOJuD4IKEsQATM7QrQ7xGBgrhjkCU9gfUuqi1l7exkzrciOJ8ERiHcJ9Ud2o9KedUzxPTe6FJz1RjfPBbEzAuPIIaV3YKjMxkxFQk1C207CgXFVZDckjw7h+PL5UF+Ainw8KeJcJYaAI3e+v+Rkf+t+X4pBC0wkpxqq5b7Rw46h8wimjnpY24tfxqA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7d0adce3-d62a-47ac-ffed-08da3d79dcd3 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:03.2814 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 39uwfPDE8BCdwlbREKCHdAAFglEaf0BcKEC8zdmydWy5Tll7hHj5qTwUaAdoTjIx57WB8qAgIAAzEWZkbR5tMg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6P192MB0469 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/ela.c | 230 +++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/ela.c diff --git a/drivers/net/wireless/celeno/cl8k/ela.c b/drivers/net/wireless/celeno/cl8k/ela.c new file mode 100644 index 000000000000..c2419b11b5c0 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/ela.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2021, Celeno Communications Ltd. */ + +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "utils.h" +#include "ela.h" + +#define CL_ELA_MODE_DFLT_ALIAS "default" +#define CL_ELA_MODE_DFLT_SYMB_LINK "lcu_default.conf" +#define CL_ELA_MODE_DFLT_OFF "OFF" +#define CL_ELA_LCU_CONF_TOKENS_CNT 3 /* cmd addr1 addr2 */ +#define CL_ELA_LCU_MEM_WRITE_CMD_STR "mem_write" +#define CL_ELA_LCU_MEM_WRITE_CMD_SZ sizeof(CL_ELA_LCU_MEM_WRITE_CMD_STR) +#define CL_ELA_LCU_UNKNOWN_CMD_TYPE 0 +#define CL_ELA_LCU_MEM_WRITE_CMD_TYPE 1 +#define CL_ELA_LCU_UNKNOWN_CMD_STR "unknown" + +static int __must_check get_lcu_cmd_type(char *cmd) +{ + if (!strncmp(CL_ELA_LCU_MEM_WRITE_CMD_STR, cmd, CL_ELA_LCU_MEM_WRITE_CMD_SZ)) + return CL_ELA_LCU_MEM_WRITE_CMD_TYPE; + + return CL_ELA_LCU_UNKNOWN_CMD_TYPE; +} + +static int add_lcu_cmd(struct cl_ela_db *ed, u32 type, u32 offset, u32 value) +{ + struct cl_lcu_cmd *cmd = NULL; + + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + if (!cmd) + return -ENOMEM; + + cmd->type = type; + cmd->offset = offset; + cmd->value = value; + + list_add_tail(&cmd->cmd_list, &ed->cmd_head); + + return 0; +} + +static void remove_lcu_cmd(struct cl_lcu_cmd *cmd) +{ + list_del(&cmd->cmd_list); + kfree(cmd); +} + +static void reset_stats(struct cl_ela_db *db) +{ + memset(&db->stats, 0, sizeof(db->stats)); +} + +static int load_cmds_from_buf(struct cl_chip *chip, char *buf, size_t size) +{ + struct cl_ela_db *ed = &chip->ela_db; + char *line = buf; + char cmd[STR_LEN_256B]; + u32 type = CL_ELA_LCU_UNKNOWN_CMD_TYPE; + u32 offset = 0; + u32 value = 0; + int tokens_cnt = 0; + int ret = 0; + + while (line && strlen(line) && (line != (buf + size))) { + if ((*line == '#') || (*line == '\n')) { + /* Skip comment or blank line */ + line = strstr(line, "\n") + 1; + } else if (*line) { + tokens_cnt = sscanf(line, "%s %x %x\n", cmd, &offset, &value); + cl_dbg_chip_trace(chip, + "tokens(%d):cmd(%s), offset(0x%X), value(0x%X)\n", + tokens_cnt, cmd, offset, value); + + type = get_lcu_cmd_type(cmd); + if (type == CL_ELA_LCU_UNKNOWN_CMD_TYPE) { + cl_dbg_chip_trace(chip, "Detected extra token, skipping\n"); + goto newline; + } + if (tokens_cnt != CL_ELA_LCU_CONF_TOKENS_CNT) { + cl_dbg_chip_err(chip, + "Tokens count is wrong! (%d != %d)\n", + CL_ELA_LCU_CONF_TOKENS_CNT, + tokens_cnt); + ret = -EBADMSG; + goto exit; + } + + ret = add_lcu_cmd(ed, type, offset, value); + if (ret) + goto exit; + +newline: + line = strstr(line, "\n") + 1; + } + } + +exit: + ed->stats.adaptations_cnt++; + return ret; +} + +void cl_ela_lcu_reset(struct cl_chip *chip) +{ + lcu_common_sw_rst_set(chip, 0x1); + + if (chip->cl_hw_tcv0) + lcu_phy_lcu_sw_rst_set(chip->cl_hw_tcv0, 0x1); + + if (chip->cl_hw_tcv1) + lcu_phy_lcu_sw_rst_set(chip->cl_hw_tcv1, 0x1); +} + +void cl_ela_lcu_apply_config(struct cl_chip *chip) +{ + struct cl_ela_db *ed = &chip->ela_db; + struct cl_lcu_cmd *cmd = NULL; + unsigned long flags; + + if (!cl_ela_lcu_is_valid_config(chip)) { + cl_dbg_chip_err(chip, "Active ELA LCU config is not valid\n"); + return; + } + + /* Extra safety to avoid local CPU interference during LCU reconfiguration */ + local_irq_save(flags); + list_for_each_entry(cmd, &ed->cmd_head, cmd_list) { + cl_dbg_chip_info(chip, "Writing cmd (0x%X, 0x%X)\n", + cmd->offset, cmd->value); + if (!chip->cl_hw_tcv1 && cl_reg_is_phy_tcv1(cmd->offset)) { + ed->stats.tcv1_skips_cnt++; + continue; + } else if (!chip->cl_hw_tcv0 && cl_reg_is_phy_tcv0(cmd->offset)) { + ed->stats.tcv0_skips_cnt++; + continue; + } + cl_reg_write_chip(chip, cmd->offset, cmd->value); + } + local_irq_restore(flags); + ed->stats.applications_cnt++; +} + +bool cl_ela_is_on(struct cl_chip *chip) +{ + return !!strncmp(CL_ELA_MODE_DFLT_OFF, chip->conf->ce_ela_mode, + sizeof(chip->conf->ce_ela_mode)); +} + +bool cl_ela_is_default(struct cl_chip *chip) +{ + return !strncmp(CL_ELA_MODE_DFLT_ALIAS, chip->conf->ce_ela_mode, + sizeof(chip->conf->ce_ela_mode)); +} + +bool cl_ela_lcu_is_valid_config(struct cl_chip *chip) +{ + struct cl_ela_db *ed = &chip->ela_db; + + return ed->error_state == 0; +} + +char *cl_ela_lcu_config_name(struct cl_chip *chip) +{ + if (!cl_ela_is_on(chip)) + return CL_ELA_MODE_DFLT_OFF; + + if (cl_ela_is_default(chip)) + return CL_ELA_MODE_DFLT_SYMB_LINK; + + return chip->conf->ce_ela_mode; +} + +int cl_ela_lcu_config_read(struct cl_chip *chip) +{ + struct cl_ela_db *ed = &chip->ela_db; + char filename[CL_FILENAME_MAX] = {0}; + size_t size = 0; + int ret = 0; + + if (!cl_ela_is_on(chip)) { + ret = -EOPNOTSUPP; + goto exit; + } + + reset_stats(ed); + + snprintf(filename, sizeof(filename), "%s", cl_ela_lcu_config_name(chip)); + size = cl_file_open_and_read(chip, filename, &ed->raw_lcu_config); + if (!ed->raw_lcu_config) { + ret = -ENODATA; + goto exit; + } + + ret = load_cmds_from_buf(chip, ed->raw_lcu_config, size); +exit: + ed->error_state = ret; + return ret; +} + +int cl_ela_init(struct cl_chip *chip) +{ + struct cl_ela_db *ed = &chip->ela_db; + int ret = 0; + + INIT_LIST_HEAD(&ed->cmd_head); + + if (!cl_ela_is_on(chip)) + return 0; + + ret = cl_ela_lcu_config_read(chip); + if (ret == 0) { + cl_ela_lcu_reset(chip); + cl_ela_lcu_apply_config(chip); + } + + return ret; +} + +void cl_ela_deinit(struct cl_chip *chip) +{ + struct cl_ela_db *ed = &chip->ela_db; + struct cl_lcu_cmd *cmd = NULL, *cmd_tmp = NULL; + + kfree(ed->raw_lcu_config); + ed->raw_lcu_config = NULL; + + list_for_each_entry_safe(cmd, cmd_tmp, &ed->cmd_head, cmd_list) + remove_lcu_cmd(cmd); +} From patchwork Tue May 24 11:33:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575983 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 E67ADC433EF for ; Tue, 24 May 2022 11:38:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236803AbiEXLiT (ORCPT ); Tue, 24 May 2022 07:38:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiEXLiO (ORCPT ); Tue, 24 May 2022 07:38:14 -0400 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80083.outbound.protection.outlook.com [40.107.8.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8897750440 for ; Tue, 24 May 2022 04:38:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=a/3JvZXWJadEnUojua6sfJOdLMkYC/OGK9klydXJcdL9eaw6I3o6tXeE4AtioDGZ/TzOXDV9Ju5SMi7ukmZcP7exoEZEnIvNVJEVaPlB0KzRO8ALtzmFTEpf0RypFtuR28Q6GkzEcm9zWJ2meSI0vYE6QrwwMUn64wTR+JvCmrXA++Xer4uiPIuuq8OmPHak/N6al9FvuYC4EeR1oRtf1jdj5H5qYW2q1I4xkwoRT2TYkXBXTi6GGrASm4i1y2hWsbI4qYFhvmQVFZ6Yft//Fcv43mKWQMJWrf2KnRPHtj2GNGjDIX2wSaBHULTZl1sg8wuwQ9zFjkeshp/qUAe1xQ== 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=bfPEhb2GCnLmNZAdirC+WHylsoqoq43L6itd9DV3PLg=; b=SkIUoXGsS0+9fiYzgbyPVJIg4j87RyWbRZDBwzIgLOdqYf/gZYCQtf/NQpeSJGVJ4bAWf6JOxedVb6zU/EthBpmgRnMkfso71xx5PEMJhkBYnqOvXAa6Z05wvy9pbSHjKWae5SMwP7Yi/PWuj25Ffg1SIb8kt8NXVodtjkIzRDCvzHssjEbDJGMo4dhrDEl9V2vtZIZGVE1Bm/A9xCqAyVwnfhwFKb7FUSK3oj/0rcsrCLgWavHWCt/FgjqX1LBJyi5KeKBPMtAKdgb0l3Qo5RfQYRHoeVnlb0tKKIYEZFLaplxOHDbTwJ9vyUwFaTRXiEAqgAEMrzoZwFBjWRoTFg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bfPEhb2GCnLmNZAdirC+WHylsoqoq43L6itd9DV3PLg=; b=yIirNEwGoRwjlXXoKFFigMq3ztG8iR5n3PrXe3/tHAVA0wPTclTOfGMsFjANosrsIjaJpSfEXlPbOB92A0cjr/J8Xm8DrJuXMcgPw6KRDQ6qtgVXHbuvJA5867gfUPZQqOCwKZfMn4t8Btb7mhG6BYin3K5MU3gmxkac7LIzyY0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:38:04 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:04 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 28/96] cl8k: add ela.h Date: Tue, 24 May 2022 14:33:54 +0300 Message-Id: <20220524113502.1094459-29-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0d0a7bc7-b17d-4ce5-a4d9-08da3d79dd4f X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: d8C60JCvZtPCOG/D6ZERMG+fgmnIEy4JSz8Y6YKGBIkJVsvtQvU7bTRmUhh3zxdrfqLU3Wb10DX9LQI7SNZis70dwBcSGqbqgUjipXGX8pXxykoQngFo4X2eL0Hp+BH71MMvZUgoZVBZS3jSXEPtpUwdqMSUxYu5BXwaywmkJ6RPUlvHjPrCtvBgdhJqsPgBMOSe9dA3JAK3uFiOp8b/SbDVQmCYNiGpWbsQuU60YHVOdtmkfXpTqwREOQb26G+VKD3UI6YZ/58/oG8Cid2+IY9pMrqn1N9obV6NppOz5uAgEGTA2J838bzRr/pnV8vHyJFI6MSrZXroaGaAbX7HS81LEaLGJI+16QYoSRA1A17PXkNHQLP/QdKq8zqnFeONBVzipJRBkTVpfpND78y9fbQxS60LDWheoI0HI5ftOExVslwDVpcKKsOWLKWEiuabSPQFeIlQlfKRWhTHZodMOuHeip2bpaAMUF9mG9wMgFCU4ssvwxEn8LprKv/ZsIp2k5mi9YB8GmgF1IgXUCcDcXsZfmdGdPPpIwFaG1cv2ZHsadGwXS8jDleGUNEcvqmZYvb6FkAk9KA7WWWjPIWxWE5qOdYr3GWOskUoN8MKLpDGJRy5dMmkNr6EUAqJAcqDdxuodzwqoNtdwSNT1826bgulW7qfmNK0v1yidNo7K5rnCy1en/4uWbVIFKCAaqf/3PHA+xzfoxmN8Ch6xbpjDjT2w0wiA8JO7wvJculqr0E= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: AESZ1USAIiemUyp8CC7Kc11guZBtJWNnulhGFv8uQmpoWD0ZjdV9+18G1xH4xiXtOU+KeNO7Nc8LM2iGmDrVRbc4o0NR2fIKOuxGiY99xj/rE0ju0z77bPHPGJExkdU5KaWXLJc2LNA21JBcOURgonXIRhURYplKdUdRP0jxBT59z9VjCIEB/NhYDyDPwC/GdhVFSPCCmVH2r88bRTUmMu4ak5oSjVlNBqysXly28Y4V0NKAmAb1dKb9aJNTkrI6xOsJOyCz5v3yJaKb5bglGLeYcflypJlCdmVG9C/EdiD0xJkqMdno6I3QADX7yfdxXIrrzd/DeVYe9GZGeezy6KZ9b6A8wtyOD0qBMkXde3u+bxzVRqZgQbKQTenCWcyOaHkx7vd05bHXJ9AMk26g1V7M6bmL9BIDNC2eKox6VxXuSgV9iMUTZq80ma85Ip2pRwRkYaSjL9A1YcLiOlIvcl7wXV2xoVClktJXDb5R4TXwWLrtXByhGvu5zC29r2sLfWZ24giYrgB9WoePFfF7YEIB9vcXPRpYuIfwL0PmO1dL1NAfXKG31KeuZuEYHQURe9OeST017Jad7cqmI5olk+nbS+BmnJtr0eIppCQn5riEWCMuN3unYsci6+yziXXcv3s8OtRXDgzLK+3QtAs09WbjQm28DuLS+rqkA0YDb456Dsn5aqirT02ui/qSrSeU88ChEZ+AmEhB2CKCETa1eLKHpcYuwQDsT1A653XzsoRWrxhAHYGBSuRmKNtocTR9XTa3ahFCTOL5elaZ5ftz/WAk2N0k6PhgGvi9IT0vEVDAmbQne3liGriKWy5mUfELxV/x2DOuEn4o4tf78OQ2qP26SEZXxbB9W/McbkNvV5F+TC4o222Mth6786ddiMEe40F/DjeL+uk0BWab4bvfxm5aExcSnfXFTtdbdgAd1KbDUOKn64VtwJpNs/+qeXUupyVR/HCeIT55tRg5+shkdYdTb0dTHQ3WrZpUImOuefvC9qk1QkUZAGFZjbDCN+x190eyk7jSdnIvm5YlSAX3t+sKuc9DL5VMW9HEtuJfboDrqGTEvgJbAhflXJaTcq1FksLUPn5Ka0vkwbeMK/zHT+C+VOAwr6l7uyVxhoyFwa3xMqTbMedzpQDUJQb+M0iq5ppz9nESz2/tMogdGYbA3dItC/W0UwjkZn9OsrVzrNWtNv0ccbNdDGSBpOqX3Le0eR4Zv4X2AdGttdYBU5r25N40SXNCyzAFm+J2KsEe5Brijba+8l0G7ha2Zn9PhVPaOYySpUbO4MvIyM4a0aBm34MziALz2x3j69j0Zh79wiExbew0WWoK1T94D/1YQvUmGchkaq/OPWO42bog6fX/wMDdIR/z6+2BioRlg5rcdUxUA5KRFDE6srCPhMd2I0BiK7QFl8llsGX9ehBQ/vYsGNVdm1l1wB1dzLBHh1N8twtTVZAxsBSyx2lPlzw9JfV/SfO+r/RGg7YdtdzDkJAzFrZ4Vh6aXK2+jNAYJ3Ck3sDSy4VIe0bvr2zP5XiNASzbxJjHfJqMAsMSLnk8ZcNIvH0ZR9COJnxvgsjrOAIyRdIWF+dWpZJnhUTGP1DhxcaW3QjWu0NZVAQOSY5oCMKmu4p3Cf4j3pT+ufrH5pSedt76xP5DLZZUXWSmupFgxwFf6bFyxy9I+8Ipr2smMpZWWQbbQPBtgh3XIkzq6v9gQYndd9OVws4ztVAyiw4QTmp7/vEkj0e+Q+8xvUjkttQUw6G9lye+CkSRInUSPM4O7Wo= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0d0a7bc7-b17d-4ce5-a4d9-08da3d79dd4f X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:04.1386 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9c+jr4RkH3oqTX3+xnnzaH+VIjuzMpweAZGOvUVx9r1YDy7aQ+OhZZ3OXlXjl4F8RRt6ZrMtC/Z2390s4YyLbw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/ela.h | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/ela.h diff --git a/drivers/net/wireless/celeno/cl8k/ela.h b/drivers/net/wireless/celeno/cl8k/ela.h new file mode 100644 index 000000000000..a0886c3a9331 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/ela.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_ELA_H +#define CL_ELA_H + +/** + * DOC: ELA (=Embedded Logic Analyzer) + * + * Chip contains built-in ELA with LCU (=Logic Capture Unit), that allows to + * collect profiling info. Collected data is aggregated via set of %cl_nlev + * elements, and saved inside special dump buffer (described by %cl_coredump) + * and fed to the userspace via DEV_COREDUMP subsystem. + * + * This layer is mandatory since it allows to set properly initial and + * post-recovery configuration. + */ + +struct cl_lcu_cmd { + u32 type; + u32 offset; + u32 value; + struct list_head cmd_list; +}; + +struct cl_ela_db { + char *raw_lcu_config; + struct list_head cmd_head; + struct { + u32 adaptations_cnt; + u32 applications_cnt; + u32 tcv0_skips_cnt; + u32 tcv1_skips_cnt; + } stats; + int error_state; +}; + +void cl_ela_lcu_reset(struct cl_chip *chip); +void cl_ela_lcu_apply_config(struct cl_chip *chip); +bool cl_ela_is_on(struct cl_chip *chip); +bool cl_ela_is_default(struct cl_chip *chip); +bool cl_ela_lcu_is_valid_config(struct cl_chip *chip); +char *cl_ela_lcu_config_name(struct cl_chip *chip); +int cl_ela_lcu_config_read(struct cl_chip *chip); +int cl_ela_init(struct cl_chip *chip); +void cl_ela_deinit(struct cl_chip *chip); + +#endif /* CL_ELA_H */ From patchwork Tue May 24 11:33:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575981 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 11531C433EF for ; Tue, 24 May 2022 11:38:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236801AbiEXLi1 (ORCPT ); Tue, 24 May 2022 07:38:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiEXLiY (ORCPT ); Tue, 24 May 2022 07:38:24 -0400 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80083.outbound.protection.outlook.com [40.107.8.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B57A28CCDC for ; Tue, 24 May 2022 04:38:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JVJz9aE1jVdaVVnVmUxBZ/0WbYVuGS0Z2Grw61kiPhgZT2dvONMfGYusPJdKpHsbx3hMKNMO1ydDgb+CofeEQ2UKuvkOpvdmIY0MHAkmfUM4GfXI3UVZDUsIkhd0i7O3IKaawoeSaZxyq0QouSGNaakH/OBbfSoPDBtYw0vepKOik9hmmwft+YM5hkCHnwY70ck9Iwe8GcHbcmV6pJFDQ9UZT5JEwStbXc/QetIsqLTQ+jZ0ST9AxCq2qTGtn/qN2ktnOnh/Bjc0ufPXCmB5KMgry2KDAxrjBxt7V9yNqYaOtkC+QObVOdb96qylnPU6Gilmk2TsLvRiOiNQeYLlyg== 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=dSg25pXC+Zj926KTkdUB9cGJkUb3sgwBOqZ8Ehe/WuY=; b=HhM4K0MuPU9uHhA3BJ+rasd9/H72Fl1K5wDz8Ws98qIvKy+Rkav9j9rgLJM2l0F1Z9UlRaDoNMuRc1JgI9JGKv+/HWSMZKVlZ2MJZFPvTAK8UqBQvVGeRVP6FRHoraeDnQlO+7gmnxBwuvaKN3IYCYlEdtzB4JZmLGEgAe7ij6CkCt7nhicAxKzWTl1EUN8i1tra60/EqSw4QY+FwSHvGvZBD81dYzGJCOhg3R9xtDvneUgjtYAbtCit5o/20DnfVjJG0jdvw8iuDNaWRGkaZ2qVTdn3qqxvtPA1JLp846WU4+w5q1g64BTi4NiqhfCavyMoKOdLPosrxWIhwMvEew== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=dSg25pXC+Zj926KTkdUB9cGJkUb3sgwBOqZ8Ehe/WuY=; b=1UgpYEENKUiJw8UYQxwE8V/lJNyz+vdhH/AzxX77K007fjdmMFaCL4yLhHG8rcWHMpA7mmfTD7wn/x5ChF2c5SQQMysOcQ1q98Ka7S2PHdtoaT8vTnATejLBBrIMd8sy6hxMuNMDAsSY3ljU1Wsk2VlnnrMDDvJ5/9d383HK0f4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:38:04 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:04 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 29/96] cl8k: add enhanced_tim.c Date: Tue, 24 May 2022 14:33:55 +0300 Message-Id: <20220524113502.1094459-30-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c5e7a7e3-e1f7-4b87-adee-08da3d79ddbf X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ebl34/+lRHhjsQFKfsIiTlCh3syyPJGtoqMY7ehdxfL1ic9yUREAJVZQ5Z8Io5kc0LPGNP0BgmeE5OppxK2ZaP6du/1FA2g//F8ajIUnqt6RVVcUM8ZUa8L2zUyH/TXTlxMLuO+g1Q3y1o7j6BEjZ2/O2rXvjNHsapbso3n/s0pWbAie90upBg7ky9avmfhzBO5oHxFV/INOwFh6zP5dbFjCwL0+YPqiIfLVwh73PMOOgkJUW96SU6Z/6IZLdANm0raoSkmIXG9cU43WrlfALidjZu01RXGysBvM+53IPbix0Mgb1cIlSlRUNsFEdSbw1xuuMAChMiMu4YBhGTfwpSw4SVmnBXAifdwOSFBAQF2FAB9qFKa6b5FQ8m02M9kj3WqvLKXOm/RZNGs2hmgOFgKSH4dTzw8HaW221OqfSQoZNwXcKAXdWjpmMViW0eoxvhWDgyZDIehAK9cQzUeMa5PV8MIkxik/FnLzjOvR8YX8DOdrK3Navs/SqO3T6B8OYO7QEEqsnDJHjUO+hO9jy2EHOqEk8FDZgtXSV/FgZMBt0bbYPVzIIsF4ZJaQNPxaGKSSjXt44/s5q6BxaJaH1Jbz/mUsarfMyEUSMosIi5WLTsPF7Hue5ue891sLgP0Ua5+Hs0LTjnoaPU7iEKM+0CraWrSUWVAMNS4DIbv6ZFEr/fDuVAb8px2KnC9bmyGiIP4nPf8/jQMQBXxcifpL1RL3GfHh/+nSNuKQdzJj/1E= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vNKHSGGNoLLT/PYzbVWwplTr8nPxzVJIE6ekJXNXvZxrwSgktp41OVg9Y3N+t1nVPOaYagh2G80ANaeUYhI6pdg4ZeiG672h4hTG69UO6gq4XnsETt/xbF8BqtgweTNAVZ7kSXgX729UWM2Ys6NzDxqVIzhH7nYoRVGfpDKHjWRnJYq9tpm8X/6BPvSuE95Rx6M8QnK2sHu9IkWXZ5/kSK5+N/Uv4yszVP5qQNJKw7xt39HpmyrA7CAQsfsVMRnJua2JCZZQV9SViIu9X5fTk18o4PMiZP6AEosZGrQYFK6yM16xSSTgsPglT0+WgF+5eTjLEbO1VtpraXhXUJ0juS9GhJvX1MQdh45mEvfGbuyY5uToL1QFT1F7lHrz7jK4LdwEklhKtWZqp7C/lO76XiLSC1KA8b5zT2EPvCe+46HOHdehEFU9FgjOQN1AZRvcm88vSLJW6fm3WYfKJXj14547qCsoHYT2xWXp8aMuS+L4GOEtioNCrPyAGt5v9oBC6bnLYgGk6GtHrrZQrx+2w8DzuXdEByk9J/YNPduN/9cUHmRTXikQdV/V4aCo4v8HHb+1SnMvrHJ2kmfrfA7zbl3tF2UyDxedKzeds8YiH5J+Qu/ClQAbilfaN/eu+i2jJGqNGrB5NejTuoGoUUOHdCePrNVG/3hGtoNrHJ6tHnVxipG5BpwVZ6U91kG3tFQWzjgjR0e/6glPYJeqHNaJHWCwWqlKxm9j9Bz5P+wGhB0tpFgFfBj2f4xM3QSBj99YSgH5/sYeQiphP35MUKFREwwblu4aIfa+Gnth0xLkszvni85D6KFcWkUD1ufQvq9zh5ojk+4F8rsWStcRPdE2hCcu7eSWwbs+a7lpcs2xdOhMeBRi/KSUE7R6Z5ItefkzX0Aj0CUg2U4AgByvWGCfDnsmrlXXfQMuMMWx7h79Gc58DYEf1PZUCv8UKD+Z6K9DaNusIP1m+ssv14f1TpI3n48Kv60fo8ZLw6zdP814VqH3cH0wthJC99EPYU29gG98zuLmR9VSSWbRnaxoATqMbqHsOUJv/iqGxokz+35hlO40ftFBtWRJjDM7EKoLne/D22MOQBX7HZphkIgd2nl8GyFZLOwHaH20W9DKget+iGKcBUJV9gN7p/v7yelStoX/eTTD93acQQc6b+MQzIGe747Tbw+x2FCFr9l34SS2zOhypWZDQHQnLEtaOoBF+ydgM35rIBMbgwHmSKj9fxUDcf6ouuWbhbekQTW7wcRkrKhITSc5U4HgsAsPELdMztcT3WFzDWFFXQFViLJoy6RNcI14tJI4thfucdosdqqsLlXw6xgEFAF5ozeOKwuBewS0sTxcHyAs6wU7xbuvHwn2XiduqkqSrtfOf9ZIDTRFvQn5gkxLhFSqzYri4izZQn0d/Q1tU1XVZm8YRKeTMW7kZxG8sDkaCNsx/ht4Ri5kclet7qkyTZ+KAwXdw+B3yuIFQAPfGBdJAd71t1MGjcnplHrVmR7pqrWtDmBNzqFnWlMP9PrLk93XzR5Fv15D1RnEDVe4GzUJTvhsddqd2D3arIFQjAFVOuTgVlh4OTyfd7pJrLhOhN1yLQtCOz3io8+ploMYuEZiU5u0ZD5l6omsOUGS63TPaRU1zkx/40HlNuI/jImJbxSQ5lNLrnjKJTxQUvHCkjo6ZCzzRdFQvDR3lUNi3oqaSEXSUQcxpucURE2nEis56rRySqhG2SdQ7KdvBXX78YMYM84pSGHWw+lTphOLmRr1L2MbUPIIzKmAGjA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: c5e7a7e3-e1f7-4b87-adee-08da3d79ddbf X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:04.8572 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: owlFOmJVNj+fsg1rGOPESv31Nw58w8rr05318KjV+aJRoqfO7Ne9f8EtemdLcwDpONXFsl2eWIrgiB/urjWTYQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/enhanced_tim.c | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/enhanced_tim.c diff --git a/drivers/net/wireless/celeno/cl8k/enhanced_tim.c b/drivers/net/wireless/celeno/cl8k/enhanced_tim.c new file mode 100644 index 000000000000..893bddb2b25b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/enhanced_tim.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "def.h" +#include "hw.h" +#include "sta.h" +#include "enhanced_tim.h" + +/* + * The kernel's test_and_set_bit() gets unsigned long * as an argument, but we actually + * pass a pointer to u32, what cause to alignment fault in 64bit platforms. + * This function gets a pointer to u32 to prevent this alignment fault. + * Notice that the kernel's function sets the bit as an atomic operation, + * and our function doesn't. Vut it's not an issue since we set the bit from one context only. + */ +static int cl_test_and_set_bit(unsigned long nr, u32 *addr) +{ + u32 *new_addr, mask, old; + + new_addr = ((u32 *)addr) + (nr >> 5); + mask = 1 << (nr & 31); + old = *new_addr & mask; + *new_addr |= mask; + + return (old != 0); +} + +static int cfm_test_and_clear_bit(unsigned long nr, u32 *addr) +{ + u32 *new_addr, mask, old; + + new_addr = ((u32 *)addr) + (nr >> 5); + mask = 1 << (nr & 31); + old = *new_addr & mask; + *new_addr &= ~mask; + + return (old != 0); +} + +void cl_enhanced_tim_reset(struct cl_hw *cl_hw) +{ + /* + * There is no need to reset cl_hw->ipc_env->shared->enhanced_tim. + * It is done as part of ipc_shared_env_init() + */ + memset(&cl_hw->ipc_env->enhanced_tim, 0, sizeof(struct cl_ipc_enhanced_tim)); +} + +/* + * NOTE: the UMAC DRAM starts with the enhanced TIM elements stractures. + * This is hard coded in the FW, this memory allocation should be changed in + * the driver module .ELF file. + */ + +void cl_enhanced_tim_clear_tx_agg(struct cl_hw *cl_hw, u32 ipc_queue_idx, + u8 ac, struct cl_sta *cl_sta, u8 tid) +{ + /* Pointer to HOST enhanced TIM */ + u32 *source = cl_hw->ipc_env->enhanced_tim.tx_rx_agg[ac]; + u32 ipc_queue_idx_common = IPC_TX_QUEUE_IDX_TO_COMMON_QUEUE_IDX(ipc_queue_idx); + /* + * Does the UMAC enhanced TIM need update? + * If the TIM element is set then clear it and update the UMAC TIM element + */ + if (cfm_test_and_clear_bit(ipc_queue_idx_common, source)) { + /* Pointer to UMAC enhanced TIM */ + u32 __iomem *target = + (u32 __iomem *)cl_hw->ipc_env->shared->enhanced_tim.tx_rx_agg[ac]; + /* Offset to UMAC encahned TIM array position */ + u32 agg_offset = ipc_queue_idx_common / (BITS_PER_BYTE * sizeof(u32)); + + /* Update tim element */ + if (cl_sta) { + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + if (test_sta_flag(stainfo, WLAN_STA_PS_STA)) + ieee80211_sta_set_buffered(cl_sta->sta, tid, false); + } + + iowrite32(source[agg_offset], (void __iomem *)&target[agg_offset]); + } +} + +void cl_enhanced_tim_clear_tx_single(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid) +{ + /* Pointer to HOST enhanced TIM */ + u32 *source = cl_hw->ipc_env->enhanced_tim.tx_single[ac]; + /* Staton index: 0 - 128 (do not use cl_sta->sta_idx which is 0 -127) */ + u32 sta_idx = ipc_queue_idx % FW_MAX_NUM_STA; + + /* + * Does the UMAC enhanced TIM need update? + * If the TIM element is set then clear it and update the UMAC TIM element + */ + if (cfm_test_and_clear_bit(sta_idx, source)) { + /* Pointer to UMAC enhanced TIM for singles or aggregation */ + u32 __iomem *target = + (u32 __iomem *)cl_hw->ipc_env->shared->enhanced_tim.tx_single[ac]; + /* Offset to UMAC encahned TIM array position */ + u32 sta_offset = sta_idx / (BITS_PER_BYTE * sizeof(u32)); + + /* Update tim element */ + if (!no_ps_buffer && cl_sta) { + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + if (test_sta_flag(stainfo, WLAN_STA_PS_STA)) + ieee80211_sta_set_buffered(cl_sta->sta, tid, false); + } + + iowrite32(source[sta_offset], (void __iomem *)&target[sta_offset]); + } +} + +void cl_enhanced_tim_set_tx_agg(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid) +{ + /* Pointer to HOST enhanced TIM */ + u32 *source = cl_hw->ipc_env->enhanced_tim.tx_rx_agg[ac]; + u32 ipc_queue_idx_common = IPC_TX_QUEUE_IDX_TO_COMMON_QUEUE_IDX(ipc_queue_idx); + /* + * Does the UMAC enhanced TIM need update? + * If the TIM element is cleared then set it and update the UMAC TIM element + */ + if (!cl_test_and_set_bit(ipc_queue_idx_common, source)) { + /* Pointer to UMAC enhanced TIM */ + u32 __iomem *target = + (u32 __iomem *)cl_hw->ipc_env->shared->enhanced_tim.tx_rx_agg[ac]; + /* Offset to UMAC encahned TIM array position */ + u32 agg_offset = ipc_queue_idx_common / (BITS_PER_BYTE * sizeof(u32)); + + /* Update tim element */ + if (!no_ps_buffer && cl_sta) { + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + if (test_sta_flag(stainfo, WLAN_STA_PS_STA)) + ieee80211_sta_set_buffered(cl_sta->sta, tid, true); + } + + iowrite32(source[agg_offset], (void __iomem *)&target[agg_offset]); + } +} + +void cl_enhanced_tim_set_tx_single(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid) +{ + /* Pointer to HOST enhanced TIM */ + u32 *source = cl_hw->ipc_env->enhanced_tim.tx_single[ac]; + /* Staton index: 0 - 128 (do not use cl_sta->sta_idx which is 0 -127) */ + u32 sta_idx = ipc_queue_idx % FW_MAX_NUM_STA; + + /* + * Does the UMAC enhanced TIM need update? + * If the TIM element is cleared then set it and update the UMAC TIM element + */ + if (!cl_test_and_set_bit(sta_idx, source)) { + /* Pointer to UMAC enhanced TIM */ + u32 __iomem *target = + (u32 __iomem *)cl_hw->ipc_env->shared->enhanced_tim.tx_single[ac]; + /* Offset to UMAC encahned TIM array position */ + u32 sta_offset = sta_idx / (BITS_PER_BYTE * sizeof(u32)); + + /* Update tim element */ + if (!no_ps_buffer && cl_sta) { + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + if (test_sta_flag(stainfo, WLAN_STA_PS_STA)) + ieee80211_sta_set_buffered(cl_sta->sta, tid, true); + } + + iowrite32(source[sta_offset], (void __iomem *)&target[sta_offset]); + } +} From patchwork Tue May 24 11:33:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576861 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 78945C433EF for ; Tue, 24 May 2022 11:38:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229702AbiEXLih (ORCPT ); Tue, 24 May 2022 07:38:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236804AbiEXLie (ORCPT ); Tue, 24 May 2022 07:38:34 -0400 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80083.outbound.protection.outlook.com [40.107.8.83]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 164F653E2D for ; Tue, 24 May 2022 04:38:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lImJ9jj8sMVxxDSyEalH5PJza8XkDxYmjSSbFLlmc5tcCQkTIs9v6HvaP36b3jzRnac75SOewaObrxrB58Qgb9DlPzAhURKS9jC8h3o/TJRwa09iwEqSkt1ROQwx4wXn5hFMXm+/l3uv6vI1VTyixoQ41Q/E5X8c3R/s/tq6YQ+zwiE5J/Ka4TC08PgOSvayCJopyQIhqvgsHCOn7T94GcV/A3UNCKVySeX3j1y4dq5ryF93mQnOztqFWjpvVfPheeZIg2yGNHO+Eds2g18cQz27lSTJTH1osigtu492V6z5sb6XMeOTW5PbwloAM2FNAch4hAelmLNHpF/5bcgENw== 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=15YbXjjVT26uE7SlUk+eFEsixW8nvxZCH58NaVpWJ40=; b=SiL/DLcimEvkEUXCWEGKRHNwB+W+OafPaMLWSs1j9sSqgL9h4QXcW0f2zQxfn3r5jCSP0fjAztt7/YXWVUJ0m/3PoYJqwEKT45A58PNP/HqnoUlB3CMEi3IAz/eczsvtieURjv8fI2HZ3yI87ZRMz09JCwfI/oeUiTLkR3+37GGFIlzgX3qF3/KlNrWtdiufzg75dhO9+DkczJK5aBNdGI0H6vWrGGNw76BeivKBtmSEpg4L+6tZKJBS7KTThAZQS1iHwX8Wh+2f09qkpAcEGWWW+NP+AcRIJgHUYSWA/qp9AXe36fHrHMu8Ry/JBvECrFdmRpquRLnn8aOsmrTQag== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=15YbXjjVT26uE7SlUk+eFEsixW8nvxZCH58NaVpWJ40=; b=qI9Qb1c5Ew8DRKErQtCvlGwEH4ZHUMoCqEG00KMwmeXUh/mAzHS+RulmU3iJUdrvcKLM8Lv//YhQoOJ9wWtxbu30kCTvb1bNJssRU5rMIkvqwqPQdBdsqO4xcs61bn+re8F5S/x/69PKBXfdVWh0OzgIqUgPrjgRfqaFh8N5lSY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:38:05 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:05 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 30/96] cl8k: add enhanced_tim.h Date: Tue, 24 May 2022 14:33:56 +0300 Message-Id: <20220524113502.1094459-31-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b9a55e40-8442-4066-4b3b-08da3d79de32 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: MvE4WEA4LcbvSHN2GEbgf/DkbeMJjp4FddPVppmNG8+FXAPDvAoXneIOZksFJctfpu6c2IK9+mjdmdfviRZmESIijXK/LL2BcIXQ6Up9qZtUOKfKzIZ3rA1+upZYGF6DVYWamld1I1lTvYGIEEz+PK+j0uzSkv1KhEdy1+ZYPGCfX0IE0/zxu+okZ3tzDjyLBBs5TFgX6fiVEGKXrNInIZ+3XGWxOfZ28yE24TrkAJ0QOR62psu7nZrxe+uYMQJsVqwfozhLtEySIEw7Z3HUEsvwoHnx7UzGieBKL05i3YiFomJHqYOLGJwsZ6pPEpkM4w24HWgQpDCyQa8LMvixHMshxIO3EyFUCzA3EkB/mT4gYRN29Oemq8+MjA1a/yDkqMJSK2fRpm+S4sETGSPdVFuiKtAzmWUxJgy1+WSC52kbn9mWbe8c+qx4Fq/+R0RtEJ5Eh7FUxH/BVUflc+iFzYmDi+kOsFoKSxvEABbyaMEVZrroyEax1Mu/qo7dtZIQtKq4PGBj40zEUh/Zy3QD99+FgmkU5cvW5YUFZDQGaxVBDAdmkxZ9Pz2KDgp36R2mTtNjt+uzk+ovOG0f77Omq45uxHmaaBqHxjQWqR6OUO1CeTWqLpgG30Ehk490fsRmQbCnUNKQsLEf4Vp1rU1QHZVeSaSGPfk+CZsm7HOcJzWLQRf1onk8ViOVjz6Naik3FG8jEzgTEA4IivKtJzdWeM3wWrebjFArQgtJnm7lJkY= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Fxe9Wp4OkDbITI0d/5yRdeGNrdReLnkPnwnLsH1grbPl1ZUhjziXDqxt/O8HyddnLbyuV06rRUdXfz367+OGHTMxKumiHelmBvaiiAyhmsPaPzbqz72yQyWFy9ZgVPhB5KkVaVfdOO+0aOCv9rtROoj/LGRo119c+luOHQEgVLGhFp/j0+LNWNzbkawS4tWjdbuFTvf6bAA75PmMeS8bhKX/NKyoY4ak9l8ZxzOapcbRhbGPkSp3djxz6nl0oK/zmv4LgYaS3uKyz+Eg6ti9H8idQJ0bFj21CSr4JHhgkHgPYhQkEfIVRR2+TgnhBfABHUiKaFdlkacmLS61K7P+3NUhr+9sYxS6aJomr3v3XatCW5qqVZ9Uv4O9gIQ68R1bNl1jr93DG+RtxwHfcp4f3PArl3TcMdSSNPY+n6Xe8nUVRtSCK/o+6IyQOjOvScePmb1bJXsw6xp7uGu3g+FGh0McLim8DQKYa/XVP3ieDt0icd3sUEQnBGg4BI6vMJiZ3hF93DfwZaluIQAjEfR9fX3ZpcbPqhEYb+KbhxsS6HtYLI/9Hy9LLiyLdapX02fZEHt//j17qDRKvH7OaVXd0GWem1G0ZrExPGcde0TUtGpj4evWceouqdAprL8UIJV58dWV4aCDwUJCy0MeUHeITMfFmg632nEVI7Oye12nZlU+J3v2ebo9CrSn8PNny9DF6psFdR+N+vHxhmPz1Yj8v1xSrbnYzX52DAmQwwzBYK09/gQ4eiC/OmnP4u8itZz19NGiQuNTsF7PVoozfI0MCgFLr9pu9E3N7HeBUetXAHiWzXBdo+E0VunbArn7eFPjLAhtb3UgvGeT06vDiUpwIZxQ42qsl0yEBVBbhMhKSVhx8obMTcxrki6gaBHuVb1IDEA2JcNvwBRaljZEA0xD4TJ/rXXVcT93mx4MtsI/L2cBppQxrhjwQ2Dxw/AhybnmmYwunKvuWDfWHCG9FZipXKzKqmSNqY7ZAHt7K6EIIQHbOvvSRCxPKNXfcgjA4wCMthcx6UMOrpuCmx427twd4nddehUDhLtOHjHOluHExWILO0xZdkXssI0kjmmL+bLAth0Z45qpgpGDzicdGJAuiaqcXeOrzfzfBe3d3WrEIXRnmOH3MgwZefm2gslOC8q1OqAfFuNkMe2f0Bu9VqN1wyTEuqC3HPoDMQw7bzb1MciqV4TxKmmPC+weIdOuKc64kNE+ZeAtrCMV7x+tlNs0hV4rvO/H8NrY5z1fN/c4JhBswr8yXPWgRk9ch9nRqsC71qzNc2tNJN3FV2cHdrwqAcK4NI9Dz3bghX44hrumrap8BKkepRXH5/2oOI4m1HZpj9SjllXGmMnAPHjNhcZC59JDrC2gmIdVMSoSn0/GMh/ciXeWNw43Mv5cusp4kwNv7y78d4ObFIwQ6ysy3RNCyPXRns+Tqu+RiVCE4EbHGcPpulsWihPTtcDjEdRBcYzLAfMaCS4xMCmQct819rVePgWyMrL7WALHUBdybl/ck5q/1CWAO9QqF5rx8LrKRC76KW6k6KdHeC4zS3CESnv3SwTE+UiNPkL2tYaiyDBFU7P9mmlFzQswskffxHoY7MJHZmZ4hGVAh2m7FZfHFl82iAdS6dj7MdcYc1o4yZLO0zCnejvMWiCHVnd0dYO92PWgjHQm44bq4zWc+jN29fZAFFAWxxGSxsHBLeX4c1DYUAuTlWfW/YbmoutRKz+jO8Q6FiEM0Fsy9i4c8Pv6AD6eHWomMyau4b4c91BSAae3SLU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9a55e40-8442-4066-4b3b-08da3d79de32 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:05.5771 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: EDW9/ZIsD+2NIEi++3QalBZtQhG4YrijjyJVYH/6GiVBtCapZ1WdQyuwyNextGQUFEJ27lfLTC6ylpQgcojmGw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/enhanced_tim.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/enhanced_tim.h diff --git a/drivers/net/wireless/celeno/cl8k/enhanced_tim.h b/drivers/net/wireless/celeno/cl8k/enhanced_tim.h new file mode 100644 index 000000000000..ec40ac03df59 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/enhanced_tim.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_ENHANCED_TIM_H +#define CL_ENHANCED_TIM_H + +#define BCN_IE_TIM_BIT_OFFSET 2 + +void cl_enhanced_tim_reset(struct cl_hw *cl_hw); +void cl_enhanced_tim_clear_tx_agg(struct cl_hw *cl_hw, u32 ipc_queue_idx, + u8 ac, struct cl_sta *cl_sta, u8 tid); +void cl_enhanced_tim_clear_tx_single(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid); +void cl_enhanced_tim_set_tx_agg(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid); +void cl_enhanced_tim_set_tx_single(struct cl_hw *cl_hw, u32 ipc_queue_idx, u8 ac, + bool no_ps_buffer, struct cl_sta *cl_sta, u8 tid); + +#endif /* CL_ENHANCED_TIM_H */ From patchwork Tue May 24 11:33:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575972 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 686A1C433F5 for ; Tue, 24 May 2022 11:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236839AbiEXLjO (ORCPT ); Tue, 24 May 2022 07:39:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236831AbiEXLjM (ORCPT ); Tue, 24 May 2022 07:39:12 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2041.outbound.protection.outlook.com [40.107.104.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D77D3C734 for ; Tue, 24 May 2022 04:38:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mhSQEtB7TZds+d0uMTBLF5itLV0988tIMLsx+DqXKxIEWdB903ZlV4Nr9ySD46tMaDrfOOx7bnTPVKSX4ICweClWf3XFWj/lwvSOtYNFyel7aBWS7+EeA0VyAyHCYIo0ZHJrClEwrJxaIF9S6jMJKKSyCkM20SFufhLkNuYt6LeNtlgZlwp7Rc3d0/kExiiIgT0S8s5v5gLP+DgZkWCxgQ6Qanjad0VLwMzRvcQeOG44I0pI/6zE2m6OmG6IowZWerLQ1teYnCrNji7fbPhyxKLBcWQdnPPIxHikMt5DROfheNQ380E7R24XKujRLLQaKvR74VBHDkSFzPjJmMn0JA== 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=ZvaKk6hSGWJNVfUJtSNLy8oQom+spkz7N1G5Oex5YuM=; b=UQDd7muH7XQJk6WYAy9fRHxkH/D4bxXUPWBhmy4FNwGLXNE2MYuWQum+RS4B7EufCkPuodvsa1Asc3kDS9Q9W5J09MvDjXPQenTuZc34oWMfL6/cc43+fqGG5EvcRgIA3WfJBXyoJUOajtWAOmQClNCfRpYTCMJelNuZmVtH9rEx1HcOpVqIgAcbTzYwZBSFTmPR5I/yK3y8fVOruC48aS+8rerb+wq8oIvFAewoK9BPC08yzv0FsFgbsfqvqzCgOsXPxnzvLfqGB6WcQe6/dtGXp3zOB7Sa2AvCSszIObqmO6Uid0PSVFJQJYT9vSntRmNH/2OXNQW2atX0wqV4NA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZvaKk6hSGWJNVfUJtSNLy8oQom+spkz7N1G5Oex5YuM=; b=FArlI2vIoRyQAZQZcJWNXEcRIbrCSk4RPk1X5fjbf58k0LyxIVDNtVZvADMn8iS7SapxKgRkSlylC71+VXTHWNsaYOCAKLJUTZE/0uYl776z0Kw82v5Xi4L/1LAt2pgPXs473Vvr8aXOyoK0absxlRZHufD17lm76wa5ZeVxjsI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:36 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:36 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 31/96] cl8k: add fw.c Date: Tue, 24 May 2022 14:33:57 +0300 Message-Id: <20220524113502.1094459-32-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: cd24e86f-a279-40b6-4145-08da3d79deae X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: eYrpTkwvAu1u/1bsDVpgm+C16RIHiFitYpHap8m8RnhncU51zcQd6nkPQrnPM/FWWI6MCFwFnACO68Kv+1ilhl8mDuMXfP6GSlShjccdt/19TYr2EIVah6iPuC2BBxGnF58NKXE+gCijCWHljhk6lS99SUJ/CeK4rfRkambpi6ZcQ0cBErJzx0iv+8ix8dVCujQZ3fMd6dCer28l5PmoDZU4WYlBdzafzXuo9EoP80NJ7QwUJS/BtrI9WX5vWubkbUg6luGwDL7WcNReDT2WFyQpf/KYzd7Fh42vsW8k5BVs9YkPNe+zpYlh/wKVA82EViJePdliyV4BxZPQKSf9NwJQsF3oOu8HeM1msQG2IYQZ7hfFX2cjO4eoe4/CYUMJLwqfaErCE7UIltoIFp43rY/PS26rM/LRNl/kb8hSCd/RfKKeg4AGKCQ5uUjlxfyIXpWlHujhjeo1nwPfk44lFApff6xyQtMawJDlCb0wyjZ1+mowitvPplgIodvl15cFdXx75hCUCmOFQeRPVV2r/y3QXud63T3AR8r+oNCoIR8sKsxytWoAPDGV56CiqWg6rENPQD/aDtFhSsnP6HzBsRbyhHPPvBU1LcnCqEX58pLBpZNljJR0lLvg85FIkRD2nMM/tqaJyo7QTQdvdaIDRjr0UvrHh+t6w1TPCimZgvfLlRqnw5C+togZssu9mSHpEYGX1HwrSOKuvAspXWVN2TWy8B0+pLy8lfl7jFF/RgAJWGh2nhG4Y1jHXnck4bsX1icO4RlGo5/0mJCJ3rHcqEu16XbI7QJojMHIDCcZpWlbxFO11lgb1VchA/Hd2DN2 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(966005)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001)(579004)(559001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 4kdPi1Lmt/6UExs39311ONqMeGcAthZX1fofkPBnbp68WS68Zm3kKbVJwjJzR/PzUEN78lCFju0LGDpOWhv7K27XONlNyfsZnGkyqqz7Bqzq+2uUbBRnW+2rrBFuLbRZFZRLVLWKaeZedC3Vg/fUqaQ6N2xrRRJIgYo3flXsd+Sye+SLYud/yfKhtJWQfIq8Exrd6dJVG1JhDN1kQsKR5a4PBJit+InYwE9sW6cMKalEDFFU9geS3vKng0EeQbD82gBntzz2Lye7Zrad5IDKi/TW4gH4GoOcbzBELurVgkEQ6SGpngVZSJqYTEAS6OYa781UGCsRHpkfoNQGdf3wGW5S6Vh4nx6iBk12QYudcPueFzh4AkXLC7xX884pOobAJYlX+jZGETFCJi6e8zwprNNVi1B6nta3mAYGUCUtLJhCOM/+poqNkjZW1EWztAmMDu5WiNqgxQ4OoKIZm+y0gvctMzo5kHsXj1ciV+uD2J5EmQhmqH+Kv821Kyf5XZp9r6x9E2OxeIEj70gr4D/tkoFmqY/99wZa8ocvn7NjwkUFTf/sAPFvEE6U6BbuxEm+z4Hl7qsmh/gEDXnJQzvjtzy0XlfL4suztqEeLQyhW0q9Hho9a1LYmsepvcoJQjxjjTxIGXij53/IWvwBuEMqiWGhvQ/lmEuuVYGEwUye8eI19PgzB3RYi7R4ezHadldImYfHh2b+EKBKVGdPoVoFe/eyAVNza19NFLLWqGhjYhlT7s0c8cPDVOSuti8wod8P3WFXRfN4/Cg2kbf/us0Co/pFtMFtrjgx8K7QDrXj8Wb+o43PZHu5ClkdpB042aowREM6esxkHUNg8kk0P0Suj5NEEYE708Q1Elo81mSIqU1sN7VnDK/SkmTxoRTMAyoklcEdOCVmcEyaqb1rMcN8pAqDuZNlSCzb6ytTLSEoo89huavoC+kiTaSwhLiNf9+FGB6aRiXKaNRzf8EgDbHLnnog2nGFi2P7Pawor6q+ajqOaMx6X4xmZS3uvobjLsGl4UdVRKTCUsvDxXl2XlPkXabHdJB2vZe8jSRP3BEuZu2sEtpSY8ZQUv1qxi1xm1uwGPvh8la/6CoVj6+OcAgIwHHIcgX0ZQux0IaaNK03T7V2V8G0ULd1R7Ml46Do65CIDC3pK9yk3+DcOJVrjTKBVHMZfH5qHQJMTVuzrpjMEqEkqzum0o+P+k4vFNHM3lx6eZ9PGiX5qLmKsHboTyqSF3Rvbn242htvoMwD8R1Rxcxj0QeNU767eNCxgzXN/eK0hVE6OHc84iqm9dWJEw0/mglMpypd7tc0TNqSDsXIlRvhh2lG7tXS4PuuAMEf7RRy9RL0OGpOZoPmoDkk9znW6y044q/8lZ6USPuWdmO22gBiFbrOslcKh8bilE25e1Sv8xEzH0AZGnycw6PzWtT9L7IOnuQ/CvQ/ARkALb3eswYUajY6lXnO5xO1ozbZcwctECYyq0NgRCKtZ9fVVI0h9I9SoJ8IZNBzRF5Q9cHcIP4j5ojYg1M8ShZwLtBdeG4R3vGJT4iB4I1Xpocdh4aSc65psx3MW+MXeKHWAYAA5e1WkJKHE936BlcKNTyQZk8l2SXcY3LvUdoHhoJNPwRM6r1yvk8y1eH5fqbh0HNTst+Dc+nvTqBcw6DT+DpEXLzTHBkC7NZ56iR+/OTYVlI+xeAMt0yJgFZ9KbeU4XU3+Y0LY+99K4JkYHnmUUJXNdskpIq1cdx61aWagI8eEC5+vg06AWHLe+48SEpkRSTWSBw= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: cd24e86f-a279-40b6-4145-08da3d79deae X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:06.6081 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: eiGYJ/9h2Pp4hqQD8iMfcyVcfjdBq0g/yz+Jgc//vvwSZJtQjOhsveBHXGShUyTEjd4C4dr8+XXCDpG+tOYvkw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/fw.c | 3167 +++++++++++++++++++++++++ 1 file changed, 3167 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/fw.c diff --git a/drivers/net/wireless/celeno/cl8k/fw.c b/drivers/net/wireless/celeno/cl8k/fw.c new file mode 100644 index 000000000000..fd981ccdfaee --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/fw.c @@ -0,0 +1,3167 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include + +#include "chip.h" +#include "utils.h" +#include "debug.h" +#include "recovery.h" +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "phy.h" +#include "rfic.h" +#include "mac_addr.h" +#include "mac80211.h" +#include "ampdu.h" +#include "tx.h" +#include "stats.h" +#include "fw.h" + +#define fw_pr(cl_hw, fmt, ...) \ + pr_debug("%cmac%u " fmt, (cl_hw)->fw_prefix, (cl_hw)->chip->idx, ##__VA_ARGS__) + +/* Location where FW codes must be written */ +#define RAM_SMAC_FW_ADDR 0x00300000 +#define RAM_UMAC_FW_ADDR 0x00280000 +#define RAM_LMAC_FW_ADDR 0x00200000 + +#define FW_START_MAGIC "CEFWHDRSTART" +#define FW_END_MAGIC "CEFWHDREND" +#define FW_OFFLOAD_MEM_BASE_ADDR 0x70000000 /* Defined in fw link script */ +#define FW_SECTION_SIZE_MASK 0x7FFFF /* Mask for max. size of a section */ +#define FW_REMOTE_ROM_BASE_ADDR 0x80000000 /* Defined in fw link script */ +#define FW_REMOTE_ROM_MAX 150000 + +/* Location (offset) where FW codes must be taken from */ +#define IRAM_START_OFFSET 0x40000 + +/* + * Poor man parser of a plain zip file + * We use it just as a container for now. Could use cpio instead. + * (no compression, no 64-bit data ... no nothing) + * Reference: ZIP File Format Specification v.6.3.4 (2014) + * http://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + * For BIG ENDIAN host: zip format is always little endian. + * TODO: need alignment on non-intel hosts! zip format has no alignment,padding + * TODO: check CRC? + */ + +struct pkzip_local_hdr { + u32 signature; + u16 ver2extract; + u16 flags; + u16 cmpr_meth; + u16 filetime; + u16 filedate; + u32 crc32; + u32 cmpr_size; + u32 orig_size; + u16 fname_len; + u16 hdr_extra_len; + /* Filename goes here - not 0 terminated! */ + /* Hdr_extra_data goes here */ + /* File data goes here; no padding, no alignment */ +} __packed; + +#define PKZIP_LOCAL_HDR_MAGIC 0x04034b50 +#define PKZIP_CENTRAL_DIR_MAGIC 0x02014b50 + +/* + * Enumerate zip data in buffer, find named item + * Return: 0 on success (the item found) + * -ENOENT the item not found, normal end of data found + * -EINVAL the data is not zip (maybe old format firmware) + * else invalid data format or other error + */ +static int cl_enum_zipfile(const void *data, size_t size, + const char *name, char **pdata, size_t *psize) +{ + const struct pkzip_local_hdr *phdr = data; + int remain_size = (int)size; + + BUILD_BUG_ON(sizeof(struct pkzip_local_hdr) != 30); + + while (remain_size > sizeof(struct pkzip_local_hdr)) { + char *pfname; + char *edata; + + if (phdr->signature != PKZIP_LOCAL_HDR_MAGIC) { + if (phdr->signature == PKZIP_CENTRAL_DIR_MAGIC) + return -ENOENT; /* Normal end of zip */ + if ((void *)phdr == data) + /* Bad signature in the first entry - not a zip at all */ + return -EINVAL; + pr_err("ZIP - unexpected block: %8.8X\n", phdr->signature); + return -1; + } + + if (phdr->fname_len == 0 || phdr->fname_len > 128) { + /* FIX max len */ + pr_err("ZIP entry name len bad: %u\n", phdr->fname_len); + return -1; + } + + if (phdr->hdr_extra_len == 0) { + pr_err("ZIP xtra hdr size=0! FIXME!\n"); /* Copy name to tmp buffer */ + return -1; + } + + pfname = (char *)phdr + sizeof(struct pkzip_local_hdr); + /* Because fname in zip is not null term! */ + pfname[phdr->fname_len] = 0; + edata = pfname + phdr->fname_len + phdr->hdr_extra_len; + remain_size -= (sizeof(*phdr) + phdr->fname_len + phdr->hdr_extra_len); + + if (phdr->cmpr_size == 0 || phdr->cmpr_size > remain_size) { + pr_err("ZIP entry data len bad: %u name=%s, left=%u\n", + phdr->cmpr_size, pfname, remain_size); + return -1; + } + + if (strncmp(name, pfname, phdr->fname_len) == 0) { + if (phdr->cmpr_meth != 0 || phdr->cmpr_size != phdr->orig_size) { + pr_err("ZIP entry compressed! name=%s\n", pfname); + return -1; + } + + *pdata = edata; + *psize = (size_t)phdr->cmpr_size; + return 0; + } + + remain_size -= phdr->cmpr_size; + phdr = (const struct pkzip_local_hdr *)(edata + phdr->cmpr_size); + } + + return -1; +} + +static int cl_fw_unpack(const void *data, size_t size, + const char *name, char **pdata, size_t *psize) +{ + /* + * Get named item in firmware container + * Args: pdata : pointer to pointer to item data, psize : pointer to item size + */ + *pdata = NULL; + *psize = 0; + return cl_enum_zipfile(data, size, name, pdata, psize); +} + +static int cl_fw_load_other(struct cl_hw *cl_hw, const char *name) +{ + /* Handle other stuff in firmware container */ + char *edata; + size_t esize; + struct cl_cached_fw *cached_fw = &cl_hw->cached_fw; + int rc = cl_fw_unpack(cached_fw->data, cached_fw->size, + name, &edata, &esize); + + if (rc) + return rc; + + cl_dbgfile_parse(cl_hw, edata, esize); + + return 0; +} + +/* + * Copy the FW code and data into the proper memory inside the firmware asic. + * vaddr - run address + * paddr - load address + * fsize - memory section size to copy + * msize - memory section physical size + * mem_base - base address of xtensa internal memory + * fw_buf - buffer holding the FW binary code and data + */ +static void cl_fw_copy_section(struct cl_chip *chip, char *fw_buf, u32 mem_base, + u32 vaddr, u32 paddr, u32 fsize, u32 msize) +{ + u32 *src_addr; + u32 dst_addr; + u32 i; + + src_addr = (u32 *)(fw_buf + (paddr & 0x0007FFFF)); + /* 512KB - cover all internal iram and dram and some more */ + + /* Check if run address is external or internal from xtensa point of view */ + if ((vaddr & 0xFF000000) == XTENSA_PIF_BASE_ADDR) + dst_addr = vaddr & 0x007FFFFF; /* Must be in 8M PCIe window */ + else + dst_addr = (mem_base | (vaddr & 0x0007FFFF)); + + for (i = 0; i < fsize; i += sizeof(*src_addr)) + cl_reg_write_chip(chip, dst_addr + i, *src_addr++); +} + +static int cl_fw_phdrs_upload(struct cl_chip *chip, struct cl_hw *cl_hw, + u32 fw_addr, const void *edata, size_t esize) +{ + /* + * Load firmware image with "phdrs" header + * and optional non-resident (offloaded) section + */ + u32 size = esize, section, section_cnt = 0; + char const *pbuf = edata; + u32 *src; + + /* Verify FW image phdrs start magic */ + if (strncmp(pbuf, FW_START_MAGIC, strlen(FW_START_MAGIC))) { + cl_dbg_err(cl_hw, "phdrs start magic not found, aborting...\n"); + return -1; + } + + cl_dbg_info(cl_hw, "phdrs start magic found !!!!!\n"); + pbuf += (strlen(FW_START_MAGIC) + 1); + size -= (strlen(FW_START_MAGIC) + 1); + + /* Verify FW image phdrs end magic */ + while (size > 0) { + if (strncmp(pbuf, FW_END_MAGIC, strlen(FW_END_MAGIC)) == 0) { + cl_dbg_info(cl_hw, "phdrs end magic found !!!!!\n"); + break; + } + + pbuf += 16; + size -= 16; + section_cnt++; + } + + /* FW image phdrs end magic not found */ + if (size == 0 || section_cnt > 100) { + cl_dbg_err(cl_hw, "phdrs end magic not found, aborting...\n"); + return -1; + } + + /* Remember where the fw code start in firmware buffer */ + src = (u32 *)(pbuf + (strlen(FW_END_MAGIC) + 1)); + /* Re-assign firmware buffer ptrs to start */ + pbuf = edata + (strlen(FW_START_MAGIC) + 1); + size = esize - (strlen(FW_START_MAGIC) + 1); + + bool is_offload_present = false; + u32 off2_start = 0, off2_end = 0; + u32 off3_start = 0, off3_end = 0; + + for (section = 0; section < section_cnt; section++) { + u32 *param = (u32 *)pbuf; + + if (param[0] == FW_REMOTE_ROM_BASE_ADDR) { + if (param[2] > FW_REMOTE_ROM_MAX) { + cl_dbg_info(cl_hw, "%cmac%u: FW remote rom too big = %uK\n", + cl_hw->fw_prefix, chip->idx, param[2]); + } else { + dma_addr_t phys_dma_addr; + char *pfake = (char *)src + (param[1] & FW_SECTION_SIZE_MASK); + struct cl_dma_accessed *fw_rom = &cl_hw->fw_remote_rom; + + fw_rom->size = param[2]; + fw_rom->drv_v_addr = dma_alloc_coherent(cl_hw->chip->dev, + fw_rom->size, + &phys_dma_addr, GFP_KERNEL); + if (!fw_rom->drv_v_addr) { + cl_dbg_info(cl_hw, "%cmac%u: FW remote rom dma_alloc_coherent failed = %uK\n", + cl_hw->fw_prefix, chip->idx, fw_rom->size); + fw_rom->size = 0; + } else { + fw_rom->fw_v_addr = FW_REMOTE_ROM_BASE_ADDR; + fw_rom->dma_addr = phys_dma_addr; + memcpy(fw_rom->drv_v_addr, pfake, fw_rom->size); + cl_dbg_info(cl_hw, "%cmac%u: FW remote rom memory use = %uK\n", + cl_hw->fw_prefix, chip->idx, fw_rom->size); + } + } + pbuf += 16; + continue; + } + + if (param[0] == FW_OFFLOAD_MEM_BASE_ADDR) { + is_offload_present = true; + u32 *pdata = (u32 *)((char *)src + (param[1] & 0x7FFFF)); + + off2_start = pdata[0]; + off2_end = pdata[1]; + off3_start = pdata[2]; + off3_end = pdata[3]; + cl_dbg_info(cl_hw, "Resident RO DATA block: start=0x%x, end=0x%x\n\n", + off2_start, off2_end); + pbuf += 16; + continue; + } + + cl_fw_copy_section(chip, (char *)src, fw_addr, + param[0], + param[1], + param[2], + param[3]); + pbuf += 16; + } + + if (is_offload_present) { + /* 2nd pass to find the resident RO data block */ + pbuf -= (16 * section_cnt); + char *resident_file_data = NULL; + char *resident_umac_file_data = NULL; + u32 *param; + + for (section = 0; section < section_cnt; section++) { + param = (u32 *)pbuf; + if (param[0] <= off2_start && + (param[0] + param[3]) > off2_end) { + resident_file_data = + (char *)src + (param[1] & FW_SECTION_SIZE_MASK) + + (off2_start - param[0]); + cl_dbg_info(cl_hw, "resident_file_data=0x%p.\n", + resident_file_data); + } + + if (param[0] <= off3_start && + (param[0] + param[3]) >= off3_end) { + resident_umac_file_data = + (char *)src + (param[1] & FW_SECTION_SIZE_MASK) + + (off3_start - param[0]); + cl_dbg_info(cl_hw, "resident_umac_file_data=0x%p.\n", + resident_umac_file_data); + } + + if (param[0] == FW_OFFLOAD_MEM_BASE_ADDR) { + char *pfake = (char *)src + (param[1] & FW_SECTION_SIZE_MASK); + + cl_dbgfile_store_offload_data(chip, + cl_hw, + pfake, param[2], + FW_OFFLOAD_MEM_BASE_ADDR, + resident_file_data, + off2_end - off2_start, + off2_start, + resident_umac_file_data, + off3_end - off3_start, + off3_start); + + break; /* This should be last section */ + } + pbuf += 16; + } + + if (!resident_file_data) + cl_dbg_warn(cl_hw, "FW resident data block [%#X-%#X] not found!\n", + off2_start, off2_end); + } + + return 0; +} + +static int cl_fw_upload(struct cl_chip *chip, struct cl_hw *cl_hw, + u32 fw_addr, const char *data, size_t size) +{ + /* Is it old .bin format (used for firmware tests) */ + if (data[IRAM_START_OFFSET] == 0x06) { + const u32 *src = (const u32 *)data; + int i; + + for (i = 0; i < size; i += sizeof(*src)) + cl_reg_write_chip(chip, fw_addr + i, *src++); + + return 0; + } + + if (cl_hw) + return cl_fw_phdrs_upload(chip, cl_hw, fw_addr, data, size); + + return 0; +} + +static int cl_fw_load_operational(struct cl_hw *cl_hw, const char *fw_name, + const char *main_str, const char *dbg_str, + u32 ram_addr) +{ + int rc; + const struct firmware *fw; + char *fw_ptr; + size_t fw_size; + struct cl_chip *chip = cl_hw->chip; + struct cl_cached_fw *cached_fw = &cl_hw->cached_fw; + + clear_bit(CL_DEV_FW_SYNC, &cl_hw->drv_flags); + + if (!cached_fw->data) { + char path_name[CL_PATH_MAX] = {0}; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", fw_name); + rc = request_firmware(&fw, path_name, chip->dev); + + if (rc) { + cl_dbg_err(cl_hw, "# Failed to get %s, with error: %x\n", + path_name, rc); + return rc; + } + cached_fw->data = vzalloc(fw->size); + if (!cached_fw->data) { + release_firmware(fw); + return -ENOMEM; + } + memcpy(cached_fw->data, fw->data, fw->size); + cached_fw->size = fw->size; + release_firmware(fw); + } + + rc = cl_fw_unpack(cached_fw->data, cached_fw->size, + main_str, &fw_ptr, &fw_size); + + if (rc == 0) { + rc = cl_fw_upload(chip, cl_hw, ram_addr, + fw_ptr, fw_size); + /* Load other stuff packed in firmware container */ + if (rc == 0) + rc = cl_fw_load_other(cl_hw, dbg_str); + } else if (rc != -ENOENT) { + /* Assume it is a single file, not a container (used for tests) */ + rc = cl_fw_upload(chip, cl_hw, ram_addr, + cached_fw->data, + cached_fw->size); + } + + return rc; +} + +static int cl_fw_load_lmac(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_fw_load_operational(cl_hw, chip->conf->ce_lmac, + "lmacfw.main", "lmacfw.dbg", + RAM_LMAC_FW_ADDR)) + return -1; + + cl_hw->fw_active = true; + + return 0; +} + +static int cl_fw_load_smac(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_fw_load_operational(cl_hw, chip->conf->ce_smac, + "smacfw.main", "smacfw.dbg", + RAM_SMAC_FW_ADDR)) + return -1; + + cl_hw->fw_active = true; + + return 0; +} + +int cl_fw_file_load(struct cl_hw *cl_hw) +{ + /* For TCV0 load lmac, and for TCV1 load smac */ + if (cl_hw_is_tcv0(cl_hw) && + strcmp(cl_hw->chip->conf->ce_lmac, "no_load")) { + if (cl_fw_load_lmac(cl_hw)) + return -1; + } else if (cl_hw_is_tcv1(cl_hw) && + strcmp(cl_hw->chip->conf->ce_smac, "no_load")) { + if (cl_fw_load_smac(cl_hw)) + return -1; + } + + return 0; +} + +void cl_fw_file_cleanup(struct cl_hw *cl_hw) +{ + /* Clean up all firmware allocations in cl_hw */ + cl_dbgfile_release_mem(&cl_hw->dbg_data, &cl_hw->str_offload_env); +} + +void cl_fw_file_release(struct cl_hw *cl_hw) +{ + struct cl_cached_fw *cached_fw = &cl_hw->cached_fw; + + if (cached_fw->data) { + struct cl_dma_accessed *fw_rom = &cl_hw->fw_remote_rom; + + vfree(cached_fw->data); + cached_fw->data = NULL; + cached_fw->size = 0; + + if (fw_rom->drv_v_addr) { + dma_addr_t phys_dma_addr = fw_rom->dma_addr; + + dma_free_coherent(cl_hw->chip->dev, fw_rom->size, fw_rom->drv_v_addr, + phys_dma_addr); + fw_rom->drv_v_addr = NULL; + fw_rom->size = 0; + fw_rom->fw_v_addr = 0; + fw_rom->dma_addr = 0; + } + } +} + +/* Should be used for REQ and CFM only */ +const char *const msg2str[MSG_TOTAL_REQ_CFM] = { + /* MM messages */ + [MM_RESET_REQ] = "MM_RESET_REQ", + [MM_RESET_CFM] = "MM_RESET_CFM", + [MM_START_REQ] = "MM_START_REQ", + [MM_START_CFM] = "MM_START_CFM", + [MM_VERSION_REQ] = "MM_VERSION_REQ", + [MM_VERSION_CFM] = "MM_VERSION_CFM", + [MM_ADD_IF_REQ] = "MM_ADD_IF_REQ", + [MM_ADD_IF_CFM] = "MM_ADD_IF_CFM", + [MM_REMOVE_IF_REQ] = "MM_REMOVE_IF_REQ", + [MM_REMOVE_IF_CFM] = "MM_REMOVE_IF_CFM", + [MM_STA_ADD_REQ] = "MM_STA_ADD_REQ", + [MM_STA_ADD_CFM] = "MM_STA_ADD_CFM", + [MM_STA_DEL_REQ] = "MM_STA_DEL_REQ", + [MM_STA_DEL_CFM] = "MM_STA_DEL_CFM", + [MM_SET_FILTER_REQ] = "MM_SET_FILTER_REQ", + [MM_SET_FILTER_CFM] = "MM_SET_FILTER_CFM", + [MM_SET_CHANNEL_REQ] = "MM_SET_CHANNEL_REQ", + [MM_SET_CHANNEL_CFM] = "MM_SET_CHANNEL_CFM", + [MM_EXT_CALIB_REQ] = "MM_EXT_CALIB_REQ", + [MM_EXT_CALIB_CFM] = "MM_EXT_CALIB_CFM", + [MM_SET_DTIM_REQ] = "MM_SET_DTIM_REQ", + [MM_SET_DTIM_CFM] = "MM_SET_DTIM_CFM", + [MM_SET_BEACON_INT_REQ] = "MM_SET_BEACON_INT_REQ", + [MM_SET_BEACON_INT_CFM] = "MM_SET_BEACON_INT_CFM", + [MM_SET_BASIC_RATES_REQ] = "MM_SET_BASIC_RATES_REQ", + [MM_SET_BASIC_RATES_CFM] = "MM_SET_BASIC_RATES_CFM", + [MM_SET_BSSID_REQ] = "MM_SET_BSSID_REQ", + [MM_SET_BSSID_CFM] = "MM_SET_BSSID_CFM", + [MM_SET_EDCA_REQ] = "MM_SET_EDCA_REQ", + [MM_SET_EDCA_CFM] = "MM_SET_EDCA_CFM", + [MM_SET_ASSOCIATED_REQ] = "MM_SET_ASSOCIATED_REQ", + [MM_SET_ASSOCIATED_CFM] = "MM_SET_ASSOCIATED_CFM", + [MM_SET_SLOTTIME_REQ] = "MM_SET_SLOTTIME_REQ", + [MM_SET_SLOTTIME_CFM] = "MM_SET_SLOTTIME_CFM", + [MM_SET_IDLE_REQ] = "MM_SET_IDLE_REQ", + [MM_SET_IDLE_CFM] = "MM_SET_IDLE_CFM", + [MM_KEY_ADD_REQ] = "MM_KEY_ADD_REQ", + [MM_KEY_ADD_CFM] = "MM_KEY_ADD_CFM", + [MM_KEY_DEL_REQ] = "MM_KEY_DEL_REQ", + [MM_KEY_DEL_CFM] = "MM_KEY_DEL_CFM", + [MM_BA_ADD_TX_REQ] = "MM_BA_ADD_TX_REQ", + [MM_BA_ADD_TX_CFM] = "MM_BA_ADD_TX_CFM", + [MM_BA_ADD_RX_REQ] = "MM_BA_ADD_RX_REQ", + [MM_BA_ADD_RX_CFM] = "MM_BA_ADD_RX_CFM", + [MM_BA_DEL_REQ] = "MM_BA_DEL_REQ", + [MM_BA_DEL_CFM] = "MM_BA_DEL_CFM", + [MM_PHY_RESET_REQ] = "MM_PHY_RESET_REQ", + [MM_PHY_RESET_CFM] = "MM_PHY_RESET_CFM", + [MM_AVAILABLE_BA_TXQ_REQ] = "MM_AVAILABLE_BA_TXQ_REQ", + [MM_AVAILABLE_BA_TXQ_CFM] = "MM_AVAILABLE_BA_TXQ_CFM", + [MM_UPDATE_RATE_DL_REQ] = "MM_UPDATE_RATE_DL_REQ", + [MM_UPDATE_RATE_DL_CFM] = "MM_UPDATE_RATE_DL_CFM", + [MM_UPDATE_RATE_UL_REQ] = "MM_UPDATE_RATE_UL_REQ", + [MM_UPDATE_RATE_UL_CFM] = "MM_UPDATE_RATE_UL_CFM", + [MM_SET_VNS_REQ] = "MM_SET_VNS_REQ", + [MM_SET_VNS_CFM] = "MM_SET_VNS_CFM", + [MM_SET_TX_BF_REQ] = "MM_SET_TX_BF_REQ", + [MM_SET_TX_BF_CFM] = "MM_SET_TX_BF_CFM", + [MM_SOUNDING_REQ] = "MM_SOUNDING_REQ", + [MM_SOUNDING_CFM] = "MM_SOUNDING_CFM", + [MM_SOUNDING_PAIRING_REQ] = "MM_SOUNDING_PAIRING_REQ", + [MM_SOUNDING_PAIRING_CFM] = "MM_SOUNDING_PAIRING_CFM", + [MM_SOUNDING_INTERVAL_REQ] = "MM_SOUNDING_INTERVAL_REQ", + [MM_SOUNDING_INTERVAL_CFM] = "MM_SOUNDING_INTERVAL_CFM", + [MM_SET_DFS_REQ] = "MM_SET_DFS_REQ", + [MM_SET_DFS_CFM] = "MM_SET_DFS_CFM", + [MM_NDP_TX_CONTROL_REQ] = "MM_NDP_TX_CONTROL_REQ", + [MM_NDP_TX_CONTROL_CFM] = "MM_NDP_TX_CONTROL_CFM", + [MM_REG_WRITE_REQ] = "MM_REG_WRITE_REQ", + [MM_REG_WRITE_CFM] = "MM_REG_WRITE_CFM", + [MM_PROT_MODE_REQ] = "MM_PROT_MODE_REQ", + [MM_PROT_MODE_CFM] = "MM_PROT_MODE_CFM", + [MM_BACKUP_BCN_EN_REQ] = "MM_BACKUP_BCN_EN_REQ", + [MM_BACKUP_BCN_EN_CFM] = "MM_BACKUP_BCN_EN_CFM", + [MM_START_PERIODIC_TX_TIME_REQ] = "MM_START_PERIODIC_TX_TIME_REQ", + [MM_START_PERIODIC_TX_TIME_CFM] = "MM_START_PERIODIC_TX_TIME_CFM", + [MM_ANAMON_READ_REQ] = "MM_ANAMON_READ_REQ", + [MM_ANAMON_READ_CFM] = "MM_ANAMON_READ_CFM", + [MM_REFRESH_PWR_REQ] = "MM_REFRESH_PWR_REQ", + [MM_REFRESH_PWR_CFM] = "MM_REFRESH_PWR_CFM", + [MM_SET_ANT_PWR_OFFSET_REQ] = "MM_SET_ANT_PWR_OFFSET_REQ", + [MM_SET_ANT_PWR_OFFSET_CFM] = "MM_SET_ANT_PWR_OFFSET_CFM", + [MM_SET_RATE_FALLBACK_REQ] = "MM_SET_RATE_FALLBACK_REQ", + [MM_SET_RATE_FALLBACK_CFM] = "MM_SET_RATE_FALLBACK_CFM", + [MM_SPI_WRITE_REQ] = "MM_SPI_WRITE_REQ", + [MM_SPI_WRITE_CFM] = "MM_SPI_WRITE_CFM", + [MM_SPI_READ_REQ] = "MM_SPI_READ_REQ", + [MM_SPI_READ_CFM] = "MM_SPI_READ_CFM", + + /* DBG messages */ + [DBG_STR_SHIFT(DBG_SET_MOD_FILTER_REQ)] = "DBG_SET_MOD_FILTER_REQ", + [DBG_STR_SHIFT(DBG_SET_MOD_FILTER_CFM)] = "DBG_SET_MOD_FILTER_CFM", + [DBG_STR_SHIFT(DBG_CE_SET_MOD_FILTER_REQ)] = "DBG_CE_SET_MOD_FILTER_REQ", + [DBG_STR_SHIFT(DBG_CE_SET_MOD_FILTER_CFM)] = "DBG_CE_SET_MOD_FILTER_CFM", + [DBG_STR_SHIFT(DBG_SET_SEV_FILTER_REQ)] = "DBG_SET_SEV_FILTER_REQ", + [DBG_STR_SHIFT(DBG_SET_SEV_FILTER_CFM)] = "DBG_SET_SEV_FILTER_CFM", + [DBG_STR_SHIFT(DBG_GET_E2W_STATS_REQ)] = "DBG_GET_E2W_STATS_REQ", + [DBG_STR_SHIFT(DBG_GET_E2W_STATS_CFM)] = "DBG_GET_E2W_STATS_CFM", + [DBG_STR_SHIFT(DBG_SET_LA_MPIF_MASK_REQ)] = "DBG_SET_LA_MPIF_MASK_REQ", + [DBG_STR_SHIFT(DBG_SET_LA_MPIF_MASK_CFM)] = "DBG_SET_LA_MPIF_MASK_CFM", + [DBG_STR_SHIFT(DBG_SET_LA_TRIG_POINT_REQ)] = "DBG_SET_LA_TRIG_POINT_REQ", + [DBG_STR_SHIFT(DBG_SET_LA_TRIG_POINT_CFM)] = "DBG_SET_LA_TRIG_POINT_CFM", + [DBG_STR_SHIFT(DBG_SET_LA_MPIF_DEBUG_MODE_REQ)] = "DBG_SET_LA_MPIF_DEBUG_MODE_REQ", + [DBG_STR_SHIFT(DBG_SET_LA_MPIF_DEBUG_MODE_CFM)] = "DBG_SET_LA_MPIF_DEBUG_MODE_CFM", + [DBG_STR_SHIFT(DBG_SET_LA_TRIG_RULE_REQ)] = "DBG_SET_LA_TRIG_RULE_REQ", + [DBG_STR_SHIFT(DBG_SET_LA_TRIG_RULE_CFM)] = "DBG_SET_LA_TRIG_RULE_CFM", + [DBG_STR_SHIFT(DBG_TX_TRACE_DEBUG_FLAG_REQ)] = "DBG_TX_TRACE_DEBUG_FLAG_REQ", + [DBG_STR_SHIFT(DBG_TX_TRACE_DEBUG_FLAG_CFM)] = "DBG_TX_TRACE_DEBUG_FLAG_CFM", + [DBG_STR_SHIFT(DBG_PRINT_STATS_REQ)] = "DBG_PRINT_STATS_REQ", + [DBG_STR_SHIFT(DBG_PRINT_STATS_CFM)] = "DBG_PRINT_STATS_CFM", + [DBG_STR_SHIFT(DBG_TRIGGER_REQ)] = "DBG_TRIGGER_REQ", + [DBG_STR_SHIFT(DBG_TRIGGER_CFM)] = "DBG_TRIGGER_CFM", + [DBG_STR_SHIFT(DBG_TEST_MODE_REQ)] = "DBG_TEST_MODE_REQ", + [DBG_STR_SHIFT(DBG_TEST_MODE_CFM)] = "DBG_TEST_MODE_CFM", + [DBG_STR_SHIFT(DBG_SOUNDING_CMD_REQ)] = "DBG_SOUNDING_CMD_REQ", + [DBG_STR_SHIFT(DBG_SOUNDING_CMD_CFM)] = "DBG_SOUNDING_CMD_CFM", + [DBG_STR_SHIFT(DBG_PRESILICON_TESTING_REQ)] = "DBG_PRESILICON_TESTING_REQ", + [DBG_STR_SHIFT(DBG_PRESILICON_TESTING_CFM)] = "DBG_PRESILICON_TESTING_CFM", +}; + +static void cl_check_exception(struct cl_hw *cl_hw) +{ + /* Check if Tensilica exception occurred */ + int i; + struct cl_ipc_exception_struct __iomem *data = + (struct cl_ipc_exception_struct __iomem *)cl_hw->ipc_env->shared; + + if (__raw_readl(&data->pattern) != IPC_EXCEPTION_PATTERN) + return; + + cl_dbg_err(cl_hw, "######################### firmware tensilica exception:\n"); + cl_dbg_err(cl_hw, "................................. type: "); + + switch (__raw_readl(&data->type)) { + case 0: + cl_dbg_err(cl_hw, "EXCEPTION_ILLEGALINSTRUCTION\n"); + break; + case 2: + cl_dbg_err(cl_hw, "EXCEPTION_INSTRUCTIONFETCHERROR\n"); + break; + case 3: + cl_dbg_err(cl_hw, "EXCEPTION_LOADSTOREERROR\n"); + break; + case 6: + cl_dbg_err(cl_hw, "EXCEPTION_INTEGERDIVIDEBYZERO\n"); + break; + case 7: + cl_dbg_err(cl_hw, "EXCEPTION_SPECULATION\n"); + break; + case 8: + cl_dbg_err(cl_hw, "EXCEPTION_PRIVILEGED\n"); + break; + case 9: + cl_dbg_err(cl_hw, "EXCEPTION_UNALIGNED\n"); + break; + case 16: + cl_dbg_err(cl_hw, "EXCEPTION_INSTTLBMISS\n"); + break; + case 17: + cl_dbg_err(cl_hw, "EXCEPTION_INSTTLBMULTIHIT\n"); + break; + case 18: + cl_dbg_err(cl_hw, "EXCEPTION_INSTFETCHPRIVILEGE\n"); + break; + case 20: + cl_dbg_err(cl_hw, "EXCEPTION_INSTFETCHPROHIBITED\n"); + break; + case 24: + cl_dbg_err(cl_hw, "EXCEPTION_LOADSTORETLBMISS\n"); + break; + case 25: + cl_dbg_err(cl_hw, "EXCEPTION_LOADSTORETLBMULTIHIT\n"); + break; + case 26: + cl_dbg_err(cl_hw, "EXCEPTION_LOADSTOREPRIVILEGE\n"); + break; + case 28: + cl_dbg_err(cl_hw, "EXCEPTION_LOADPROHIBITED\n"); + break; + default: + cl_dbg_err(cl_hw, "unknown\n"); + break; + } + + cl_dbg_err(cl_hw, "................................. EPC: %08X\n", + __raw_readl(&data->epc)); + cl_dbg_err(cl_hw, "................................. EXCSAVE: %08X\n", + __raw_readl(&data->excsave)); + cl_dbg_err(cl_hw, "..............BACKTRACE-PC.....................\n"); + + for (i = 0; i < IPC_BACKTRACT_DEPTH; i++) + cl_dbg_err(cl_hw, "PC#%d: 0x%08X\n", i, + __raw_readl(&data->backtrace.pc[i])); +} + +static u16 cl_msg_cfm_clear_bit(u16 cfm) +{ + if (cfm < MM_REQ_CFM_MAX) + return ((cfm - 1) >> 1); + + return ((cfm - 1 - FIRST_MSG(TASK_DBG) + MM_REQ_CFM_MAX) >> 1); +} + +u16 cl_msg_cfm_set_bit(u16 req) +{ + if (req < MM_REQ_CFM_MAX) + return (req >> 1); + + return ((req - FIRST_MSG(TASK_DBG) + MM_REQ_CFM_MAX) >> 1); +} + +int cl_msg_cfm_wait(struct cl_hw *cl_hw, u16 bit, u16 req_id) +{ + /* + * Start a timeout to stop on the main waiting queue, + * and then check the result. + */ + struct cl_chip *chip = cl_hw->chip; + int timeout = 0, error = 0; + int max_timeout = 0; + + if (IS_REAL_PHY(chip)) { + if (!cl_hw->msg_calib_timeout) + max_timeout = CL_MSG_CFM_TIMEOUT_JIFFIES; + else + max_timeout = CL_MSG_CFM_TIMEOUT_CALIB_JIFFIES; + } else if (chip->conf->ci_phy_dev == PHY_DEV_FRU) { + max_timeout = CL_MSG_CFM_TIMEOUT_FRU_JIFFIES; + } else { + max_timeout = CL_MSG_CFM_TIMEOUT_DUMMY_JIFFIES; + } + + /* Wait for confirmation message */ + timeout = wait_event_timeout(cl_hw->wait_queue, + !CFM_TEST_BIT(bit, &cl_hw->cfm_flags), + max_timeout); + + if (timeout == 0) { + /* + * Timeout occurred! + * Make sure that confirmation wasn't received after the timeout. + */ + if (CFM_TEST_BIT(bit, &cl_hw->cfm_flags)) { + cl_dbg_verbose(cl_hw, "[WARN] Timeout occurred - %s\n", + MSG_ID_STR(req_id)); + error = -ETIMEDOUT; + } + } + + if (error) { + struct cl_irq_stats *irq_stats = &chip->irq_stats; + unsigned long now = jiffies, flags; + u32 status, raw_status; + + /* + * The interrupt was not handled in time, lets try to handle it safely. + * The spin lock protects us from the following race scenarios: + * 1) atomic read of the IPC status register, + * 2) execution on the msg handler twice from different context. + * 3) disable context switch from the same core. + */ + spin_lock_irqsave(&chip->isr_lock, flags); + + status = ipc_xmac_2_host_status_get(chip); + raw_status = ipc_xmac_2_host_raw_status_get(chip); + + cl_dbg_verbose(cl_hw, + "[INFO] status=0x%x, raw_status=0x%x, last_isr_statuses=0x%x, " + "last_rx=%ums, last_tx=%ums, last_isr=%ums\n", + status, + raw_status, + irq_stats->last_isr_statuses, + jiffies_to_msecs(now - irq_stats->last_rx), + jiffies_to_msecs(now - irq_stats->last_tx), + jiffies_to_msecs(now - irq_stats->last_isr)); + + if (status & cl_hw->ipc_e2a_irq.msg) { + /* + * WORKAROUND #1: In some cases the kernel is losing sync with the + * interrupt handler and the reason is still unknown. + * It seems that disabling master interrupt for a couple of cycles and + * then re-enabling it restores the sync with the cl interrupt handler. + */ + ipc_host_global_int_en_set(chip, 0); + + /* Acknowledge the MSG interrupt */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.msg); + + /* + * Unlock before calling cl_msg_rx_tasklet() because + * spin_unlock_irqrestore() disables interrupts, but in + * cl_msg_rx_tasklet() there might be several places that + * use spin_unlock_bh() which enables soft-irqs. + */ + spin_unlock_irqrestore(&chip->isr_lock, flags); + + /* + * Call the tasklet handler (it also gives the CPU that + * is mapped to the cl_interrupt few cycle to recover) + */ + cl_msg_rx_tasklet((unsigned long)cl_hw); + + /* Re-enable master interrupts */ + ipc_host_global_int_en_set(chip, 1); + } else { + /* + * WORKAROUND #2: Try to call the handler unconditioanly. + * Maybe we cleared the "cl_hw->ipc_e2a_irq.msg" without handling it. + */ + + /* + * Unlock before calling cl_msg_rx_tasklet() because + * spin_unlock_irqrestore() disables interrupts, but in + * cl_msg_rx_tasklet() there might be several places + * that use spin_unlock_bh() which enables soft-irqs. + */ + spin_unlock_irqrestore(&chip->isr_lock, flags); + + /* Call the tasklet handler */ + cl_msg_rx_tasklet((unsigned long)cl_hw); + } + + /* Did the workarounds work? */ + if (CFM_TEST_BIT(bit, &cl_hw->cfm_flags)) { + cl_dbg_verbose(cl_hw, "[ERR] Failed to recover from timeout\n"); + } else { + cl_dbg_verbose(cl_hw, "[INFO] Managed to recover from timeout\n"); + error = 0; + goto exit; + } + + /* Failed handling the message */ + CFM_CLEAR_BIT(bit, &cl_hw->cfm_flags); + + cl_check_exception(cl_hw); + + cl_hw_assert_check(cl_hw); + + if (!strcmp(chip->conf->ce_ela_mode, "XTDEBUG") || + !strcmp(chip->conf->ce_ela_mode, "XTDEBUG_STD")) { + /* + * TODO: Special debug hack: collect debug info & skip restart + * "wait4cfm" string is expected by debug functionality + */ + goto exit; + } + + if (!test_bit(CL_DEV_HW_RESTART, &cl_hw->drv_flags) && + !test_bit(CL_DEV_SW_RESTART, &cl_hw->drv_flags) && + test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) && + !cl_hw->is_stop_context) { + /* Unlock msg mutex before restarting */ + mutex_unlock(&cl_hw->msg_tx_mutex); + + cl_recovery_start(cl_hw, RECOVERY_WAIT4CFM); + return error; + } + } + +exit: + /* Unlock msg mutex */ + mutex_unlock(&cl_hw->msg_tx_mutex); + + return error; +} + +static void cl_msg_cfm_assign_params(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + u32 *param; + u16 msg_id = le16_to_cpu(msg->id); + u16 msg_len = le16_to_cpu(msg->param_len); + + /* A message sent in background is not allowed to assign confirmation parameters */ + if (cl_hw->msg_background) { + cl_dbg_verbose(cl_hw, + "Background message can't assign confirmation parameters (%s)\n", + MSG_ID_STR(msg_id)); + return; + } + + if (msg->param_len) { + param = kzalloc(msg_len, GFP_ATOMIC); + if (param) { + memcpy(param, msg->param, msg_len); + if (cl_hw->msg_cfm_params[msg_id]) + cl_dbg_err(cl_hw, "msg_cfm_params is not NULL for %s\n", + MSG_ID_STR(msg_id)); + cl_hw->msg_cfm_params[msg_id] = param; + } else { + cl_dbg_err(cl_hw, "param allocation failed\n"); + } + } else { + u16 dummy_dest_id = le16_to_cpu(msg->dummy_dest_id); + u16 dummy_src_id = le16_to_cpu(msg->dummy_src_id); + + cl_dbg_err(cl_hw, "msg->param_len is 0 [%u,%u,%u]\n", + msg_id, dummy_dest_id, dummy_src_id); + } +} + +void cl_msg_cfm_assign_and_clear(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + u16 bit = cl_msg_cfm_clear_bit(le16_to_cpu(msg->id)); + + if (CFM_TEST_BIT(bit, &cl_hw->cfm_flags)) { + cl_msg_cfm_assign_params(cl_hw, msg); + CFM_CLEAR_BIT(bit, &cl_hw->cfm_flags); + } else { + cl_dbg_verbose(cl_hw, "Msg ID not set in cfm_flags (%s)\n", + MSG_ID_STR(le16_to_cpu(msg->id))); + } +} + +void cl_msg_cfm_clear(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + u16 bit = cl_msg_cfm_clear_bit(le16_to_cpu(msg->id)); + + if (!CFM_TEST_AND_CLEAR_BIT(bit, &cl_hw->cfm_flags)) + cl_dbg_verbose(cl_hw, "Msg ID not set in cfm_flags (%s)\n", + MSG_ID_STR(le16_to_cpu(msg->id))); +} + +static inline void rx_mm_start_cfm(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + cl_msg_cfm_clear(cl_hw, msg); + + /* Send indication to the embedded that a new rxbuffer element are ready */ + cl_hw->ipc_host2xmac_trigger_set(cl_hw->chip, IPC_IRQ_A2E_RXBUF_BACK); +} + +static inline void rx_mm_ba_add_cfm(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + if (le16_to_cpu(msg->id) == MM_BA_ADD_TX_CFM) + cl_msg_cfm_assign_and_clear(cl_hw, msg); + else + cl_msg_cfm_clear(cl_hw, msg); +} + +static inline void rx_mm_agg_tx_report_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + struct cl_agg_tx_report *agg_report = (struct cl_agg_tx_report *)msg->param; + struct cl_sta *cl_sta; + union cl_rate_ctrl_info rate_ctrl_info; + u8 queue_idx = agg_report->tx_queue_idx; + u16 ssn = agg_report->new_ssn; + + /* First handle agg cfm */ + cl_tx_release_skbs_from_cfm(cl_hw, queue_idx, ssn); + /* + * Take care of endianness and update gi and format_mod fields of rate + * ctrl info in agg_report for the sake of any function that needs to + * use them + */ + rate_ctrl_info.word = le32_to_cpu(agg_report->rate_cntrl_info); + + cl_rate_ctrl_convert(&rate_ctrl_info); + agg_report->rate_cntrl_info = cpu_to_le32(rate_ctrl_info.word); + + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, agg_report->sta_idx); + + if (cl_sta) { + /* TX stats */ + cl_agg_tx_report_handler(cl_hw, cl_sta, (void *)agg_report); + cl_stats_update_tx_agg(cl_hw, cl_sta, agg_report); + + /* RSSI stats */ + if (!agg_report->ba_not_received) + cl_rssi_block_ack_handler(cl_hw, cl_sta, agg_report); + + /* + * TODO: Do we need to notify upper layer at agg_report->success? + * Ageout may need to reset ageout counter if at least one + * frame was success. + * May be needed when sending UDP downlink because BA's are not + * forwarded to driver. + */ + } + + cl_sta_unlock(cl_hw); + + /* Schedule tasklet to try and empty the queue */ + tasklet_schedule(&cl_hw->tx_task); +} + +static inline void rx_mm_agg_rx_report_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + struct mm_agg_rx_ind *agg_report = (struct mm_agg_rx_ind *)msg->param; + struct cl_sta *cl_sta = NULL; + u8 sta_loc; + + for (sta_loc = 0; sta_loc < agg_report->sta_num; sta_loc++) { + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, agg_report->sta_idx[sta_loc]); + if (cl_sta) + cl_agg_rx_report_handler(cl_hw, cl_sta, sta_loc, agg_report); + cl_sta_unlock(cl_hw); + } +} + +static inline void rx_mm_sounding_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + struct mm_sounding_ind *ind = (struct mm_sounding_ind *)msg->param; + + cl_sounding_indication(cl_hw, ind); +} + +static inline void rx_mm_fw_error_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + struct mm_fw_error_ind *ind = (struct mm_fw_error_ind *)msg->param; + + switch (ind->error_type) { + case MM_FW_ERROR_TYPE_MAX: + default: + cl_dbg_err(cl_hw, "Invalid fw error type %u\n", ind->error_type); + break; + } +} + +static inline void rx_mm_idle_async_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + cl_hw->idle_async_set = false; + + cl_dbg_trace(cl_hw, "Clear MM_IDLE_ASYNC_IND\n"); +} + +static inline void rx_dbg_print_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + cl_hw_assert_print(cl_hw, msg); +} + +static inline void rx_dbg_info_ind(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + cl_fw_dbg_handler(cl_hw); +} + +static void (*mm_hdlrs[])(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) = { + [MM_RESET_CFM] = cl_msg_cfm_clear, + [MM_START_CFM] = rx_mm_start_cfm, + [MM_VERSION_CFM] = cl_msg_cfm_assign_and_clear, + [MM_ADD_IF_CFM] = cl_msg_cfm_assign_and_clear, + [MM_REMOVE_IF_CFM] = cl_msg_cfm_clear, + [MM_STA_ADD_CFM] = cl_msg_cfm_assign_and_clear, + [MM_STA_DEL_CFM] = cl_msg_cfm_clear, + [MM_SET_FILTER_CFM] = cl_msg_cfm_clear, + [MM_SET_CHANNEL_CFM] = cl_msg_cfm_clear, + [MM_EXT_CALIB_CFM] = cl_msg_cfm_clear, + [MM_SET_DTIM_CFM] = cl_msg_cfm_clear, + [MM_SET_BEACON_INT_CFM] = cl_msg_cfm_clear, + [MM_SET_BASIC_RATES_CFM] = cl_msg_cfm_clear, + [MM_SET_BSSID_CFM] = cl_msg_cfm_clear, + [MM_SET_EDCA_CFM] = cl_msg_cfm_clear, + [MM_SET_ASSOCIATED_CFM] = cl_msg_cfm_clear, + [MM_SET_SLOTTIME_CFM] = cl_msg_cfm_clear, + [MM_SET_IDLE_CFM] = cl_msg_cfm_clear, + [MM_KEY_ADD_CFM] = cl_msg_cfm_assign_and_clear, + [MM_KEY_DEL_CFM] = cl_msg_cfm_clear, + [MM_BA_ADD_TX_CFM] = rx_mm_ba_add_cfm, + [MM_BA_ADD_RX_CFM] = rx_mm_ba_add_cfm, + [MM_BA_DEL_CFM] = cl_msg_cfm_assign_and_clear, + [MM_AVAILABLE_BA_TXQ_CFM] = cl_msg_cfm_assign_and_clear, + [MM_UPDATE_RATE_DL_CFM] = cl_msg_cfm_clear, + [MM_UPDATE_RATE_UL_CFM] = cl_msg_cfm_clear, + [MM_SET_VNS_CFM] = cl_msg_cfm_clear, + [MM_SET_TX_BF_CFM] = cl_msg_cfm_clear, + [MM_PHY_RESET_CFM] = cl_msg_cfm_clear, + [MM_SET_DFS_CFM] = cl_msg_cfm_clear, + [MM_NDP_TX_CONTROL_CFM] = cl_msg_cfm_clear, + [MM_REG_WRITE_CFM] = cl_msg_cfm_clear, + [MM_PROT_MODE_CFM] = cl_msg_cfm_clear, + [MM_SOUNDING_CFM] = cl_msg_cfm_assign_and_clear, + [MM_SOUNDING_PAIRING_CFM] = cl_msg_cfm_clear, + [MM_SOUNDING_INTERVAL_CFM] = cl_msg_cfm_assign_and_clear, + [MM_BACKUP_BCN_EN_CFM] = cl_msg_cfm_clear, + [MM_START_PERIODIC_TX_TIME_CFM] = cl_msg_cfm_clear, + [MM_ANAMON_READ_CFM] = cl_msg_cfm_assign_and_clear, + [MM_REFRESH_PWR_CFM] = cl_msg_cfm_clear, + [MM_SET_ANT_PWR_OFFSET_CFM] = cl_msg_cfm_clear, + [MM_SET_RATE_FALLBACK_CFM] = cl_msg_cfm_clear, + [MM_SPI_WRITE_CFM] = cl_msg_cfm_clear, + [MM_SPI_READ_CFM] = cl_msg_cfm_assign_and_clear, + [MM_AGG_TX_REPORT_IND] = rx_mm_agg_tx_report_ind, + [MM_AGG_RX_REPORT_IND] = rx_mm_agg_rx_report_ind, + [MM_SOUNDING_IND] = rx_mm_sounding_ind, + [MM_FW_ERROR_IND] = rx_mm_fw_error_ind, + [MM_IDLE_ASYNC_IND] = rx_mm_idle_async_ind, + [MM_MAX] = NULL, +}; + +#define DBG_MSG_SHIFT(id) ((id) - FIRST_MSG(TASK_DBG)) + +static void (*dbg_hdlrs[])(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) = { + [DBG_MSG_SHIFT(DBG_SET_MOD_FILTER_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_SET_SEV_FILTER_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_CE_SET_MOD_FILTER_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_GET_E2W_STATS_CFM)] = cl_msg_cfm_assign_and_clear, + [DBG_MSG_SHIFT(DBG_SET_LA_MPIF_MASK_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_SET_LA_TRIG_POINT_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_SET_LA_MPIF_DEBUG_MODE_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_SET_LA_TRIG_RULE_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_TX_TRACE_DEBUG_FLAG_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_PRINT_STATS_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_TRIGGER_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_TEST_MODE_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_SOUNDING_CMD_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_PRESILICON_TESTING_CFM)] = cl_msg_cfm_clear, + [DBG_MSG_SHIFT(DBG_PRINT_IND)] = rx_dbg_print_ind, + [DBG_MSG_SHIFT(DBG_INFO_IND)] = rx_dbg_info_ind, + [DBG_MSG_SHIFT(DBG_MAX)] = NULL, +}; + +static bool cl_is_dbg_msg(u16 msg_id) +{ + return (msg_id >= FIRST_MSG(TASK_DBG) && msg_id < DBG_MAX); +} + +static void cl_msg_rx_run_mm(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg, u16 msg_id) +{ + if (msg_id < MM_REQ_CFM_MAX) + cl_dbg_trace(cl_hw, "%s\n", msg2str[msg_id]); + + mm_hdlrs[msg_id](cl_hw, msg); +} + +static int cl_msg_rx_run_dbg(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg, u16 msg_id) +{ + u16 dbg_id = DBG_MSG_SHIFT(msg_id); + + if (dbg_hdlrs[dbg_id]) { + if (msg_id < DBG_REQ_CFM_MAX) { + u16 str_id = DBG_STR_SHIFT(msg_id); + + cl_dbg_trace(cl_hw, "%s\n", msg2str[str_id]); + } + + dbg_hdlrs[dbg_id](cl_hw, msg); + return 0; + } + + return -1; +} + +static int cl_msg_rx_run(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + u16 msg_id = le16_to_cpu(msg->id); + + if (msg_id < MM_MAX && mm_hdlrs[msg_id]) { + cl_msg_rx_run_mm(cl_hw, msg, msg_id); + return 0; + } + + if (cl_is_dbg_msg(msg_id)) + return cl_msg_rx_run_dbg(cl_hw, msg, msg_id); + + return -1; +} + +static bool cl_is_cfm_msg(u16 msg_id) +{ + /* A confirmation must be an odd id */ + if ((msg_id & 0x1) == 0) + return false; + + return ((msg_id < MM_FIRST_IND) || cl_is_dbg_msg(msg_id)); +} + +static int cl_msg_rx_handler(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + int ret = 0; + u16 msg_id = le16_to_cpu(msg->id); + + /* Relay further actions to the msg parser */ + ret = cl_msg_rx_run(cl_hw, msg); + + if (ret) { + cl_dbg_err(cl_hw, "Unexpected msg (%u)\n", msg_id); + } else { + /* Wake up the queue in case the msg is a confirmation */ + if (cl_is_cfm_msg(msg_id)) + wake_up(&cl_hw->wait_queue); + } + + return ret; +} + +void cl_msg_rx_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_e2a_msg_elem *msg_elem = NULL; + struct cl_ipc_e2a_msg *msg = NULL; + int msg_handled = 0; + u8 idx; + + while (1) { + idx = ipc_env->e2a_msg_host_idx; + msg_elem = (struct cl_e2a_msg_elem *)(ipc_env->e2a_msg_hostbuf_array[idx].hostid); + msg = msg_elem->msgbuf_ptr; + + /* Look for pattern which means that this hostbuf has been used for a MSG */ + if (le32_to_cpu(msg->pattern) != IPC_E2A_MSG_VALID_PATTERN) + break; + + cl_msg_rx_handler(cl_hw, msg); + msg_handled++; + + /* Reset the msg element and re-use it */ + msg->pattern = 0; + + /* Make sure memory is written before push to HW */ + wmb(); + + /* Push back the buffer */ + cl_ipc_msgbuf_push(ipc_env, (ptrdiff_t)msg_elem, msg_elem->dma_addr); + } +} + +void cl_msg_rx_flush_all(struct cl_hw *cl_hw) +{ + int i = 0; + + for (i = FIRST_MSG(TASK_MM); i < MM_MAX; i++) { + if (cl_hw->msg_cfm_params[i]) { + cl_dbg_verbose(cl_hw, "free MM msg_cfm_params %d\n", i); + cl_msg_tx_free_cfm_params(cl_hw, i); + } + } + + for (i = FIRST_MSG(TASK_DBG); i < DBG_MAX; i++) { + if (cl_hw->msg_cfm_params[i]) { + cl_dbg_verbose(cl_hw, "free DBG msg_cfm_params %d\n", i); + cl_msg_tx_free_cfm_params(cl_hw, i); + } + } +} + +#define DRV_TASK_ID 100 + +#define CL_DEF_ANT_BITMAP 0x55 + +/* No scale-down on ASIC platform */ +#define CL_ASIC_FW_SCALEDOWN 1 + +struct cl_msg_tx_work { + struct work_struct ws; + + /* Background message info */ + struct cl_hw *cl_hw; + void *msg_params; +}; + +void cl_msg_tx_free_cfm_params(struct cl_hw *cl_hw, u16 id) +{ + /* Free message and set pointer to NULL */ + kfree(cl_hw->msg_cfm_params[id]); + cl_hw->msg_cfm_params[id] = NULL; +} + +static inline void *cl_msg_zalloc(struct cl_hw *cl_hw, u16 msg_id, u8 dst_task_id, u16 param_len) +{ + struct cl_fw_msg *msg; + u32 total_size = ALIGN(sizeof(struct cl_fw_msg) + param_len, sizeof(u32)); + u32 max_size = sizeof(u32) * IPC_A2E_MSG_BUF_SIZE; + + if (total_size > max_size) { + cl_dbg_err(cl_hw, "total size (%u) > max size (%u)\n", + total_size, max_size); + return NULL; + } + + /* msg is freed out of the scope of this function */ + msg = kzalloc(total_size, GFP_ATOMIC); + if (!msg) + return NULL; + + msg->msg_id = cpu_to_le16(msg_id); + msg->dst_kern_id = cl_hw->fw_dst_kern_id; + msg->dst_task_id = dst_task_id; + msg->src_kern_id = KERN_HOST; + msg->src_task_id = DRV_TASK_ID; + msg->param_len = cpu_to_le16(param_len); + + return msg->param; +} + +static inline void cl_msg_free(const void *msg_param) +{ + kfree(container_of((void *)msg_param, struct cl_fw_msg, param)); +} + +static void cl_send_msg_background_handler(struct work_struct *ws) +{ + struct cl_msg_tx_work *msg_tx_work = container_of(ws, struct cl_msg_tx_work, ws); + + cl_drv_ops_msg_fw_send(msg_tx_work->cl_hw, msg_tx_work->msg_params, true); + kfree(msg_tx_work); +} + +static int cl_send_msg_background(struct cl_hw *cl_hw, + const void *msg_params) +{ + /* Generate & populate the work struct wrapper for the background msg */ + struct cl_msg_tx_work *msg_tx_work = kzalloc(sizeof(*msg_tx_work), GFP_ATOMIC); + + if (msg_tx_work) { + INIT_WORK(&msg_tx_work->ws, cl_send_msg_background_handler); + msg_tx_work->cl_hw = cl_hw; + msg_tx_work->msg_params = (void *)msg_params; + + /* Schedule work, the work will be executed in the background */ + queue_work(cl_hw->drv_workqueue, &msg_tx_work->ws); + + return 0; + } + + cl_dbg_err(cl_hw, "msg_tx_work allocation failed\n"); + cl_msg_free(msg_params); + + return -ENODATA; +} + +static int cl_send_request(struct cl_hw *cl_hw, const void *msg_params) +{ + int ret; + bool background = (preempt_count() != 0); + + if (background) { + /* + * asynchronous operation mode, message would be triggered in the background + */ + ret = cl_send_msg_background(cl_hw, msg_params); + } else { + /* + * synchronous operation mode, message would be triggered immediately + * feedback to caller given immediately + */ + ret = cl_drv_ops_msg_fw_send(cl_hw, msg_params, false); + } + + /* + * In case of synchronous mode ret success implies that the msg was successfully + * transmited where is asynchronous mode ret success implies that the msg was + * successfully pushed to background queue + */ + return ret; +} + +int cl_msg_tx_reset(struct cl_hw *cl_hw) +{ + void *void_param; + + /* RESET REQ has no parameter */ + void_param = cl_msg_zalloc(cl_hw, MM_RESET_REQ, TASK_MM, 0); + if (!void_param) + return -ENOMEM; + + return cl_send_request(cl_hw, void_param); +} + +static u8 cl_copy_mask_bits(u8 mask, u8 num_bits) +{ + /* Copy first X bits that are set in mask to new_mask */ + u8 i = 0, cntr = 0, new_mask = 0; + + for (i = 0; i < MAX_ANTENNAS; i++) { + if (mask & BIT(i)) { + new_mask |= BIT(i); + + cntr++; + if (cntr == num_bits) + break; + } + } + + return new_mask; +} + +static void cl_fill_ant_config(struct cl_hw *cl_hw, + struct cl_antenna_config *ant_config, + u8 num_antennas, u8 mask_antennas, + u8 tx_mask_cck, u8 rx_mask_cck) +{ + struct cl_chip *chip = cl_hw->chip; + u8 ricu_cdb = 0; + u8 riu_chain_mask = 0x0; + u8 ant, riu_chain; + + riu_chain_mask = cl_hw_ant_mask_to_riu_chain_mask(cl_hw, mask_antennas); + ant_config->num_tx_he = num_antennas; + ant_config->num_rx = num_antennas; + ant_config->mask_tx_he = riu_chain_mask; + ant_config->mask_rx = riu_chain_mask; + + /* Configuration for TX OFDM/HT/VHT (limited to 4 antennas) */ + if (num_antennas <= MAX_ANTENNAS_OFDM_HT_VHT) { + ant_config->num_tx_ofdm_ht_vht = num_antennas; + ant_config->mask_tx_ofdm_ht_vht = riu_chain_mask; + } else { + ant_config->num_tx_ofdm_ht_vht = MAX_ANTENNAS_OFDM_HT_VHT; + ant_config->mask_tx_ofdm_ht_vht = + cl_copy_mask_bits(riu_chain_mask, MAX_ANTENNAS_OFDM_HT_VHT); + } + + /* Antenna configuration for CCK */ + if (cl_band_is_24g(cl_hw)) { + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + riu_chain = cl_hw_ant_to_riu_chain(cl_hw, ant); + + if (tx_mask_cck & BIT(ant)) + ant_config->mask_tx_cck |= BIT(riu_chain); + + if (rx_mask_cck & BIT(ant)) + ant_config->mask_rx_cck |= BIT(riu_chain); + } + } + + if (IS_REAL_PHY(chip)) + ricu_cdb = ricu_static_conf_0_cdb_mode_maj_getf(chip); + else + ricu_cdb = 4; + + /* + * In current implementation cdb_mode equals the num of ants for SX1 + * cbd_mask 0x0 -> SX0 chain. 0x1-> SX1 chain. + */ + ricu_cdb = MAX_ANTENNAS_CHIP - ricu_cdb; + ricu_cdb = ANT_MASK(ricu_cdb); + ricu_cdb = ~ricu_cdb; + + ant_config->cdb_mask = ricu_cdb; + + cl_dbg_trace(cl_hw, "num_tx_he %u, num_rx %u, mask_tx he 0x%x, mask_rx 0x%x, " + "mask_tx_ofdm_ht_vht 0x%x, mask_tx_cck 0x%x, mask_rx_cck 0x%x\n", + ant_config->num_tx_he, ant_config->num_rx, ant_config->mask_tx_he, + ant_config->mask_rx, ant_config->mask_tx_ofdm_ht_vht, ant_config->mask_tx_cck, + ant_config->mask_rx_cck); +} + +static void cl_fill_fem_config(struct cl_hw *cl_hw, struct cl_fem_config *fem_conf) +{ + int i; + u32 reg[FEM_REGISTERS_AMOUNT] = {0}; + + cl_fem_get_registers(cl_hw, reg); + + for (i = 0; i < FEM_REGISTERS_AMOUNT; i++) + fem_conf->reg[i] = cpu_to_le32(reg[i]); +} + +static void cl_fill_calib_chain(struct cl_calib_chain *chain, u8 pair, u8 tx_gain, u8 rx_gain) +{ + chain->pair = pair; + chain->initial_tx_gain = tx_gain; + chain->initial_rx_gain = rx_gain; +} + +static void cl_fill_chain_by_plan(struct cl_hw *cl_hw, struct cl_calib_param *calib_param, u8 chain, + bool is_tx) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + struct cl_calib_chain *chain_msg_dst = is_tx ? + &calib_param->tx_calib_chain[chain] : + &calib_param->rx_calib_chain[chain]; + + /* Fill chain params by default values from nvram */ + if (is_tx) + cl_fill_calib_chain(chain_msg_dst, conf->ci_calib_ant_tx[chain], + conf->ci_calib_tx_init_tx_gain[chain], + conf->ci_calib_tx_init_rx_gain[chain]); + else + cl_fill_calib_chain(chain_msg_dst, conf->ci_calib_ant_rx[chain], + conf->ci_calib_rx_init_tx_gain[chain], + conf->ci_calib_rx_init_rx_gain[chain]); +} + +static void cl_fill_calib_config(struct cl_hw *cl_hw, struct cl_calib_param *calib_param, + u16 primary, u16 center, struct cl_calib_params calib_params) +{ + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + struct cl_tcv_conf *conf = cl_hw->conf; + s8 sx_freq_offset_mhz; + u8 mode = calib_params.mode; + u8 chain = 0; + u8 calib_bitmap = calib_params.plan_bitmap; + + memset(calib_param->tx_calib_chain, U8_MAX, sizeof(struct cl_calib_chain) * MAX_ANTENNAS); + memset(calib_param->rx_calib_chain, U8_MAX, sizeof(struct cl_calib_chain) * MAX_ANTENNAS); + + riu_chain_for_each(chain) { + if (calib_bitmap & (1 << chain)) { + /* TX fill */ + cl_fill_chain_by_plan(cl_hw, calib_param, chain, true); + if (mode & SET_CHANNEL_MODE_CALIB_IQ) + /* RX fill */ + cl_fill_chain_by_plan(cl_hw, calib_param, chain, false); + } + } + + calib_param->conf.rx_gain_upper_limit = conf->ci_calib_conf_rx_gain_upper_limit; + calib_param->conf.rx_gain_lower_limit = conf->ci_calib_conf_rx_gain_lower_limit; + calib_param->conf.nco_freq = cpu_to_le16(CALIB_NCO_FREQ_DEFAULT); + calib_param->conf.nco_amp = CALIB_NCO_AMP_DEFAULT; + calib_param->conf.sleeve_trshld = GAIN_SLEEVE_TRSHLD_DEFAULT; + calib_param->conf.n_samples_exp_lolc = N_SAMPLES_EXP_LOLC; + calib_param->conf.n_samples_exp_iqc = N_SAMPLES_EXP_IQC; + calib_param->conf.p_thresh = cpu_to_le32(LO_P_THRESH); + calib_param->conf.n_bit_fir_scale = N_BIT_FIR_SCALE; + calib_param->conf.n_bit_amp_scale = N_BIT_AMP_SCALE; + calib_param->conf.n_bit_phase_scale = N_BIT_PHASE_SCALE; + + cl_calib_iq_get_tone_vector(cl_hw, calib_param->conf.tone_vector); + + calib_param->conf.gp_rad_trshld = cpu_to_le32(conf->ci_calib_conf_gp_rad_trshld); + calib_param->conf.ga_lin_upper_trshld = + cpu_to_le32(conf->ci_calib_conf_ga_lin_upper_trshld); + calib_param->conf.ga_lin_lower_trshld = + cpu_to_le32(conf->ci_calib_conf_ga_lin_lower_trshld); + calib_param->conf.comp_filter_len = COMP_FILTER_LEN_DEFAULT; + calib_param->conf.singletons_num = conf->ci_calib_conf_singletons_num; + calib_param->conf.tones_num = IQ_NUM_TONES_REQ; + calib_param->conf.rampup_time = cpu_to_le16(conf->ci_calib_conf_rampup_time); + calib_param->conf.lo_coarse_step = cpu_to_le16(conf->ci_calib_conf_lo_coarse_step); + calib_param->conf.lo_fine_step = cpu_to_le16(conf->ci_calib_conf_lo_fine_step); + + sx_freq_offset_mhz = calib_params.sx_freq_offset_mhz; + + calib_param->other_tcv.prim20_freq = cpu_to_le16(primary + sx_freq_offset_mhz); + cl_phy_oly_lut_update(cl_hw->chip->rfic_version, cl_hw->nl_band, + center + sx_freq_offset_mhz, + &calib_param->other_tcv.center1_freq_lut); + + if (cl_chip_is_both_enabled(cl_hw->chip)) { + calib_param->other_tcv.mask_tx_he = + cl_hw_ant_mask_to_riu_chain_mask(cl_hw_other, + cl_hw_other->mask_num_antennas); + calib_param->other_tcv.num_tx_he = cl_hw_other->num_antennas; + calib_param->other_tcv.band = cl_band_to_fw_idx(cl_hw_other); + } else { + calib_param->other_tcv.mask_tx_he = + cl_hw_ant_mask_to_riu_chain_mask(cl_hw, cl_hw->mask_num_antennas); + calib_param->other_tcv.num_tx_he = cl_hw->num_antennas; + calib_param->other_tcv.band = cl_band_to_fw_idx(cl_hw); + } + + cl_dbg_info(cl_hw, "tcv_idx = %u, channel = %u, bw = %u, sx_freq_offset_mhz = %d\n", + cl_hw->tcv_idx, cl_hw->channel, cl_hw->bw, sx_freq_offset_mhz); + cl_dbg_info(cl_hw, "| TX Calibration || RX Calibration |\n"); + cl_dbg_info(cl_hw, "|chain|pair |tx_gain|rx_gain||chain|pair |tx_gain|rx_gain|\n"); + riu_chain_for_each(chain) { + cl_dbg_info(cl_hw, "| %u | %u | 0x%X | 0x%X || %u | %u | 0x%X | 0x%X |" + "\n", chain, calib_param->tx_calib_chain[chain].pair, + calib_param->tx_calib_chain[chain].initial_tx_gain, + calib_param->tx_calib_chain[chain].initial_rx_gain, chain, + calib_param->rx_calib_chain[chain].pair, + calib_param->rx_calib_chain[chain].initial_tx_gain, + calib_param->rx_calib_chain[chain].initial_rx_gain); + } +} + +int cl_msg_tx_start(struct cl_hw *cl_hw) +{ + struct mm_start_req *req; + struct cl_phy_cfg *phy_cfg; + struct cl_start_param *param; + struct cl_cca_config *cca_config; + struct dbg_meta_data *dbg_metadata; + struct cl_chip *chip = cl_hw->chip; + struct cl_tcv_conf *tcv_conf = cl_hw->conf; + struct cl_chip_conf *chip_conf = chip->conf; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + + u8 bw = 0, ant = 0; + int ret_val; + + req = cl_msg_zalloc(cl_hw, MM_START_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + phy_cfg = &req->phy_cfg; + param = &req->param; + cca_config = &phy_cfg->cca_config; + dbg_metadata = ¶m->dbg_metadata; + + phy_cfg->band = cl_band_to_fw_idx(cl_hw); + + if (cl_hw_other) + phy_cfg->other_band = cl_band_to_fw_idx(cl_hw_other); + + phy_cfg->channel_bandwidth = tcv_conf->ci_cap_bandwidth; + phy_cfg->ht_rxldpc_en = tcv_conf->ci_ht_rxldpc_en; + phy_cfg->freq_offset = cpu_to_le16(chip->eeprom_cache->calib_power.freq_offset); + phy_cfg->vns_tx_power_mode = cl_hw_is_prod_or_listener(cl_hw) ? 0 : + tcv_conf->ci_vns_pwr_mode; + phy_cfg->vns_rssi_suto_resp_th = tcv_conf->ci_vns_rssi_auto_resp_thr; + phy_cfg->afe_config_en = chip_conf->ci_afe_config_en; + phy_cfg->no_capture_noise_sleep = chip_conf->ci_no_capture_noise_sleep; + phy_cfg->gain_update_enable = tcv_conf->ci_gain_update_enable; + phy_cfg->mcs_sig_b = tcv_conf->ci_mcs_sig_b; + phy_cfg->ofdm_only = tcv_conf->ci_ofdm_only; + phy_cfg->hr_factor = tcv_conf->ci_hr_factor[phy_cfg->channel_bandwidth]; + phy_cfg->td_csd_en = tcv_conf->ci_csd_en; + phy_cfg->pe_duration_bcast = tcv_conf->ci_pe_duration_bcast; + phy_cfg->tx_digital_gain = cpu_to_le32(tcv_conf->ci_tx_digital_gain); + phy_cfg->tx_digital_gain_cck = cpu_to_le32(tcv_conf->ci_tx_digital_gain_cck); + phy_cfg->ofdm_cck_power_offset = (u8)tcv_conf->ci_ofdm_cck_power_offset; + phy_cfg->phy_clk_gating_en = tcv_conf->ci_phy_clk_gating_en; + phy_cfg->tcv1_chains_sx0 = chip_conf->ci_tcv1_chains_sx0; + phy_cfg->dsp_lcu_mode = tcv_conf->ci_dsp_lcu_mode; + + /* + * Set rx_sensitivity according to number of antennas. + * For all other antennas set 0xff which is equal to -1 + */ + memcpy(phy_cfg->rx_sensitivity, cl_hw->rx_sensitivity, MAX_ANTENNAS); + + if (!cl_hw->fw_send_start) { + cl_hw->fw_send_start = true; + phy_cfg->first_start = true; + } + + cl_fill_ant_config(cl_hw, &phy_cfg->ant_config, cl_hw->num_antennas, + cl_hw->mask_num_antennas, tcv_conf->ce_cck_tx_ant_mask, + tcv_conf->ce_cck_rx_ant_mask); + cl_fill_fem_config(cl_hw, &phy_cfg->fem_conf); + + if (!chip->rf_reg_overwrite || cl_recovery_in_progress(cl_hw)) { + chip->rf_reg_overwrite = true; + cl_rfic_read_overwrite_file(cl_hw, + phy_cfg->rf_reg_overwrite_info, + true); + } + + cca_config->ed_rise_thr_dbm = (u8)tcv_conf->ci_cca_ed_rise_thr_dbm; + cca_config->ed_fall_thr_dbm = (u8)tcv_conf->ci_cca_ed_fall_thr_dbm; + cca_config->cs_en = tcv_conf->ci_cca_cs_en; + cca_config->modem_en = tcv_conf->ci_cca_modem_en; + cca_config->main_ant = cl_hw_ant_to_riu_chain(cl_hw, tcv_conf->ci_cca_main_ant); + cca_config->second_ant = cl_hw_ant_to_riu_chain(cl_hw, tcv_conf->ci_cca_second_ant); + cca_config->flag0_ctrl = tcv_conf->ci_cca_flag0_ctrl; + cca_config->flag1_ctrl = tcv_conf->ci_cca_flag1_ctrl; + cca_config->flag2_ctrl = tcv_conf->ci_cca_flag2_ctrl; + cca_config->flag3_ctrl = tcv_conf->ci_cca_flag3_ctrl; + cca_config->gi_rise_thr_dbm = (u8)tcv_conf->ci_cca_gi_rise_thr_dbm; + cca_config->gi_fall_thr_dbm = (u8)tcv_conf->ci_cca_gi_fall_thr_dbm; + cca_config->gi_pow_lim_dbm = (u8)tcv_conf->ci_cca_gi_pow_lim_dbm; + cca_config->ed_en = cpu_to_le16(tcv_conf->ci_cca_ed_en); + cca_config->gi_en = tcv_conf->ci_cca_gi_en; + + param->prot_log_nav_en = tcv_conf->ce_prot_log_nav_en; + param->prot_mode = cl_prot_mode_get(cl_hw); + param->prot_rate_format = tcv_conf->ce_prot_rate_format; + param->prot_rate_mcs = tcv_conf->ce_prot_rate_mcs; + param->prot_rate_pre_type = tcv_conf->ce_prot_rate_pre_type; + param->bw_signaling_mode = tcv_conf->ce_bw_signaling_mode; + param->cfm_size = cpu_to_le16(IPC_CFM_SIZE); + param->cfm_dma_base_addr = cpu_to_le32(ipc_env->cfm_dma_base_addr); + param->phy_dev = cpu_to_le16(chip_conf->ci_phy_dev); + param->fw_scale_down = cpu_to_le16(CL_ASIC_FW_SCALEDOWN); + param->hal_timeout.idle = cpu_to_le32(tcv_conf->ci_hal_idle_to); + param->hal_timeout.ac0 = cpu_to_le32(tcv_conf->ci_tx_ac0_to); + param->hal_timeout.ac1 = cpu_to_le32(tcv_conf->ci_tx_ac1_to); + param->hal_timeout.ac2 = cpu_to_le32(tcv_conf->ci_tx_ac2_to); + param->hal_timeout.ac3 = cpu_to_le32(tcv_conf->ci_tx_ac3_to); + param->hal_timeout.bcn = cpu_to_le32(tcv_conf->ci_tx_bcn_to); + + /* Update rxbuff/txqueue & ring_indices that hold the array metadata */ + param->ipc_ring_indices_base = cpu_to_le32(ipc_env->ring_indices_elem->dma_addr); + param->host_rxbuf_base_addr[CL_RX_BUF_RXM] = + ipc_env->rx_hostbuf_array[CL_RX_BUF_RXM].dma_payload_base_addr; + param->host_rxbuf_base_addr[CL_RX_BUF_FW] = + ipc_env->rx_hostbuf_array[CL_RX_BUF_FW].dma_payload_base_addr; + + /* + * The FW needs to be aware of the DMA addresses of the + * TX queues so it could fetch txdesc from the host. + */ + param->ipc_host_tx_queues_dma_addr = cpu_to_le32(cl_hw->ipc_env->tx_queues.dma_addr); + + /* + * Compilation flags match check - please add here all compilation flags + * which should be compiled on both driver and firmware. + */ + param->comp_flags = cpu_to_le32(0) | cpu_to_le32(BIT(CENX_CFG_CE_TX_CFM)); + param->dbg_test_mode_max = cpu_to_le16(DBG_TEST_MODE_MAX); + param->ipc_rxbuf_size[CL_RX_BUF_RXM] = + cpu_to_le16(tcv_conf->ci_ipc_rxbuf_size[CL_RX_BUF_RXM]); + param->ipc_rxbuf_size[CL_RX_BUF_FW] = + cpu_to_le16(tcv_conf->ci_ipc_rxbuf_size[CL_RX_BUF_FW]); + + param->host_pci_gen_ver = chip_conf->ce_host_pci_gen_ver; + param->dma_lli_max_chan[0] = chip_conf->ci_dma_lli_max_chan[0]; + param->dma_lli_max_chan[1] = chip_conf->ci_dma_lli_max_chan[1]; + param->production_mode = chip_conf->ce_production_mode; + param->mult_ampdu_in_txop_en = tcv_conf->ci_mult_ampdu_in_txop_en; + param->cca_timeout = cpu_to_le32(tcv_conf->ci_cca_timeout); + param->long_retry_limit = tcv_conf->ce_long_retry_limit; + param->short_retry_limit = tcv_conf->ce_short_retry_limit; + param->assoc_auth_retry_limit = tcv_conf->ci_assoc_auth_retry_limit; + param->bcn_tx_path_min_time = cpu_to_le16(tcv_conf->ce_bcn_tx_path_min_time); + param->backup_bcn_en = tcv_conf->ci_backup_bcn_en; + param->tx_txop_cut_en = tcv_conf->ce_tx_txop_cut_en; + param->ac_with_bcns_flushed_cnt_thr = tcv_conf->ci_bcns_flushed_cnt_thr; + param->txl_statistics_struct_size = cpu_to_le32(sizeof(struct cl_txl_statistics)); + param->rxl_statistics_struct_size = cpu_to_le32(sizeof(struct cl_rxl_statistics)); + param->phy_err_prevents_phy_dump = tcv_conf->ci_phy_err_prevents_phy_dump; + param->tx_rx_delay = tcv_conf->ci_tx_rx_delay; + param->assert_storm_detect_thd = tcv_conf->ci_fw_assert_storm_detect_thd; + param->assert_time_diff_sec = tcv_conf->ci_fw_assert_time_diff_sec; + param->ps_ctrl_enabled = tcv_conf->ce_ps_ctrl_enabled; + param->phy_data_dma_addr = cpu_to_le32(cl_hw->phy_data_info.dma_addr); + param->phy_remote_rom_dma_addr = cpu_to_le32(cl_hw->fw_remote_rom.dma_addr); + param->iq_dcoc_calib_tables_dma_addr = cpu_to_le32(cl_hw->iq_dcoc_data_info.dma_addr); + param->power_table_dma_addr = cpu_to_le32(cl_hw->power_table_info.dma_addr); + param->min_ant_pwr_q1 = cl_power_min_ant_q1(cl_hw); + + for (bw = 0; bw < ARRAY_SIZE(param->bw_factor_q2); bw++) { + cl_hw->power_db.bw_factor_q2[bw] = cl_power_bw_factor_q2(cl_hw, bw); + param->bw_factor_q2[bw] = + cl_convert_signed_to_reg_value(cl_hw->power_db.bw_factor_q2[bw]); + } + + for (ant = 0; ant < ARRAY_SIZE(param->ant_factor_q2); ant++) { + cl_hw->power_db.ant_factor_q2[ant] = cl_power_array_gain_q2(cl_hw, ant + 1); + param->ant_factor_q2[ant] = cl_hw->power_db.ant_factor_q2[ant]; + } + + param->default_distance.auto_resp_all = tcv_conf->ci_distance_auto_resp_all; + param->default_distance.auto_resp_msta = tcv_conf->ci_distance_auto_resp_msta; + param->su_force_min_spacing_usec = tcv_conf->ci_su_force_min_spacing; + param->mu_force_min_spacing_usec = tcv_conf->ci_mu_force_min_spacing; + param->single_tcv = cl_hw_is_tcv0(cl_hw) ? + cl_chip_is_only_tcv0_enabled(chip) : cl_chip_is_only_tcv1_enabled(chip); + param->rx_padding = tcv_conf->ci_rx_padding_en; + param->bar_cap_disable = tcv_conf->ci_bar_disable; + param->hw_bsr = tcv_conf->ci_hw_bsr; + param->drop_to_lower_bw = tcv_conf->ci_drop_to_lower_bw; + param->dra_enable = cl_chip_is_both_enabled(chip); /* DRA enable only in CDB mode */ + param->mac_clk_gating_en = tcv_conf->ci_mac_clk_gating_en; + param->imaging_blocker = tcv_conf->ci_imaging_blocker; + param->fec_coding = tcv_conf->ci_he_rxldpc_en; + param->cs_required = tcv_conf->ci_cs_required; + param->fw_disable_recovery = tcv_conf->ci_fw_disable_recovery; + + dbg_metadata->lmac_req_buf_size = cpu_to_le32(sizeof(struct dbg_error_trace_info_drv)); + dbg_metadata->physical_queue_cnt = CL_MAX_BA_PHYSICAL_QUEUE_CNT; + dbg_metadata->agg_index_max = AGG_IDX_MAX; + dbg_metadata->ce_ac_max = CE_AC_MAX; + dbg_metadata->mu_user_max = MU_MAX_STREAMS; + dbg_metadata->txl_exch_trace_depth = DBG_TXL_FRAME_EXCH_TRACE_DEPTH; + dbg_metadata->mac_hw_regs_max = cpu_to_le16(HAL_MACHW_REG_NUM); + dbg_metadata->phy_hw_regs_max = cpu_to_le16(PHY_HW_DBG_REGS_CNT); + dbg_metadata->thd_chains_data_size = cpu_to_le16(DBG_THD_CHAINS_INFO_ARRAY_SIZE); + dbg_metadata->chains_info_elem_cnt = DBG_CHAINS_INFO_ELEM_CNT; + + /* RFIC_init requires that only one TCV may enter */ + mutex_lock(&chip->start_msg_lock); + phy_cfg->is_first_rfic = !chip->first_start_sent; + chip->first_start_sent = true; + + ret_val = cl_send_request(cl_hw, req); + mutex_unlock(&chip->start_msg_lock); + + return ret_val; +} + +int cl_msg_tx_version(struct cl_hw *cl_hw) +{ + void *void_param; + + /* VERSION REQ has no parameter */ + void_param = cl_msg_zalloc(cl_hw, MM_VERSION_REQ, TASK_MM, 0); + if (!void_param) + return -ENOMEM; + + return cl_send_request(cl_hw, void_param); +} + +int cl_msg_tx_add_if(struct cl_hw *cl_hw, struct ieee80211_vif *vif, + u8 vif_index) +{ + struct mm_add_if_req *req; + + req = cl_msg_zalloc(cl_hw, MM_ADD_IF_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + cl_mac_addr_copy(req->addr.array, vif->addr); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + req->type = MM_STA; + break; + + case NL80211_IFTYPE_ADHOC: + req->type = MM_IBSS; + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + req->type = MM_AP; + break; + + case NL80211_IFTYPE_MONITOR: + req->type = MM_MONITOR; + break; + + case NL80211_IFTYPE_MESH_POINT: + req->type = MM_MESH_POINT; + break; + + default: + req->type = MM_STA; + break; + } + + req->tx_strip_vlan = 1; + req->mac_addr_hi_mask = cpu_to_le32(cl_hw->mask_hi); + req->mac_addr_low_mask = cpu_to_le32(cl_hw->mask_low); + req->inst_nbr = vif_index; + + if (vif->type == NL80211_IFTYPE_AP) { + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ps_data *ps = &sdata->u.ap.ps; + + req->start_dtim_count = (u8)(ps->dtim_count); + } + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_remove_if(struct cl_hw *cl_hw, u8 vif_index) +{ + struct mm_remove_if_req *req; + + req = cl_msg_zalloc(cl_hw, MM_REMOVE_IF_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->inst_nbr = vif_index; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta, + struct cl_vif *cl_vif, u8 recovery_sta_idx, + u32 rate_ctrl_info) +{ + struct mm_sta_add_req *req; + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + u16 my_aid = 0; + u8 inst_nbr = cl_vif->vif_index; + bool is_6g = cl_band_is_6g(cl_hw); + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + req = cl_msg_zalloc(cl_hw, MM_STA_ADD_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + cl_mac_addr_copy(req->mac_addr.array, sta->addr); + + if (cl_vif->vif->type == NL80211_IFTYPE_STATION) + my_aid = cl_vif->vif->bss_conf.aid; + + if (is_6g) { + u8 mac_cap_info4 = he_cap->he_cap_elem.mac_cap_info[4]; + + req->su_bfee = !!(mac_cap_info4 & IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE); + req->mu_bfee = !!(mac_cap_info4 & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER); + } else if (vht_cap->vht_supported) { + req->su_bfee = !!(vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); + req->mu_bfee = !!(vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); + } + + req->ampdu_min_spacing = cl_sta->ampdu_min_spacing; + + if (he_cap->has_he) { + u8 mac_cap_info1 = he_cap->he_cap_elem.mac_cap_info[1]; + u8 mac_cap_info3 = he_cap->he_cap_elem.mac_cap_info[3]; + + req->he_tf_mac_padding_duration = + (mac_cap_info1 & IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK); + + req->he_rx_ctrl_frm_to_mbss = + (mac_cap_info3 & IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS); + /* Fill PE duration table */ + cl_cap_ppe_duration(cl_hw, sta, req->pe_duration); + } + + cl_ampdu_size_exp(cl_hw, sta, &req->ampdu_size_exp_he, + &req->ampdu_size_exp_vht, &req->ampdu_size_exp_ht); + + if (cl_hw->conf->ce_txldpc_en) { + if (he_cap->has_he) + req->ldpc_enabled = !!(he_cap->he_cap_elem.phy_cap_info[1] & + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); + else if (vht_cap->vht_supported) + req->ldpc_enabled = !!(vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC); + else if (ht_cap->ht_supported) + req->ldpc_enabled = !!(ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING); + } + + /* TODO: Set the interface index from the vif structure */ + req->inst_nbr = inst_nbr; + + req->aid = cpu_to_le16(sta->aid); + req->my_aid = cpu_to_le16(my_aid); + req->recovery_sta_idx = recovery_sta_idx; + + /* Station power save configuration */ + req->uapsd_queues = sta->uapsd_queues; + req->max_sp = sta->max_sp; + + /* Set WRS default parameters for rate control */ + req->tx_params.rate = cpu_to_le32(rate_ctrl_info); + + /* Fill TX antenna with default value */ + req->tx_params.ant_set = CL_DEF_ANT_BITMAP; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_sta_del(struct cl_hw *cl_hw, u8 sta_idx) +{ + struct mm_sta_del_req *req; + + req = cl_msg_zalloc(cl_hw, MM_STA_DEL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_filter(struct cl_hw *cl_hw, u32 filter, bool force) +{ + struct mm_set_filter_req *req; + u32 rx_filter = 0; + + if (force) + rx_filter = filter; + else + rx_filter = cl_rx_filter_update_flags(cl_hw, filter); + + if (rx_filter == cl_hw->rx_filter) { + cl_dbg_trace(cl_hw, "Rx filter 0x%x already set - return\n", rx_filter); + return 0; + } + + req = cl_msg_zalloc(cl_hw, MM_SET_FILTER_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + /* Now copy all the flags into the message parameter */ + req->filter = cpu_to_le32(rx_filter); + cl_hw->rx_filter = rx_filter; + + cl_dbg_trace(cl_hw, "new total_flags = 0x%08x\nrx filter set to 0x%08x\n", + filter, rx_filter); + + return cl_send_request(cl_hw, req); +} + +static u8 cl_mark_calib_flags(struct cl_hw *cl_hw, u8 mode) +{ + int lna = 0; + int chain = 0; + u8 calib_info_set = 0; + struct cl_iq_dcoc_info *iq_dcoc_db = &cl_hw->phy_data_info.data->iq_dcoc_db; + + /* In case DCOC is going to be calibrated, no need to raise any calibration flag. */ + if (mode & SET_CHANNEL_MODE_CALIB_DCOC) + return calib_info_set; + + /* Check if DCOC flag should be marked */ + for (lna = 0; lna < DCOC_LNA_GAIN_NUM; lna++) { + riu_chain_for_each(chain) { + if (iq_dcoc_db->dcoc[lna][chain].i || iq_dcoc_db->dcoc[lna][chain].q) { + calib_info_set |= SET_PHY_DATA_FLAGS_DCOC; + break; + } + } + } + + /* Check if IQ Tx LOLC flag should be marked */ + riu_chain_for_each(chain) { + if (iq_dcoc_db->iq_tx_lolc[chain]) { + calib_info_set |= SET_PHY_DATA_FLAGS_IQ_TX_LOLC; + break; + } + } + + /* Check if IQ Tx flag should be marked */ + riu_chain_for_each(chain) { + if (iq_dcoc_db->iq_tx[chain].coef0 || iq_dcoc_db->iq_tx[chain].coef1 || + iq_dcoc_db->iq_tx[chain].coef2 || iq_dcoc_db->iq_tx[chain].gain) { + calib_info_set |= SET_PHY_DATA_FLAGS_IQ_TX; + break; + } + } + + /* Check if IQ Rx flag should be marked */ + riu_chain_for_each(chain) { + if (iq_dcoc_db->iq_rx[chain].coef0 || iq_dcoc_db->iq_rx[chain].coef1 || + iq_dcoc_db->iq_rx[chain].coef2 || iq_dcoc_db->iq_rx[chain].gain) { + calib_info_set |= SET_PHY_DATA_FLAGS_IQ_RX; + return calib_info_set; + } + } + return calib_info_set; +} + +static int _cl_msg_tx_set_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u16 primary, + u16 center, struct cl_calib_params calib_params) +{ + struct mm_set_channel_req *req; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + + int res = 0; + struct cl_phy_data *data = cl_hw->phy_data_info.data; + u8 mode = calib_params.mode; + + if (WARN_ON_ONCE(channel == 0)) + return -EINVAL; + + /* Fill AGC parameters - check before we start building the message */ + if (cl_agc_params_fill(cl_hw, &data->agc_params)) + return -1; + + req = cl_msg_zalloc(cl_hw, MM_SET_CHANNEL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->band = cl_band_to_fw_idx(cl_hw); + + if (cl_hw_other) + req->other_band = cl_band_to_fw_idx(cl_hw_other); + + req->bandwidth = bw; + req->prim20_freq = cpu_to_le16(primary); + cl_phy_oly_lut_update(cl_hw->chip->rfic_version, cl_hw->nl_band, center, + &req->center1_freq_lut); + req->sx_freq_offset_mhz = calib_params.sx_freq_offset_mhz; + req->hr_factor = cl_hw->conf->ci_hr_factor[bw]; + req->signal_ext = cl_hw->conf->ci_signal_extension_en; + + /* Set power per mcs offset after EIRP truncation */ + cl_power_tables_update(cl_hw, &data->pwr_tables); + + /* Get antenna power offset from eeprom */ + cl_calib_power_offset_fill(cl_hw, channel, bw, req->ant_pwr_offset); + + if (cl_hw->conf->ce_listener_en) + cl_calib_common_fill_phy_data(cl_hw, &data->iq_dcoc_db, + SET_PHY_DATA_FLAGS_LISTENER); + else + cl_calib_common_fill_phy_data(cl_hw, &data->iq_dcoc_db, SET_PHY_DATA_FLAGS_ALL); + + req->calib_info_set = cl_mark_calib_flags(cl_hw, mode); + req->calib_param.mode = mode; + + if (mode & (SET_CHANNEL_MODE_CALIB_LOLC | SET_CHANNEL_MODE_CALIB_IQ)) + cl_fill_calib_config(cl_hw, &req->calib_param, primary, center, calib_params); + + if (mode & SET_CHANNEL_MODE_CALIB_DCOC) { + if (cl_hw->chip->conf->ci_phy_dev == PHY_DEV_ATHOS) { + u8 rfic_version = cl_hw->chip->rfic_version; + + if (rfic_version == U8_MAX) + cl_dbg_trace(cl_hw, "Couldn't read rfic version\n"); + + if (rfic_version == ATHOS_B_VER) + req->calib_param.dcoc_max_vga = DCOC_MAX_VGA_ATHOS_B; + else + req->calib_param.dcoc_max_vga = DCOC_MAX_VGA_ATHOS; + } else { + req->calib_param.dcoc_max_vga = DCOC_MAX_VGA; + } + } + + /* Antenna configuration */ + cl_fill_ant_config(cl_hw, &req->ant_config, cl_hw->num_antennas, cl_hw->mask_num_antennas, + cl_hw->conf->ce_cck_tx_ant_mask, cl_hw->conf->ce_cck_rx_ant_mask); + /* FEM configuration */ + cl_fill_fem_config(cl_hw, &req->fem_conf); + + cl_rfic_read_overwrite_file(cl_hw, req->rf_reg_overwrite_info, false); + + cl_dbg_info(cl_hw, + "band=%u, other_band=%u, channel=%u, bw=%u, primary=%u.%u, center=%u.%u, sx_index=%u\n", + cl_hw->conf->ci_band_num, req->other_band, channel, bw, GET_FREQ_INT(primary), + GET_FREQ_FRAC(primary), GET_FREQ_INT(center), GET_FREQ_FRAC(center), + cl_hw->tcv_idx); + + res = cl_send_request(cl_hw, req); + + cl_temperature_comp_update_calib(cl_hw); + + return res; +} + +int cl_msg_tx_set_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u32 primary, + u32 center, struct cl_calib_params calib_params) +{ + int res = 0; + u8 mode = calib_params.mode; + s8 sx_freq_offset_mhz = calib_params.sx_freq_offset_mhz; + u32 primary_q2 = FREQ_TO_Q2(primary); + u32 center_q2 = FREQ_TO_Q2(center); + + /* + * Need to take mutex lock to ensure that no one touching the phy_data + * DMA before FW is reading all its values. + * The mutex is unlocked right after the iq_dcoc_data_info DMA is + * handled in cl_calib_common_handle_set_channel_cfm. + */ + res = mutex_lock_interruptible(&cl_hw->set_channel_mutex); + + if (res != 0) { + cl_dbg_verbose(cl_hw, "Error - mutex_lock_interruptible (%d)\n", res); + return res; + } + + cl_hw->channel = channel; + cl_hw->bw = bw; + cl_hw->primary_freq = primary; + cl_hw->center_freq = center; + + if (mode == SET_CHANNEL_MODE_CALIB_MANUAL) { + primary_q2 += sx_freq_offset_mhz; + center_q2 += sx_freq_offset_mhz; + } + + if (mode & SET_CHANNEL_MODE_CALIB) + cl_hw->msg_calib_timeout = true; + + res = _cl_msg_tx_set_channel(cl_hw, channel, bw, primary_q2, center_q2, calib_params); + + if (mode & SET_CHANNEL_MODE_CALIB) { + cl_hw->msg_calib_timeout = false; + + if (!res) + res = cl_calib_common_handle_set_channel_cfm(cl_hw, calib_params); + } + + mutex_unlock(&cl_hw->set_channel_mutex); + + return res; +} + +int cl_msg_tx_dtim(struct cl_hw *cl_hw, u8 dtim_period) +{ + struct mm_set_dtim_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_DTIM_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->dtim_period = dtim_period; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_beacon_int(struct cl_hw *cl_hw, u16 beacon_int, u8 vif_idx) +{ + struct mm_set_beacon_int_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_BEACON_INT_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->beacon_int = cpu_to_le16(beacon_int); + req->inst_nbr = vif_idx; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_basic_rates(struct cl_hw *cl_hw, u32 basic_rates) +{ + struct mm_set_basic_rates_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_BASIC_RATES_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->rates = cpu_to_le32(basic_rates); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_bssid(struct cl_hw *cl_hw, const u8 *bssid, u8 vif_idx) +{ + struct mm_set_bssid_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_BSSID_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + cl_mac_addr_copy(req->bssid.array, bssid); + req->inst_nbr = vif_idx; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_edca(struct cl_hw *cl_hw, u8 hw_queue, u32 param, + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca) +{ + struct mm_set_edca_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_EDCA_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->ac_param = cpu_to_le32(param); + req->hw_queue = hw_queue; + + if (mu_edca) { + req->mu_edca_aifsn = mu_edca->aifsn; + req->mu_edca_ecw_min_max = mu_edca->ecw_min_max; + req->mu_edca_timer = mu_edca->mu_edca_timer; + } + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_associated(struct cl_hw *cl_hw, + struct ieee80211_bss_conf *bss_conf) +{ + struct mm_set_associated_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_ASSOCIATED_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->aid = cpu_to_le16(bss_conf->aid); + + /* Multiple BSSID feature support */ + if (bss_conf->nontransmitted && bss_conf->assoc) { + u8 i = 0; + u8 mask_addr[ETH_ALEN] = {0}; + u32 bssid_hi_mask = 0; + u32 bssid_low_mask = 0; + + for (i = 0; i < ETH_ALEN; i++) + mask_addr[i] = (bss_conf->transmitter_bssid[i] ^ + bss_conf->bssid[i]); + cl_mac_addr_array_to_nxmac(mask_addr, &bssid_low_mask, + &bssid_hi_mask); + /* Set mask to allow the transmitter BSSID Rx reception */ + req->bssid_hi_mask = cpu_to_le32(bssid_hi_mask); + req->bssid_low_mask = cpu_to_le32(bssid_low_mask); + } + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_slottime(struct cl_hw *cl_hw, bool use_short_slot) +{ + struct mm_set_slottime_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_SLOTTIME_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->slottime = use_short_slot ? 9 : 20; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_idle(struct cl_hw *cl_hw, u8 idle, bool is_lock) +{ + struct mm_set_idle_req *req; + int ret = 0; + + if (cl_fem_read_wiring_id(cl_hw->chip)) { + cl_dbg_err(cl_hw, "!!! Invalid wiring id [%u] !!! Aborting\n", + cl_hw->chip->fem.wiring_id); + return -1; + } + + req = cl_msg_zalloc(cl_hw, MM_SET_IDLE_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + if (is_lock) + mutex_lock(&cl_hw->chip->set_idle_mutex); + + req->hw_idle = idle; + + cl_dbg_info(cl_hw, "idle = %s\n", idle ? "True" : "False"); + + ret = cl_send_request(cl_hw, req); + + if (is_lock) + mutex_unlock(&cl_hw->chip->set_idle_mutex); + + return ret; +} + +void cl_msg_tx_idle_async(struct cl_hw *cl_hw, bool is_lock) +{ + if (!IS_REAL_PHY(cl_hw->chip)) + return; + + cl_hw->idle_async_set = true; + cl_msg_tx_set_idle(cl_hw, MAC_IDLE_ASYNC, is_lock); +} + +int cl_msg_tx_key_add(struct cl_hw *cl_hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf, + u8 cipher_suite) +{ + struct mm_key_add_req *req; + + req = cl_msg_zalloc(cl_hw, MM_KEY_ADD_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + /* Set Pairwise Default key */ + if (sta) + req->sta_idx = ((struct cl_sta *)sta->drv_priv)->sta_idx; + else + req->sta_idx = 0xFF; + + req->key_idx = (u8)(key_conf->keyidx); + req->inst_nbr = ((struct cl_vif *)vif->drv_priv)->vif_index; + req->key.length = key_conf->keylen; + + /* TODO: check if this works well in Big endian platforms */ + memcpy(req->key.array, key_conf->key, key_conf->keylen); + + req->cipher_suite = cipher_suite; + req->spp = cl_hw->conf->ci_spp_ksr_value; + + cl_dbg_info(cl_hw, "sta_idx:%u, key_idx:%u, inst_nbr:%u, cipher:%u, key_len:%u, spp:%u\n", + req->sta_idx, req->key_idx, req->inst_nbr, + req->cipher_suite, req->key.length, req->spp); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_key_del(struct cl_hw *cl_hw, u8 hw_key_idx) +{ + struct mm_key_del_req *req; + + req = cl_msg_zalloc(cl_hw, MM_KEY_DEL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->hw_key_idx = hw_key_idx; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_ba_add(struct cl_hw *cl_hw, u8 type, u8 sta_idx, + u16 tid, u16 bufsz, u16 ssn) +{ + struct mm_ba_add_req *req; + u16 msg_id = ((type == BA_AGMT_TX) ? MM_BA_ADD_TX_REQ : MM_BA_ADD_RX_REQ); + + req = cl_msg_zalloc(cl_hw, msg_id, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->type = type; + req->sta_idx = sta_idx; + req->tid = (u8)tid; + req->bufsz = cpu_to_le16(bufsz); + req->ssn = cpu_to_le16(ssn); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_ba_del(struct cl_hw *cl_hw, u8 sta_idx, u16 tid) +{ + struct mm_ba_del_req *req; + + req = cl_msg_zalloc(cl_hw, MM_BA_DEL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + req->tid = (u8)tid; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_available_ba_txq(struct cl_hw *cl_hw, u8 sta_idx, u16 tid) +{ + struct mm_available_ba_txq_req *req; + + req = cl_msg_zalloc(cl_hw, MM_AVAILABLE_BA_TXQ_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + req->tid = (u8)tid; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_update_rate_dl(struct cl_hw *cl_hw, u8 sta_idx, u32 rate, u32 rate_fallback, + u8 req_bw_tx, u8 op_mode, u8 gid, u8 mu_valid, u8 ltf, + u8 ltf_fallback, u32 rate_he) +{ + struct mm_update_rate_dl_req *req; + + cl_dbg_info(cl_hw, "sta_idx=%u, rate=0x%x, rate_fallback=0x%x, req_bw_tx=%u, " + "op_mode=%u, gid=%u, mu_valid=%u, ltf=%u, ltf_fallback=%u, rate_he=0x%x\n", + sta_idx, rate, rate_fallback, req_bw_tx, op_mode, gid, mu_valid, + ltf, ltf_fallback, rate_he); + + req = cl_msg_zalloc(cl_hw, MM_UPDATE_RATE_DL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->tx_params.rate = cpu_to_le32(rate); + req->tx_params.rate_he = cpu_to_le32(rate_he); + req->tx_params.req_bw_tx = req_bw_tx; + req->tx_params.ant_set = CL_DEF_ANT_BITMAP; + req->tx_params.ltf = ltf; + + req->op_mode = op_mode; + req->sta_idx = sta_idx; + req->rate_fallback = cpu_to_le32(rate_fallback); + req->ltf_fallback = ltf_fallback; + + /* Gid & mu valid bit is relevant only for MU rate updates. */ + if (op_mode == RATE_OP_MODE_STA_MU) { + req->group_id = gid; + req->mu_is_rate_valid = mu_valid; + } + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_update_rate_ul(struct cl_hw *cl_hw, u8 sta_idx, u8 bw, u8 nss, u8 mcs, u8 gi_ltf) +{ + struct mm_update_rate_ul_req *req; + + req = cl_msg_zalloc(cl_hw, MM_UPDATE_RATE_UL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + req->bw = bw; + req->nss = nss; + req->mcs = mcs; + req->gi_ltf = gi_ltf; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_vns(struct cl_hw *cl_hw, u8 sta_idx, u8 is_vns) +{ + struct mm_set_vns_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_VNS_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + req->is_vns = is_vns; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_tx_bf(struct cl_hw *cl_hw, u8 sta_idx, u8 is_on, u8 is_on_fallback) +{ + struct mm_set_tx_bf_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_TX_BF_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sta_idx = sta_idx; + req->is_on = is_on; + req->is_on_fallback = is_on_fallback; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_sounding(struct cl_hw *cl_hw, + struct mm_sounding_req *sounding_req) +{ + struct mm_sounding_req *req; + u8 i; + + req = cl_msg_zalloc(cl_hw, MM_SOUNDING_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + memcpy(req, sounding_req, sizeof(*req)); + + /* In case of non-TB HE SU/CQI, nc should be set to 0 */ + if (req->sounding_type == SOUNDING_TYPE_HE_CQI || + req->sounding_type == SOUNDING_TYPE_HE_SU) + for (i = 0; i < req->sta_num; i++) + req->info_per_sta[i].nc = 0; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_sounding_pairing(struct cl_hw *cl_hw, u8 sounding_id, u8 sounding_type, + u8 gid, u8 sta_idx) +{ + struct mm_sounding_pairing *req; + + req = cl_msg_zalloc(cl_hw, MM_SOUNDING_PAIRING_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sounding_type = sounding_type; + req->sta_idx = sta_idx; + req->gid = gid; + req->sounding_id = sounding_id; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_sounding_interval(struct cl_hw *cl_hw, u16 interval, u16 lifetime, + u8 sounding_type, u8 sta_idx) +{ + struct mm_sounding_interval_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SOUNDING_INTERVAL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->interval = cpu_to_le16(interval); + req->bfr_lifetime = cpu_to_le16(lifetime); + req->sounding_type = sounding_type; + req->sta_idx = sta_idx; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_dfs(struct cl_hw *cl_hw, bool enable, u8 standard, + u8 initial_gain, u8 agc_cd_th) +{ + struct mm_set_dfs_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SET_DFS_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->enable = enable; + req->standard_fcc = standard == NL80211_DFS_FCC; + req->initial_gain = initial_gain; + req->agc_cd_th = agc_cd_th; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_ndp_tx_control(struct cl_hw *cl_hw, u8 chain_mask, u8 bw, u8 format, u8 num_ltf) +{ + struct mm_ndp_tx_control_req *req; + + req = cl_msg_zalloc(cl_hw, MM_NDP_TX_CONTROL_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->chain_mask = chain_mask; + req->bw = bw; + req->format = format; + req->num_ltf = num_ltf; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_reg_write(struct cl_hw *cl_hw, u32 address, u32 value, u32 mask) +{ + struct mm_reg_write_req *req; + + req = cl_msg_zalloc(cl_hw, MM_REG_WRITE_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->address = cpu_to_le32(address); + req->value = cpu_to_le32(value); + req->mask = cpu_to_le32(mask); + + cl_dbg_info(cl_hw, "address=0x%x, value=0x%x, mask=0x%x\n", address, value, mask); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_prot_mode(struct cl_hw *cl_hw, u8 log_nav_en, u8 mode, u8 rate_format, + u8 rate_mcs, u8 rate_pre_type) +{ + struct mm_prot_mode_req *req; + + req = cl_msg_zalloc(cl_hw, MM_PROT_MODE_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->log_nav_en = log_nav_en; + req->mode = mode; + req->rate_format = rate_format; + req->rate_mcs = rate_mcs; + req->rate_pre_type = rate_pre_type; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_backup_bcn_en(struct cl_hw *cl_hw, bool backup_bcn_en) +{ + struct mm_set_backup_bcn_en_req *req; + + req = cl_msg_zalloc(cl_hw, MM_BACKUP_BCN_EN_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->backup_bcn_en = backup_bcn_en; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_start_periodic_tx_time(struct cl_hw *cl_hw, u16 periodic_tx_time_off, + u16 periodic_tx_time_on) +{ + struct mm_start_periodic_tx_time_req *req; + + req = cl_msg_zalloc(cl_hw, MM_START_PERIODIC_TX_TIME_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->periodic_tx_time_off = cpu_to_le16(periodic_tx_time_off); + req->periodic_tx_time_on = cpu_to_le16(periodic_tx_time_on); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_anamon_read(struct cl_hw *cl_hw, u8 mode, u8 param1, u8 param2) +{ + struct mm_anamon_read_req *req; + + req = cl_msg_zalloc(cl_hw, MM_ANAMON_READ_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->mode = mode; + req->param1 = param1; + req->param2 = param2; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_refresh_power(struct cl_hw *cl_hw) +{ + void *void_param; + + /* MM_REFRESH_PWR_REQ has no parameter */ + void_param = cl_msg_zalloc(cl_hw, MM_REFRESH_PWR_REQ, TASK_MM, 0); + if (!void_param) + return -ENOMEM; + + return cl_send_request(cl_hw, void_param); +} + +int cl_msg_tx_set_ant_pwr_offset(struct cl_hw *cl_hw, s8 pwr_offset[MAX_ANTENNAS]) +{ + struct mm_set_ant_pwr_offset_req *req; + u8 chain, i = 0; + + req = cl_msg_zalloc(cl_hw, MM_SET_ANT_PWR_OFFSET_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + for (i = 0; i < MAX_ANTENNAS; i++) { + if (!(cl_hw->mask_num_antennas & BIT(i))) + continue; + + chain = cl_hw_ant_to_riu_chain(cl_hw, i); + pwr_offset[i] = cl_power_offset_check_margin(cl_hw, cl_hw->bw, i, pwr_offset[i]); + req->pwr_offset[chain] = cl_convert_signed_to_reg_value(pwr_offset[i]); + } + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_set_rate_fallback(struct cl_hw *cl_hw) +{ + struct mm_rate_fallback_req *req; + struct cl_tcv_conf *conf = cl_hw->conf; + + req = cl_msg_zalloc(cl_hw, MM_SET_RATE_FALLBACK_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->fallback_count_su = conf->ci_rate_fallback[CL_RATE_FALLBACK_COUNT_SU]; + req->fallback_count_mu = conf->ci_rate_fallback[CL_RATE_FALLBACK_COUNT_MU]; + req->retry_count_thr = conf->ci_rate_fallback[CL_RATE_FALLBACK_RETRY_COUNT_THR]; + req->ba_per_thr = conf->ci_rate_fallback[CL_RATE_FALLBACK_BA_PER_THR]; + req->ba_not_received_thr = conf->ci_rate_fallback[CL_RATE_FALLBACK_BA_NOT_RECEIVED_THR]; + req->disable_mcs0 = conf->ci_rate_fallback[CL_RATE_FALLBACK_DISABLE_MCS]; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_spi_write(struct cl_hw *cl_hw, u8 page, u8 addr, u8 val, u8 mask) +{ + struct mm_spi_write_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SPI_WRITE_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->page = page; + req->addr = addr; + req->val = val; + req->mask = mask; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_spi_read(struct cl_hw *cl_hw, u8 page, u8 addr) +{ + struct mm_spi_read_req *req; + + req = cl_msg_zalloc(cl_hw, MM_SPI_READ_REQ, TASK_MM, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->page = page; + req->addr = addr; + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_dbg_set_ce_mod_filter(struct cl_hw *cl_hw, u32 filter) +{ + struct dbg_set_mod_filter_req *req; + + req = cl_msg_zalloc(cl_hw, DBG_CE_SET_MOD_FILTER_REQ, TASK_DBG, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->mod_filter = cpu_to_le32(filter); + + return cl_send_request(cl_hw, req); +} + +int cl_msg_tx_dbg_set_sev_filter(struct cl_hw *cl_hw, u32 filter) +{ + struct dbg_set_sev_filter_req *req; + + req = cl_msg_zalloc(cl_hw, DBG_SET_SEV_FILTER_REQ, TASK_DBG, sizeof(*req)); + if (!req) + return -ENOMEM; + + req->sev_filter = cpu_to_le32(filter); + + return cl_send_request(cl_hw, req); +} + +/* Work struct wrapper for print statistics */ +struct cl_print_stats_work { + struct work_struct ws; + struct cl_hw *cl_hw; + u32 dbg_info_type; +}; + +static void cl_print_rx_stats_precent(struct cl_hw *cl_hw, const char *str, u32 x, u32 y) +{ + /* + * Example: + * x = 541, y = 19 + * Result 28.4736 + */ + u32 integer = x / y; + u32 fraction = 10000 * (x - y * (x / y)) / y; + + fw_pr(cl_hw, "%s = %u.%04u\n", str, integer, fraction); +} + +static void cl_print_rx_stats(struct cl_hw *cl_hw, struct cl_rxl_statistics *rx_stats) +{ + int i, mu_idx, total_rx = 0; + enum format_mode fm; + + fw_pr(cl_hw, "=========================================\n"); + fw_pr(cl_hw, " Global RX stats\n"); + fw_pr(cl_hw, "=========================================\n"); + fw_pr(cl_hw, "host rxelem not ready = %u\n", + rx_stats->host_rxelem_not_ready_cnt); + fw_pr(cl_hw, "MSDU host rxelem not ready = %u\n", + rx_stats->msdu_host_rxelem_not_ready_cnt); + fw_pr(cl_hw, "MSDU dma pool not ready = %u\n", + rx_stats->dma_rx_pool_not_ready_cnt); + fw_pr(cl_hw, "Percent of Rx CCA busy = %u\n", + rx_stats->cca_busy_percent); + fw_pr(cl_hw, "Percent of Rx mine CCA busy = %u\n", + rx_stats->rx_mine_busy_percent); + fw_pr(cl_hw, "Percent of Tx mine busy = %u\n", + rx_stats->tx_mine_busy_percent); + fw_pr(cl_hw, "\n"); + + fw_pr(cl_hw, "=== Rx Format ==\n"); + for (fm = 0; fm < FORMATMOD_MAX; fm++) + if (rx_stats->stats_rx_format[fm]) + fw_pr(cl_hw, "Rx Format[%d] = %u\n", fm, rx_stats->stats_rx_format[fm]); + + fw_pr(cl_hw, "=== Rx Decryption errors ==\n"); + for (i = RHD_DECR_ICVFAIL_IDX; i < RHD_DECR_IDX_MAX; i++) + if (rx_stats->decrypt_err[i]) + fw_pr(cl_hw, "decrypt_err[%d] = %u\n", i, rx_stats->decrypt_err[i]); + + /* RX prints */ + for (mu_idx = 0; mu_idx < MU_UL_MAX; mu_idx++) { + fw_pr(cl_hw, "============================================\n"); + fw_pr(cl_hw, "===== RX MAC HW MU [%2d] =====\n", mu_idx); + fw_pr(cl_hw, "============================================\n"); + total_rx = rx_stats->total_rx_packets[mu_idx] + + rx_stats->fcs_error_counter[mu_idx] + + rx_stats->phy_error_counter[mu_idx] + + rx_stats->ampdu_incorrect_received_counter[mu_idx] + + rx_stats->delimiter_error_counter[mu_idx] + + rx_stats->rx_fifo_overflow_err_cnt[mu_idx]; + + if (total_rx == 0) + continue; + + for (i = 0; i < MAX_HANDLED_FRM_TYPE; i++) { + if (!rx_stats->emb_ll1_handled_frame_counter[mu_idx][i]) + continue; + + fw_pr(cl_hw, "emb_handled_packet[%d] - %u\n", + i, rx_stats->emb_ll1_handled_frame_counter[mu_idx][i]); + } + + fw_pr(cl_hw, "Total packets dropped (pckt_len > %u) %u\n", + rx_stats->max_mpdu_data_len[mu_idx], + rx_stats->rx_pckt_exceed_max_len_cnt[mu_idx]); + fw_pr(cl_hw, "Number of bad formated BA frames = %u\n", + rx_stats->rx_pckt_bad_ba_statinfo_cnt[mu_idx]); + fw_pr(cl_hw, "Max occupancy list2 = %u\n", + rx_stats->rhd_ll2_max_cnt[mu_idx]); + fw_pr(cl_hw, "Max occupancy list1 = %u\n", + rx_stats->rhd_ll1_max_cnt[mu_idx]); + fw_pr(cl_hw, "\n"); + fw_pr(cl_hw, "Total Qos MPDU received = %u\n", + rx_stats->total_rx_packets[mu_idx]); + fw_pr(cl_hw, "Total Aggregation received = %u\n", + rx_stats->total_agg_packets[mu_idx]); + fw_pr(cl_hw, "Number of Rx Fifo Overflow = %u\n", + rx_stats->rx_fifo_overflow_err_cnt[mu_idx]); + fw_pr(cl_hw, "Number of FCS ERROR = %u\n", + rx_stats->fcs_error_counter[mu_idx]); + fw_pr(cl_hw, "Number of PHY ERROR = %u\n", + rx_stats->phy_error_counter[mu_idx]); + fw_pr(cl_hw, "Number of AMPDUS = %u\n", + rx_stats->ampdu_received_counter[mu_idx]); + fw_pr(cl_hw, "Number of Incorrect AMPDUS = %u\n", + rx_stats->ampdu_incorrect_received_counter[mu_idx]); + fw_pr(cl_hw, "Number of Delimiter errors = %u\n", + rx_stats->delimiter_error_counter[mu_idx]); + + if (rx_stats->total_rx_packets[mu_idx]) { + u32 total_rx_packets = rx_stats->total_rx_packets[mu_idx] + + rx_stats->rx_fifo_overflow_err_cnt[mu_idx] + + rx_stats->fcs_error_counter[mu_idx] + + rx_stats->phy_error_counter[mu_idx] + + rx_stats->delimiter_error_counter[mu_idx]; + + cl_print_rx_stats_precent(cl_hw, + "Rx Fifo Overflow percent ", + 100 * rx_stats->rx_fifo_overflow_err_cnt[mu_idx], + total_rx_packets); + cl_print_rx_stats_precent(cl_hw, + "FCS Error percent ", + 100 * rx_stats->fcs_error_counter[mu_idx], + total_rx_packets); + cl_print_rx_stats_precent(cl_hw, + "Phy Error percent ", + 100 * rx_stats->phy_error_counter[mu_idx], + total_rx_packets); + cl_print_rx_stats_precent(cl_hw, + "Delimiter Error percent ", + 100 * rx_stats->delimiter_error_counter[mu_idx], + total_rx_packets); + } + + fw_pr(cl_hw, "Current NAV value = %u\n", rx_stats->nav_value[mu_idx]); + fw_pr(cl_hw, "\n"); + fw_pr(cl_hw, "Rx LL split stats: 1st LL interrupts = %u\n", + rx_stats->counter_timer_trigger_ll1[mu_idx]); + fw_pr(cl_hw, "Rx LL split stats: 2nd LL interrupts = %u\n", + rx_stats->counter_timer_trigger_ll2[mu_idx]); + fw_pr(cl_hw, "Number of incorrect format mode received = %u\n", + rx_stats->rx_incorrect_format_mode[mu_idx]); + + for (i = 0; i < RX_CLASSIFICATION_MAX; i++) { + if (!rx_stats->rx_class_counter[mu_idx][i]) + continue; + + fw_pr(cl_hw, "Rx classification rules stats: Rx rule%d= %u\n", + i, rx_stats->rx_class_counter[mu_idx][i]); + } + + if (rx_stats->rx_class_int_counter[mu_idx]) + fw_pr(cl_hw, "Rx classification interrupts rules = %u\n", + rx_stats->rx_class_int_counter[mu_idx]); + + fw_pr(cl_hw, "\n"); + fw_pr(cl_hw, "Rx Implicit BF statistics: = %u\n", + rx_stats->rx_imp_bf_counter[mu_idx]); + fw_pr(cl_hw, "Rx Implicit BF interrupts stats = %u\n", + rx_stats->rx_imp_bf_int_counter[mu_idx]); + fw_pr(cl_hw, "RXM STATISTICS\n"); + fw_pr(cl_hw, "rxm_stats_overflow = %u\n", + rx_stats->rxm_stats_overflow[mu_idx]); + fw_pr(cl_hw, "rx_incorrect_format_mode= %u\n", + rx_stats->rx_incorrect_format_mode[mu_idx]); + fw_pr(cl_hw, "correct_received_mpdu = %u\n", + rx_stats->correct_received_mpdu[mu_idx]); + fw_pr(cl_hw, "incorrect_received_mpdu = %u\n", + rx_stats->incorrect_received_mpdu[mu_idx]); + fw_pr(cl_hw, "discarded_mpdu = %u\n", + rx_stats->discarded_mpdu[mu_idx]); + fw_pr(cl_hw, "incorrect_delimiter = %u\n", + rx_stats->incorrect_delimiter[mu_idx]); + fw_pr(cl_hw, "rts_bar_cnt = %u\n", + rx_stats->rts_bar_cnt[mu_idx]); + fw_pr(cl_hw, "rxm_mpdu_cnt = %u\n", + rx_stats->rxm_mpdu_cnt[mu_idx]); + + if (rx_stats->rxm_mpdu_cnt[mu_idx]) { + fw_pr(cl_hw, "rxm_rule0_match = %u\n", + rx_stats->rxm_rule0_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule1_match = %u\n", + rx_stats->rxm_rule1_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule2_match = %u\n", + rx_stats->rxm_rule2_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule3_match = %u\n", + rx_stats->rxm_rule3_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule4_match = %u\n", + rx_stats->rxm_rule4_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule5_match = %u\n", + rx_stats->rxm_rule5_match[mu_idx]); + fw_pr(cl_hw, "rxm_rule6_match = %u\n", + rx_stats->rxm_rule6_match[mu_idx]); + fw_pr(cl_hw, "rxm_default_rule_match = %u\n", + rx_stats->rxm_default_rule_match[mu_idx]); + + fw_pr(cl_hw, "RXM amsdu stat not supported. use iwcl stats instead\n"); + } + + /* RX AMSDU prints */ + fw_pr(cl_hw, "\n"); + fw_pr(cl_hw, "RX AMSDU STATS\n"); + fw_pr(cl_hw, "AMSDU RX cnt = %u\n", + rx_stats->stats_tot_rx_amsdu_cnt[mu_idx]); + + for (i = 0; i < ARRAY_SIZE(rx_stats->stats_rx_amsdu_cnt[mu_idx]); i++) + if (rx_stats->stats_rx_amsdu_cnt[mu_idx][i]) + fw_pr(cl_hw, "A-MSDU of %d = %u\n", + i + 1, rx_stats->stats_rx_amsdu_cnt[mu_idx][i]); + + fw_pr(cl_hw, "A-MSDU RX errors:\n"); + for (i = 0; i < AMSDU_DEAGGREGATION_ERR_MAX; i++) + if (rx_stats->stats_rx_amsdu_err[mu_idx][i]) + fw_pr(cl_hw, " err_id[%d] = %u\n", + i, rx_stats->stats_rx_amsdu_err[mu_idx][i]); + } + + fw_pr(cl_hw, "Frequency offset:\n"); + for (i = 0; i < FREQ_OFFSET_TABLE_IDX_MAX; i++) + if (rx_stats->frequency_offset[i]) + fw_pr(cl_hw, "frequency_offset = %u\n", rx_stats->frequency_offset[i]); +} + +static void cl_print_stats_handler(struct work_struct *ws) +{ + struct cl_print_stats_work *stats_work = container_of(ws, struct cl_print_stats_work, ws); + struct cl_hw *cl_hw = stats_work->cl_hw; + u32 dbg_info_type = stats_work->dbg_info_type; + + if (dbg_info_type == DBG_INFO_RX_STATS) { + struct cl_rxl_statistics *rx_stats = + &(((struct dbg_info *)cl_hw->dbginfo.buf)->u.rx_stats); + + cl_print_rx_stats(cl_hw, rx_stats); + } else { + cl_dbg_err(cl_hw, "Info type is not supported: %u\n", dbg_info_type); + } + + cl_ipc_dbginfobuf_push(cl_hw->ipc_env, cl_hw->dbginfo.dma_addr); + kfree(stats_work); +} + +static void cl_schedule_print_stats(struct cl_hw *cl_hw, u32 dbg_info_type) +{ + struct cl_print_stats_work *stats_work = + kzalloc(sizeof(*stats_work), GFP_ATOMIC); + + if (stats_work) { + INIT_WORK(&stats_work->ws, cl_print_stats_handler); + stats_work->cl_hw = cl_hw; + stats_work->dbg_info_type = dbg_info_type; + + /* Schedule work, the work will be executed in the background */ + queue_work(cl_hw->drv_workqueue, &stats_work->ws); + } else { + cl_dbg_err(cl_hw, "stats_work allocation failed\n"); + } +} + +void cl_fw_dbg_handler(struct cl_hw *cl_hw) +{ + struct dbg_info *dbg_info = NULL; + + /* Function called upon DBG_INFO_IND message reception. */ + dma_sync_single_for_device(cl_hw->chip->dev, cl_hw->dbginfo.dma_addr, + cl_hw->dbginfo.bufsz, DMA_FROM_DEVICE); + dbg_info = (struct dbg_info *)cl_hw->dbginfo.buf; + + if (dbg_info->u.type == DBG_INFO_DUMP) { + cl_dbg_info(cl_hw, "type %u): dump received\n", + cl_hw->dbginfo.buf->u.dump.general_data.error_type); + } else if (dbg_info->u.type < DBG_INFO_MAX) { + cl_schedule_print_stats(cl_hw, dbg_info->u.type); + } else { + cl_dbg_warn(cl_hw, "Debug info wrong type - %u\n", dbg_info->u.type); + } +} + +int cl_fw_dbg_trigger_based_init(struct cl_hw *cl_hw) +{ + cl_hw->tb_stats = vzalloc(sizeof(*cl_hw->tb_stats)); + if (!cl_hw->tb_stats) + return -ENOMEM; + + cl_hw->tb_sta_stats = vzalloc(sizeof(*cl_hw->tb_sta_stats)); + if (!cl_hw->tb_sta_stats) + return -ENOMEM; + + cl_hw->tb_stats->ampdu_cnt = INVALID_AMPDU_CNT; + + return 0; +} + +void cl_fw_dbg_trigger_based_deinit(struct cl_hw *cl_hw) +{ + vfree(cl_hw->tb_stats); + vfree(cl_hw->tb_sta_stats); +} + +void cl_fw_dbg_trigger_based_update(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, + struct ieee80211_hdr *hdr) +{ + struct cl_rx_trigger_based_stats *tb_stats = cl_hw->tb_stats; + u8 mu = 0; + + if (!tb_stats->enable) + return; + + if (tb_stats->ampdu_cnt == INVALID_AMPDU_CNT) { + tb_stats->ampdu_cnt = rxhdr->ampdu_cnt; + if (rxhdr->format_mod == FORMATMOD_HE_TRIG) { + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + tb_stats->qos_null_per_agg += rxhdr->frm_successful_rx; + else + tb_stats->data_per_agg += rxhdr->frm_successful_rx; + + tb_stats->total += rxhdr->frm_successful_rx; + } + } else if (tb_stats->ampdu_cnt == rxhdr->ampdu_cnt) { + if (rxhdr->format_mod == FORMATMOD_HE_TRIG) { + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + tb_stats->qos_null_per_agg += rxhdr->frm_successful_rx; + else + tb_stats->data_per_agg += rxhdr->frm_successful_rx; + + tb_stats->total += rxhdr->frm_successful_rx; + } + } else { + tb_stats->ampdu_cnt = rxhdr->ampdu_cnt; + if (unlikely(tb_stats->data_per_agg >= DBG_STATS_MAX_AGG_SIZE)) + cl_dbg_err(cl_hw, "rx trigger_based agg size %u > 256\n", + tb_stats->data_per_agg); + else + tb_stats->data[tb_stats->data_per_agg]++; + + if (unlikely(tb_stats->qos_null_per_agg > TID_MAX)) + tb_stats->qos_null[TID_MAX + 1]++; + else + tb_stats->qos_null[tb_stats->qos_null_per_agg]++; + + if (tb_stats->modify) { + tb_stats->modify = false; + + for (mu = 0; mu < MU_UL_MAX; mu++) { + tb_stats->data_per_mu_agg_size[mu][tb_stats->data_per_mu_agg[mu]]++; + tb_stats->data_per_mu_agg[mu] = 0; + } + } + + tb_stats->data_per_agg = 0; + tb_stats->qos_null_per_agg = 0; + + if (rxhdr->format_mod == FORMATMOD_HE_TRIG) { + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + tb_stats->qos_null_per_agg += rxhdr->frm_successful_rx; + else + tb_stats->data_per_agg += rxhdr->frm_successful_rx; + + tb_stats->total += rxhdr->frm_successful_rx; + } + } + + if (rxhdr->format_mod == FORMATMOD_HE_TRIG) { + mu = rxhdr->key_sram_index - KEY_SRAM_BASE_VAL; + + if (unlikely(mu >= MU_UL_MAX)) { + cl_dbg_err(cl_hw, "rxhdr->key_sram_index = %u; valid range: %u...%u\n", + rxhdr->key_sram_index, KEY_SRAM_BASE_VAL, + KEY_SRAM_BASE_VAL + MU_UL_MAX - 1); + return; + } + + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { + tb_stats->qos_null_per_mu[mu]++; + } else if (ieee80211_is_data(hdr->frame_control)) { + tb_stats->modify = true; + tb_stats->data_per_mu[mu]++; + tb_stats->data_per_mu_agg[mu]++; + } + + tb_stats->total_per_mu[mu]++; + } +} + +void cl_fw_dbg_trigger_based_sta_update(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, + struct ieee80211_hdr *hdr) +{ + struct cl_rx_trigger_based_sta_stats *tb_sta_stat = cl_hw->tb_sta_stats; + u8 id = 0; + + if (tb_sta_stat->ampdu_cnt != rxhdr->ampdu_cnt) { + tb_sta_stat->ampdu_cnt = rxhdr->ampdu_cnt; + if (tb_sta_stat->modify) { + tb_sta_stat->modify = false; + + for (id = 0; id < CL_MAX_NUM_STA; id++) { + tb_sta_stat->data_per_sta_agg[id][tb_sta_stat->data_per_sta[id]]++; + tb_sta_stat->data_per_sta[id] = 0; + } + } + } + + if (rxhdr->format_mod == FORMATMOD_HE_TRIG) { + id = rxhdr->key_sram_index - KEY_SRAM_BASE_VAL; + tb_sta_stat->modify = true; + tb_sta_stat->data_per_sta[id]++; + } +} From patchwork Tue May 24 11:33:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575974 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 CCB65C433EF for ; Tue, 24 May 2022 11:39:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236832AbiEXLjJ (ORCPT ); Tue, 24 May 2022 07:39:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236833AbiEXLjI (ORCPT ); Tue, 24 May 2022 07:39:08 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2086.outbound.protection.outlook.com [40.107.104.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FB044130C for ; Tue, 24 May 2022 04:38:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FpcpgLV5iTdBNMSoCzEQmBKcJJ3RydfredsXRyVjaytskcWGcsJWSaxkH/5haIVk2hdFeWB8RtIBzztJoHF/Aq+Lf6+Mg1/SxpYpyvS+yjQ2qlPvU6HUEMxra0SQF5NcYXTMXm2XJ20PC0tYWnG2xvloLVxA6EbgeQiV9sl5zKhejbwEyPKpVb2+hyvsY8o1YGQtWZjB8vnY5rTQnEpZjgQZQhj9BBVKgM0+IzwaR8HhhIUunOJEMVG2ZdUU4t5j+qxqDsddd7Rz7BPd3jyt4dJfkWvmC/pYqzy630qD84IWDaZZrPtjNiI4tX1vJm9vD0QUPvKqAm7gHl/sEcaunA== 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=G4pCHF9gp7sEz693J8QX4CnSm0VS2lyIw0BvSapRomA=; b=M97hxtgpIx7Vr1QM0VwZUOeDa74cvVR1J5hiUHIb/MX2bMpz6rULN9vYc/0HpHvc8q/oagrt0Ssvb94FQizN7P9qSI7G3Ls9rFwJ5rCBhqmVAlTiWIBfSmh1dPaRiO8vrbCLtG1aLY/p3vR/hQz/W17vJnn6qsqNHAYQblsHq2Cd+Tz4+8m1xSWNk9Ai1SKxkdmbzIthvgBgTB5hWJjLaWTtzEvVht5QXXpcbdbVB1/yZ4ZJUwiiB9VR8GZmyiZa2g/m7esXCx1j0Cs16KnFNJgTM5IH9UxrLSdM6jlz7StqXB3QdEJuSTHjH0dx0mMAE+3A0oZ5MyFKGO7p/ybhcQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=G4pCHF9gp7sEz693J8QX4CnSm0VS2lyIw0BvSapRomA=; b=yAVbLhu/QyOCYFHO3FDcEoYE5OGyDeQXg2jM5NeuQ6yB4T4Hf+rZ03S33LbcGkEyC4ZRaOjPdyYQAH0wyUxkw+TRQvZfLJMJzlO0H1CWoKO8GRtpUbl8KG72XcR8LBd0UHE6Cgyd+IkP7IXGlvTLrg3pEkTaKkrk3lpbn1jFGe0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:37 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:37 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 32/96] cl8k: add fw.h Date: Tue, 24 May 2022 14:33:58 +0300 Message-Id: <20220524113502.1094459-33-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b654ba23-7186-4873-775c-08da3d79df3d X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 0FHC5Pm19UnyfMZ9zbQpV5k667ulb0562LF2MNQPj+nUnfGu7nWRH6IBz5wb4NtYTwn/J8TWRZEc7KZRZkscmcw1gzYvzo8ieWMbLI2WpF6TUgskhcM+PdDkhRJjbqggPpPAlScE2NMpNR0quft5am7ahRbC849y2h0HsbCxCnJfIq9g0nKhst/CNTirs6kjjvLPAde399rdNroRRXGuTnsG6ZWlPL7ADWCzyXahFm3NSZ5Xq7BpDeQNav7WerIVbKaIXvt1ciU9jwH6ft+Mic6ZeObtk0C5SM5raZEyvJtazklGdPOfA7L3bpLuMG6oAE3tffBkQ8/kdxzSOy+9nNz2ca/cGOaDXcCof3mKv8eet3K8jNSF3H6WU2TRI4Gz35piR7mMwaIW1zRlfjenTl1CxpKfxzi4jP0S9T+kVFvYm9M4cT2eCifvdLw/RZjn47Teb0bGtQXDl2VcFs9VOqjj3jqt5yBEuHpY7JiC+/t3Uv9Qqm9T1+3a/XULPNLz7qFecqldzybo33nl/3lW02ZZGvAmIUnK5tKzZptfurhlykeLTFFyCdRgp3P+b8t9AE2RZ1OA0KvsSI/zUEoqYz9sv7U4mL5T6JM8EWyq8GUwZK0KfEJ16rBd3Tbmd0PCFiIbIVH2Pe09c0l0xLqOUrrxCIVBcNcCdTaDn4pIe9xW83cdT5b29SjeMoWGxR4UkbPQ5EbPER9aSbihDJbkUJ+/jE78jWNgriuR7qLJC3o= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: xITO+sEKeTDK/PdwEmFxFGGxCkW9h50pnX++MW2wkUJTFpv6/PaGxdGWTv+T1wucM6fKv8T0jYhROSFJnV/+/Q/cvcVwS5QLRz8cRBephRajnM8VUf1sRX6ilLFIjBcJgFeIAtJJvEblN3ks857+UCjow3G+lqqe734ApuNcEFz7C66X7R0Kx0Ud/gOZuJRoZw3VfqecaenwWQzoQXlRm5pIbboLgd1OXeOu7xuE7pVcsfGpJdnfhK2dfORKGeiCAQv1LGFwVQlXSIlVagu7z/EFRXkLgBIGA+buhqcbSM/27jnRkIohXGiXVnd2M7gQz8HqethYj5bLKpMHTSU19sOuoANTDpibfallXab3v2DnNuCVVE8DUncMwIJ+Nl5UJNVXNzlbwQaFkX5yesUWLgDl/5R9992e+c4eOOVPUAK+O7u+etEr/sCpC9WbyabalWXrpLCrND7euwmHLRopEF7FwkjK9NU5G+tqZbtuZeWEznicnd5RuV5x70DV+draPUtP+4fK6EHhh2PCbNb+n6s8RfXMRM+wTbGRiTEeraOylHWzCJYS6orxOgr9wSu4KbckZiCn4k0qPVuxgfRIF1JwsF0CQ/mglQNpUKZswxL7vaUptZMHKzNfC0gxcYj+Lqk0DktP1VjnhxAvDe2ayv3MnlZ3YCuS78TyS8tM7lDgmPK8vP5+DFpgonHbP8vkrrPXxKMCQ8pTMUEE7rbj3m1zU6lH8pipyd9XqawXSe/re2ajmHOd2dGOBEqfsPX5F644T+S5DbvzO1SmUP7hLvDBo+85vbYT5CB/4m25yUEHBhcuuHbEt8Kp3yxmSp2Lw2tIMIWG9hNPDbCoW95tj1JBJztigISJBYq3U9qKpum0UHAnGhSCIG0VGC4XG47A3dzR7v7I9BqI1pfFzg+cnEgOdUW14j3DiPZYo6oP2CYIePZM1Qsre9frcSsKNT8NvJk4NjXqzQGVI9ZawuJMt6lIs/JRKd6Q8FPw0PL2/v7ptliokjOu6EBI8HSbms6HH4NvqfXEBTfiaYbXYc5ohGQOWG6IeAy7ljZP1ntUYNc2I4cL5uHUM0KzXCcMQvCW1fjSrTBIFT6DvtiUnGP0HIxPAL/Dx7qgw+OugN5wQ4Tiowy137Mt9PccKrqeAdFmxH4oDPg06HSE625iqhs4o+3BJhcK4HpjkbsDIbg3G5KSxlsAqyogSuFya2lI+b4gSdYiqOtoUgCZ51XSP7xSAzQt3RQEfmY7CGotdx6b6iRu/o7WxrXx2V+uJWGuxZ7CHHV53ximdbcQmAqJ8+uLk/Nle6ItbUc79X2MY69WpD1DTyDOrRGs9mw5I1OM2Ia6nq5oLaTx/lglZSH5Cac+g6hpKxrntZj70kHmowhyn0BK8ekvulp7pomKjQNtqr2DRv6ZAdJUfkTtHUDpVhcU+L9XOIT0MVbb9TB1FEV1D+aZ8HvBSrRB78uJ04VcetIZ7qqNCyZlkBzdxdx+9Ltk634JVvb/hCp/ebTkSFYOX1Ux0DjCXPsqD1fDCGh0c2C7fUidQFTAa1yfiUmBXp5PYGrvYMWVr42sHLCQIoYj0tWyRwNhkRb8MaCrEamUxJK/tiHFubCW4cC2Wx6xt+3tybUhvfbXuXl32EcwYTEntKIFEEZ7TrFL8Tr5Hl2ekWq3S6/707ILmT4KYNa0OAJto1Wm2d58HdpVHjbchmg+vJHeD2yCPxmxTYt4YcoIUsj2djgucqPBQ853b+mbChxXR5Eie9RClulIkV+fEjeF7ko= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b654ba23-7186-4873-775c-08da3d79df3d X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:07.4061 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: IPKB1ZkioRi2fSg3Y5THvqpVTGX4kV4dasFenepDLK1zXSaTM4rtOlPjDWhHsJ57DyZqpWbGzsy7tKRFj8HVbQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/fw.h | 1462 +++++++++++++++++++++++++ 1 file changed, 1462 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/fw.h diff --git a/drivers/net/wireless/celeno/cl8k/fw.h b/drivers/net/wireless/celeno/cl8k/fw.h new file mode 100644 index 000000000000..12f573c0188c --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/fw.h @@ -0,0 +1,1462 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_FW_H +#define CL_FW_H + +#include + +#include "calib.h" +#include "wrs.h" + +#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD) +#error "Please fix " +#endif + +#define KEY_SRAM_BASE_VAL 64 +#define INVALID_AMPDU_CNT U8_MAX + +enum { + DBG_INFO_DUMP = 1, + DBG_INFO_TX_STATS, + DBG_INFO_BCN_STATS, + DBG_INFO_RX_STATS, + DBG_INFO_DYN_CAL_STATS, + DBG_INFO_RATE_FALLBACK_STATS, + DBG_INFO_BF, + DBG_INFO_TRIGGER_FLOW, + DBG_INFO_QUEUE_IDX_DIFF, + DBG_INFO_MAX, + DBG_INFO_UNSET = DBG_INFO_MAX +}; + +struct cl_rx_trigger_based_stats { + bool enable; + bool modify; + u8 ampdu_cnt; + u16 data_per_agg; + u16 qos_null_per_agg; + u32 total; + u32 data[DBG_STATS_MAX_AGG_SIZE]; + u32 qos_null[TID_MAX + 2]; + u32 total_per_mu[MU_UL_MAX]; + u32 qos_null_per_mu[MU_UL_MAX]; + u32 data_per_mu[MU_UL_MAX]; + u16 data_per_mu_agg[MU_UL_MAX]; + u32 data_per_mu_agg_size[MU_UL_MAX][DBG_STATS_MAX_AGG_SIZE]; +}; + +struct cl_rx_trigger_based_sta_stats { + bool modify; + u8 ampdu_cnt; + u16 data_per_sta[CL_MAX_NUM_STA]; + u32 data_per_sta_agg[CL_MAX_NUM_STA][DBG_STATS_MAX_AGG_SIZE]; +}; + +void cl_fw_dbg_handler(struct cl_hw *cl_hw); +int cl_fw_dbg_trigger_based_init(struct cl_hw *cl_hw); +void cl_fw_dbg_trigger_based_deinit(struct cl_hw *cl_hw); +void cl_fw_dbg_trigger_based_update(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, + struct ieee80211_hdr *hdr); +void cl_fw_dbg_trigger_based_sta_update(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, + struct ieee80211_hdr *hdr); + +struct cl_dma_accessed { + void *drv_v_addr; + u32 size; + u32 fw_v_addr; + u32 dma_addr; +}; + +struct cl_cached_fw { + void *data; + size_t size; +}; + +int cl_fw_file_load(struct cl_hw *cl_hw); +void cl_fw_file_cleanup(struct cl_hw *cl_hw); +void cl_fw_file_release(struct cl_hw *cl_hw); + +#define MSG_SHIFT 8 +#define NEW_MSG_SHIFT 1 +#define INTERNAL_MSG_COUNT 5 +#define FIRST_MSG(task) ((task) << MSG_SHIFT) +#define SHIFTED_MSG(id, shift) ((id) + NEW_MSG_SHIFT + (shift)) + +/* Message structure. */ +struct cl_fw_msg { + __le16 msg_id; /* Message ID. */ + u8 dst_kern_id; /* Destination kernel ID. */ + u8 dst_task_id; /* Destination task ID. */ + u8 src_kern_id; /* Source kernel ID. */ + u8 src_task_id; /* Source task ID. */ + __le16 param_len; /* Parameter embedded struct length. */ + __le32 param[1]; /* Parameter embedded struct - must be word-aligned. */ +}; + +enum { + TASK_MM, + TASK_DBG, + TASK_MAX, +}; + +/* List of messages related to the task. */ +enum mm_msg_tag { + /* Reset message */ + MM_RESET_REQ = FIRST_MSG(TASK_MM), + MM_RESET_CFM, + /* Start message */ + MM_START_REQ, + MM_START_CFM, + /* Version message */ + MM_VERSION_REQ, + MM_VERSION_CFM, + /* Add interface message */ + MM_ADD_IF_REQ, + MM_ADD_IF_CFM, + /* Remove interface message */ + MM_REMOVE_IF_REQ, + MM_REMOVE_IF_CFM, + /* Station add message */ + MM_STA_ADD_REQ, + MM_STA_ADD_CFM, + /* Station del message */ + MM_STA_DEL_REQ, + MM_STA_DEL_CFM, + /* Set filter message */ + MM_SET_FILTER_REQ, + MM_SET_FILTER_CFM, + /* Set channel message */ + MM_SET_CHANNEL_REQ = SHIFTED_MSG(MM_SET_FILTER_CFM, 2), + MM_SET_CHANNEL_CFM, + /* External calibration message */ + MM_EXT_CALIB_REQ, + MM_EXT_CALIB_CFM, + /* Set DTIM message */ + MM_SET_DTIM_REQ, + MM_SET_DTIM_CFM, + /* Set beacon interval message */ + MM_SET_BEACON_INT_REQ, + MM_SET_BEACON_INT_CFM, + /* Set basic rates message */ + MM_SET_BASIC_RATES_REQ, + MM_SET_BASIC_RATES_CFM, + /* Set BSSID message */ + MM_SET_BSSID_REQ, + MM_SET_BSSID_CFM, + /* Set EDCA message */ + MM_SET_EDCA_REQ, + MM_SET_EDCA_CFM, + /* Set association message */ + MM_SET_ASSOCIATED_REQ, + MM_SET_ASSOCIATED_CFM, + /* Set slot time message */ + MM_SET_SLOTTIME_REQ, + MM_SET_SLOTTIME_CFM, + /* Set idle message */ + MM_SET_IDLE_REQ, + MM_SET_IDLE_CFM, + /* Key add message */ + MM_KEY_ADD_REQ = SHIFTED_MSG(MM_SET_IDLE_CFM, 2), + MM_KEY_ADD_CFM, + /* Key delete message */ + MM_KEY_DEL_REQ, + MM_KEY_DEL_CFM, + /* Block ack add TX message */ + MM_BA_ADD_TX_REQ, + MM_BA_ADD_TX_CFM, + /* Block ack add RX message */ + MM_BA_ADD_RX_REQ, + MM_BA_ADD_RX_CFM, + /* Block ack delete message */ + MM_BA_DEL_REQ, + MM_BA_DEL_CFM, + /* PHY reset message */ + MM_PHY_RESET_REQ, + MM_PHY_RESET_CFM, + /* Available BA TX queue message */ + MM_AVAILABLE_BA_TXQ_REQ, + MM_AVAILABLE_BA_TXQ_CFM, + /* Update rate DL message */ + MM_UPDATE_RATE_DL_REQ, + MM_UPDATE_RATE_DL_CFM, + /* Update rate UL message */ + MM_UPDATE_RATE_UL_REQ, + MM_UPDATE_RATE_UL_CFM, + /* Set VNS message */ + MM_SET_VNS_REQ, + MM_SET_VNS_CFM, + /* Set TX BF message */ + MM_SET_TX_BF_REQ, + MM_SET_TX_BF_CFM, + /* Sounding message */ + MM_SOUNDING_REQ, + MM_SOUNDING_CFM, + /* Sounding pairing message */ + MM_SOUNDING_PAIRING_REQ, + MM_SOUNDING_PAIRING_CFM, + /* Sounding interval message */ + MM_SOUNDING_INTERVAL_REQ, + MM_SOUNDING_INTERVAL_CFM, + /* Set DFS message */ + MM_SET_DFS_REQ = SHIFTED_MSG(MM_SOUNDING_INTERVAL_CFM, 4), + MM_SET_DFS_CFM, + /* Set NDP TX control message */ + MM_NDP_TX_CONTROL_REQ = SHIFTED_MSG(MM_SET_DFS_CFM, 2), + MM_NDP_TX_CONTROL_CFM, + /* Register write message */ + MM_REG_WRITE_REQ, + MM_REG_WRITE_CFM, + /* Protection mode message */ + MM_PROT_MODE_REQ, + MM_PROT_MODE_CFM, + /* Backup beacon enable message */ + MM_BACKUP_BCN_EN_REQ = SHIFTED_MSG(MM_PROT_MODE_CFM, 4), + MM_BACKUP_BCN_EN_CFM, + /* Start periodic TX time message */ + MM_START_PERIODIC_TX_TIME_REQ, + MM_START_PERIODIC_TX_TIME_CFM, + /* Anamon read message */ + MM_ANAMON_READ_REQ, + MM_ANAMON_READ_CFM, + /* Refresh power message */ + MM_REFRESH_PWR_REQ = SHIFTED_MSG(MM_ANAMON_READ_CFM, 10), + MM_REFRESH_PWR_CFM, + /* Set antenna power offset message */ + MM_SET_ANT_PWR_OFFSET_REQ, + MM_SET_ANT_PWR_OFFSET_CFM, + /* Set rate fallback message */ + MM_SET_RATE_FALLBACK_REQ, + MM_SET_RATE_FALLBACK_CFM, + /* SPI write message */ + MM_SPI_WRITE_REQ = SHIFTED_MSG(MM_SET_RATE_FALLBACK_CFM, 6), + MM_SPI_WRITE_CFM, + /* SPI read message */ + MM_SPI_READ_REQ, + MM_SPI_READ_CFM, + MM_REQ_CFM_MAX = SHIFTED_MSG(MM_SPI_READ_CFM, 2), + + /* ############### Firmware indication messages ############### */ + /* Start of indication messages */ + MM_FIRST_IND = SHIFTED_MSG(MM_REQ_CFM_MAX, INTERNAL_MSG_COUNT), + /* TX aggregation indication from FW */ + MM_AGG_TX_REPORT_IND = MM_FIRST_IND, + /* RX aggregation indication from FW */ + MM_AGG_RX_REPORT_IND, + /* Indication for BF sounding */ + MM_SOUNDING_IND, + /* Indication of fw error */ + MM_FW_ERROR_IND = SHIFTED_MSG(MM_SOUNDING_IND, 2), + /* Async indication that MAC is in idle */ + MM_IDLE_ASYNC_IND, + + /* MAX number of messages */ + MM_MAX, +}; + +/* Interface types */ +enum { + MM_STA, + MM_IBSS, + MM_AP, + MM_MONITOR, + MM_MESH_POINT, +}; + +/* BA agreement types */ +enum { + /* BlockAck agreement for TX */ + BA_AGMT_TX, + /* BlockAck agreement for RX */ + BA_AGMT_RX, +}; + +/* BA agreement related status */ +enum { + BA_AGMT_ESTABLISHED, + BA_AGMT_ALREADY_EXISTS, + BA_AGMT_DELETED, + BA_AGMT_DOES_NOT_EXIST, + BA_AGMT_NOT_ESTABLISHED, +}; + +/* MM_BA_TXQUEUE request / confirm related status */ +enum { + BA_TXQUEUE_INVALID, + BA_TXQUEUE_VALID, +}; + +/* MAC address structure. */ +struct mac_addr { + /* Array of bytes that make up the MAC address. */ + u8 array[ETH_ALEN]; +}; + +/* DCOC/IQ Calibration related defines */ +#define CALIB_SUCCESS 0x00 +#define CALIB_FAIL 0x01 + +#define REG_OVERWRITE_DATA_MAX 3 +#define REG_OVERWRITE_REGS_MAX 20 + +struct cl_rf_reg_overwrite_info { + u8 cmd; + __le32 data[REG_OVERWRITE_DATA_MAX]; +}; + +struct cl_antenna_config { + /* Number of antennas */ + u8 num_tx_he; + u8 num_tx_ofdm_ht_vht; + u8 num_rx; + /* Mask of antennas */ + u8 mask_tx_he; + u8 mask_tx_ofdm_ht_vht; + u8 mask_rx; + /* CCK mask */ + u8 mask_tx_cck; + u8 mask_rx_cck; + /* CDB_mask 0x0 -> SX0 chain. 0x1-> SX1 chain. */ + u8 cdb_mask; +}; + +#define FEM_LUTS_PER_REGISTER 2 +#define FEM_LUT_AMOUNT_PER_MAC 6 +#define FEM_REGISTERS_AMOUNT (FEM_LUT_AMOUNT_PER_MAC / FEM_LUTS_PER_REGISTER) + +struct cl_fem_config { + __le32 reg[FEM_REGISTERS_AMOUNT]; +}; + +struct cl_cca_config { + u8 ed_rise_thr_dbm; + u8 ed_fall_thr_dbm; + u8 cs_en; + u8 modem_en; + u8 main_ant; + u8 second_ant; + u8 flag0_ctrl; + u8 flag1_ctrl; + u8 flag2_ctrl; + u8 flag3_ctrl; + u8 gi_rise_thr_dbm; + u8 gi_fall_thr_dbm; + u8 gi_pow_lim_dbm; + __le16 ed_en; + u8 gi_en; +}; + +/* Structure containing the parameters of the PHY configuration */ +struct cl_phy_cfg { + struct cl_cca_config cca_config; + struct cl_antenna_config ant_config; + struct cl_fem_config fem_conf; + u8 first_start; + u8 channel_bandwidth; + u8 band; /* 0 = 2.4g / 1 = 5g / 2 = 6g */ + u8 other_band; + __le16 freq_offset; + u8 rx_sensitivity[MAX_ANTENNAS]; + u8 vns_tx_power_mode; + u8 vns_rssi_suto_resp_th; + u8 afe_config_en; + u8 no_capture_noise_sleep; + u8 ht_rxldpc_en; + u8 gain_update_enable; + u8 mcs_sig_b; + u8 ofdm_only; + u8 hr_factor; + u8 td_csd_en; + u8 pe_duration_bcast; + __le32 tx_digital_gain; + __le32 tx_digital_gain_cck; + u8 ofdm_cck_power_offset; + u8 phy_clk_gating_en; + u8 tcv1_chains_sx0; + u8 dsp_lcu_mode; + u8 is_first_rfic; + u8 precalibration_enable; + /* For RF debug - this field should be deleted after RF bring up */ + struct cl_rf_reg_overwrite_info rf_reg_overwrite_info[REG_OVERWRITE_REGS_MAX]; +}; + +enum { + CENX_CFG_DEBUG_PRINT, + CENX_CFG_INT_FRAME, + CENX_CFG_CE_TX_CFM, +}; + +#define IPC_TXQ_CNT 5 + +/* MM_START_REQ parameters */ +struct cl_start_param { + __le32 comp_flags; + __le16 cfm_size; + __le32 cfm_dma_base_addr; + __le16 phy_dev; + __le16 fw_scale_down; + __le16 dbg_test_mode_max; + struct { + __le32 idle; + __le32 ac0; + __le32 ac1; + __le32 ac2; + __le32 ac3; + __le32 bcn; + } hal_timeout; + /* + * this is the pointer to the dma base address of the host struct + * that hold all the dma addresses of the ipc host queues + */ + __le32 ipc_host_tx_queues_dma_addr; + /* Address of RX buffer in host RAM */ + __le32 host_rxbuf_base_addr[CL_RX_BUF_MAX]; + /* Address of HOST indices */ + __le32 ipc_ring_indices_base; + u8 prot_log_nav_en; + u8 prot_mode; + u8 prot_rate_format; + u8 prot_rate_mcs; + u8 prot_rate_pre_type; + u8 bw_signaling_mode; + u8 mult_ampdu_in_txop_en; + u8 preemptive_backoff_en; + __le32 cca_timeout; + u8 short_retry_limit; + u8 long_retry_limit; + u8 assoc_auth_retry_limit; + __le16 bcn_tx_path_min_time; + u8 backup_bcn_en; + u8 tx_txop_cut_en; + u8 ps_ctrl_enabled; + u8 ac_with_bcns_flushed_cnt_thr; + __le32 txl_statistics_struct_size; + __le32 rxl_statistics_struct_size; + struct dbg_meta_data dbg_metadata; + u8 phy_err_prevents_phy_dump; + u8 tx_rx_delay; + u8 assert_storm_detect_thd; + u8 assert_time_diff_sec; + __le16 ipc_rxbuf_size[CL_RX_BUF_MAX]; + u8 host_pci_gen_ver; + u8 dma_lli_max_chan[2]; + u8 production_mode; + u8 bw_factor_q2[CHNL_BW_MAX]; + u8 ant_factor_q2[MAX_ANTENNAS]; + u8 min_ant_pwr_q1; + struct { + u8 auto_resp_all : 2; + u8 auto_resp_msta : 2; + u8 rsv : 4; + } default_distance; + __le32 phy_data_dma_addr; + __le32 phy_remote_rom_dma_addr; + __le32 iq_dcoc_calib_tables_dma_addr; + __le32 power_table_dma_addr; + __le32 tf_info_dma_addr; + u8 su_force_min_spacing_usec; + u8 mu_force_min_spacing_usec; + u8 single_tcv; + u8 rx_padding; + u8 bar_cap_disable; + u8 hw_bsr; + u8 drop_to_lower_bw; + u8 dra_enable; + u8 mac_clk_gating_en; + u8 imaging_blocker; + u8 fec_coding; + u8 cs_required; + u8 fw_disable_recovery; +}; + +struct cl_tx_params { + __le32 rate; + __le32 rate_he; + u8 req_bw_tx; + u8 ant_set; + u8 ltf; +}; + +struct mm_update_rate_dl_req { + u8 op_mode; + u8 sta_idx; + u8 mu_is_rate_valid; + u8 group_id; + struct cl_tx_params tx_params; + __le32 rate_fallback; + u8 ltf_fallback; +}; + +struct mm_update_rate_ul_req { + u8 op_mode; + u8 mu_is_rate_valid; + u8 group_id; + u8 sta_idx; + u8 bw; + u8 nss; + u8 mcs; + u8 gi_ltf; +}; + +struct mm_set_ant_pwr_offset_req { + /* Power offset (0.25dB resoultion) */ + u8 pwr_offset[MAX_ANTENNAS]; +}; + +struct mm_rate_fallback_req { + u8 fallback_count_su; + u8 fallback_count_mu; + u8 ba_per_thr; + u8 ba_not_received_thr; + u8 retry_count_thr; + u8 disable_mcs0; +}; + +struct mm_set_vns_req { + u8 sta_idx; + u8 is_vns; +}; + +struct mm_set_tx_bf_req { + u8 sta_idx; + u8 is_on; + u8 is_on_fallback; +}; + +/* Structure containing the parameters of the MM_START_REQ message */ +struct mm_start_req { + /* PHY configuration */ + struct cl_phy_cfg phy_cfg; + /* Other start parameters */ + struct cl_start_param param; +}; + +struct mm_mac_api_lut_line { + __le16 frequency_q2; + union { + struct { + struct { + u8 vcocalsel; + u8 nint; + __le32 nfrac; + __le32 freqmeastarg; + } xco_40M; + struct { + u8 vcocalsel; + u8 nint; + __le32 nfrac; + __le32 freqmeastarg; + } xco_60M; + } olympus_2_lines; + struct { + struct { + u8 vcocalsel; + u8 nint; + __le32 nfrac; + __le32 freqmeastarg; + } xco_40M; + struct { + u8 vcocalsel; + u8 nint; + __le32 nfrac; + __le32 freqmeastarg; + } xco_60M_s0; + struct { + u8 vcocalsel; + u8 nint; + __le32 nfrac; + __le32 freqmeastarg; + } xco_60M_s1; + } olympus_3_lines; + } rfic_specific; +}; + +struct cl_calib_other_tcv { + /* Parameters for calibration */ + __le16 prim20_freq; + struct mm_mac_api_lut_line center1_freq_lut; + /* Parameter to restore previous configuration of other TCV */ + u8 mask_tx_he; + u8 num_tx_he; + u8 band; +}; + +struct cl_calib_conf { + u8 rx_gain_upper_limit; + u8 rx_gain_lower_limit; + __le16 nco_freq; + s8 nco_amp; + u8 sleeve_trshld; + u8 n_samples_exp_lolc; + u8 n_samples_exp_iqc; + __le32 p_thresh; + u8 n_bit_fir_scale; + u8 n_bit_amp_scale; + u8 n_bit_phase_scale; + __le16 tone_vector[IQ_NUM_TONES_REQ]; + __le32 gp_rad_trshld; + __le32 ga_lin_upper_trshld; + __le32 ga_lin_lower_trshld; + u8 comp_filter_len; + u8 singletons_num; + u8 tones_num; + __le16 rampup_time; + __le16 lo_coarse_step; + __le16 lo_fine_step; + u8 precalibration_enable; +}; + +struct cl_calib_param { + u8 mode; + u8 dcoc_max_vga; + struct cl_calib_chain tx_calib_chain[MAX_ANTENNAS]; + struct cl_calib_chain rx_calib_chain[MAX_ANTENNAS]; + struct cl_calib_conf conf; + struct cl_calib_other_tcv other_tcv; +}; + +/* Structure containing the parameters of the MM_SET_CHANNEL_REQ message */ +struct mm_set_channel_req { + /* Band (2.4GHz, 5GHz, 6GHz) */ + u8 band; + u8 other_band; + /* Channel type: 20,40,80 or 160 MHz */ + u8 bandwidth; + /* Frequency for Primary 20MHz channel (in MHz) */ + __le16 prim20_freq; + /* Frequency for Center of the contiguous channel or center of Primary 80+80 */ + struct mm_mac_api_lut_line center1_freq_lut; + /* Antenna configuration */ + struct cl_antenna_config ant_config; + /* FEM configuration */ + struct cl_fem_config fem_conf; + /* For RF debug - this field should be deleted after RF bring up */ + struct cl_rf_reg_overwrite_info rf_reg_overwrite_info[REG_OVERWRITE_REGS_MAX]; + u8 calib_info_set; + /* Calibration configuration */ + struct cl_calib_param calib_param; + /* Antenna power offset */ + u8 ant_pwr_offset[MAX_ANTENNAS]; + /* + * Frequency offset in MHz between current synthesizer's center channel, + * and the other synthesizer's channel. + * Needed for LOLC and IQC Calibration. Otherwise, shouldn't be used. + */ + s8 sx_freq_offset_mhz; + /* Hr factor */ + u8 hr_factor; + /* Signal extension enable (for 2.4G sifs10 mode), should be 1 for 2,4 band by default */ + u8 signal_ext; +}; + +enum mm_ext_calib_command { + MM_EXT_CALIB_CMD_INIT_SX, + MM_EXT_CALIB_CMD_SET_CHANNEL, + MM_EXT_CALIB_CMD_INIT_AND_SET_CHANNEL, + MM_EXT_CALIB_CMD_MAX +}; + +struct mm_ext_calib_init_sx_req { + u8 band; + u8 cdb_mask; + u8 mask_tx_he; + u8 num_tx_he; + u8 sx_idx; +}; + +struct mm_ext_calib_set_channel_req { + u8 band; + u8 bandwidth; + __le16 prim20_freq; + struct mm_mac_api_lut_line center1_freq_lut; + u8 sx_idx; +}; + +struct mm_ext_calib_init_and_set_req { + u8 band; + u8 cdb_mask; + u8 bandwidth; + __le16 prim20_freq; + struct mm_mac_api_lut_line center1_freq_lut; + __le16 remote_prim20_freq; + struct mm_mac_api_lut_line remote_center1_freq_lut; +}; + +union mm_ext_calib_cmd_req { + struct mm_ext_calib_init_sx_req init_sx; + struct mm_ext_calib_set_channel_req set_channel; + struct mm_ext_calib_init_and_set_req init_and_set; +}; + +struct mm_ext_calib_req { + u8 cmd; + union mm_ext_calib_cmd_req u; +}; + +/* Structure containing the parameters of the MM_SET_DTIM_REQ message */ +struct mm_set_dtim_req { + u8 dtim_period; +}; + +/* Structure containing the parameters of the MM_SET_BEACON_INT_REQ message */ +struct mm_set_beacon_int_req { + __le16 beacon_int; + /* Index of the interface */ + u8 inst_nbr; +}; + +/* Structure containing the parameters of the MM_SET_BASIC_RATES_REQ message */ +struct mm_set_basic_rates_req { + /* Basic rate set (as expected by bssBasicRateSet field of Rates MAC HW register) */ + __le32 rates; +}; + +/* Structure containing the parameters of the MM_SET_BSSID_REQ message */ +struct mm_set_bssid_req { + /* BSSID to be configured in HW */ + struct mac_addr bssid; + /* Index of the interface for which the parameter is configured */ + u8 inst_nbr; +}; + +/* Structure containing the parameters of the MM_SET_FILTER_REQ message */ +struct mm_set_filter_req { + __le32 filter; +}; + +/* Structure containing the parameters of the MM_ADD_IF_REQ message. */ +struct mm_add_if_req { + u8 type; + struct mac_addr addr; + u8 inst_nbr; + u8 tx_strip_vlan; + u8 rx_push_vlan; + __le32 rx_push_vlan_tag; + __le32 rx_filter_monitor_mask; + __le32 mac_addr_hi_mask; + __le32 mac_addr_low_mask; + u8 start_dtim_count; + u8 mbssid_mode; +}; + +/* Structure containing the parameters of the MM_SET_EDCA_REQ message */ +struct mm_set_edca_req { + __le32 ac_param; + u8 hw_queue; + u8 mu_edca_aifsn; + u8 mu_edca_ecw_min_max; + u8 mu_edca_timer; +}; + +struct mm_config_cca_req { + u8 enable; +}; + +struct mm_set_dfs_req { + bool enable; + bool standard_fcc; + u8 initial_gain; + u8 agc_cd_th; +}; + +struct mm_ndp_tx_control_req { + u8 chain_mask; + u8 bw; + u8 format; + u8 num_ltf; +}; + +struct mm_reg_write_req { + __le32 address; + __le32 value; + __le32 mask; +}; + +struct mm_prot_mode_req { + u8 log_nav_en; + u8 mode; + u8 rate_format; + u8 rate_mcs; + u8 rate_pre_type; +}; + +enum mac_idle_cmd { + MAC_ACTIVE = 0, + MAC_IDLE_SYNC, + MAC_IDLE_ASYNC +}; + +struct mm_set_idle_req { + u8 hw_idle; +}; + +/* Structure containing the parameters of the MM_SET_SLOTTIME_REQ message */ +struct mm_set_slottime_req { + /* Slot time expressed in us */ + u8 slottime; +}; + +/* Structure containing the parameters of the MM_SET_ASSOCIATED_REQ message */ +struct mm_set_associated_req { + /* Association Id received from the AP */ + __le16 aid; + /* Mask address high - [47:32] */ + __le32 bssid_hi_mask; + /* Mask address low - [31:0] */ + __le32 bssid_low_mask; +}; + +/* Structure containing the parameters of the MM_ADD_IF_CFM message. */ +struct mm_add_if_cfm { + /* Status of operation (different from 0 if unsuccessful) */ + u8 status; +}; + +/* Structure containing the parameters of the MM_REMOVE_IF_REQ message. */ +struct mm_remove_if_req { + /* Interface index assigned by the firmware */ + u8 inst_nbr; +}; + +/* Structure containing the parameters of the MM_VERSION_CFM message. */ +struct mm_version_cfm { + struct { + __le32 dsp; + __le32 rfic_sw; + __le32 rfic_hw; + __le32 agcram; + char fw[CL_VERSION_STR_SIZE]; + } versions; + u8 rf_crystal_mhz; +}; + +/* Structure containing the parameters of the MM_STA_ADD_REQ message. */ +struct mm_sta_add_req { + /* Exponent for calculating HE Maximum A-MPDU size */ + u8 ampdu_size_exp_he; + /* Exponent for calculating VHT Maximum A-MPDU size */ + u8 ampdu_size_exp_vht; + /* Exponent for calculating HT Maximum A-MPDU size */ + u8 ampdu_size_exp_ht; + /* MAC address of the station to be added */ + struct mac_addr mac_addr; + /* A-MPDU spacing, in us */ + u8 ampdu_min_spacing; + /* Interface index */ + u8 inst_nbr; + /* Support ldpc Tx */ + u8 ldpc_enabled; + /* MU beamformee capable */ + u8 mu_bfee; + /* SU beamformee capable */ + u8 su_bfee; + /* Station AID */ + __le16 aid; + /* My_aid - ??? */ + __le16 my_aid; + /* Index of station in case of recovery */ + u8 recovery_sta_idx; + u8 max_sp; + u8 uapsd_queues; + /* TX params */ + struct cl_tx_params tx_params; + /* + * PE duration (0 = 0us, 1 = 8us, 2 = 16us) + * SS0 bits 0-1, SS1 bits 2-3, SS2 bits 4-5, SS3 bits 6-7. + */ + u8 pe_duration[CHNL_BW_MAX][WRS_MCS_MAX_HE]; + u8 he_tf_mac_padding_duration; + u8 he_rx_ctrl_frm_to_mbss; + u8 he_rx_1024qam_under_ru242; +}; + +/* Structure containing the parameters of the MM_STA_ADD_CFM message. */ +struct mm_sta_add_cfm { + /* Status of the operation (different from 0 if unsuccessful) */ + u8 status; + /* Index assigned by the firmware to the newly added station */ + u8 sta_idx; +}; + +/* Structure containing the parameters of the MM_STA_DEL_REQ message. */ +struct mm_sta_del_req { + u8 sta_idx; +}; + +/* MAC Secret Key */ +#define MAC_SEC_KEY_LEN 32 /* TKIP keys 256 bits (max length) with MIC keys */ + +struct mac_sec_key { + /* Key material length */ + u8 length; + /* Key material */ + u32 array[MAC_SEC_KEY_LEN / 4]; +}; + +enum mac_cipher_suite { + MAC_CIPHER_SUITE_NULL, + MAC_CIPHER_SUITE_WEP40, + MAC_CIPHER_SUITE_TKIP, + MAC_CIPHER_SUITE_CCMP, + MAC_CIPHER_SUITE_WEP104, + MAC_CIPHER_SUITE_GCMP, + + MAC_CIPHER_SUITE_MAX +}; + +/* Structure containing the parameters of the MM_KEY_ADD REQ message. */ +struct mm_key_add_req { + /* Key index (valid only for default keys) */ + u8 key_idx; + /* STA index (valid only for pairwise keys) */ + u8 sta_idx; + /* Key material */ + struct mac_sec_key key; + /* Cipher suite */ + u8 cipher_suite; + /* Index of the interface for which the key is set (valid only for default keys) */ + u8 inst_nbr; + /* A-MSDU SPP parameter */ + u8 spp; +}; + +/* Structure containing the parameters of the MM_KEY_ADD_CFM message. */ +struct mm_key_add_cfm { + /* Status of the operation (different from 0 if unsuccessful) */ + u8 status; + /* HW index of the key just added */ + u8 hw_key_idx; +}; + +/* Structure containing the parameters of the MM_KEY_DEL_REQ message. */ +struct mm_key_del_req { + u8 hw_key_idx; +}; + +/* Structure containing the parameters of the MM_BA_ADD_REQ message. */ +struct mm_ba_add_req { + /* Type of agreement (0: TX, 1: RX) */ + u8 type; + /* Index of peer station with which the agreement is made */ + u8 sta_idx; + /* TID for which the agreement is made with peer station */ + u8 tid; + /* Buffer size - number of MPDUs that can be held in its buffer per TID */ + __le16 bufsz; + /* Start sequence number negotiated during BA setup */ + __le16 ssn; +}; + +/* Structure containing the parameters of the MM_BA_ADD_CFM message. */ +struct mm_ba_add_cfm { + /* Index of peer station for which the agreement is being confirmed */ + u8 sta_idx; + /* TID for which the agreement is being confirmed */ + u8 tid; + /* Status of ba establishment */ + u8 status; + /* Aggregation index */ + u8 agg_idx; + /* Number of descriptors the queue of session can hold */ + u16 desc_cnt; +}; + +/* Structure containing the parameters of the MM_BA_DEL_REQ message. */ +struct mm_ba_del_req { + /* Index of peer station for which the agreement is being deleted */ + u8 sta_idx; + /* TID for which the agreement is being deleted */ + u8 tid; +}; + +/* Structure containing the parameters of the MM_BA_DEL_CFM message. */ +struct mm_ba_del_cfm { + /* Index of peer station for which the agreement deletion is being confirmed */ + u8 sta_idx; + /* TID for which the agreement deletion is being confirmed */ + u8 tid; + /* Status of ba deletion */ + u8 status; +}; + +/* Structure containing the parameters of the MM_AVAILABLE_BA_TXQ_REQ message. */ +struct mm_available_ba_txq_req { + /* Index of peer station for which the agreement deletion is being confirmed */ + u8 sta_idx; + /* TID for which the agreement deletion is being confirmed */ + u8 tid; +}; + +/* Structure containing the parameters of the MM_AVAILABLE_BA_TXQ_CFM message. */ +struct mm_available_ba_txq_cfm { + /* Index of peer station for which the agreement deletion is being confirmed */ + u8 sta_idx; + /* TID for which the agreement deletion is being confirmed */ + u8 tid; + /* Status if ba txqueue available */ + u8 status; +}; + +struct sounding_info_per_sta { + u8 sta_idx; +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 nc : 4, /* [3:0] NC of the STA */ + fb_type_ng_cb_size : 3, /* [6:4] */ + rsv1 : 1; /* [7] reserved */ +#else + u8 rsv1 : 1, /* [7] reserved */ + fb_type_ng_cb_size : 3, /* [6:4] */ + nc : 4; /* [3:0] NC of the STA */ +#endif +}; + +/* Information provided by application to firmware */ +struct mm_sounding_req { + struct sounding_info_per_sta info_per_sta[CL_MU_MAX_STA_PER_GROUP]; + __le32 host_address; +#if defined(__LITTLE_ENDIAN_BITFIELD) + /* [2:0] sounding type (HE-SU/HE-MU/HE_CQI/VHT-SU/VHT-MU) */ + u32 sounding_type : 3, + /* [3:6] number of stations in the sounding sequence */ + sta_num : 4, + /* [7] start/stop sounding sequence */ + start : 1, + /* [19:8] life expectancy of BFR in ms */ + lifetime : 12, + /* [31:20] sounding interval. 0 means a single sounding */ + interval : 12; + /* [1:0] requested bw for the sounding sequence (BFR/NDP) */ + u8 req_txbw : 2, + /* [5:2] NSTS in the NDP frame */ + ndp_nsts : 4, + /* [7:6] reserved bits */ + rsv1 : 2; + /* [3:0] Bitmap of STAs to create SU Q-matrix for */ + u8 q_matrix_bitmap : 4, + /* [7:4] reserved bits */ + rsv2 : 4; +#else + /* [31:20] sounding interval. 0 means a single sounding */ + u32 interval : 12, + /* [19:8] life expectancy of BFR in ms */ + lifetime : 12, + /* [7] start/stop sounding sequence */ + start : 1, + /* [3:6] number of stations in the sounding sequence */ + sta_num : 4, + /* [2:0] sounding type (HE-SU/HE-MU/HE_CQI/VHT-SU/VHT-MU) */ + sounding_type : 3; + /* [7:6] reserved bits */ + u8 rsv1 : 2, + /* [5:2] NSTS in the NDP frame */ + ndp_nsts : 4, + /* [1:0] requested bw for the sounding sequence (BFR/NDP) */ + req_txbw : 2; + /* [7:4] reserved bits */ + u8 rsv2 : 4, + /* [3:0] Bitmap of STAs to create SU Q-matrix for */ + q_matrix_bitmap : 4; +#endif + /* Sounding id. Used when deleting a sounding sequence */ + u8 sid; +}; + +/* Application feedback for sounding request */ +struct mm_sounding_cfm { + u8 param_err; + u8 sounding_id; +}; + +struct mm_sounding_pairing { + u8 sounding_type; + u8 sounding_id; + u8 sta_idx; + u8 gid; +}; + +struct mm_sounding_interval_req { + __le16 interval; /* Sounding interval */ + __le16 bfr_lifetime; /* Life expectancy of BFR in ms */ + u8 sounding_type; /* Type of sounding (VHT/HT/SU/MU) */ + u8 sta_idx; /* Sta idx */ +}; + +struct mm_sounding_interval_cfm { + u8 param_err; +}; + +/* Structure containing the parameters of the MM_BACKUP_BCN_EN_REQ message */ +struct mm_set_backup_bcn_en_req { + /* Backup beacon disable/enable */ + bool backup_bcn_en; +}; + +/* Structure containing the parameters of the MM_START_PERIODIC_TX_TIME_REQ message */ +struct mm_start_periodic_tx_time_req { + __le16 periodic_tx_time_off; + __le16 periodic_tx_time_on; +}; + +enum ANAMON_MODE { + ANAMON_MODE_TEMPERATURE, + ANAMON_MODE_CHAINS, + ANAMON_MODE_SX +}; + +/* Structure containing the parameters of the MM_ANAMON_READ_REQ message */ +struct mm_anamon_read_req { + u8 mode; /* 0 - Temperature, 1 - Chains, 2 - SX */ + u8 param1; /* For mode = 0: 0 - Internal, 1 - External ; For mode = 1/2: Page number */ + u8 param2; /* For mode = 5 bit value corresponding to mode selection */ +}; + +struct mm_anamon_read_cfm { + u8 retval; + __le16 raw_bits_data_0; + __le16 raw_bits_data_1; +}; + +struct mm_spi_write_req { + u8 page; + u8 addr; + u8 val; + u8 mask; +}; + +struct mm_spi_read_req { + u8 page; + u8 addr; +}; + +struct mm_spi_read_cfm { + u8 status; + u8 val; +}; + +/* +++++++++++++++++++++++++ Debug messages +++++++++++++++++++++++++ */ + +/* Messages related to Debug Task */ +enum dbg_msg_tag { + /* Set module filter message */ + DBG_SET_MOD_FILTER_REQ = FIRST_MSG(TASK_DBG), + DBG_SET_MOD_FILTER_CFM, + /* Set module filter message */ + DBG_CE_SET_MOD_FILTER_REQ, + DBG_CE_SET_MOD_FILTER_CFM, + /* Set severity filter message */ + DBG_SET_SEV_FILTER_REQ, + DBG_SET_SEV_FILTER_CFM, + /* Get ETH2WLAN statistics message */ + DBG_GET_E2W_STATS_REQ, + DBG_GET_E2W_STATS_CFM, + /* Set LA MPIF mask message */ + DBG_SET_LA_MPIF_MASK_REQ, + DBG_SET_LA_MPIF_MASK_CFM, + /* Set LA trigger point message */ + DBG_SET_LA_TRIG_POINT_REQ, + DBG_SET_LA_TRIG_POINT_CFM, + /* Set LA MPIF debug mode message */ + DBG_SET_LA_MPIF_DEBUG_MODE_REQ, + DBG_SET_LA_MPIF_DEBUG_MODE_CFM, + /* Set LA trigger rule message */ + DBG_SET_LA_TRIG_RULE_REQ, + DBG_SET_LA_TRIG_RULE_CFM, + /* TX trace dump debug flag message */ + DBG_TX_TRACE_DEBUG_FLAG_REQ, + DBG_TX_TRACE_DEBUG_FLAG_CFM, + /* Print statistics message */ + DBG_PRINT_STATS_REQ, + DBG_PRINT_STATS_CFM, + /* Trigger the embedded logic analyzer message */ + DBG_TRIGGER_REQ, + DBG_TRIGGER_CFM, + /* Test mode message */ + DBG_TEST_MODE_REQ, + DBG_TEST_MODE_CFM, + /* Sounding command message */ + DBG_SOUNDING_CMD_REQ, + DBG_SOUNDING_CMD_CFM, + /* Presilicon HW testing message */ + DBG_PRESILICON_TESTING_REQ, + DBG_PRESILICON_TESTING_CFM, + + DBG_REQ_CFM_MAX, + + /* Print request */ + DBG_PRINT_IND = DBG_REQ_CFM_MAX, + /* Information indication */ + DBG_INFO_IND, + /* Max number of debug messages */ + DBG_MAX, +}; + +/* Structure containing the parameters of the DBG_SET_MOD_FILTER_REQ message. */ +struct dbg_set_mod_filter_req { + /* Bit field indicating for each module if the traces are enabled or not */ + __le32 mod_filter; +}; + +/* Structure containing the parameters of the DBG_SEV_MOD_FILTER_REQ message. */ +struct dbg_set_sev_filter_req { + /* Bit field indicating the severity threshold for the traces */ + __le32 sev_filter; +}; + +/* Must be aligned with FW (dbg.h) */ +enum dbg_test_mode { + DBG_TEST_MODE_HELP = 0, + DBG_TEST_MODE_ASSERT_REC, + DBG_TEST_MODE_ERR_CORRECT_MODE, + DBG_TEST_MODE_PRESILICON_TESTS, + DBG_TEST_MODE_TRIGGER_BA_NOT_RECEIVED, + DBG_TEST_MODE_TRIGGER_ABOVE_BAW, + DBG_TEST_MODE_TRIGGER_BELOW_BAW, + DBG_TEST_MODE_TRIGGER_RETRY_LIMIT_REACHED, + DBG_TEST_MODE_DMA_DATA_PRINT, + DBG_TEST_MODE_SET_AGC_MEM, + DBG_TEST_MODE_FW_TRACE_MODE, + DBG_TEST_MODE_TX_POWER_DEBUG, + DBG_TEST_MODE_DCOC_IQ_MODE, + DBG_TEST_MODE_MACHW_STATE, + DBG_TEST_MODE_PHY_GLOBAL_RESET, + DBG_TEST_MODE_PHY_OLYMPUS_TXRX_MODE, + DBG_TEST_MODE_AFE_LOOPBACK_MODE, + DBG_TEST_MODE_MIN_SPACING_MODE, + DBG_TEST_MODE_DELAY_CHAIN, + DBG_TEST_MODE_ERR_DUMP_PRINT, + DBG_TEST_MODE_BW_SIG_PRINT, + DBG_TEST_MODE_RECOVER_BA_NOT_RECEIVED, + DBG_TEST_MODE_BAP_MODE, + DBG_TEST_MODE_DPHY_INJECT_RXERR, + DBG_TEST_MODE_RXM_RXVECTOR_PRINT, + DBG_TEST_MODE_STOP_CHAIN, + DBG_TEST_MODE_MAX_AGG_SIZE, + DBG_TEST_MODE_DISABLE_RECOVERY, + DBG_TEST_MODE_SET_NAV_DURATION, + DBG_TEST_MODE_SET_NAV_CLEAR, + DBG_TEST_MODE_DRA_GRP_LIMIT_SET, + DBG_TEST_MODE_DURATION_FROM_THD, + DBG_TEST_MODE_RIU_INT_EN, + DBG_TEST_MODE_MU_OF_1_USER, + DBG_TEST_MODE_FORCE_TRIGGER, + DBG_TEST_MODE_RECOVERY_DEBUG, + DBG_TEST_MODE_CHAIN_SUSPEND, + DBG_TEST_MODE_DSP_LCU_TRIG, + DBG_TEST_MODE_POWER_SAVE, + DBG_TEST_MODE_TRIGGER_RX_NOT_RECEIVED, + DBG_TEST_MODE_SNIFFER_MODE, + DBG_TEST_MODE_AGC_CAPTURE_NOISE, + DBG_TEST_MODE_TRIGGER_UNDERRUN, + DBG_TEST_MODE_TF_IN_AMPDU_EN, + DBG_TEST_MODE_HOST_FW_QUEUE_WR_RD, + DBG_TEST_MODE_TXDESC_DMA_TOKEN_SET, + DBG_TEST_MODE_ASSERT_ERR, + DBG_TEST_MODE_MAX, +}; + +/* Information sent from firmware to host indicating the rx bfr variables */ +struct mm_sounding_ind { + /* Param that are application private, collected by host without local copy */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 sounding_type : 3, + status : 1, + fail_reason : 4; + u8 mu : 1, + rsv : 7; +#else + u8 fail_reason : 4, + status : 1, + sounding_type : 3; + u8 rsv : 7, + mu : 1; +#endif + u8 sid; + u8 sta_idx; + u16 v_matrix_offset[CL_MU_MAX_STA_PER_GROUP]; +}; + +/* Possible fw errors types */ +enum mm_fw_error_type { + MM_FW_ERROR_TYPE_MU_OFDMA_SLOW_SECONDARY, + MM_FW_ERROR_TYPE_MAX +}; + +/* Structure containing the parameters of the MM_FW_ERROR_IND message */ +struct mm_fw_error_ind { + u8 group_id; + u8 error_type; + u8 sta_inidices[CL_MU_MAX_STA_PER_GROUP]; + u8 sta_num; +}; + +enum mm_agg_rx_status_type { + MM_AGG_RX_REPORT_STAT_OK, + MM_AGG_RX_REPORT_STAT_COLISION_WITH_COUNTER, + MM_AGG_RX_REPORT_STAT_COUNTER_LOST, + MM_AGG_RX_REPORT_STAT_NOT_RECEIVED, + MM_AGG_RX_REPORT_STAT_NOT_HE +}; + +struct mm_agg_rx_ind { + u8 sta_num; + u8 sta_idx[CL_MU_MAX_STA_PER_GROUP]; + u8 status[CL_MU_MAX_STA_PER_GROUP]; + __le16 ampdu_received_counter[CL_MU_MAX_STA_PER_GROUP]; + __le16 discarded_mpdu_count[CL_MU_MAX_STA_PER_GROUP]; + __le16 correct_received_mpdu_count[CL_MU_MAX_STA_PER_GROUP]; + __le16 incorrect_received_mpdu_count[CL_MU_MAX_STA_PER_GROUP]; + __le16 rx_discarded_mpdu_count[CL_MU_MAX_STA_PER_GROUP]; + __le16 incorrect_delimiter_count[CL_MU_MAX_STA_PER_GROUP]; + u8 nss_per_user[CL_MU_MAX_STA_PER_GROUP]; + u8 mcs_rate[CL_MU_MAX_STA_PER_GROUP]; + u8 ru_allocation[CL_MU_MAX_STA_PER_GROUP]; + u8 gi_ltf; + u8 rcpi[CL_MU_MAX_STA_PER_GROUP]; + u8 evm1[CL_MU_MAX_STA_PER_GROUP]; + u8 evm2[CL_MU_MAX_STA_PER_GROUP]; + u8 evm3[CL_MU_MAX_STA_PER_GROUP]; + u8 evm4[CL_MU_MAX_STA_PER_GROUP]; +}; + +#define MSG_TOTAL_REQ_CFM (MM_REQ_CFM_MAX + DBG_REQ_CFM_MAX) +#define DBG_STR_SHIFT(id) ((id) - FIRST_MSG(TASK_DBG) + MM_REQ_CFM_MAX) +#define MSG_ID_STR(id) (((id) < MM_REQ_CFM_MAX) ? msg2str[id] : msg2str[DBG_STR_SHIFT(id)]) + +extern const char *const msg2str[MSG_TOTAL_REQ_CFM]; + +/* Timeout waiting for firmware confirmation */ +#define CL_MSG_CFM_TIMEOUT_MS 400 +#define CL_MSG_CFM_TIMEOUT_JIFFIES msecs_to_jiffies(CL_MSG_CFM_TIMEOUT_MS) + +#define CL_MSG_CFM_TIMEOUT_CALIB_MS 1800 +#define CL_MSG_CFM_TIMEOUT_CALIB_JIFFIES msecs_to_jiffies(CL_MSG_CFM_TIMEOUT_CALIB_MS) + +#define CL_MSG_CFM_TIMEOUT_DUMMY_MS 7000 +#define CL_MSG_CFM_TIMEOUT_DUMMY_JIFFIES msecs_to_jiffies(CL_MSG_CFM_TIMEOUT_DUMMY_MS) + +#define CL_MSG_CFM_TIMEOUT_FRU_MS 35000 +#define CL_MSG_CFM_TIMEOUT_FRU_JIFFIES msecs_to_jiffies(CL_MSG_CFM_TIMEOUT_FRU_MS) + +#define CFM_CLEAR_BIT(bit, cfm_flags) \ + clear_bit((bit) & 0x1f, *(cfm_flags) + ((bit) >> 5)) + +#define CFM_SET_BIT(bit, cfm_flags) \ + set_bit((bit) & 0x1f, *(cfm_flags) + ((bit) >> 5)) + +#define CFM_TEST_BIT(bit, cfm_flags) \ + test_bit((bit) & 0x1f, *(cfm_flags) + ((bit) >> 5)) + +#define CFM_TEST_AND_CLEAR_BIT(bit, cfm_flags) \ + test_and_clear_bit((bit) & 0x1f, *(cfm_flags) + ((bit) >> 5)) + +u16 cl_msg_cfm_set_bit(u16 req); +int cl_msg_cfm_wait(struct cl_hw *cl_hw, u16 bit, u16 req_id); +void cl_msg_cfm_assign_and_clear(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg); +void cl_msg_cfm_clear(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg); +void cl_msg_rx_tasklet(unsigned long data); +void cl_msg_rx_flush_all(struct cl_hw *cl_hw); + +#define FREQUENCY_INT_MASK 0xfffc +#define FREQUENCY_FRAC_MASK 0x0003 +#define FREQUENCY_INT_SHIFT 2 +#define FREQUENCY_FRAC_RESOLUTION 25 + +#define GET_FREQ_INT(freq) (((freq) & FREQUENCY_INT_MASK) >> FREQUENCY_INT_SHIFT) +#define GET_FREQ_FRAC(freq) (((freq) & FREQUENCY_FRAC_MASK) * FREQUENCY_FRAC_RESOLUTION) + +enum ke_kern_tag { + KERN_HOST, + KERN_LMAC, + KERN_UMAC, + KERN_SMAC, + + KERN_MAX, +}; + +#define SET_CHANNEL_MODE_OPERETIONAL 0x01 +#define SET_CHANNEL_MODE_CALIB_DCOC 0x02 +#define SET_CHANNEL_MODE_CALIB_IQ 0x04 +#define SET_CHANNEL_MODE_CALIB_LOLC 0x08 +#define SET_CHANNEL_MODE_CALIB_MANUAL 0x10 +#define SET_CHANNEL_MODE_CALIB (SET_CHANNEL_MODE_CALIB_DCOC | \ + SET_CHANNEL_MODE_CALIB_IQ | \ + SET_CHANNEL_MODE_CALIB_LOLC) + +/* + * confirmation call back params + * @err: general msg transmitting error + * @param: pointer to lower layer feedback param (FW layer) + */ +struct cl_msg_cfm_cb_param { + int err; + void *param; /* Pointer to msg cfm param, the caller should be aware to that type */ +}; + +/* + * call back function definition, associate with all backgrounf triggered messages + * if caller intersting in message done feedback it must declare function of this type! + */ +typedef void (*cl_msg_cfm_cb_func)(struct cl_msg_cfm_cb_param *p_cfm_cb_param, u32 token); + +void cl_msg_tx_free_cfm_params(struct cl_hw *cl_hw, u16 id); +int cl_msg_tx_reset(struct cl_hw *cl_hw); +int cl_msg_tx_start(struct cl_hw *cl_hw); +int cl_msg_tx_version(struct cl_hw *cl_hw); +int cl_msg_tx_add_if(struct cl_hw *cl_hw, struct ieee80211_vif *vif, u8 vif_index); +int cl_msg_tx_remove_if(struct cl_hw *cl_hw, u8 vif_index); +int cl_msg_tx_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta, struct cl_vif *cl_vif, + u8 recovery_sta_idx, u32 rate_ctrl_info); +int cl_msg_tx_sta_del(struct cl_hw *cl_hw, u8 sta_idx); +int cl_msg_tx_set_filter(struct cl_hw *cl_hw, u32 filter, bool force); +int cl_msg_tx_set_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u32 primary, u32 center, + struct cl_calib_params calib_params); +int cl_msg_tx_dtim(struct cl_hw *cl_hw, u8 dtim_period); +int cl_msg_tx_set_beacon_int(struct cl_hw *cl_hw, u16 beacon_int, u8 vif_idx); +int cl_msg_tx_set_basic_rates(struct cl_hw *cl_hw, u32 basic_rates); +int cl_msg_tx_set_bssid(struct cl_hw *cl_hw, const u8 *bssid, u8 vif_idx); +int cl_msg_tx_set_edca(struct cl_hw *cl_hw, u8 hw_queue, u32 param, + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca); +int cl_msg_tx_set_associated(struct cl_hw *cl_hw, + struct ieee80211_bss_conf *bss_conf); +int cl_msg_tx_set_slottime(struct cl_hw *cl_hw, bool use_short_slot); +int cl_msg_tx_set_idle(struct cl_hw *cl_hw, u8 idle, bool is_lock); +void cl_msg_tx_idle_async(struct cl_hw *cl_hw, bool is_lock); +int cl_msg_tx_key_add(struct cl_hw *cl_hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf, u8 cipher_suite); +int cl_msg_tx_key_del(struct cl_hw *cl_hw, u8 hw_key_idx); +int cl_msg_tx_ba_add(struct cl_hw *cl_hw, u8 type, u8 sta_idx, u16 tid, u16 bufsz, u16 ssn); +int cl_msg_tx_ba_del(struct cl_hw *cl_hw, u8 sta_idx, u16 tid); +int cl_msg_tx_available_ba_txq(struct cl_hw *cl_hw, u8 sta_idx, u16 tid); +int cl_msg_tx_update_rate_dl(struct cl_hw *cl_hw, u8 sta_idx, u32 rate, u32 rate_fallback, + u8 req_bw_tx, u8 op_mode, u8 gid, u8 mu_valid, u8 ltf, + u8 ltf_fallback, u32 rate_he); +int cl_msg_tx_update_rate_ul(struct cl_hw *cl_hw, u8 sta_idx, u8 bw, u8 nss, u8 mcs, u8 gi_ltf); +int cl_msg_tx_set_vns(struct cl_hw *cl_hw, u8 sta_idx, u8 is_vns); +int cl_msg_tx_set_tx_bf(struct cl_hw *cl_hw, u8 sta_idx, u8 is_on, u8 is_on_fallback); +int cl_msg_tx_sounding(struct cl_hw *cl_hw, + struct mm_sounding_req *sounding_req); +int cl_msg_tx_sounding_pairing(struct cl_hw *cl_hw, u8 sounding_id, u8 sounding_type, + u8 gid, u8 sta_idx); +int cl_msg_tx_sounding_interval(struct cl_hw *cl_hw, u16 interval, u16 lifetime, + u8 sounding_type, u8 sta_idx); +int cl_msg_tx_set_dfs(struct cl_hw *cl_hw, bool enable, u8 standard, + u8 initial_gain, u8 agc_cd_th); +int cl_msg_tx_ndp_tx_control(struct cl_hw *cl_hw, u8 chain_mask, u8 bw, u8 format, u8 num_ltf); +int cl_msg_tx_reg_write(struct cl_hw *cl_hw, u32 address, u32 value, u32 mask); +int cl_msg_tx_prot_mode(struct cl_hw *cl_hw, u8 log_nav_en, u8 mode, + u8 rate_format, u8 rate_mcs, u8 rate_pre_type); +int cl_msg_tx_backup_bcn_en(struct cl_hw *cl_hw, bool backup_bcn_en); +int cl_msg_tx_start_periodic_tx_time(struct cl_hw *cl_hw, u16 periodic_tx_time_off, + u16 periodic_tx_time_on); +int cl_msg_tx_anamon_read(struct cl_hw *cl_hw, u8 mode, u8 param1, u8 param2); +int cl_msg_tx_refresh_power(struct cl_hw *cl_hw); +int cl_msg_tx_set_ant_pwr_offset(struct cl_hw *cl_hw, s8 pwr_offset[MAX_ANTENNAS]); +int cl_msg_tx_set_rate_fallback(struct cl_hw *cl_hw); +int cl_msg_tx_spi_write(struct cl_hw *cl_hw, u8 page, u8 addr, u8 val, u8 mask); +int cl_msg_tx_spi_read(struct cl_hw *cl_hw, u8 page, u8 addr); + +/* Debug messages */ +int cl_msg_tx_dbg_set_ce_mod_filter(struct cl_hw *cl_hw, u32 filter); +int cl_msg_tx_dbg_set_sev_filter(struct cl_hw *cl_hw, u32 filter); + +#endif /* CL_FW_H */ From patchwork Tue May 24 11:33:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576858 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 2DBDEC433FE for ; Tue, 24 May 2022 11:38:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236825AbiEXLi4 (ORCPT ); Tue, 24 May 2022 07:38:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236832AbiEXLiz (ORCPT ); Tue, 24 May 2022 07:38:55 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2041.outbound.protection.outlook.com [40.107.104.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCF228CCEB for ; Tue, 24 May 2022 04:38:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FLHdFpwtwsVrBv+Z0cAbeaAfsh+SoHBng2lFdjTbfx6N5hJIlDhkBu7ZUpz/51qGJeYzy+J6g039FsknvvedbFH+bjnc2R7uFNebnWkSWnf0swg8kG/JsZHyxYfX+A9SWYZVnqU6EcJk33glreRV8/fQj8+Mi869kANpQ9pIxlg355wa3ail20tBaS8hf3VYkM3XLspL87jkZCYW/P/YT4iCsJ67kv9qOqO0oIPw9iaKJSvkNrKLhJI6jDDM3faSgxTLv4ZQ4OFZXlw+E0IhTijMwTzsZ5SRZAX4PSvu5kf22exI3eV3gQJ12nDRxsjlnWxlmdg0n+marygIAEklOA== 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=W0yqa9mwBVjCKcu9pGBZ+EOGbpSkNVkptIQnl4NsrUs=; b=hp4Y4ZRyrNRyI8zg7J0mnMDqzdtBU9cXA0lIh6cMtfzUbO3XVmbwFv8mKJJ5un/9gUyyrZ7f7rfNriZZx4gigjy1cW4HcundY7b3A0Y+wgp6Jn5I0S0A1H5o4HpTdhrM5fStCDmlOje9n8rTYgQvsfx0ZVccjLgNLXLBfGkVf7c8823J2Kc/8pGuf93b9Xy9YClNf+Bchixjhuw7dzecJAYxLKEMRqJg4LGatwOjmmr8pCrE1NOqkoeS6QjM//96FDheIWw5mYaLVVc3WA08k3b2bNwz/vkJBZv9DAmWjmu6uEFXD7CucopEeaUfJWjDrT+noX6vLOikMG3izuxWTg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W0yqa9mwBVjCKcu9pGBZ+EOGbpSkNVkptIQnl4NsrUs=; b=cp4YZNWvVbYOlTLVMWhazQ5fNOefKatkM//Pnlcnnj3OiXsAQ6d9ZaOVX1vOsANxb/0vPKij5HWSlyHPznPiVH6mW/GJDgQS8pZLzR439Sf/pbyHOsVQ8yLqlczbP4fkkQ9nTeNLbi3IIj0Ulip5CxHyG48h96fultDYhfzM8fk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:37 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:37 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 33/96] cl8k: add hw.c Date: Tue, 24 May 2022 14:33:59 +0300 Message-Id: <20220524113502.1094459-34-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6b5f82b6-00dd-4e8a-a736-08da3d79dfb4 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BC7OLjl2Iz0X5MDY2XtZ7QBarSjlQh82qGcIFzb46J6ogwwdrrQoEUwXbpFoHrbzEbOENsyWKEDu4EirD54C8k8kWUaJJ4wEjPgCOuLAp83nNAAebj45DLlo0JGAg5VO1X5OroYQ1WneZ8Nor1+uB4PLeBiT4as9umJ4+9Q7XGT8U5vJUFY7a3WNfSX2YoSe2nv17NuqAdW6xLb6FFJPQMwcBsl3k/nOrDpKvZGN8aHYspvR1dv1tk5dhulBISaKSHMIkh3xuYPVrF3clU31WKH86BPh5rkxQACF3gub07s5495jzaLeieeu3dAct234lSMZLiQe5HD9ZEgG2YXlCKyvZo2OWqJgyKZUdzyIBNc+YF4fAVqQcer9EwxazGKxmkjuJnflaXLWj5dDTqqVDAzb/YJoahSWqwLWrSkjQ3d6bSisyuKFM3+e9un+9lGDMWFz101/v6lvmpFsLYZGXNsQtCFve4XErXAXpqgyzDqZlVxPTvXZ238kRcY73VKhWZhCJNtHLVg/1J7s7q+fdwhxMVnkLh+SwlGuy/zy3ClxdSHC+J/kyKbSZf2vURnR5MRqG7pIy63tTPbLF7F+QF9fcM77q3AN9Qmd9oQGAD40QZOuSIMbyS2zwPHZ7hZJOXcICdROVaU/P9ao/ahAViLvXBWxrto0O2R4MGbs59Cy5jwTpoc02Ay5VM0wOuBnqXtGlIKIgJqchk6/2glV59U8Snn05Ri3wD9a+Iokzf4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 5hXB3+r1UNVc8rQHJgprUDuukeb/QVjSZO9EkqlSeOkaTbDukmYLCDAAjR2hab5GOa5AvCKsRoeJhFhTbWlfUwkuxyTX36NGFi/UeJ0jKJj3W8tlGxXNLd79FPffPzNoLRlaXsT2QuxTaDfCTQOW2V98ttkG4MjK4tE5SQkQgsGu6RvHZXKMY/uG5mYmhzUeAzdgW+uLxsGya4E2grLc7UOB5d7TKBX2OTwPyvEUTkv/KZYn45wGEQgkluR1Ev6OACRIAK/tTsJ8ioaLRLzZ7EXJKpZAt+f13CNJMO+25XR553p37LpORn8KjUCb4WWYJd/6qpvmPnH7HnRVhjE3jlYxuRu0sfrhRqyHrb2wPoTuSSVdYkix8tkSxp2QiGaXFNcizwiiznjafw+2oOw3Ejz91JpcugKQye2KLJzSYaK2n3KpikIo38tPhwaKR0Q0yWUXHxXxhyElGfoMzJSoA9D/7Bg3KFiq+DneN25fq8fnP4yHdGpX+MftS57gLQ1bzDgyCLVFKVXdDVCxx2NQPyoI3YFwWiOQdmD7OscYjLK+65cBcxPuQHSOBkF2LnUUumH44T5oyIs10qQGPvGkSEJbDJRAl3Wwm7yAV4Y9W6oR8+CKLoEDc+6h4xhSBDYR6EpqKDG8yb08G9dkqoOWtiVMr5ytrBMo8j0bgl58jNV1/k8En6wGXDyJPcM0fGx6kFgmaihMfB3qrwOTQQhmjXmsIAeGtyPG4cMI3wuH3+MwJKyTuxMUUplVJw8f8rrTERBZzL2FPUzehFM3cqWy8jezMSajQyIeB1ZEqZppNRjfGufTt0iMe4InmtBX0ApJkY2NYEkTyAbY2EIe0qQ9iakcob/sY8akdWb6z7bNjAndhbIWBWMdGMvD1CpIVcXu33P1ssP8MTD8rr0e7ITfppIfkSSEVfPlOJVWYAapMCBZtT5dbbhZpR62SYs19xB2mEN56IfTxixxZmmDnaO1rS9FnGorc5oXi5a1rVn4uWBSEFtwyamyoZCpPoZV3cN7lAmWoYSQLxUVhvSo2w2iUELPdcP02sDYnQcuEdg5BvhNUy3lSYAEaNkfI1SrC5+pjg+ej5lTwqILMFBotA8fRTR5+I54ZNbOf+71OYbnxAsnz+T6ONm2m7Kv4r+xbEQGnY/3g5US8kdhyLTAjRbj3pLUy/y0+bFiXbHp9e1qSGJl9h8+WQxIgJxYx5h0VZpwihs3CmgtRAQQF7NWuEGnhLSb6+zoE/4jJpqsFDzX08kCt8G2fu5xMwMU1mq8oZBrPXmC8je92lFuA9nMjTtMRwMXq60SrwzjYZl7KP8MI0eKcm8NL67yAZ2kO/2nvAd6kn2SEAtAEezMnGw2XG/R5P2dOuPsSmI1CNQb5BDKxIy1bt6gk5VVJ42WCXCNNCbIodCRb7emj0HFtgSo+wz2FNfGFeGCvy5iHuxCa/NmWldHsAu72TOAJi6VuBUHn17RMDuhxb2Ael2h6Lm2RzE0YzAnI3RYrFOAc8ulJt+d8U+rm6AFAaguisxaNkpCkYX1lhgwdM7hk7iIg1RgHa+wA8jNJ8NPiUK1tHZIuERx5ZqIFKZnBwdCkFRaGa984gk94zmwdOkVwMgMimxlwDz9L3K7M88ua+zNyXDD1zwbcIBYHyLJKAI1fdRzpmUqzWvgJKQiPIeld3WIEcnDGBTYGdYtSHSZi4JG6M7y9DAL54jhd9W8Owb067JrZ5Vja+p/CgYADU4hmzb7nDq1jxqQ0yQbd/EGHHIUqZTvalNMspA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6b5f82b6-00dd-4e8a-a736-08da3d79dfb4 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:08.1248 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Gc8WBeoS6xXgyZwsvFte5zBLgAiJTJg3TJvN0iTrUy+iL1zMvgyU93AsG4wEd8V2kRJ17V0GA0FyoMWAMoL3Jw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/hw.c | 432 ++++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/hw.c diff --git a/drivers/net/wireless/celeno/cl8k/hw.c b/drivers/net/wireless/celeno/cl8k/hw.c new file mode 100644 index 000000000000..834622549f9a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/hw.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "tx.h" +#include "rates.h" +#include "reg/reg_access.h" +#include "recovery.h" +#include "hw.h" + +static void cl_hw_init_tcv0(struct cl_hw *cl_hw) +{ + struct cl_controller_reg *controller_reg = &cl_hw->controller_reg; + + cl_hw->fw_dst_kern_id = KERN_LMAC; + cl_hw->fw_prefix = 'l'; + + controller_reg->breset = LMAC_BRESET; + controller_reg->debug_enable = LMAC_DEBUG_ENABLE; + controller_reg->dreset = LMAC_DRESET; + controller_reg->ocd_halt_on_reset = LMAC_OCD_HALT_ON_RESET; + controller_reg->run_stall = LMAC_RUN_STALL; + + cl_hw->mac_hw_regs_offset = 0; + cl_hw->phy_regs_offset = REG_PHY_LMAC_OFFSET; +} + +static void cl_hw_init_tcv1(struct cl_hw *cl_hw) +{ + struct cl_controller_reg *controller_reg = &cl_hw->controller_reg; + + cl_hw->fw_dst_kern_id = KERN_SMAC; + cl_hw->fw_prefix = 's'; + + controller_reg->breset = SMAC_BRESET; + controller_reg->debug_enable = SMAC_DEBUG_ENABLE; + controller_reg->dreset = SMAC_DRESET; + controller_reg->ocd_halt_on_reset = SMAC_OCD_HALT_ON_RESET; + controller_reg->run_stall = SMAC_RUN_STALL; + + cl_hw->mac_hw_regs_offset = REG_MAC_HW_SMAC_OFFSET; + cl_hw->phy_regs_offset = REG_PHY_SMAC_OFFSET; +} + +static void cl_hw_set_first_last_riu_chains(struct cl_hw *cl_hw, u8 first_ant, u8 last_ant) +{ + u8 ant, chain; + u8 min_chain = U8_MAX; + u8 max_chain = 0; + + for (ant = first_ant; ant <= last_ant; ant++) { + chain = cl_hw_ant_to_riu_chain(cl_hw, ant); + + if (chain < min_chain) + min_chain = chain; + + if (chain > max_chain) + max_chain = chain; + } + + cl_hw->first_riu_chain = min_chain; + cl_hw->last_riu_chain = max_chain; +} + +void cl_hw_init(struct cl_chip *chip, struct cl_hw *cl_hw, u8 tcv_idx) +{ + write_lock(&chip->cl_hw_lock); + chip->cl_hw_lut[tcv_idx] = cl_hw; + write_unlock(&chip->cl_hw_lock); + + if (tcv_idx == TCV0) + cl_hw_init_tcv0(cl_hw); + else + cl_hw_init_tcv1(cl_hw); +} + +void cl_hw_deinit(struct cl_hw *cl_hw, u8 tcv_idx) +{ + struct cl_chip *chip = cl_hw->chip; + + write_lock(&chip->cl_hw_lock); + chip->cl_hw_lut[tcv_idx] = NULL; + write_unlock(&chip->cl_hw_lock); +} + +struct cl_hw *cl_hw_other_tcv(struct cl_hw *cl_hw) +{ + /* This function must be called after read lock is taken */ + return cl_hw->chip->cl_hw_lut[1 - cl_hw->tcv_idx]; +} + +bool cl_hw_is_tcv0(struct cl_hw *cl_hw) +{ + return (cl_hw->tcv_idx == TCV0); +} + +bool cl_hw_is_tcv1(struct cl_hw *cl_hw) +{ + return (cl_hw->tcv_idx == TCV1); +} + +bool cl_hw_is_first_tcv(struct cl_hw *cl_hw) +{ + if (cl_hw_is_tcv0(cl_hw)) + return true; + else + return cl_chip_is_only_tcv1_enabled(cl_hw->chip); +} + +int cl_hw_set_antennas(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + u8 last_ant; + u8 ant_shift = cl_hw_ant_shift(cl_hw); + + /* Set num_antennas and max_antennas + masks for both. */ + switch (chip->fem.wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + cl_hw->max_antennas = 6; + break; + case FEM_WIRING_24_TCV0_6_TCV1_4: + cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 6 : 4; + break; + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_33_TCV0_4_TCV1_4: + cl_hw->max_antennas = 4; + break; + case FEM_WIRING_13_SENSING_4RX_2TX: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_29_TCV0_4_TCV1_2: + cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 4 : 2; + break; + case FEM_WIRING_30_TCV0_4_TCV1_2: + cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 4 : 2; + break; + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_32_TCV0_4_TCV1_0: + cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 4 : 0; + break; + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_20_TCV0_2_TCV1_2: + cl_hw->max_antennas = 2; + break; + case FEM_WIRING_27_TCV0_2_TCV1_1: + case FEM_WIRING_31_TCV0_2_TCV1_1: + cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 2 : 1; + break; + default: + if (chip->conf->ce_production_mode) + cl_hw->max_antennas = chip->max_antennas; + else + return -1; + break; + } + + cl_hw->num_antennas = cl_hw->conf->ce_num_antennas; + cl_hw->mask_num_antennas = ANT_MASK(cl_hw->num_antennas) << ant_shift; + cl_hw->first_ant = ant_shift; + last_ant = max_t(s8, cl_hw->num_antennas + ant_shift - 1, 0); + + cl_hw_set_first_last_riu_chains(cl_hw, cl_hw->first_ant, last_ant); + + cl_dbg_trace(cl_hw, "num_antennas = %u, max_antennas = %u\n", + cl_hw->num_antennas, cl_hw->max_antennas); + + if (cl_hw->num_antennas > cl_hw->max_antennas) { + CL_DBG_ERROR(cl_hw, "num_antennas (%u) > max_antennas (%u)\n", + cl_hw->num_antennas, cl_hw->max_antennas); + return -1; + } + + return 0; +} + +u8 cl_hw_ant_shift(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + /* CL808x uses antennas 0 - 3 for both bands */ + if (cl_chip_is_8ant(chip)) + return 0; + + if (cl_chip_is_6ant(chip)) { + /* + * CL806X on wiring id 24 uses antennas 0-3 for TCV0 and antennas 2-3 for TCV1. + * When only 1 antenna is configured - ant 3 is used. + */ + if (cl_hw_is_tcv1(cl_hw) && chip->fem.wiring_id == FEM_WIRING_24_TCV0_6_TCV1_4) + return (4 - cl_hw->conf->ce_num_antennas); + + /* Other CL806X use antennas 0 - 3 for TCV0 and antennas 0-1 for TCV1 */ + return 0; + } + + /* + * CL8046 uses chains 0 - 3 for TCV0 and no chain for TCV1. + * Wiring ID 31 uses chains 2-3 for TCV0 and chain 4 for TCV1. + */ + if (cl_chip_is_6g(chip)) { + if (chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + return cl_hw_is_tcv0(cl_hw) ? 2 : 4; + + return 0; + } + + /* CL8040 uses chains 1 - 2 for TCV0 and TCV1 */ + return 1; +} + +u8 cl_hw_ant_to_riu_chain(struct cl_hw *cl_hw, u8 ant) +{ + struct cl_chip *chip = cl_hw->chip; + u8 res = ant; + + if (cl_hw_is_tcv0(cl_hw)) { + if (chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + return ((ant - 2) & 0x3); + + if (chip->fem.wiring_id == FEM_WIRING_30_TCV0_4_TCV1_2) { + if (ant == 2) + return 3; + if (ant == 3) + return 2; + + return ant; + } + + return ant; + } + + switch (chip->fem.wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_32_TCV0_4_TCV1_0: + return ant; + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_13_SENSING_4RX_2TX: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_20_TCV0_2_TCV1_2: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_29_TCV0_4_TCV1_2: + case FEM_WIRING_30_TCV0_4_TCV1_2: + case FEM_WIRING_33_TCV0_4_TCV1_4: + res = (3 - ant); + break; + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_24_TCV0_6_TCV1_4: + res = (5 - ant); + break; + case FEM_WIRING_27_TCV0_2_TCV1_1: + res = (2 - ant); + break; + case FEM_WIRING_31_TCV0_2_TCV1_1: + res = (ant == 2 ? 4 : (ant == 4 ? 2 : 0)); + break; + default: + break; + } + + /* Verify that the returned value is valid */ + return res & ANT_MASK(MAX_ANTENNAS); +} + +u8 cl_hw_ant_mask_to_riu_chain_mask(struct cl_hw *cl_hw, u8 ant_mask) +{ + u8 ant, riu_chain, riu_chain_mask = 0x0; + + for (ant = 0; ant < MAX_ANTENNAS; ant++) { + if (ant_mask & BIT(ant)) { + riu_chain = cl_hw_ant_to_riu_chain(cl_hw, ant); + riu_chain_mask |= BIT(riu_chain); + } + } + + return riu_chain_mask; +} + +bool cl_hw_is_prod_or_listener(struct cl_hw *cl_hw) +{ + /* TODO: Move ce_listener_en to cl_chip */ + if (cl_hw->chip->conf->ce_production_mode || + (cl_hw->conf && cl_hw->conf->ce_listener_en)) + return true; + + return false; +} + +#define ASSERT_PATTERN 0xC0DEDEAD + +/* + * Function will take time stamp for each hw error indication. + * when time diff between each error is less than ce_hw_assert_time_max + * cl_hw_restart work will be scheduled + */ +static bool cl_hw_assert_storm_detect(struct cl_hw *cl_hw) +{ + struct cl_hw_asserts_info *assert_info = &cl_hw->assert_info; + u8 idx = assert_info->index % CL_MIN_ASSERT_CNT; + /* Get the oldest assert timestamp. */ + u8 prev_idx = (assert_info->index + 1) % CL_MIN_ASSERT_CNT; + bool is_hw_restarted = false; + + if (assert_info->restart_sched) { + is_hw_restarted = true; + } else { + /* Take time stamp of the assert */ + assert_info->timestamp[idx] = jiffies; + assert_info->index++; + /* In case hw assert time diff is less than CL_HW_ASSERT_TIME_MAX, restart hw. */ + if (assert_info->index > CL_MIN_ASSERT_CNT) { + unsigned long time_diff_jiffies = + assert_info->timestamp[idx] - assert_info->timestamp[prev_idx]; + unsigned int time_diff_msecs = jiffies_to_msecs(time_diff_jiffies); + + if (time_diff_msecs < cl_hw->conf->ce_hw_assert_time_max) { + assert_info->index = 0; + + cl_dbg_err(cl_hw, "Assert storm detect (time_diff = %u)\n", + time_diff_msecs); + cl_recovery_start(cl_hw, RECOVERY_ASSERT_STORM_DETECT); + + is_hw_restarted = true; + } + } + } + + return is_hw_restarted; +} + +void cl_hw_assert_info_init(struct cl_hw *cl_hw) +{ + memset(&cl_hw->assert_info, 0, sizeof(cl_hw->assert_info)); +} + +static void cl_recovery_no_dump_start(struct cl_hw *cl_hw, enum recovery_reason reason) +{ + cl_dbg_trace(cl_hw, "Starting recovery due to assert no dump\n"); + cl_recovery_start(cl_hw, reason); +} + +void cl_hw_assert_print(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg) +{ + struct dbg_print_ind *ind = (struct dbg_print_ind *)msg->param; + const char *assert_string; + u32 assert_pattern; + u16 file_id = le16_to_cpu(ind->file_id); + u16 line = le16_to_cpu(ind->line); + u16 has_param = le16_to_cpu(ind->has_param); + u32 param = le32_to_cpu(ind->param); + + /* If ce_hw_assert_time_max is 0, HW assert storm detection is disabled */ + if (cl_hw->conf->ce_hw_assert_time_max) + if (cl_hw_assert_storm_detect(cl_hw)) + return; + + assert_string = cl_dbgfile_get_msg_txt(&cl_hw->dbg_data, file_id, line); + + /* Avoid printing background asserts */ + if (cl_hw->conf->ce_bg_assert_print || !strstr(assert_string, "ASSERT_REC")) { + /* Print ASSERT message with file_id, line, [parameter] */ + if (has_param) + cl_dbg_err(cl_hw, "ASSERT_TCV%u @ FILE=%u LINE=%u param=0x%08X\n", + cl_hw->idx, file_id, line, param); + else + cl_dbg_err(cl_hw, "ASSERT_TCV%u @ file=%u line=%u\n", + cl_hw->idx, file_id, line); + + if (!assert_string) + assert_string = "ASSERT STRING NOT FOUND"; + + /* TODO:length of single print may be limited,consider print long msgs by pieces */ + cl_dbg_err(cl_hw, "%.500s\n", assert_string); + } + + assert_pattern = ioread32((void __iomem *)&cl_hw->ipc_env->shared->assert_pattern); + + /* Reset ASSERT pattern if needed (in order to prevent assert prints loop) */ + if (assert_pattern == ASSERT_PATTERN) + iowrite32(0, (void __iomem *)&cl_hw->ipc_env->shared->assert_pattern); + + if (!ind->err_no_dump) + return; + + cl_recovery_no_dump_start(cl_hw, RECOVERY_UNRECOVERABLE_ASSERT_NO_DUMP); +} + +void cl_hw_assert_check(struct cl_hw *cl_hw) +{ + struct cl_ipc_shared_env __iomem *shared_env = cl_hw->ipc_env->shared; + u32 assert_pattern = ioread32((void __iomem *)&shared_env->assert_pattern); + + if (assert_pattern == ASSERT_PATTERN) { + u16 line = ioread16((void __iomem *)&shared_env->assert_line_num); + u16 file_id = ioread16((void __iomem *)&shared_env->assert_file_id); + u32 param = ioread32((void __iomem *)&shared_env->assert_param); + const char *assert_string = cl_dbgfile_get_msg_txt(&cl_hw->dbg_data, file_id, line); + + /* Print 1st ASSERT message with file_id, line, [parameter] */ + cl_dbg_err(cl_hw, "ASSERT_%cmac @ FILE=%u LINE=%u param=0x%08X\n", + cl_hw->fw_prefix, file_id, line, param); + + if (!assert_string) + assert_string = "ASSERT STRING NOT FOUND"; + + cl_dbg_err(cl_hw, "%.500s\n", assert_string); + + /* Reset ASSERT pattern in order to prevent assert prints loop */ + iowrite32(0, (void __iomem *)&shared_env->assert_pattern); + } +} From patchwork Tue May 24 11:34:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576857 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 C0801C433FE for ; Tue, 24 May 2022 11:39:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236830AbiEXLjB (ORCPT ); Tue, 24 May 2022 07:39:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236831AbiEXLjB (ORCPT ); Tue, 24 May 2022 07:39:01 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2081.outbound.protection.outlook.com [40.107.104.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAEF58CCFF for ; Tue, 24 May 2022 04:38:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PSV0H9mRmQaYB8ux4et05pqvVxA1JVNwJOzkmxZwsByQgXYZLdr2Uox39B5RAnCo7raoJ7spPnAG0vUMVgjKHCKNSfZP6Asim8mgNcmjglmx/hEeLFAGVl4KW/QtCfMQZTY3ps/DFhjhSLvz4B6/s3JUbmziTkp77PEiaJUF3Tpagt0vSo6QYLj0/QaUgMV3XLSzg0flx67EEiTD/cXIyQYUSpyjiTMznzLYBk80hrXqmz7hmcq9U+CTAioqAnP/zyGETl2N1TxNfJmsc2l3NvnUSC81VT0obDEB2bFZyhtXG5cVoBpNtsLHZ5KWJQbg0vQzv3QvqkcxykiyX88Utw== 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=YPmbr2CTVs8CdY+F0+fdiSG0bK2SC0pjIPt1Fblu9gc=; b=FZZVTXptVSfRSMw07hZqAvxt1TOmBnNRfkoEZ83RAOt+watGpM2mxgZ7DFYbDL/DbmyaFrGYBGY0lXenZEx8engpbAuNfoOn913eSQEKZ2J2XvNNYi7uwzweziU2LyixduaweexZcaaJG5I7ncP8pnGG7a7ZyRL/WPd9xyg1XSKpfJI6/M3Y7G6mHScMLChO/WGM1ZlhZ0msG9jdTtQqNjaZUZnGb826ABQTpIO+Um4vjPNYLqafTin1tcU7lhKKeNO2K28/4iJIS/UDUbqXcVFddVf3o343IXi+OhcBDgkGWSlxx0DSmwbzCZSt0B9JymEUmCsvMnVLdnflZt3Xlw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YPmbr2CTVs8CdY+F0+fdiSG0bK2SC0pjIPt1Fblu9gc=; b=Yd5ncC7lKghzHMcijOulnjtyasNzi1yiG/gyWYNPxG4cefq/otyFWJhjD7AGVb3VM6EOWlIb1cP3EdX6MVdnxn9yJ2XyzeQw57+BPsakv2UhqJPNxqnSOJFsCcwURFW78T4jMl9AV3cUBc60Z75LM+OoojpkxbSLAujTLD6x6hE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:39 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:39 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 34/96] cl8k: add hw.h Date: Tue, 24 May 2022 14:34:00 +0300 Message-Id: <20220524113502.1094459-35-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 99891eb9-15e8-485c-8999-08da3d79e01d X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ZS7AH6cVa65a4MscWO2vEQT8xsatIhbwUAvg8CH00utK/3BycGk7CGXPOM4EOt8JROds1qN/Zh/qA8sPBUXYH6alFEkc7DGOo+VOwLh2tjoMk7r7r0BPx7zL3R51F+ljgzrli1E3lcOlpLW+QrMOAOr2/Nl7AL7pNfuad1C7KGpinkElaWjpT6lfnIU1AynOeLVCb9PcJ6myvR0z5F0SGRlK1BxdMrSfqDdhdfJLzx1ALDe0HLOxay3VzOIFuIOIuTQ1MBnMpkwGuSPO9IdJd7rphCqMriptdS9T2JIt+cCaSlBM5xweoC3uqF+AAbGQ0xxPpbDiFSNJeAc+5HGe2jxv3ZolqKUgIPneggu2XaWoGuOLJT+sPMNFJmGdHpa18GYTkCrxTayWxDIi/vTa8DkHsbDCwWmkqmTeirZEHMabdHwaX70Nhi9BaYVFzI9ERMEwGrCSVfY9tpL6OvFO7vYZ8Xyllg4NZw4KJ/XBsQbyHiOL0wjTXt+whA3S3LHpSi2rZ+TntIt//Yu6AVGlgec9uPZ3WBa5pksjxNJeJqEkHaCrp2DLJNKSCQ3Wg45Prrpa7UoTsZVzwIGNajY9xQaiTsb1iT1RvP5vF95ps7S2J9k3ZMm+oh2q2LR/90Boor7f091x83z0w92SEvfUzMqnaKd/3qE4p9peduBNwRdEY4eSzD6mdDCQHf2mHQ1Eg7caPmCeGApqdUYoxKlS0OzPjnmRH9V6kWbMUyR2IrM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: l0TsvF6DJVPOI7I8UlO4rg+jal1XZZHwSecXH5vsInmC5f48emS2xhr7i96b4gB6zFQ8kawGi3ITFj3jt6RfsqpK6BmqWqS/2fQJNDg4241ioR+uJ1gwZmk5lN9Qnx6YfkTH/7V5Bcoa3PW42sOyXMH1gc+wZogk4zZL8NQ6xvLUJjW6MPicFtbFjMD7MHshAzDNnmaTTp3N1kc2QkxtjF0sa6RNOxXgNKCApjxarRwIEj/ywrkOQFiyJasbTBeNnGyWvyo20pr5PMhezMtkzG8MOh5LmRTUO2EQxJZqGszgcDhEipj4dI6yCjcFQ/VG3II8CW/QoLcsaw8AMsiLWkDKHUx2SshB4G7dp/liO2GAYM8wgxEQctytCHIuYRGsZ4VRcjrDGqeJXl+Yrkh3e+hCs+PamIL8ZLXboj3ywCd4oQHfCAvKZh8ddy0cH/Vw98j/YKRTneZ2zLYyXujK6QB/GMzABq3kjqDNhdA+GX0zVFm49Z8W0Rax+No98HNzbRkM76GSiBQ49lCq5Yzub+ldN5hrtuPruxTu5wfdx2QzMYCBl5VkxqWWffaDtnO9DaqS0qoXl1u4ngwOjN5gz4nwmwZROitkhLrddCkcjQp5aP2Zidy2OAFyTrA6cMUZk1WxG0fXL8m70P9kxDhmszkv1U+KOE/tCF+kwE1k3PDydi36ro676yO0CLUB2q1mp4jjw3mFGp40MGVFZE10BkXayPuJa6hc8SxJ6bjqnlDik0mloZVLETjJJKKQxjIaT7yUAc48R0S+9u4VPuYVPOCUlzcLupW5SMSIi6WMEg41Sf467liMGHtfsxC69xGWfiJi/KXX/40vpQy5UIFQ/wcMrhmv5Uhg8UeNwmvFPp+RV2fasGHSXqQhpE3jSOumx8c2Yr1ocKJMY2xozjRVjG85LwgtwDOHpaRcNnW4GpAQqjKWyil6B+O5FzsLWTvifztDIbfbFfHOi7CJ4I0Me/yW7azCLABaj9610fEM8GQ+kknxyUAmyU5n1463GfvZCOxWHfVyxhMP+UTeBIaV6/GBlODMRfe31DtN3fRMteD2oQTTQosWub8KsF/aVxp3R5xUzShKojQ+VG4jGgQkJ5MVgxeaPzdbrNRLbWeN9dGMTfJ9kF9iL+lNhad7ME3wRkLyfX7R/C2+mr+UB3KkX+jwmte+tR3Lx8gcIMfy29lHjpc7GEnbrdY2NFIAWbfvvC7l0SADMNgyXve17Th4ATG06aer1uVTOjz0LVUZxPP62hy2X5tqM7Esxvg/acLC/5GwXnEUWqFWTMW1BWMqnpPNnUT6BbbWWhzhxw2NgMEHJcFi35i51cNHXn0OhDQ8v+QocrVL/Bjen6NLjV8hs6c1NLP/sbi0yLa0LQ1jdeg7r4eV7Mseug+AEESDh6eMS3s4s+CJxHXSW9JxDloZgbL62j/dkvH7YLCPLOZCflBSKwsBFDYHEXGPGwfBOCRVwVhmHl0uIMBNN8CAohrEIj+eO0KvZlUg6IxlPDJQ6ABBrtSw/m89Wy8Ud80ldzS7qwK6MNjmKFtFhBjwN4WRGZ888iZjJjx7YrCx7zR7mBrayFhRcsypKMNlIFY0EKMDpJDkPhHs5WKe97fhszrfoDiZmF4C7r7IKlIlaIhDVXV3FiuZoSZ1Y3kZbzuYCj15clhgS+abWErGj0RJIPeXv9HcdscJZcCRCnjzZgpgy5gl3hWs+0EIzH6TJPfBpbuXepHl1DbCt5aIyfuUkO7U50L0ib5AQzLrLAVqPEzS8Uc= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 99891eb9-15e8-485c-8999-08da3d79e01d X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:08.8121 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: kv8MlRWW7vDK5R914OBNbsE4a20dZQUcRT8hyBrbFSe8vm5e/IP+YcDTF/XUcvSvU+xm1iCZ3c0WgRdEDFvCtQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/hw.h | 280 ++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/hw.h diff --git a/drivers/net/wireless/celeno/cl8k/hw.h b/drivers/net/wireless/celeno/cl8k/hw.h new file mode 100644 index 000000000000..c34a2bc0d990 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/hw.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_HW_H +#define CL_HW_H + +#include + +#include "traffic.h" +#include "temperature.h" +#include "dfs.h" +#include "calib.h" +#include "ipc_shared.h" +#include "fw.h" +#include "rates.h" +#include "def.h" +#include "tx.h" +#include "radio.h" +#include "mac80211.h" +#include "scan.h" +#include "rx.h" +#include "wrs.h" +#include "vns.h" +#include "sta.h" +#include "debug.h" +#include "chip.h" +#include "recovery.h" +#include "bf.h" +#include "power.h" +#include "phy.h" +#include "vif.h" +#include "tcv.h" +#include "sounding.h" +#include "version.h" + +#define cl_hw_get_iface_conf(cl_hw) atomic_read(&(cl_hw)->iface_conf) +#define cl_hw_set_iface_conf(cl_hw, value) atomic_set(&(cl_hw)->iface_conf, value) + +/* Structure used to store information regarding E2A msg buffers in the driver */ +struct cl_e2a_msg_elem { + struct cl_ipc_e2a_msg *msgbuf_ptr; + dma_addr_t dma_addr; +}; + +enum cl_iface_conf { + CL_IFCONF_AP, + CL_IFCONF_STA, + CL_IFCONF_REPEATER, + CL_IFCONF_MESH_AP, + CL_IFCONF_MESH_ONLY, + + CL_IFCONF_MAX +}; + +struct cl_hw_asserts_info { + /* Timestamp (jiffies) of the last CL_MIN_ASSERT_CNT hw assert. */ + unsigned long timestamp[CL_MIN_ASSERT_CNT]; + /* Hw assert index. */ + u8 index; + /* Indicate if hw_restart was schedule */ + u8 restart_sched; +}; + +struct cl_hw { + u8 idx; /* Global index (0-3) */ + u8 tcv_idx; /* Transceiver index (0-1) */ + u8 sx_idx; + struct cl_tcv_conf *conf; + struct cl_chip *chip; + struct ieee80211_hw *hw; + const struct cl_driver_ops *drv_ops; + struct cl_vif_db vif_db; + atomic_t iface_conf; + u32 num_ap_started; + u8 hw_mode; + enum cl_wireless_mode wireless_mode; + u8 tx_power_version; + struct cl_vif *mc_vif; + u8 bw; + u32 channel; + u32 primary_freq; + u32 center_freq; + enum nl80211_band nl_band; + u8 num_antennas; + u8 mask_num_antennas; + u8 first_ant; + u8 first_riu_chain; + u8 last_riu_chain; + u8 max_antennas; + struct cl_tx_db tx_db; + struct cl_sta_db cl_sta_db; + struct cl_ipc_e2a_irq ipc_e2a_irq; + struct cl_controller_reg controller_reg; + struct ieee80211_supported_band sband; + void (*ipc_host2xmac_trigger_set)(struct cl_chip *chip, u32 value); + unsigned long drv_flags; + unsigned long tx_disable_flags; + struct cl_ipc_host_env *ipc_env; + spinlock_t tx_lock_agg; + spinlock_t tx_lock_cfm_agg; + spinlock_t tx_lock_single; + spinlock_t tx_lock_bcmc; + struct mutex msg_tx_mutex; + wait_queue_head_t wait_queue; /* Synchronize driver<-->firmware message exchanges */ + unsigned long cfm_flags[MAX_CFM_FLAGS]; + void *msg_cfm_params[MM_MAX + DBG_MAX]; /* Array of pointers per received msg CFM */ + bool msg_background; + wait_queue_head_t fw_sync_wq; + wait_queue_head_t radio_wait_queue; + struct cl_rx_elem *rx_elems; + struct cl_e2a_msg_elem *e2a_msg_elems; + struct cl_dbg_elem *dbg_elems; + struct cl_radar_elem *radar_elems; + struct dma_pool *txdesc_pool; + struct dma_pool *dbg_pool; + struct dma_pool *e2a_msg_pool; + struct dma_pool *radar_pool; + struct cl_debug_info dbginfo; + struct cl_hw_asserts_info assert_info; + char fw_prefix; /* Single character for fw prefix - l/u/s */ + u8 fw_dst_kern_id; /* Firmware destination (LMAC/SMAC) */ + bool fw_active; /* Firmware is active */ + bool fw_send_start; /* Did driver already send a start request message to firmware? */ + struct cl_dbg_data dbg_data; + struct cl_tx_power_info tx_pow_info[MAX_EXT_CHANNELS][MAX_ANTENNAS]; + spinlock_t channel_info_lock; + struct cl_channel_info channel_info; + struct cl_phy_data_info phy_data_info; + u32 mask_hi; + u32 mask_low; + struct timer_list maintenance_slow_timer; + struct timer_list maintenance_fast_timer; + struct tasklet_struct tx_task; + struct list_head list_sched_q_agg; + struct list_head list_sched_q_single; + struct cl_req_agg_db req_agg_db[IPC_MAX_BA_SESSIONS]; + u8 req_agg_queues; + u8 used_agg_queues; + bool is_stop_context; + struct workqueue_struct *drv_workqueue; + struct cl_amsdu_rx_state amsdu_rx_state; + struct cl_tx_queues *tx_queues; + struct kmem_cache *sw_txhdr_cache; + struct kmem_cache *amsdu_txhdr_cache; + u32 radio_stats[CL_RADIO_ERRORS_MAX]; + struct cl_rx_path_info rx_info; + struct cl_prot_mode prot_mode; + struct cl_agg_cfm_queue agg_cfm_queues[IPC_MAX_BA_SESSIONS]; + struct cl_single_cfm_queue single_cfm_queues[MAX_SINGLE_QUEUES]; + struct cl_single_cfm_queue bcmc_cfm_queue; + atomic_t radio_lock; + struct cl_assoc_queue assoc_queue; + struct cl_wrs_db wrs_db; + struct cl_traffic_main traffic_db; + struct cl_power_db power_db; + struct cl_bf_db bf_db; + struct cl_edca_db edca_db; + struct cl_vns_db *vns_db; + struct cl_str_offload_env str_offload_env; + struct cl_dma_accessed fw_remote_rom; + struct cl_recovery_db recovery_db; + struct cl_radar_queue radar_queue; + struct tasklet_struct radar_tasklet; + struct cl_cached_fw cached_fw; + s8 rx_sensitivity[MAX_ANTENNAS]; + struct cl_cca_db cca_db; + struct cl_noise_db noise_db; + struct cl_temp_comp_db temp_comp_db; + struct cl_sounding_db sounding; +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + struct cl_dyn_mcast_rate dyn_mcast_rate; +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + struct cl_dyn_bcast_rate dyn_bcast_rate; +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + struct cl_dfs_db dfs_db; + struct cl_version_db version_db; + bool entry_fixed_rate; + unsigned long last_tbtt_irq; + u16 smallest_beacon_int; + u32 tbtt_cnt; + u8 mesh_tbtt_div; + struct tasklet_struct tx_mesh_bcn_task; + u32 fw_recovery_cntr; + u32 rx_filter; + ptrdiff_t mac_hw_regs_offset; + ptrdiff_t phy_regs_offset; + struct list_head head_amsdu_txhdr_pool; + struct list_head head_sw_txhdr_pool; + spinlock_t lock_sw_txhdr_pool; + struct sk_buff_head rx_remote_queue_mac; + struct sk_buff_head rx_skb_queue; + struct tasklet_struct rx_tasklet; + struct tasklet_struct rx_resched_tasklet; + u8 fem_mode; + struct cl_tx_packet_cntr tx_packet_cntr; + struct cl_cpu_cntr cpu_cntr; + struct cl_iq_dcoc_data_info iq_dcoc_data_info; + struct cl_power_table_info power_table_info; + struct ieee80211_sband_iftype_data iftype_data[3]; + bool motion_sense_dbg; + struct cl_power_truncate pwr_trunc; + struct mutex set_channel_mutex; + u8 radio_status; + u8 rf_crystal_mhz; + bool iq_cal_ready; + s8 rssi_simulate; + struct mac_address addresses[MAX_BSS_NUM]; + struct cl_rx_stats *rx_stats; /* RX statistics for production mode. */ + spinlock_t lock_stats; + u16 n_addresses; + u8 txamsdu_en; + bool reg_dbg; + s32 new_tx_power; + struct cl_rx_trigger_based_stats *tb_stats; + struct cl_rx_trigger_based_sta_stats *tb_sta_stats; + bool idle_async_set; + bool msg_calib_timeout; + struct cl_calib_work *calib_work; + struct cl_chan_scanner *scanner; + bool calib_runtime_needed; + u8 ht40_preffered_ch_type; + u8 sw_scan_in_progress; +}; + +void cl_hw_init(struct cl_chip *chip, struct cl_hw *cl_hw, u8 tcv_idx); +void cl_hw_deinit(struct cl_hw *cl_hw, u8 tcv_idx); +struct cl_hw *cl_hw_other_tcv(struct cl_hw *cl_hw); +bool cl_hw_is_tcv0(struct cl_hw *cl_hw); +bool cl_hw_is_tcv1(struct cl_hw *cl_hw); +bool cl_hw_is_first_tcv(struct cl_hw *cl_hw); +int cl_hw_set_antennas(struct cl_hw *cl_hw); +u8 cl_hw_ant_shift(struct cl_hw *cl_hw); +u8 cl_hw_ant_to_riu_chain(struct cl_hw *cl_hw, u8 ant); +u8 cl_hw_ant_mask_to_riu_chain_mask(struct cl_hw *cl_hw, u8 ant_mask); +bool cl_hw_is_prod_or_listener(struct cl_hw *cl_hw); +void cl_hw_assert_info_init(struct cl_hw *cl_hw); +void cl_hw_assert_print(struct cl_hw *cl_hw, struct cl_ipc_e2a_msg *msg); +void cl_hw_assert_check(struct cl_hw *cl_hw); + +static inline void cl_sta_lock_bh(struct cl_hw *cl_hw) +{ + read_lock_bh(&cl_hw->cl_sta_db.lock); +} + +static inline void cl_sta_unlock_bh(struct cl_hw *cl_hw) +{ + read_unlock_bh(&cl_hw->cl_sta_db.lock); +} + +static inline void cl_sta_lock(struct cl_hw *cl_hw) +{ + read_lock(&cl_hw->cl_sta_db.lock); +} + +static inline void cl_sta_unlock(struct cl_hw *cl_hw) +{ + read_unlock(&cl_hw->cl_sta_db.lock); +} + +/* FW communication opses */ +static inline int cl_drv_ops_msg_fw_send(struct cl_hw *cl_hw, + const void *msg_params, + bool background) +{ + if (cl_hw->drv_ops->msg_fw_send) + return cl_hw->drv_ops->msg_fw_send(cl_hw, msg_params, + background); + return 0; +} + +static inline void cl_drv_ops_pkt_fw_send(struct cl_hw *cl_hw, + struct cl_sw_txhdr *sw_txhdr, + struct cl_tx_queue *tx_queue) +{ + if (cl_hw->drv_ops->pkt_fw_send) + cl_hw->drv_ops->pkt_fw_send(cl_hw, sw_txhdr, tx_queue); +} + +#endif /* CL_HW_H */ From patchwork Tue May 24 11:34:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575973 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 D1003C433EF for ; Tue, 24 May 2022 11:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236840AbiEXLjP (ORCPT ); Tue, 24 May 2022 07:39:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236835AbiEXLjN (ORCPT ); Tue, 24 May 2022 07:39:13 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2049.outbound.protection.outlook.com [40.107.21.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47EFA84A19 for ; Tue, 24 May 2022 04:38:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=d+MPfer5Z63W1BBQLTq7piipz//mz5sU0ISMkeq8p2F2teHYnHmzAIvc9KjgkFbRbYaO5D8ab+A0RSXS9NifSwSdhe9ho/6jfueRqHlxRZuy9sCgIxxUqFOaiNAKdHlGS6Rlg1jtPlV2RBUN+t3Sarj5QsyXS8/fbHeZtfnvzqp/M2bi7cshW9PLaUvt6b8D5eaO6Nm7lGl7hp/pjkvb7fmTY4DcXcakEf74odIRsNq+l3zbIuWyymK0pys884ErTLzDBDE4oVF1PB8F8OMoAUqP7nQNEXA7lydXo90vdzZq9xJfdcpUy3AxFCezR9UePr1ZYsuDDk4hnoIM3yToBQ== 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=saLagVdEJcwvy0SK/qSNW2bOKZlh8ZsljFy6tjamgP0=; b=doSwuT/qmJv+KTe/ZdKqz5jJkX3dI1W0TUm1xzyoVvwG2UonbK/rvu3KZCKo2qj28d8Yu+541OD/FRaRVWna1HpwuHlJD8Pu2A3xj7HNT3nSeeysqjha9IxbtapPP6YI/wyCE+Scnv3lgtcgvh20WJ7l6wo3ZFyhmuhgGaLnbyzHhR86IoeDAZrVnkK+mY9J/FDHyRD+etPgHQu5HbSCvO/mRjMRRHshAGmmpQacLWH70HreKXm3dFqOkUsF5kqyapmA0JKXvjLVHnOzzbwa4d18GhkhEwwo0CcxihY1UM6MAo6JVO5IhpRQz1ROBLUYLo+U1Ib7ElI4eXsnNmWkfw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=saLagVdEJcwvy0SK/qSNW2bOKZlh8ZsljFy6tjamgP0=; b=po2DbkKsK7TZeuV8FJ845dC1xDwpG3W4/4lMTnl9D7dKkMa+XFSTB+fv/Z3SgCSYs4a+NVbBqctATJzIOfZHMrhLJvnSHsi/mnRnzRrwZ65r63Uo0RtlKJDz7LIMjYnMjOcY3YdhDlHIv7f6lZLn/JqwHcdV8qdFCMfdldjmS4U= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:38:39 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:39 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 35/96] cl8k: add ipc_shared.h Date: Tue, 24 May 2022 14:34:01 +0300 Message-Id: <20220524113502.1094459-36-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 13e586da-0947-451b-1f19-08da3d79e092 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: OBy8jZuRYnSplflL5c7eh7mLgCRearMJujpX5gFPP7K7nRn4cMVMH25aEnG9blURnQWjHWqBuhew/fbT2pY6HrFgRZAtSZKe6BfbzUaua9MUgLpdNRGEiDlTBEvCW7CljqW9ewLEs2LNzI/X4qA7PkdxNscaExgDeTHiJ1yLbpByw5cTlP48JhTNGN6IDKMevOPSzjb+pCcLcxcXp6SPxAaVRzAHeVLkPp6awb6FNaOPnfQCHh0/L4BN05lpaLTCGJ6Ki82tdOBGqjqzUboHvT5qQwdGxsAVjn3lYUMx2C1dwkBFpiCz2Yo0iKZ1Ksa+BX52yi0i6/P3kwOlUvzPOLCDJgJkB3+zmbSpszq50iN0KwdKhydf/OdBhmmE7FJXrVflXcHRJGFIe7ysWZlAWN2Y6Is3SXeOta/O4aJoFt5FFm8ZnXGZAxgLsVRMO4YHYY5vXq5U2pOqwiouR4i73o1/L24jbWhiMdLZVG6ocehCeog2IHIHWB9kbo6mrRBmQnOx9g9KknhmQadTp6I+X1X4xuQOHZcEYOY1zJk05tPZkgc7WT+1H3RuLGJR8WhoADBoIxORlS7oueo15bcw770bDzK58CevSiu6l/2v8nbxDlxfozmPAJ7u5qjyonTgyiO4E2F2cflyJSfQwHMudSpCq0N1BxtTgwdiWqAo52dKDf+swsigvYSeV8oWMDx/mrTh7Nw1DbbYQUeOkdCoIRj451I+nlkYJXLxnPu3IKA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(30864003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: BVRmYO4Zd7l7CIceZY/WUW2XP0udnOE8ZwWz1zcubo3R92o+mzSrGYsrQvgj+vwLte/4eQumHhHXyg/+oJi7z5Xu75mS7bJe75gDpLKuGxFHbLR4bNCgx6vJF0N2Fk6roDsA5+BgQ3eE/2QX7dEatZUwN3A7gNbgdCiUOLbR7hOYTL2smOueCcuwjgWb08TtUQTkRNDsZ6D6u/UnvBzsyYjZ8jpn2AS66RMspo+/E85kmeJW6KG/hLf4QW6CLBonN1jwAkksRVaa5AASdle4FdlNpLIyajlE27nz4tD5DlWqNngLRvHml2YbDI6xJ1RNV+HtHBGCnvSgS/SC8ryRlCtLuI+HiqerVUqtnBjinytr4kDk/1VCM5fWju5srb7FuqgshZxlRiMiL8N8yeUQRW1K2SqhZ9f7axiHnZUHR/XsrLM7nitHxnWXtwBc0MV7KsTDSh3lQYc2kszQN+1XmVcO/aoi7ThWWqw3S2FEqrV9Cyx7RtMie6jDbzZqfjUnpHqbmxWbofp1oL5TnL6tP6BaeKBt7LvgNlSRAdaqkBmRJhZMHgbB7c4vBLI1LbAYZsSMTOIbNb3kkkPyLCDIN2y2UHFqtZ6jX2DWOSbxX3v1LmsnJBDxZoNerxxLg/f9VUQ7OjKOBq7s7ggxHF4mAsRKC+Rt+aPB+ajcnP9zoEAZHr7l2zpDhemW5bECO9T/YqCOhsGFCWYXTPrV7kQ7pzJDtu8Ha5GHNTJcd2X+ibx7h1O2ipPGwQInF3C3OcRKQ8Q8rEbqOnc7XHgDkcI27WTzX4oUm1b6lp6ooR67j6j/YuYoVdO5q6hXACXtCEmb+NUHjbLhTqRm03E4i0r7B1Sn4nT2+L26c0sP2EoSIJyX1Qhf9qVV9yvw8RALnhjBm9JKihSsqvAN25oUYkXZkzzU1K3uDApCxj/xGaIrg3wALHh2qHgEX1Z0GMgxgUA6PT1EAxkj2ST83CjY6DdVYwL1MPblD+kLpq1FQjdnmXvVUzrY12G5CUPocAPiFskKyhigQhY0Ma+pDyYV88/+TttHiZXVUSEnTbRSKOLIgOgqOCYCIqogv1LsZwOM41fc3UbWGvfiS+Lo48t+iIBLLzotwD4zUbpSDuseQWgs9PB4jeTKAjM0G66CF6WC07ZzRiQCV92tmdz/oSXj0LVPuDt+jvd6iOJNhsmeZmbLN/G5AX1faNrRAnuu0c3ove7G4IcrjTj3fV4s9tXohquAJ44DPw/uRJH/hzgNNYY3PTGR+aXvVBP8KhJ1elpUMLai3gIqR5ajoG8jVd7gJc40qUWFlokrrxrFZ8UxcD4fmsHfjui/lJDsy1US6LnMEjKptMhMPUz48v/u7Cz5b5QOyvk2LBeJe0XMt25rNdWTwCqScjTYTUq0P0jmdOQyULPt0MVjWXYfoOo1JXK4Fv3yIO+pJAgNg8bZKjO1/SUWxPJg2+P3b96aSMbVKCny0e9iWGGUotqo6Kp9RFGW2jhDqZmhNmpsqmD3XXBQEW/BGRCN7M/Svvn9E7qpHuzkTe3vy1YtqHQuuvkum93+PDDv/jo0V4Cek49FeILUk46hso1AgdPNxez5uFPxMJ0JgfncFUML4tkC9mHrutmkDnUB13BCUKombBsDCzxuwDYVnyRkHKAKQUXG3i8zh//pfcDhy0YDC0ISawTeaFIpOlP2VVcHaMlAgcjZsdERSOmgf++NRbOcLz+WQwLK2l4O5MQcKJZDSOH1Wo6F4HaHrf7hYDj87oLRnXpfWl2n0dC1hr0= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 13e586da-0947-451b-1f19-08da3d79e092 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:09.9199 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: MfwSHfNVr4KotS46lL9op320U0Ea+KUq6vua7KdkdoSKdPeE0C0XN5HchxAsg8N4mMi5nrnoDQizv1JwI+XW8g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/ipc_shared.h | 1386 +++++++++++++++++ 1 file changed, 1386 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/ipc_shared.h diff --git a/drivers/net/wireless/celeno/cl8k/ipc_shared.h b/drivers/net/wireless/celeno/cl8k/ipc_shared.h new file mode 100644 index 000000000000..b8560bc632c7 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/ipc_shared.h @@ -0,0 +1,1386 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_IPC_SHARED_H +#define CL_IPC_SHARED_H + +#include + +#include "def.h" + +/** DOC: IPC - introduction + * + * IPC layer between the FW (XMAC -> LMAC, SMAC, UMAC) and the driver. Driver + * talks with lower layer via custom IPC messages and DMA. Basically, drv <-> + * fw messages flow consists of %cl_fw_msg, that contains info about direction, + * message id (which is enum field of %mm_msg_tag or %dbg_msg_tag) and payload + * itself. + * + * Messages may be synchronous (with the confirmation feedback) and + * asynchronous. The latter is typically being used as inidication of + * occurrence of some event. + * + * Driver LMAC/SMAC + * + + + * | AA_REQ | + * |-------------------->|...+ (Request) + * | AA_CFM | | Mandatory control messages + * |<--------------------|...+ (Confirmation) + * | | + * . BB_IND . + * |<--------------------|... Asynchronous indication + * + * Messages are using prelocated buffers and size limit of %IPC_RXBUF_SIZE. + * Each message may have verification pattern, that allows to verify the + * validity of payload. Most important TX/RX flow operations are tracked and + * are reflected by stats change (like &cl_rx_path_info structure). + */ + +/* + * Number of Host buffers available for Data Rx handling (through DMA) + * Must correspond to FW code definition, and must be power of 2. + */ +#define IPC_RXBUF_CNT_RXM 2048 +#define IPC_RXBUF_CNT_FW 128 + +/* Bucket debug */ +#define IPC_RXBUF_BUCKET_POW_SIZE 5 +#define IPC_RXBUF_BUCKET_SIZE BIT(IPC_RXBUF_BUCKET_POW_SIZE) /* 2 ^ 5 = 32 */ +#define IPC_RXBUF_NUM_BUCKETS_RXM (IPC_RXBUF_CNT_RXM / IPC_RXBUF_BUCKET_SIZE) +#define IPC_RXBUF_NUM_BUCKETS_FW (IPC_RXBUF_CNT_FW / IPC_RXBUF_BUCKET_SIZE) + +#define MU_MAX_STREAMS 8 +#define MU_MAX_SECONDARIES (MU_MAX_STREAMS - 1) + +#define CL_MU0_IDX 0 +#define CL_MU1_IDX 1 +#define CL_MU2_IDX 2 +#define CL_MU3_IDX 3 +#define CL_MU4_IDX 4 +#define CL_MU5_IDX 5 +#define CL_MU6_IDX 6 +#define CL_MU7_IDX 7 +#define CL_MU_IDX_MAX CL_MU7_IDX + +#define IPC_TX_QUEUE_CNT 5 + +#define IPC_MAX_BA_SESSIONS 128 + +#if IPC_MAX_BA_SESSIONS > CL_MAX_NUM_STA +#define IPC_MAX_TIM_TX_OR_RX_AGG_SIZE IPC_MAX_BA_SESSIONS +#else +#define IPC_MAX_TIM_TX_OR_RX_AGG_SIZE CL_MAX_NUM_STA +#endif + +#define IPC_QUEUE_IDX_DIFF_ARRAY_SIZE 6 + +#define IPC_TIM_AGG_SIZE (IPC_MAX_TIM_TX_OR_RX_AGG_SIZE * 2) + +#define IPC_TX_QUEUE_IDX_TO_COMMON_QUEUE_IDX(idx) ((idx) * 2) + +#define IPC_RX_QUEUE_IDX_TO_COMMON_QUEUE_IDX(idx) (((idx) * 2) + 1) + +#define CL_MAX_BA_PHYSICAL_QUEUE_CNT (AC_MAX + MU_MAX_SECONDARIES) +#define CE_AC_MAX (IPC_TX_QUEUE_CNT + MU_MAX_SECONDARIES) + +enum { + AGG_AC0_IDX = AC_BK, + AGG_AC1_IDX = AC_BE, + AGG_AC2_IDX = AC_VI, + AGG_AC3_IDX = AC_VO, + AGG_MU1_IDX, + AGG_MU2_IDX, + AGG_MU3_IDX, + AGG_MU4_IDX, + AGG_MU5_IDX, + AGG_MU6_IDX, + AGG_MU7_IDX, + AGG_IDX_MAX, +}; + +#define DBG_DUMP_BUFFER_SIZE (1024 * 40) + +#define IPC_TXDESC_CNT_SINGLE 16 +#define IPC_TXDESC_CNT_BCMC 16 + +/* Max count of Tx MSDU in A-MSDU */ +#define CL_AMSDU_TX_PAYLOAD_MAX 4 + +#define TXDESC_AGG_Q_SIZE_MAX 512 + +#define CL_MAX_AGG_IN_TXOP 20 + +/* Keep LMAC & SMAC debug agg stats arrays size aligned */ +#define DBG_STATS_MAX_AGG_SIZE (256 + 1) + +/* Must be power of 2 */ +#define IPC_CFM_CNT 4096 + +#define IPC_CFM_SIZE (IPC_CFM_CNT * sizeof(struct cl_ipc_cfm_msg)) + +/* Number of rates in Policy table */ +#define CL_RATE_CONTROL_STEPS 4 + +/* + * Stringified DRV/FW versions should be small enough to fit related ethtool + * descriptors size (32) + */ +#define CL_VERSION_STR_SIZE 32 + +#if (IPC_CFM_CNT & (IPC_CFM_CNT - 1)) +#error "IPC_CFM_CNT Not a power of 2" +#endif + +/* + * the calculation is conducted as follow: + * 1500 - max ethernet frame + * conversion of ETH to MSDU: + * 1500[eth max] - 12[hdr frame] + 14[msdu frame] + 8[llc snap] + 4[MSDU Padding] = 1514 + * MSDU + WLAN HDR = 1514[MSDU MAX] + 36[MAX WLAN HDR] = 1550 + * 2 bytes is being PADDED by SKB alloc for alignment. + * 18 byte encryption + * sizeof(struct hw_rxhdr) + */ +#define IPC_RXBUF_SIZE (1570 + sizeof(struct hw_rxhdr)) + +/* Number of available host buffers */ +#define IPC_RADAR_BUF_CNT 32 +#define IPC_E2A_MSG_BUF_CNT 128 +#define IPC_DBG_BUF_CNT 64 + +/* Length used in MSGs structures (size in 4-byte words) */ +#define IPC_A2E_MSG_BUF_SIZE 255 +#define IPC_E2A_MSG_PARAM_SIZE 63 + +/* Debug messages buffers size (in bytes) */ +#define IPC_DBG_PARAM_SIZE 256 + +/* Pattern indication for validity */ +#define IPC_RX_DMA_OVER_PATTERN 0xAAAAAA00 +#define IPC_E2A_MSG_VALID_PATTERN 0xADDEDE2A +#define IPC_DBG_VALID_PATTERN 0x000CACA0 +#define IPC_EXCEPTION_PATTERN 0xDEADDEAD + +#define HB_POOL_DMA_DESCS_NUM 2 + +/* Tensilica backtrace depth */ +#define IPC_BACKTRACT_DEPTH 5 + +/* Maximum length of the SW diag trace */ +#define DBG_SW_DIAG_MAX_LEN 1024 + +/* Maximum length of the error trace */ +#define DBG_ERROR_TRACE_SIZE 256 + +/* Number of MAC diagnostic port banks */ +#define DBG_DIAGS_MAC_MAX 48 + +/* Driver mem size used for THDs PTs & PBDs */ +#define DBG_THD_CHAINS_INFO_THD_CNT 5 +#define DBG_THD_CHAINS_INFO_PBD_CNT 9 +#define DBG_THD_CHAINS_INFO_PT_CNT 1 +#define DBG_THD_CHAINS_INFO_ARRAY_SIZE \ + ((DBG_THD_CHAINS_INFO_THD_CNT * sizeof(struct tx_hd)) + \ + (DBG_THD_CHAINS_INFO_PBD_CNT * sizeof(struct tx_pbd)) + \ + (DBG_THD_CHAINS_INFO_PT_CNT * sizeof(struct tx_policy_tbl))) + +#define DBG_CHAINS_INFO_ELEM_CNT 10 + +/* Txl chain info - per ac */ +#define DBG_TXL_FRAME_EXCH_TRACE_DEPTH 5 + +/* FW debug trace size */ +#define DBG_FW_TRACE_SIZE 30 +#define DBG_FW_TRACE_STR_MAX 20 + +/* Number of embedded logic analyzers */ +#define LA_CNT 1 + +/* Length of the configuration data of a logic analyzer */ +#define LA_CONF_LEN 102 + +/* Structure containing the configuration data of a logic analyzer */ +struct la_conf_tag { + u32 conf[LA_CONF_LEN]; +}; + +/* Size of a logic analyzer memory */ +#define LA_MEM_LEN (256 * 1024) + +/* Message structure for MSGs from Emb to App */ +struct cl_ipc_e2a_msg { + __le16 id; + __le16 dummy_dest_id; + __le16 dummy_src_id; + __le16 param_len; + u32 param[IPC_E2A_MSG_PARAM_SIZE]; + __le32 pattern; +}; + +enum rx_buf_type { + CL_RX_BUF_RXM, + CL_RX_BUF_FW, + CL_RX_BUF_MAX +}; + +/* + * Structs & function associated with HW & SW debug data + * The Debug information forwarded to host when an error occurs, and printed to stdout + * This data must be consistent with firmware, any new debug data should exist also in + * firmware side + */ + +struct tx_hd { + u32 upatterntx; + u32 nextfrmexseq_ptr; + u32 nextmpdudesc_ptr; + u32 first_pbd_ptr; + u32 datastartptr; + u32 dataendptr; + u32 frmlen; + u32 spacinginfo; + u32 phyctrlinfo1; + u32 policyentryaddr; + u32 bar_thd_desc_ptr; + u32 reserved1; + u32 macctrlinfo1; + u32 macctrlinfo2; + u32 statinfo; + u32 phyctrlinfo2; +}; + +struct tx_policy_tbl { + u32 upatterntx; + u32 phycntrlinfo1; + u32 phycntrlinfo2; + u32 maccntrlinfo1; + u32 maccntrlinfo2; + u32 ratecntrlinfo[CL_RATE_CONTROL_STEPS]; + u32 phycntrlinfo3; + u32 phycntrlinfo4; + u32 phycntrlinfo5; + u32 stationinfo; + u32 ratecntrlinfohe[CL_RATE_CONTROL_STEPS]; + u32 maccntrlinfo3; + u32 triggercommoninfo; + u32 triggerinforuallocationu0u3; + u32 triggerinforuallocationu4u7; + u32 triggerperuserinfo[MU_MAX_STREAMS]; +}; + +struct tx_pbd { + u32 upatterntx; + u32 next; + u32 datastartptr; + u32 dataendptr; + u32 bufctrlinfo; +}; + +enum cl_macfw_dbg_severity { + CL_MACFW_DBG_SEV_NONE, + CL_MACFW_DBG_SEV_ERROR, + CL_MACFW_DBG_SEV_WARNING, + CL_MACFW_DBG_SEV_INFO, + CL_MACFW_DBG_SEV_VERBOSE, + + CL_MACFW_DBG_SEV_MAX +}; + +struct phy_channel_info { + __le32 info1; + __le32 info2; +}; + +struct dbg_debug_info_tag { + u32 error_type; /* (0: recoverable, 1: fatal) */ + u32 hw_diag; + char error[DBG_ERROR_TRACE_SIZE]; + u32 sw_diag_len; + char sw_diag[DBG_SW_DIAG_MAX_LEN]; + struct phy_channel_info chan_info; + struct la_conf_tag la_conf[LA_CNT]; + u16 diags_mac[DBG_DIAGS_MAC_MAX]; +}; + +/* + * Defines, enums and structs below are used at TX statistics + * structure. + * Because of the TX statistics structure should be same at + * host and at firmware,the change of these parameters requires + * similar firmware changes + */ + +struct cl_txl_ba_statistics { + u32 total_cnt; + u32 total_rtx_cnt; + u16 total_ba_received; + u16 total_ba_not_received_cnt; + u16 total_lifetime_expired_cnt; + u16 total_rtx_limit_reached; + u16 total_packets_below_baw; + u16 total_packets_above_baw; + u16 total_ba_not_received_cnt_ps; + u16 total_cleard_ba; + u16 total_unexpected_ba; + u16 total_invalid_ba; + u16 total_ack_instead_ba; +}; + +struct cl_txl_single_statistics { + u32 total_cnt; + u32 total_rtx_cnt; + u16 total_lifetime_expired_cnt; + u16 total_rtx_limit_reached; + u16 total_rtx_limit_reached_ps; +}; + +enum { + CE_BACKOFF_25, + CE_BACKOFF_50, + CE_BACKOFF_100, + CE_BACKOFF_500, + CE_BACKOFF_1000, + CE_BACKOFF_5000, + CE_BACKOFF_10000, + CE_BACKOFF_20000, + CE_BACKOFF_20000_ABOVE, + CE_BACKOFF_MAX +}; + +struct cl_txl_backoff_statistics { + u32 chain_time; + u32 backoff_hist[CE_BACKOFF_MAX]; +}; + +struct cl_txl_tid_statistics { + u32 total_tid_desc_cnt; +}; + +/* Natt closed an aggregation due to one of the bellow reasons. */ +enum { + NATT_REASON_MAX_LEN = 0x1, + NATT_REASON_TXOP_LIMIT = 0x2, + NATT_REASON_MPDU_NUM = 0x4, + NATT_REASON_LAST_BIT = 0x8, + NATT_REASON_MAX +}; + +/* Tx BW */ +enum { + NATT_BW_20, + NATT_BW_40, + NATT_BW_80, + NATT_BW_160, + NATT_BW_MAX +}; + +struct cl_txl_natt_statistics { + u32 agg_close_reason[NATT_REASON_MAX]; + u32 chosen_frame_bw[NATT_BW_MAX]; + u32 operation_mode[8]; +}; + +enum { + AGG_IN_TXOP_CLOSE_REASON_NO_TXDESC, + AGG_IN_TXOP_CLOSE_REASON_TXOP_EXPIRED, + AGG_IN_TXOP_CLOSE_REASON_ACTIVE_DELBA, + AGG_IN_TXOP_CLOSE_REASON_MAX +}; + +struct amsdu_stat { + u16 packet_cnt_2; + u16 packet_cnt_3; + u16 packet_cnt_4; + u16 packet_cnt_5_or_more; +}; + +struct cl_txl_mu_statistics { + u16 chain_cnt; + u16 status_cnt; + u16 ba_received; + u16 ba_no_received; + u16 clear_ba; + u16 correct_ba; + u16 unexpected_ba; + u16 invalid_ba; +}; + +struct cl_txl_agg_statistics { + u16 agg_size_statistics[DBG_STATS_MAX_AGG_SIZE]; + u32 packet_failed_statistics[DBG_STATS_MAX_AGG_SIZE]; + u32 packet_passed_statistics[DBG_STATS_MAX_AGG_SIZE]; + u16 htp_agg_size_statistics[DBG_STATS_MAX_AGG_SIZE]; + u32 htp_packet_failed_statistics[DBG_STATS_MAX_AGG_SIZE]; + u32 htp_packet_passed_statistics[DBG_STATS_MAX_AGG_SIZE]; + u16 agg_in_txop_statistics[CL_MAX_AGG_IN_TXOP]; + u16 agg_in_txop_close_reason[AGG_IN_TXOP_CLOSE_REASON_MAX]; + u16 agg_in_txop_queue_switch; + u16 agg_in_txop_queue_switch_abort_bw; + struct amsdu_stat amsdu_stat[IPC_MAX_BA_SESSIONS]; + u16 mu_agg_size_statistics[MU_MAX_STREAMS][DBG_STATS_MAX_AGG_SIZE]; + struct cl_txl_mu_statistics mu_stats[MU_MAX_STREAMS]; +}; + +struct cl_txl_ac_statistics { + u32 total_q_switch_cnt; + u32 total_ac_desc_cnt; +}; + +struct cl_txl_underrun_statistics { + u16 length_cnt; + u16 pattern_cnt; + u16 flushed_frames_cnt; +}; + +struct cl_txl_rts_cts_statistics { + u32 fw_rts_cnt; + u32 fw_rts_retry_cnt; + u32 fw_rts_retry_limit_cnt; + u32 hw_rts_cnt; + u32 fw_cts_cnt; + u32 hw_cts_cnt; +}; + +struct cl_txl_backoff_params { + u32 singelton_total[AC_MAX]; + u32 singelton_cnt[AC_MAX]; + u32 agg_total[AC_MAX]; + u32 agg_cnt[AC_MAX]; +}; + +struct cl_txl_htp_statistics { + u32 total_cnt[TID_MAX]; + u32 need_response; + u32 tb_response_required; + u32 ac_not_found; + u32 end_of_packet_int; + u32 tb_bw_decision; + u32 tb_ba_thd_removed; + u32 tb_ac_unchain; + u32 tb_htp_unchain; + u32 tb_dummy_htp_tx; + u32 tb_dummy_no_tx; + u32 msta_ba_received; + u32 msta_ba_aid_not_found; + u32 uora_cnt_trigger_frame_tx; + u32 uora_cnt_trigger_frame_rx; + u32 uora_cnt_probe_req_tx; + u32 uora_cnt_probe_req_rx; +}; + +struct cl_txl_vns_statistics { + u32 off_he; + u32 off_ht_vht; + u32 off_ofdm; + u32 off_cck; + u32 on_he; + u32 on_ht_vht; + u32 on_ofdm; + u32 on_cck; +}; + +struct cl_txl_fec_statistics { + u32 ldpc; + u32 bcc; +}; + +struct cl_txl_mu_desision_statistics { + u32 num_sta_in_mu_group[MU_MAX_STREAMS]; + u32 mu_tx_active; + u32 prim_not_in_mu_group; + u32 prim_rate_invalid; + u32 other_reason; + u32 total_num_su; + u32 is_2nd_rate_invalid; + u32 is_2nd_awake; + u32 is_2nd_enouhg_data; +}; + +struct cl_txl_statistics { + u32 type; /* This field should be first in the struct */ + u32 recovery_count; + u32 tx_obtain_bw_fail_cnt; + struct cl_txl_single_statistics single[IPC_TX_QUEUE_CNT]; + struct cl_txl_ba_statistics ba[IPC_MAX_BA_SESSIONS]; + struct cl_txl_backoff_statistics backoff_stats[AC_MAX]; + struct cl_txl_natt_statistics natt; + struct cl_txl_tid_statistics tid[TID_MAX]; + struct cl_txl_agg_statistics agg; + struct cl_txl_ac_statistics ac[CE_AC_MAX]; + struct cl_txl_underrun_statistics underrun; + struct cl_txl_rts_cts_statistics rts_cts; + struct cl_txl_backoff_params backoff_params; + struct cl_txl_htp_statistics htp; + struct cl_txl_vns_statistics vns; + struct cl_txl_fec_statistics fec; + struct cl_txl_mu_desision_statistics mu_desision; +}; + +/* Flushed beacon list options */ +enum { + BCN_FLUSH_PENDING, + BCN_FLUSH_DOWNLOADING, + BCN_FLUSH_TRANSMITTING, + BCN_FLUSH_MAX, +}; + +struct bcn_backup_stats { + u32 bcn_backup_used_cnt; + u32 bcn_backup_tx_cnt; + u32 bcn_backup_flushed_cnt; + u32 bcn_backup_used_in_arow_cnt; + u32 bcn_backup_max_used_in_arow_cnt; +}; + +struct beacon_timing { + /* Time measurements between beacons */ + u32 last_bcn_start_time; + u32 max_time_from_last_bcn; + u32 min_time_from_last_bcn; + u32 total_bcn_time; + /* Time measurements until beacon chained */ + u32 imp_tbtt_start_time; + u32 bcn_chain_total_time; + u32 bcn_chain_max_time; + u32 bcn_chain_min_time; + /* Time measurements until received beacon from host */ + u32 bcn_last_request_time; + u32 max_bcn_time_until_get_beacon_from_driver_in_tbtt; + u32 bcn_last_req_rec_time; + /* Time measurements of bcn from pending to chain */ + u32 bcn_push_pending_start_time; + u32 bcn_pending_2_chain_max_time; +}; + +struct beacon_counters { + u32 bcn_time_from_driver_not_in_threshold_cnt; + u32 nof_time_intervals_between_beacons; + u32 total_cnt; + u32 bcn_chain_total_cnt; + u32 ce_txl_flushed_beacons[BCN_FLUSH_MAX]; + u32 pending2chain_not_in_threshold_cnt; + u32 total_beacons_received_from_driver; +}; + +struct cl_bcn_statistics { + u32 type; /* This field should be first in the struct */ + struct beacon_counters beacon_counters; + struct beacon_timing beacon_timing; + struct bcn_backup_stats bcn_backup_stats; +}; + +struct cl_queue_idx_dif_stats { + u32 type; /* This field should be first in the struct */ + u32 diff_array_count[IPC_QUEUE_IDX_DIFF_ARRAY_SIZE]; + u32 last_diff; + u32 wr_idx; + u32 rd_idx; +}; + +enum agg_tx_rate_drop_reason { + AGG_TX_RATE_DROP_MAX_BA_NOT_RECEIVED_REACHED, + AGG_TX_RATE_DROP_MAX_BA_PER_REACHED, + AGG_TX_RATE_DROP_MAX_RETRY_REACHED, + AGG_TX_RATE_DROP_MAX, +}; + +struct cl_rate_drop_statistics { + u32 type; + u32 drop_reason[AGG_TX_RATE_DROP_MAX]; +}; + +#define BF_DB_MAX 16 + +enum bfr_rx_err { + BFR_RX_ERR_BW_MISMATCH, + BFR_RX_ERR_NSS_MISMATCH, + BFR_RX_ERR_SOUNDING_CHBW, + BFR_RX_ERR_TOKEN_MISMATCH, + BFR_RX_ERR_NDP_DROP, + BFR_SEGMENTED_DROP, + BFR_RX_ERR_MISS_ACK, + BFR_RX_ERR_RESOURCE_NA, + BFR_RX_ERR_MAX +}; + +enum TX_BF_DATA_STAT { + TX_BF_DATA_OK = 0, + TX_BF_DATA_BUFFERED_RESOURCE_ERR, + TX_BF_DATA_RELEASED_RESOURCE_ERR, + TX_BF_DATA_BUFFERED_PS_STA, + TX_BF_DATA_RELEASED_PS_STA, + TX_BF_DATA_ERR_BFR_MISS, + TX_BF_DATA_ERR_BFR_OUTDATED, + TX_BF_DATA_ERR_MISMATCH_BW, + TX_BF_DATA_ERR_MISMATCH_NSS, + TX_BF_DATA_ERR_MAX +}; + +struct bf_ctrl_dbg { + u16 ndp_cnt; + u16 bfp_cnt; + u16 su_bfr_cnt; + u16 mu_bfr_cnt; + u16 bf_invalid_cnt[BFR_RX_ERR_MAX]; + u16 tx_bf_data_err[TX_BF_DATA_ERR_MAX]; +}; + +struct bf_stats_database { + bool is_active_list; + struct bf_ctrl_dbg dbg; + u8 sta_idx; + u16 active_dsp_idx; + u16 passive_dsp_idx; +}; + +struct cl_bf_statistics { + u32 type; + bool print_active_free_list; + struct bf_stats_database stats_data[BF_DB_MAX]; +}; + +enum amsdu_deaggregation_err { + AMSDU_DEAGGREGATION_ERR_MAX_MSDU_REACH, + AMSDU_DEAGGREGATION_ERR_MSDU_GT_AMSDU_LEN, + AMSDU_DEAGGREGATION_ERR_MSDU_LEN, + AMSDU_ENCRYPTION_KEY_GET_ERR, + + AMSDU_DEAGGREGATION_ERR_MAX +}; + +enum emb_ll1_handled_frm_type { + BA_FRM_TYPE, + NDPA_FRM_TYPE, + NDP_FRM_TYPE, + ACTION_NO_ACK_FRM_TYPE, + + MAX_HANDLED_FRM_TYPE +}; + +enum rhd_decr_idx { + RHD_DECR_UNENC_IDX, + RHD_DECR_ICVFAIL_IDX, + RHD_DECR_CCMPFAIL_IDX, + RHD_DECR_AMSDUDISCARD_IDX, + RHD_DECR_NULLKEY_IDX, + RHD_DECR_IDX_MAX +}; + +#define RX_CLASSIFICATION_MAX 6 +#define FREQ_OFFSET_TABLE_IDX_MAX 8 /* Must be a power of 2 */ +#define RX_MAX_MSDU_IN_SINGLE_AMSDU 16 + +struct cl_rxl_statistics { + u32 type; /* This field should be first in the struct */ + u32 rx_imp_bf_counter[MU_UL_MAX]; + u32 rx_imp_bf_int_counter[MU_UL_MAX]; + u32 rx_class_counter[MU_UL_MAX][RX_CLASSIFICATION_MAX]; + u32 rx_class_int_counter[MU_UL_MAX]; + u32 counter_timer_trigger_ll1[MU_UL_MAX]; + u32 counter_timer_trigger_ll2[MU_UL_MAX]; + u32 total_rx_packets[MU_UL_MAX]; + u32 total_agg_packets[MU_UL_MAX]; + u32 rx_fifo_overflow_err_cnt[MU_UL_MAX]; + u32 rx_dma_discard_cnt; + u32 host_rxelem_not_ready_cnt; + u32 msdu_host_rxelem_not_ready_cnt; + u32 dma_rx_pool_not_ready_cnt; + u32 rx_pckt_exceed_max_len_cnt[MU_UL_MAX]; + u32 rx_pckt_bad_ba_statinfo_cnt[MU_UL_MAX]; + u32 nav_value[MU_UL_MAX]; + u16 max_mpdu_data_len[MU_UL_MAX]; + u8 rhd_ll2_max_cnt[MU_UL_MAX]; /* Rhd first list */ + u8 rhd_ll1_max_cnt[MU_UL_MAX]; /* Rhd second list */ + u8 cca_busy_percent; + u8 rx_mine_busy_percent; + u8 tx_mine_busy_percent; + u8 sample_cnt; + /* Emb handled frames */ + u32 emb_ll1_handled_frame_counter[MU_UL_MAX][MAX_HANDLED_FRM_TYPE]; + u32 rxm_stats_overflow[MU_UL_MAX]; + /* RX AMSDU statistics counters */ + u32 stats_tot_rx_amsdu_cnt[MU_UL_MAX]; + u32 stats_rx_amsdu_cnt[MU_UL_MAX][RX_MAX_MSDU_IN_SINGLE_AMSDU]; + u32 stats_rx_amsdu_err[MU_UL_MAX][AMSDU_DEAGGREGATION_ERR_MAX]; + u32 stats_rx_format[FORMATMOD_MAX]; + /* RX decryption error */ + u32 decrypt_err[RHD_DECR_IDX_MAX]; + u32 rx_incorrect_format_mode[MU_UL_MAX]; + u32 fcs_error_counter[MU_UL_MAX]; + u32 phy_error_counter[MU_UL_MAX]; + u32 ampdu_received_counter[MU_UL_MAX]; + u32 delimiter_error_counter[MU_UL_MAX]; + u32 ampdu_incorrect_received_counter[MU_UL_MAX]; + u32 correct_received_mpdu[MU_UL_MAX]; + u32 incorrect_received_mpdu[MU_UL_MAX]; + u32 discarded_mpdu[MU_UL_MAX]; + u32 incorrect_delimiter[MU_UL_MAX]; + u32 rxm_mpdu_cnt[MU_UL_MAX]; + u32 rxm_rule0_match[MU_UL_MAX]; + u32 rxm_rule1_match[MU_UL_MAX]; + u32 rxm_rule2_match[MU_UL_MAX]; + u32 rxm_rule3_match[MU_UL_MAX]; + u32 rxm_rule4_match[MU_UL_MAX]; + u32 rxm_rule5_match[MU_UL_MAX]; + u32 rxm_rule6_match[MU_UL_MAX]; + u32 rxm_default_rule_match[MU_UL_MAX]; + u32 rxm_amsdu_1[MU_UL_MAX]; + u32 rxm_amsdu_2[MU_UL_MAX]; + u32 rxm_amsdu_3[MU_UL_MAX]; + u32 rxm_amsdu_4[MU_UL_MAX]; + u32 rxm_amsdu_5_15[MU_UL_MAX]; + u32 rxm_amsdu_16_or_more[MU_UL_MAX]; + u32 frequency_offset[FREQ_OFFSET_TABLE_IDX_MAX]; + u32 frequency_offset_idx; + u32 rts_bar_cnt[MU_UL_MAX]; +}; + +enum trigger_flow_single_trigger_type { + TRIGGER_FLOW_BASIC_TRIGGER_TYPE, + TRIGGER_FLOW_BSRP_TYPE, + TRIGGER_FLOW_BFRP_TYPE, + TRIGGER_FLOW_MAX +}; + +struct cl_trigger_flow_statistics { + u32 type; /* This field should be first in the struct */ + u32 single_trigger_sent[TRIGGER_FLOW_MAX][AC_MAX]; + u32 htp_rx_failure[AC_MAX]; + u32 trigger_based_mpdu[MU_UL_MAX]; +}; + +#define DYN_CAL_DEBUG_NUM_ITER 3 + +struct dyn_cal_debug_info_t { + u16 calib_num; + u8 curr_config; + union { + struct { + u8 iter_num; + u32 measured_val; + }; + struct { + u8 min_config; + u32 dyn_cal_min_val; + u32 dyn_cal_max_val; + u8 max_config; + }; + }; + + u8 new_config; +}; + +struct cl_dyn_calib_statistics { + u32 type; /* This field should be first in the struct */ + u8 is_multi_client_mode; + u8 default_dyn_cal_val; + u8 dyn_cal_debug_info_ix; + u16 dyn_cal_process_cnt; + u16 mac_phy_sync_err_cnt; + struct dyn_cal_debug_info_t dyn_cal_debug_info[DYN_CAL_DEBUG_NUM_ITER]; +}; + +/* End of parameters that require host changes */ + +/* Structure containing the parameters for assert prints DBG_PRINT_IND message. */ +struct dbg_print_ind { + __le16 file_id; + __le16 line; + __le16 has_param; + u8 err_no_dump; + u8 reserved; + __le32 param; +}; + +/* 4 ACs + BCN + HTP + current THD */ +#define MACHW_THD_REGS_CNT (IPC_TX_QUEUE_CNT + 2) + +/* Enumeration of MAC-HW registers (debug dump at recovery event) */ +enum { + HAL_MACHW_AGGR_STATUS, + HAL_MACHW_DEBUG_HWSM_1, + HAL_MACHW_DEBUG_HWSM_2, + HAL_MACHW_DEBUG_HWSM_3, + HAL_MACHW_DMA_STATUS_1, + HAL_MACHW_DMA_STATUS_2, + HAL_MACHW_DMA_STATUS_3, + HAL_MACHW_DMA_STATUS_4, + HAL_MACHW_RX_HEADER_H_PTR, + HAL_MACHW_RX_PAYLOAD_H_PTR, + HAL_MACHW_DEBUG_BCN_S_PTR, + HAL_MACHW_DEBUG_AC0_S_PTR, + HAL_MACHW_DEBUG_AC1_S_PTR, + HAL_MACHW_DEBUG_AC2_S_PTR, + HAL_MACHW_DEBUG_AC3_S_PTR, + HAL_MACHW_DEBUG_HTP_S_PTR, + HAL_MACHW_DEBUG_TX_C_PTR, + HAL_MACHW_DEBUG_RX_HDR_C_PTR, + HAL_MACHW_DEBUG_RX_PAY_C_PTR, + HAL_MACHW_MU0_TX_POWER_LEVEL_DELTA_1, + HAL_MACHW_MU0_TX_POWER_LEVEL_DELTA_2, + HAL_MACHW_POWER_BW_CALIB_FACTOR, + HAL_MACHW_TX_POWER_ANTENNA_FACTOR_1_ADDR, + HAL_MACHW_TX_POWER_ANTENNA_FACTOR_2_ADDR, + /* Keep this entry last */ + HAL_MACHW_REG_NUM +}; + +#define HAL_MACHW_FSM_REG_NUM ((HAL_MACHW_DEBUG_HWSM_3 - HAL_MACHW_AGGR_STATUS) + 1) + +enum { + MPU_COMMON_FORMAT, + MPU_COMMON_FIELD_CTRL, + MPU_COMMON_LEGACY_INFO, + MPU_COMMON_COMMON_CFG_1, + MPU_COMMON_COMMON_CFG_2, + MPU_COMMON_COMMON_CFG_3, + MPU_COMMON_HE_CFG_1, + MPU_COMMON_HE_CFG_2, + MPU_COMMON_INT_STAT_RAW, + RIU_CCAGENSTAT, + PHY_HW_DBG_REGS_CNT +}; + +/* Error trace CE_AC info */ +struct dbg_ac_info { + u8 chk_state; + u8 tx_path_state; + u8 physical_queue_idx; + u16 active_session; + u32 last_frame_exch_ptr; +}; + +/* Error trace txdesc lists info */ +struct dbg_txlist_info { + u8 curr_session_idx; + u8 next_session_idx; + u16 pending_cnt; + u16 download_cnt; + u16 transmit_cnt; + u16 wait_for_ba_cnt; + u16 next_pending_cnt; +}; + +/* Txl chain info */ +struct dbg_txl_chain_info { + u32 count; + u32 frm_type; + u32 first_thd_ptr; + u32 last_thd_ptr; + u32 prev_thd_ptr; + u32 req_phy_flags; + u8 reqbw; + u8 ce_txq_idx; + u16 mpdu_count; + u8 chbw; + u32 rate_ctrl_info; + u32 rate_ctrl_info_he; + u32 txstatus; + u32 length; + u32 tx_time; +}; + +struct dbg_txl_ac_chain_trace { + struct dbg_txl_chain_info data[DBG_TXL_FRAME_EXCH_TRACE_DEPTH]; + u32 count; + u8 next_chain_index; + u8 next_done_index; + u8 delta; +}; + +struct dbg_fw_trace { + u32 string_ptr; + u32 var_1; + u32 var_2; + u32 var_3; + u32 var_4; + u32 var_5; + u32 var_6; + /* + * This field is used only for driver pring dump file. + * collect string char is done at error dump collect data function. + */ + char string_char[DBG_FW_TRACE_STR_MAX]; +}; + +/* Error trace MAC-FW info */ +struct dbg_fw_info { + struct dbg_ac_info ac_info[CE_AC_MAX]; + struct dbg_txlist_info txlist_info_singles[IPC_TX_QUEUE_CNT]; + struct dbg_txlist_info txlist_info_agg[AGG_IDX_MAX]; + struct dbg_txl_ac_chain_trace txl_ac_chain_trace[CE_AC_MAX]; + struct dbg_fw_trace fw_trace[DBG_FW_TRACE_SIZE]; + u32 fw_trace_idx; +}; + +/* TXM regs */ +struct dbg_txm_regs { + u8 hw_state; + u8 fw_state; + u8 spx_state; + u8 free_buf_state; + u8 mpdu_cnt; + u8 lli_cnt; + u8 lli_done_reason; + u8 lli_done_mpdu_num; + u16 active_bytes; + u16 prefetch_bytes; + u32 last_thd_done_addr; + u16 last_thd_done_mpdu_num; + u16 underrun_cnt; +}; + +/* Error trace HW registers */ +struct dbg_hw_reg_info { + u32 mac_hw_reg[HAL_MACHW_REG_NUM]; + u32 mac_hw_sec_fsm[CL_MU_IDX_MAX][HAL_MACHW_FSM_REG_NUM]; + u32 phy_mpu_hw_reg[PHY_HW_DBG_REGS_CNT]; + struct dbg_txm_regs txm_regs[AGG_IDX_MAX]; +}; + +struct dbg_meta_data { + __le32 lmac_req_buf_size; + u8 physical_queue_cnt; + u8 agg_index_max; + u8 ce_ac_max; + u8 mu_user_max; + u8 txl_exch_trace_depth; + __le16 mac_hw_regs_max; + __le16 phy_hw_regs_max; + __le16 thd_chains_data_size; + u8 chains_info_elem_cnt; +}; + +struct dbg_agg_thds_addr { + u32 rts_cts_thd_addr; + u32 athd_addr; + u32 tf_thd_addr; + u32 bar_thd_addr; + u32 policy_table_addr; +}; + +struct dbg_agg_thd_info { + struct tx_hd rts_cts_thd; + struct tx_hd athd; + struct tx_hd tf_thd; + struct tx_hd bar_thd; + struct tx_policy_tbl policy_table; +}; + +struct dbg_machw_regs_thd_info { + struct tx_hd thd[MACHW_THD_REGS_CNT]; +}; + +struct dbg_thd_chains_info { + u8 type_array[DBG_CHAINS_INFO_ELEM_CNT]; + u32 elem_address[DBG_CHAINS_INFO_ELEM_CNT]; +}; + +struct dbg_thd_chains_data { + u8 data[DBG_THD_CHAINS_INFO_ARRAY_SIZE]; +}; + +/* Error trace debug structure. common to fw & drv */ +struct dbg_error_trace_info_common { + struct dbg_print_ind error_info; + struct dbg_meta_data dbg_metadata; + struct dbg_hw_reg_info hw_info; + struct dbg_fw_info fw_info; + struct dbg_agg_thds_addr agg_thds_addr[AGG_IDX_MAX]; +}; + +/* Dbg error info driver side */ +struct dbg_error_trace_info_drv { + struct dbg_error_trace_info_common common_info; + struct dbg_agg_thd_info agg_thd_info[AGG_IDX_MAX]; + struct dbg_machw_regs_thd_info machw_thd_info; + struct dbg_thd_chains_info thd_chains_info[CE_AC_MAX]; + struct dbg_thd_chains_data thd_chains_data[CE_AC_MAX]; +}; + +/* + * This is the main debug struct, the kernel allocate the needed spaces using kmalloc(). + * the firmware holds a pointer to this struct. + */ +struct dbg_dump_info { + u32 dbg_info; /* Should be first member in the struct */ + /* Dump data transferred to host */ + struct dbg_debug_info_tag general_data; + struct dbg_error_trace_info_drv fw_dump; + u8 la_mem[LA_CNT][LA_MEM_LEN]; +}; + +struct dbg_info { + union { + u32 type; + struct cl_txl_statistics tx_stats; + struct cl_bcn_statistics bcn_stats; + struct cl_rxl_statistics rx_stats; + struct cl_dyn_calib_statistics dyn_calib_stats; + struct cl_rate_drop_statistics rate_drop_stats; + struct cl_bf_statistics bf_stats; + struct cl_trigger_flow_statistics trigger_flow_stats; + struct cl_queue_idx_dif_stats txdesc_idx_diff_stats; + struct dbg_dump_info dump; + } u; +}; + +/* Structure of a list element header */ +struct co_list_hdr { + __le32 next; +}; + +/* ETH2WLAN and NATT common parameters field (e2w_natt_param) struct definition: */ +struct cl_e2w_natt_param { +#ifdef __LITTLE_ENDIAN_BITFIELD + u32 valid : 1, /* [0] */ + ampdu : 1, /* [1] */ + last_mpdu : 1, /* [2] */ + lc_snap : 1, /* [3] */ + vlan : 1, /* [4] */ + amsdu : 1, /* [5] */ + e2w_band_id : 1, /* [6] */ + use_local_addr : 1, /* [7] */ + hdr_conv_enable : 1, /* [8] */ + sta_index : 7, /* [9:15] */ + packet_length : 15, /* [30:16] */ + e2w_int_enable : 1; /* [31] */ +#else /* __BIG_ENDIAN_BITFIELD */ + u32 e2w_int_enable : 1, /* [0] */ + packet_length : 15, /* [15:1] */ + sta_index : 7, /* [22:16] */ + hdr_conv_enable : 1, /* [23] */ + use_local_addr : 1, /* [24] */ + e2w_band_id : 1, /* [25] */ + amsdu : 1, /* [26] */ + vlan : 1, /* [27] */ + llc_snap : 1, /* [28] */ + last_mpdu : 1, /* [29] */ + ampdu : 1, /* [30] */ + valid : 1; /* [31] */ +#endif +}; + +#define CL_CCMP_GCMP_PN_SIZE 6 + +struct cl_e2w_txhdr_param { + __le16 frame_ctrl; + __le16 seq_ctrl; + __le32 ht_ctrl; + u8 encrypt_pn[CL_CCMP_GCMP_PN_SIZE]; + __le16 qos_ctrl; +}; + +/* Bit 16 Has different usage for single (valid sta - set by host) or agg (tx done - set by HW) */ +struct cl_e2w_result { +#ifdef __LITTLE_ENDIAN_BITFIELD + u32 backup_bcn : 1, /* [0] */ + dont_chain : 1, /* [1] */ + is_flush_needed : 1, /* [2] */ + is_internal : 1, /* [3] */ + which_descriptor : 2, /* [5:4] */ + is_first_in_AMPDU : 1, /* [6] */ + is_ext_buff : 1, /* [7] */ + is_txinject : 1, /* [8] */ + is_vns : 1, /* [9] */ + single_type : 2, /* [11:10] */ + tid : 4, /* [15:12] */ + single_valid_sta__agg_e2w_tx_done : 1, /* [16] */ + msdu_length : 13, /* [29:17] */ + bcmc : 1, /* [30] */ + sw_padding : 1; /* [31] */ +#else /* __BIG_ENDIAN_BITFIELD */ + u32 sw_padding : 1, /* [0] */ + bcmc : 1, /* [1] */ + msdu_length : 13, /* [14:2] */ + single_valid_sta__agg_e2w_tx_done : 1, /* [15] */ + tid : 4, /* [19:16] */ + single_type : 2, /* [21:20] */ + is_vns : 1, /* [22] */ + is_txinject : 1, /* [23] */ + is_ext_buff : 1, /* [24] */ + is_first_in_AMPDU : 1, /* [25] */ + which_descriptor : 2, /* [27:26] */ + is_internal : 1, /* [28] */ + is_flush_needed : 1, /* [29] */ + dont_chain : 1, /* [30] */ + backup_bcn : 1; /* [31] */ +#endif +}; + +struct tx_host_info { +#ifdef __LITTLE_ENDIAN_BITFIELD + u32 packet_cnt : 4, /* [3:0] */ + host_padding : 8, /* [11:4] */ + last_MSDU_LLI_INT_enable : 1, /* [12] */ + is_eth_802_3 : 1, /* [13] */ + is_protected : 1, /* [14] */ + vif_index : 4, /* [18:15] */ + rate_ctrl_entry : 3, /* [21:19] */ + expected_ack : 1, /* [22] */ + is_bcn : 1, /* [23] */ + hw_key_idx : 8; /* [31:24] */ +#else /* __BIG_ENDIAN_BITFIELD */ + u32 hw_key_idx : 8, /* [7:0] */ + is_bcn : 1, /* [8] */ + expected_ack : 1, /* [9] */ + rate_ctrl_entry : 3, /* [12:10] */ + vif_index : 4, /* [16:13] */ + is_protected : 1, /* [17] */ + is_eth_802_3 : 1, /* [18] */ + last_MSDU_LLI_INT_enable : 1, /* [19] */ + host_padding : 8, /* [27:20] */ + packet_cnt : 4; /* [31:28] */ +#endif +}; + +struct lmacapi { + __le32 packet_addr[CL_AMSDU_TX_PAYLOAD_MAX]; + __le16 packet_len[CL_AMSDU_TX_PAYLOAD_MAX]; + __le16 push_timestamp; /* Milisec */ +}; + +struct txdesc { + /* Pointer to the next element in the queue */ + struct co_list_hdr list_hdr; + /* E2w txhdr parameters */ + struct cl_e2w_txhdr_param e2w_txhdr_param __aligned(4); + /* Celeno flags field */ + struct tx_host_info host_info __aligned(4); + /* Common parameters for ETH2WLAN and NATT hardware modules */ + struct cl_e2w_natt_param e2w_natt_param; + /* ETH2WLAN status and NATT calculation results */ + struct cl_e2w_result e2w_result; + /* Information provided by UMAC to LMAC */ + struct lmacapi umacdesc; +}; + +/* + * Comes from ipc_dma.h + * Element in the pool of TX DMA bridge descriptors. + * PAY ATTENTION - Avoid Changing/adding pointers to that struct, + * or any shared-memory-related-structs !!! + * Since in 64Bit platforms (Where pointers are 64Bit) such pointers + * might change alignments in shared-memory-related-structs of FW and DRV. + */ +struct dma_desc { + /* + * Application subsystem address which is used as source address for DMA payload + * transfer + */ + u32 src; + /* + * Points to the start of the embedded data buffer associated with this descriptor. + * This address acts as the destination address for the DMA payload transfer + */ + u32 dest; + /* Complete length of the buffer in memory */ + u16 length; + /* Control word for the DMA engine (e.g. for interrupt generation) */ + u16 ctrl; + /* Pointer to the next element of the chained list */ + u32 next; + /* + * When working with 64bit application the high 32bit address should be provided + * in the following variable (note: "PCIEW_CONF" register should be configured accordingly) + */ + u32 app_hi_32bit; +}; + +/* Message structure for CFMs from Emb to App */ +struct cl_ipc_cfm_msg { + __le32 status; + __le32 dma_addr; + __le32 single_queue_idx; +}; + +/* Message structure for Debug messages from Emb to App */ +struct cl_ipc_dbg_msg { + char string[IPC_DBG_PARAM_SIZE]; + __le32 pattern; +}; + +/* + * Message structure for MSGs from App to Emb. + * Actually a sub-structure will be used when filling the messages. + */ +struct cl_ipc_a2e_msg { + u32 dummy_word; + u32 msg[IPC_A2E_MSG_BUF_SIZE]; +}; + +/* Struct for tensilica backtrace */ +struct cl_ipc_backtrace_struct { + u32 pc[IPC_BACKTRACT_DEPTH]; +}; + +/* Struct for tensilica exception indication */ +struct cl_ipc_exception_struct { + u32 pattern; + u32 type; + u32 epc; + u32 excsave; + struct cl_ipc_backtrace_struct backtrace; +}; + +/* + * Can't use BITS_TO_LONGS since in firmware sizeof(long) == 4 and in the host + * this might be different from compiler to compiler. We need our own macro to + * match the firmware definition. + */ +#define CL_BITS_TO_U32S(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) + +/* + * struct cl_ipc_enhanced_tim - ipc enhanced tim element + * + * This structure hold indication on the buffered traffic resembles the TIM element. + * This enhanced TIM holds more info on the buffered traffic, it indicate whether the + * traffic is associated with BA or singles and on which AC's. + * + * @tx_agg: indicate buffered tx-aggregated traffic per AC per BA session index + * @tx_single: indicate buffered tx-singles traffic per AC per station index + * @rx: indicate buffered rx traffic per AC per station index + */ +struct cl_ipc_enhanced_tim { + /* + * Traffic indication map + * our driver push packets to the IPC queues (DRIVER_LAYER -> IPC_LAYER), + * on each push it also notify the IPC_LAYER for which queue it pushed packets. + * this indication done by filling the bitmap. + * + * this is enhanced tim element because it is divided into AC and packet type + * (aggregatable/non aggregatable). + * the regular tim element which exist in the beacon is divided by AID only + * which is less informative. + * + * TODO: add TIM element maintenance in the FW, this can be achived by the + * enhanced tim elements abstraction. + */ + u32 tx_rx_agg[AC_MAX][CL_BITS_TO_U32S(IPC_TIM_AGG_SIZE)]; + u32 tx_single[AC_MAX][CL_BITS_TO_U32S(FW_MAX_NUM_STA)]; +}; + +struct cl_ipc_shared_env { + volatile struct cl_ipc_a2e_msg a2e_msg_buf; + /* Fields for MSGs sending from Emb to App */ + volatile struct cl_ipc_e2a_msg e2a_msg_buf; + volatile struct dma_desc msg_dma_desc; + volatile __le32 e2a_msg_hostbuf_addr[IPC_E2A_MSG_BUF_CNT]; + /* Fields for Debug MSGs sending from Emb to App */ + volatile struct cl_ipc_dbg_msg dbg_buf; + volatile struct dma_desc dbg_dma_desc; + volatile __le32 dbg_hostbuf_addr[IPC_DBG_BUF_CNT]; + volatile __le32 dbginfo_addr; + volatile __le32 dbginfo_size; + volatile __le32 pattern_addr; + volatile __le32 radarbuf_hostbuf[IPC_RADAR_BUF_CNT]; /* Buffers for radar events */ + /* Used to update host general debug data */ + volatile struct dma_desc dbg_info_dma_desc; + /* + * The following members are associated ith the process of fetching + * "application txdesc" from the application and copy them to the + * internal embedded queues. + * + * @host_address_dma: dedicated dma descriptor to fetch the addresses of + * "application txdesc" queues + * @write_dma_desc_pool: dedicated dma descriptor to fetch the "@txdesc_emb_wr_idx" + * index (dma for application txdesc metadata) + * @last_txdesc_dma_desc_pool: dedicated dma descriptor to fetch "application txdescs" + * (dma for application txdesc) + * @txdesc_emb_wr_idx: indicate the last valid "application txdesc" fetched + */ + volatile struct dma_desc host_address_dma; + volatile struct dma_desc tx_power_tables_dma_desc; + volatile __le32 txdesc_emb_wr_idx[IPC_TX_QUEUE_CNT + CL_MAX_BA_PHYSICAL_QUEUE_CNT]; + volatile __le32 host_rxbuf_rd_idx[CL_RX_BUF_MAX]; /* For FW only */ + volatile struct dma_desc rx_fw_hb_pool_dma_desc[HB_POOL_DMA_DESCS_NUM]; /* For FW only */ + volatile struct dma_desc rxm_hb_pool_dma_desc[HB_POOL_DMA_DESCS_NUM]; /* For FW only */ + volatile __le32 cfm_read_pointer; /* CFM read point. Updated by Host, Read by FW */ + volatile __le16 phy_dev; + volatile u8 la_enable; + volatile u8 flags; + volatile u8 first_tcv; + volatile u8 ant_num; + volatile __le16 max_retry; + volatile __le16 lft_limit_ms; + volatile __le16 bar_max_retry; /* Not used by driver */ + volatile __le32 assert_pattern; + volatile __le16 assert_file_id; + volatile __le16 assert_line_num; + volatile __le32 assert_param; + volatile struct cl_ipc_enhanced_tim enhanced_tim; + volatile u8 la_mirror_enable; +}; + +/* IRQs from app to emb */ +#define IPC_IRQ_A2E_TXDESC 0xFF00 +#define IPC_IRQ_A2E_RXBUF_BACK BIT(2) +#define IPC_IRQ_A2E_MSG BIT(1) +#define IPC_IRQ_A2E_RXREQ 0x78 +#define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC | IPC_IRQ_A2E_MSG) + +#define IPC_IRQ_A2E_TXDESC_FIRSTBIT 8 +#define IPC_IRQ_A2E_RXREQ_FIRSTBIT 3 + +#define IPC_IRQ_A2E_TXDESC_AGG_MAP(ac) (IPC_IRQ_A2E_TXDESC_FIRSTBIT + IPC_TXQ_CNT + (ac)) +#define IPC_IRQ_A2E_TXDESC_SINGLE_MAP(ac) (IPC_IRQ_A2E_TXDESC_FIRSTBIT + (ac)) +#define IPC_IRQ_A2E_RX_STA_MAP(ac) (IPC_IRQ_A2E_RXREQ_FIRSTBIT + (ac)) + +struct cl_ipc_e2a_irq { + u32 dbg; + u32 msg; + u32 rxdesc; + u32 txcfm; + u32 radar; + u32 txdesc_ind; + u32 tbtt; + u32 sync; + u32 all; +}; + +/* + * IRQs from emb to app + * This interrupt is used by the firmware to indicate the driver that it may proceed. + * The corresponding interrupt handler sets the CL_DEV_FW_SYNC flag in cl_hw->drv_flags. + * There is also the cl_hw->fw_sync_wq wait queue, on which we may sleep while waiting for + * the interrupt, if we are allowed to do so (e.g., when we are in a system call). + */ +#define IPC_IRQ_L2H_DBG BIT(0) +#define IPC_IRQ_L2H_MSG BIT(1) +#define IPC_IRQ_L2H_RXDESC BIT(2) +#define IPC_IRQ_L2H_TXCFM 0x000000F8 +#define IPC_IRQ_L2H_RADAR BIT(8) +#define IPC_IRQ_L2H_TXDESC_IND BIT(9) +#define IPC_IRQ_L2H_TBTT BIT(10) +#define IPC_IRQ_L2H_SYNC BIT(11) + +#define IPC_IRQ_L2H_ALL \ + (IPC_IRQ_L2H_TXCFM | \ + IPC_IRQ_L2H_RXDESC | \ + IPC_IRQ_L2H_MSG | \ + IPC_IRQ_L2H_DBG | \ + IPC_IRQ_L2H_RADAR | \ + IPC_IRQ_L2H_TXDESC_IND | \ + IPC_IRQ_L2H_TBTT | \ + IPC_IRQ_L2H_SYNC) + +#define IPC_IRQ_S2H_DBG BIT(12) +#define IPC_IRQ_S2H_MSG BIT(13) +#define IPC_IRQ_S2H_RXDESC BIT(14) +#define IPC_IRQ_S2H_TXCFM 0x000F8000 +#define IPC_IRQ_S2H_RADAR BIT(20) +#define IPC_IRQ_S2H_TXDESC_IND BIT(21) +#define IPC_IRQ_S2H_TBTT BIT(22) +#define IPC_IRQ_S2H_SYNC BIT(23) + +#define IPC_IRQ_S2H_ALL \ + (IPC_IRQ_S2H_TXCFM | \ + IPC_IRQ_S2H_RXDESC | \ + IPC_IRQ_S2H_MSG | \ + IPC_IRQ_S2H_DBG | \ + IPC_IRQ_S2H_RADAR | \ + IPC_IRQ_S2H_TXDESC_IND | \ + IPC_IRQ_S2H_TBTT | \ + IPC_IRQ_S2H_SYNC) + +#endif /* CL_IPC_SHARED_H */ From patchwork Tue May 24 11:34:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575976 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 2992CC433EF for ; Tue, 24 May 2022 11:39:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236797AbiEXLi7 (ORCPT ); Tue, 24 May 2022 07:38:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236830AbiEXLi6 (ORCPT ); Tue, 24 May 2022 07:38:58 -0400 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2049.outbound.protection.outlook.com [40.107.21.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 910F88D68D for ; Tue, 24 May 2022 04:38:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hIaHgoLU0N78Wwomd0BbfZvVVDLVsW60Dp3T8c6r1VyGtke6V6944Cgng4545EHx23sDksjZTboWtsn8SsnOXLKXfgJ84wrXgn64jNaXXBITiH9V2xHO9Bry0b0jQgVsM1uL8G8Tjnb/PwH+i6y0Fgts6gji4aKKWUfNT0xMrYKOkIDdHQ/q2GDCcQCTWatNroeKGh/m/bVrNQTOE+9+WhNCSk71SMlHDTUXrG9xGbl9X4bE+cGFiEaaSfTHTeYaKdqXbFRdyqsq0YiY0t9ylBsfFHj9HY/Kmm2uYpfLAGgZMlb729x+gqZ+94w3ZTdgIoWDl4DgArbzlkcXGIXQQw== 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=ogZKDoI7cvYL82g31NEXuCUB8DODR2apYpQpHvJ9eog=; b=WyHZK6nySf7i9mijf97g3g8iUePrn1OFTBwjo5qhRkBp2SFoqd6jD4ZNlutbV8EGfstsYeesiKQUKXvNnuCfDrGWOUmEVeO80FXgHOk0o+6PiGeoZAw5HyK5DQnnd0nZMLMgx9HKTtg5QsCmPAekKwsOfAphwTL9UrJZBuWt4YZE+jdbEI7Qrahq+bB5RsYHKWJfIrKjWh6NNGglK1HAHQ78xqW8y5U+x063CkTrJwmIkY4x84jjhJyxb/k1aV13tGJBD701G1pob9YTF2h9oc/Lj68XAPGfqPIykJpe1MEP4u/Dtkb8a8jZRfUrr0LsmbpAvGjbNu6qx7F0a99qcQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ogZKDoI7cvYL82g31NEXuCUB8DODR2apYpQpHvJ9eog=; b=MCo3n909G48GFxjsnpp3NRiPfYky7asLTFouw4gq6YarPi4V+6skXqJBmJf6ik8mRKrKDoiCoSzjF5OEBimg9mxRN3mBWQMXN+fiu6M8BponcQYKyraSxRGRD0jYS3qEjeHlKC1V05ZWIKV5fYIHGVi+/XefsMMKRgO/nnbnhj4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM0P192MB0305.EURP192.PROD.OUTLOOK.COM (2603:10a6:208:4e::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.15; Tue, 24 May 2022 11:38:40 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:40 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 36/96] cl8k: add key.c Date: Tue, 24 May 2022 14:34:02 +0300 Message-Id: <20220524113502.1094459-37-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 05668b09-9693-4631-d4ea-08da3d79e131 X-MS-TrafficTypeDiagnostic: AM0P192MB0305:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yeVbnOEMDbhf/UX8ZDYaJ36iAMf2prNfPodZbjnKQzG1N7WPp2rinW0XkctMtHtTzpRXsuqDCtmzyo05xw4tsvdPnABDJ8mZEFrze5QV0edBy+M/sKXklz5A/ZofLOhHJJ2SulDkwa9xkV7gHQW8QM4MKbrAwjk8dn3hFSCowAxUH+npBz4nvwvYW0IZk+LlElb6ZT4P2rmXrSS2aiVRFibSE30I8wdENh1tdVsmqmnS2ycIx8pAt6T44TOqWAgubrlaEA1GPLWNYuJYfkk7jUbJt26IstyOMlRzJcybRjPgtJCikz2BZUH0hDYLOswnoPOhvNb9Oq3cjMhp75naQoFMptj6JMigRfE5GdEw0AaUtwq4iZ+TcY6kLtBeFDS18N04cwr5S0Hg3+dZA+sLx9rZJ3osYIaIlq4LWz2KcK5xlWetc9QfyUReD9Irx4l3QZSHkiO/Hkl23+GrdS5iKZK21eoduSRrZ7h8l/BdL3oFHAqjiHHvhNXKAL04Wfp8w/thFmPhYq+n1dzRLyGp9+N/KIa7fsU6mjbN2SaMMz8wUipaC/RQpCQh5LfzNIl3DnDxCslWhIrCcFUKX6flQOEdMKZxQk4Niqkgx3VI3VZlqx3EhVZEOLIaDkIejT/bFf9XX75v4rPnt1ObwPhgDo5G7afe7CkrsZlKIppAr3nRyZ/WnrrcDoR+y4Z0E3yXGsljHnobQgjNKA4BLCG57i48GclhSZnULgajAkatPBU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(396003)(366004)(39850400004)(376002)(136003)(6486002)(6916009)(508600001)(38350700002)(38100700002)(52116002)(6666004)(2906002)(8936002)(54906003)(6512007)(6506007)(26005)(9686003)(8676002)(36756003)(5660300002)(316002)(66476007)(4326008)(66556008)(107886003)(66946007)(1076003)(41300700001)(186003)(2616005)(83380400001)(86362001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 3gcNOhqgJ+5vp67nheIhDZVx9ZE1oVl6jvdHwmnEY8OzjFop4Li+V6fS/rIA4gE7pLJOc/5cUw8qmBMeynB5CwQYJrC86foIsPxj5tMSRT3vQ+TwrGTEUvajlr1sDNzVTwEq8mhcID08gtaG0CELMvkVFcOhm5dKqoVZPUsx+OQwEJZvYOr3nsTmxNDi9+HLOtUCebFMJpYn3SBnVG8Z8eMOYZB9oIUMhgLmubG1B746wbOyu1zA18YAB9Cqet53s8IuJFdT4hZXuaPVmF4K/FjqWYPmxZXh/DnQ1oeZYkq3jHi7i5UJA5CJbijWxbHoRQqRPFnlxQT0z381bW0wyxhP4ngMfe5i2xp6+jNAOK5MlbpjFq9wJQDJ527yyZZx0/iHhlvm9oML/n+HHoNSfGfMvZk4/V2oOxneAe3Z3N3n2lePq1wHgVX5+ZW+iCXCE92OXDuOEK3P+bk9wurdN4lWN874VpObvRprIwoB/OrnjR/Onv1itVCzxMsLBWymtlbM9B67RtGU5xMWleknbbnjZK9DkpI/9ozi5ps4vVvPvTUBhW5kUX8DIhgRCEOqhYEqnoBm9s0t/YynRdZ3rbmcFNyLZcx5cdanSOIcOfLljLN62LMBcbChrTQjwehsw7fOTsARfTW3hPbcjiNnG5UudmvzKW6iAf0Xf/czRfn8mOde1nXX0k7ggjpqltuDBVSg0nH205RfrfD5spsODdanpzY0u4cQgDTV1xT4IfF9F/Vzh3FQFTOYdyMQEA11iHBn3R2WKYwSmVdKj8S5RrH06omVixYSY3VG0iPBAO6q3GUERXMaUMkpDigHMtaPOCmAy1ioRlaCbXYUU0MuirRKHSZJ5LRVZ6HD3v8xeTutg2LXIuYVBMhwlfxNAVrPg5afz+GxFi8GsyZ1kYgKWRnynoqG0wLgcH1Flgs8D2kJ0VRNHqqS489Rx3hIVzFkBU5znonXO31rvWw0r/kn1xXb5n84Zkd6cC72f1XMwQ41woHvLCwcalR9Wqk4FQOYA77cXWGfaUc7nJvqWqj7p8Tzxj3bfbCUKxuZklXSryZWBFaZr68EUIOZk7jAc1NIvhs/9b+vTlvKVfyLm/L7mYZnnuI/TREPwJd62enpglyvRN3Z7p+KcUT+hPPUxa/fuPJdcx7SLIUNK5LgO3Nu/l4zN4BWHM/UK79GLWUi2JsJHk+2hH44w71S8op5Y84ukRjinz0goldwnJsw1xvRieRGE6pBqm3bPieajNKEvQ46XWbBtAEpY0a0cV+q/bT7A1+DRVA5kP9FsF55ZuUPCkfoEjqBd+Vp/2r0iU4CfCdolrcMhKmiXsleKuGmi5VrhJV2sbfsFYq+yuaM31okHYNFHqbDFZqdk9ZJ83AV7gRNgi+47WCigCxzxfEo8Lt+IYwrWKTkuZFEpv4ke85eXsd20PkXUDOOYBj3wDFPGG8XUgN9HaeWIcIDRh7ENw2scbMbE1XVDlOQk7+Jx0FWhwYB4wXevtYEalO/foz7zWuijq3MEWPuA+kkgyJtK6VbzVPSfQWvLy+8B8fwDYKJc3BtdkB5HuOR7EUT4njH92sP7d1w1x/Hyz2i0xvXds7Bv7F+c4YRsGFS7GbCmYcfkPboPJOLyuFmn7SH63TH8nTh81n0TNYoiAq16eV8PqgnHeHSNyp6ABURIuXoWXJ4Y1NuhgrUSZiuE92YsqSeyWlwlGyD9Q5xdbJ5H8mNnL0rubxxGHXgtqy9CVZ6Azy+WrRHYH0QmmOxL43d9wH75Lk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 05668b09-9693-4631-d4ea-08da3d79e131 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:10.6398 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: lE+wifefK5a7nJLhL0jDEF6DtcqeBsPAyeSaKNl0CljvFQzNpDXQ5ywe8kJPYiAQz0b5b6oHW4DjkGiHEW7bdw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0P192MB0305 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/key.c | 382 +++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/key.c diff --git a/drivers/net/wireless/celeno/cl8k/key.c b/drivers/net/wireless/celeno/cl8k/key.c new file mode 100644 index 000000000000..99821b86a795 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/key.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "phy.h" +#include "fw.h" +#include "sta.h" +#include "enhanced_tim.h" +#include "key.h" + +#define DECRYPT_CCMPSUCCESS_FLAGS (RX_FLAG_DECRYPTED | RX_FLAG_MIC_STRIPPED) + +void cl_vif_key_init(struct cl_vif *cl_vif) +{ + INIT_LIST_HEAD(&cl_vif->key_list_head); +} + +static struct cl_key_conf *cl_vif_key_find(struct cl_vif *cl_vif, + struct ieee80211_key_conf *key_conf_in) +{ + struct cl_key_conf *key, *tmp, *out = NULL; + + if (!key_conf_in) + return NULL; + + list_for_each_entry_safe(key, tmp, &cl_vif->key_list_head, list) { + struct ieee80211_key_conf *key_conf = key->key_conf; + + if (key_conf_in->keyidx != key_conf->keyidx) + continue; + + out = key; + break; + } + + return out; +} + +static struct ieee80211_key_conf *cl_vif_key_conf_default(struct cl_vif *cl_vif) +{ + struct cl_key_conf *key, *tmp; + struct ieee80211_key_conf *out = NULL; + + list_for_each_entry_safe(key, tmp, &cl_vif->key_list_head, list) { + if (key->key_conf->keyidx != cl_vif->key_idx_default) + continue; + + out = key->key_conf; + break; + } + + return out; +} + +static int cl_vif_key_add(struct cl_vif *cl_vif, struct ieee80211_key_conf *key_conf) +{ + struct cl_key_conf *key = NULL, *old_key = NULL; + + key = kzalloc(sizeof(*key), GFP_KERNEL); + if (!key) + return -ENOMEM; + + if (!list_empty(&cl_vif->key_list_head)) + old_key = list_first_entry(&cl_vif->key_list_head, struct cl_key_conf, list); + + cl_vif->key_idx_default = old_key ? old_key->key_conf->keyidx : key_conf->keyidx; + key->key_conf = key_conf; + list_add_tail(&key->list, &cl_vif->key_list_head); + + return 0; +} + +static void cl_vif_key_del(struct cl_vif *cl_vif, struct ieee80211_key_conf *key_conf_in) +{ + struct cl_key_conf *key, *tmp; + + if (!key_conf_in) + return; + + list_for_each_entry_safe(key, tmp, &cl_vif->key_list_head, list) { + struct ieee80211_key_conf *key_conf = key->key_conf; + + if (key_conf_in->keyidx != key_conf->keyidx) + continue; + + list_del(&key->list); + kfree(key); + } + + if (!list_empty(&cl_vif->key_list_head)) { + struct cl_key_conf *new_key = list_first_entry(&cl_vif->key_list_head, + struct cl_key_conf, list); + + cl_vif->key_idx_default = new_key->key_conf->keyidx; + } +} + +static int cl_vif_key_check_and_add(struct cl_vif *cl_vif, + struct ieee80211_key_conf *key_conf) +{ + struct cl_key_conf *key = cl_vif_key_find(cl_vif, key_conf); + + if (key) { + cl_dbg_warn(cl_vif->cl_hw, + "[%s] error: previous key found. delete old key and add new key\n", + __func__); + cl_vif_key_del(cl_vif, key->key_conf); + } + + return cl_vif_key_add(cl_vif, key_conf); +} + +static inline void cl_ccmp_hdr2pn(u8 *pn, u8 *hdr) +{ + pn[0] = hdr[7]; + pn[1] = hdr[6]; + pn[2] = hdr[5]; + pn[3] = hdr[4]; + pn[4] = hdr[1]; + pn[5] = hdr[0]; +} + +static int cl_key_validate_pn(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + int hdrlen = 0, res = 0; + u8 pn[IEEE80211_CCMP_PN_LEN]; + u8 tid = 0; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + tid = ieee80211_get_tid(hdr); + + cl_ccmp_hdr2pn(pn, skb->data + hdrlen); + res = memcmp(pn, cl_sta->rx_pn[tid], IEEE80211_CCMP_PN_LEN); + if (res < 0) { + cl_hw->rx_info.pkt_drop_invalid_pn++; + return -1; + } + + memcpy(cl_sta->rx_pn[tid], pn, IEEE80211_CCMP_PN_LEN); + + return 0; +} + +void cl_vif_key_deinit(struct cl_vif *cl_vif) +{ + struct cl_key_conf *key, *tmp; + + list_for_each_entry_safe(key, tmp, &cl_vif->key_list_head, list) { + list_del(&key->list); + kfree(key); + } +} + +static int cl_cmd_set_key(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int error = 0; + struct mm_key_add_cfm *key_add_cfm; + u8 cipher_suite = 0; + + /* Retrieve the cipher suite selector */ + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + cipher_suite = MAC_CIPHER_SUITE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + cipher_suite = MAC_CIPHER_SUITE_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + cipher_suite = MAC_CIPHER_SUITE_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + cipher_suite = MAC_CIPHER_SUITE_CCMP; + break; + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + cipher_suite = MAC_CIPHER_SUITE_GCMP; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + return -EOPNOTSUPP; + default: + return -EINVAL; + } + + error = cl_msg_tx_key_add(cl_hw, vif, sta, key, cipher_suite); + if (error) + return error; + + key_add_cfm = (struct mm_key_add_cfm *)(cl_hw->msg_cfm_params[MM_KEY_ADD_CFM]); + if (!key_add_cfm) + return -ENOMSG; + + if (key_add_cfm->status != 0) { + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", key_add_cfm->status); + cl_msg_tx_free_cfm_params(cl_hw, MM_KEY_ADD_CFM); + return -EIO; + } + + /* Save the index retrieved from firmware */ + key->hw_key_idx = key_add_cfm->hw_key_idx; + + cl_msg_tx_free_cfm_params(cl_hw, MM_KEY_ADD_CFM); + + /* + * Now inform mac80211 about our choices regarding header fields generation: + * we let mac80211 take care of all generations + */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + + if (sta) { + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + + cl_sta->key_conf = key; + } else { + error = cl_vif_key_check_and_add((struct cl_vif *)vif->drv_priv, key); + } + + return error; +} + +static int cl_cmd_disable_key(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int ret = 0; + struct cl_sta *cl_sta = NULL; + struct cl_tx_queue *tx_queue = &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE]; + + if (sta) { + cl_sta = (struct cl_sta *)sta->drv_priv; + + cl_sta->key_conf = NULL; + cl_sta->key_disable = true; + + /* + * Make sure there aren't any packets in firmware before deleting the key, + * otherwise they will be transmitted without encryption. + */ + cl_sta->stop_tx = true; + cl_single_cfm_clear_tim_bit_sta(cl_hw, cl_sta->sta_idx); + cl_agg_cfm_clear_tim_bit_sta(cl_hw, cl_sta); + cl_txq_flush_sta(cl_hw, cl_sta); + cl_single_cfm_poll_empty_sta(cl_hw, cl_sta->sta_idx); + cl_agg_cfm_poll_empty_sta(cl_hw, cl_sta); + + if (!list_empty(&tx_queue->hdrs)) { + spin_lock_bh(&cl_hw->tx_lock_single); + cl_enhanced_tim_set_tx_single(cl_hw, HIGH_PRIORITY_QUEUE, + tx_queue->hw_index, + false, tx_queue->cl_sta, + tx_queue->tid); + spin_unlock_bh(&cl_hw->tx_lock_single); + } + } else { + cl_vif_key_del((struct cl_vif *)vif->drv_priv, key); + } + + ret = cl_msg_tx_key_del(cl_hw, key->hw_key_idx); + + if (cl_sta) + cl_sta->stop_tx = false; + + return ret; +} + +int cl_key_set(struct cl_hw *cl_hw, + enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int error = 0; + + switch (cmd) { + case SET_KEY: + error = cl_cmd_set_key(cl_hw, vif, sta, key); + break; + + case DISABLE_KEY: + error = cl_cmd_disable_key(cl_hw, vif, sta, key); + break; + + default: + error = -EINVAL; + break; + } + + return error; +} + +struct ieee80211_key_conf *cl_key_get(struct cl_sta *cl_sta) +{ + if (cl_sta->key_conf) + return cl_sta->key_conf; + + if (cl_sta->cl_vif) + return cl_vif_key_conf_default(cl_sta->cl_vif); + + return NULL; +} + +bool cl_key_is_cipher_ccmp_gcmp(struct ieee80211_key_conf *keyconf) +{ + u32 cipher; + + if (!keyconf) + return false; + + cipher = keyconf->cipher; + + return ((cipher == WLAN_CIPHER_SUITE_CCMP) || + (cipher == WLAN_CIPHER_SUITE_GCMP) || + (cipher == WLAN_CIPHER_SUITE_GCMP_256)); +} + +void cl_key_ccmp_gcmp_pn_to_hdr(u8 *hdr, u64 pn, int key_id) +{ + hdr[0] = pn; + hdr[1] = pn >> 8; + hdr[2] = 0; + hdr[3] = 0x20 | (key_id << 6); + hdr[4] = pn >> 16; + hdr[5] = pn >> 24; + hdr[6] = pn >> 32; + hdr[7] = pn >> 40; +} + +u8 cl_key_get_cipher_len(struct sk_buff *skb) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + + if (key_conf) { + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + return IEEE80211_WEP_IV_LEN; + case WLAN_CIPHER_SUITE_TKIP: + return IEEE80211_TKIP_IV_LEN; + case WLAN_CIPHER_SUITE_CCMP: + return IEEE80211_CCMP_HDR_LEN; + case WLAN_CIPHER_SUITE_CCMP_256: + return IEEE80211_CCMP_256_HDR_LEN; + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + return IEEE80211_GCMP_HDR_LEN; + } + } + + return 0; +} + +int cl_key_handle_pn_validation(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_sta *cl_sta) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + + if (!ieee80211_is_data(hdr->frame_control) || + ieee80211_is_frag(hdr)) + return CL_PN_VALID_STATE_NOT_NEEDED; + + if (!(status->flag & DECRYPT_CCMPSUCCESS_FLAGS)) + return CL_PN_VALID_STATE_NOT_NEEDED; + + if (!cl_sta) + return CL_PN_VALID_STATE_NOT_NEEDED; + + if (cl_key_validate_pn(cl_hw, cl_sta, skb)) + return CL_PN_VALID_STATE_FAILED; + + status = IEEE80211_SKB_RXCB(skb); + status->flag |= RX_FLAG_PN_VALIDATED; + + return CL_PN_VALID_STATE_SUCCESS; +} From patchwork Tue May 24 11:34:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576854 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 75E49C433FE for ; Tue, 24 May 2022 11:39:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236836AbiEXLjQ (ORCPT ); Tue, 24 May 2022 07:39:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41596 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236835AbiEXLjP (ORCPT ); Tue, 24 May 2022 07:39:15 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2081.outbound.protection.outlook.com [40.107.104.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C59B8CCFA for ; Tue, 24 May 2022 04:39:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dLww2rz9VLX9wjvKZZFkX+cVR4LaW/cE0pp/hbZrqkMMChtilrejTKeDFrv0wWJ3PhtFKNR4DeWnKj3jTfmTtqFhk1C4UaS1QCIG2oULjA+/sb3Kp7CgvztnMI3HpGcVxEWwfgJMf/KeP7s+ZPPdD1EvGbHqUoxJlWc69CuIJPb48ToyS9jqQgqYO0h7DZqqJmtA2ceJ41I3BP++yFpTd+SQwB5O4z01RcrOtqx2b62ocuWB/tWPNqzp/swuZiOEXc9Hf+iJbxL12x/3Y0HOvQffOyKiQznQ5u3pxDlxpov73sUwdLA6nnT88DxRdsxqy9sGKjAcPPoeP2oxSj6T+g== 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=WCrjD385YbFOSBmwfsR2keCEPmC5oz2aDqYm5W8imSc=; b=hcS7tMDKAyF2Pyt8jjIvOoEh8z/EFmSO54wCYWM0aI9GLA5fnADC37xk9iEWdJNQeQr8oAUzSWQEtwRU3eAWOrMMIxIvvoPEhmXKyrf+00HpmKpCuZMaw7tdfHzzSbECBRXG/eYOnyFiN01Jdhr5wc7hdkBRQobMTXhII9nxO0I7DUTCwg5f5zYzBhGb42nJNA51SnrqnlV3HO2lLOyBkznHgHk1Jxd03uX18o/tRalCn3Ief3GdJQUVSZ0WxsRC5jjfx6lSpHAqQ+n043b/l24QPNH5PIKN0cPyseN4ekLZsqWIfrZrgp1mJgWowumDV+lkD7SZK6HTaDpQav/62Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WCrjD385YbFOSBmwfsR2keCEPmC5oz2aDqYm5W8imSc=; b=uwit51Bgsu7lM7NVEwSi8wN6LUaOh56sun0bZ2Ocg7MPDvkfLUp0sF/NObhMy+eSiny0e9mQgXv+uIg+wX6wrtaIDOEQx9TEYYbhX7A2UHjqvxYfyiOwPnDqNLvX8RqQ4EhsDEcLwkEuWhYtWR21gsdkqZius4FQkJj8SU+zluU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:40 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:40 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 37/96] cl8k: add key.h Date: Tue, 24 May 2022 14:34:03 +0300 Message-Id: <20220524113502.1094459-38-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 495b7315-980c-483b-fd14-08da3d79e1af X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: keJ2gBEtn+1qQOCulx5M1OpM2pkj+vyQMxlLIKJqGM0K1ZAvLcLddiJS+91XV4zHNRiF3n3dZ81oKrVKsIa6WRvxN8I9bJJkbV7k+S7nBJ46PUeJhjGkQMW8JN0iQnVqYc32Bnwm6eHLDwAWZldNBf1IKH5+24pUR16lIPUJlxDNkBIL+8B6uw6gkY2J+wNixXtYq7kkhQmeG6CZn+2/S1Z8bn8tMfZoiNACRmwY96R2jCcqcqMPW1lQkEsbl9t1eTwo2lKLZ0vQe5nACEg/xhEUOlTU+dpkMYZ8IktwhfyCvKEmqdno6kelX7dyK+p0jXQc+yq9ycxzXAH2K74SCdPcHtNL/n4y6vK5HSb3jWOfWXq/sPU4OS8V53cuKEmLJOyIsPsTY97AUHqwJPI4KC2Ris8XE31q1r3Ey+0rHpHYiAe5pb/hFgNEziXYn48Mj4VPQvR3vgkIzxzXt33WYa5p7/iLTpIcU38LnhdmM3Mz4ixTRUO6pgX9XtXJ61dN5CmUsCSPoQXy0gY7BxnZ7lCcUDbqh7ka1R9jqj+KewLX0z/+55l9C0y0lgwKVrlwSqdffF4eNtBqWkKNqCOHh6x2wD5LlDqQsO1m3APHdbKECvHOsHdEQB6g6ywdpKF3xXd46vP49XQY+f9LGfKsZv9dU0T1Rugppf+pKQCplHPj1X1P1nbvwmDrrtpJEDd9f31gCIolOsmwFHAe2hkRMy8Vmyq59CTAnyNhZBriDN8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: q3D24uLrcjmHJ5IEYAyTy7BdOY8I+tbyPsDG6wATlLbPXUGGkk9JChMkDeAV5twWImN9mFnN7qzXRSX6MnCtLEqNLF248bdWntUA0sZUo8cQMWcSQEICXONj32xsNndMg3vPsn1SYkeqwVIePR76FPdoa40T4oCo0oKZDcjej3ozDGRfpCyHqYpu1VQXTxkBdBhbWJ9PHG7naE00FJN/jA4si7XsG9vLZ+gZRwCNy75itmOs1whfT0ooCO6IZKp8roBt/4C10pYSgVPbJsZfnZzrJgzjoLZ0jpGQK1vRciH/AoYTdv5IeG8KVuDmsOiVvbvD0apqYbXVh++1OI7jZdgK4P74ogigWzrFJZW7m/wSGujC4s+rgKzm45KOoEHssBfW149PSzPRSMpOI5ggXpuk91UwmiDinTX+phUX1PEsE6kQ8br5+Ah//ig0LQHfmrQEw4pA7k3J/EIr9cmigWnaz4UJjzR2OYbhwrJvkrz9aeXA4WqnJQoH851DjfaWBlF4oRDpvOTaqN+GGuokRO3fRFXbqt8nMMQFx70tVPgL/S6aMdIAxIejZZqs5WCncDK4LjOj3a35V8Qm3Md8TpJK0CE/9CIxoqzMQS1qG+d2W2YwKPUBHnkKfWlLgN1WfIDhChQkXed74XUCQEZmW/luHI9RQgAUKKEJ0pU94FfSGfQCFH8bX/WH+42KcZ7/d1jbW2ykdtISnAzUMsevxH3COyxBkLNJ0W8iYitOVFKQVbbGsUftL4fxrFR2Wh6RZTt4FtnvRQ1qsVURmVR8qCEkqzUp3dtwcDYl+bDrl3dzQTSIrCxOccUhbOrR2FHnKykOr3kcr3W+ItWtAK4/sM7cZfCN7neV3ZXuYgwDUYTfZssHplbk/vxKG1upfMHh2L413trc5sHAoJKNGfT/2nxUM7F7z/iAJtQgNKjMMf9cz02AGosGyYrsSi/qtt/EL+QA8R9EtWDWSynYP2y/4xoJ1yAx11F4YEbro1WYmisu0e0qp2WFUtSVdMWgZtwkhaLlN6a4YIS1nTOEDNk1i5cYY85N4vW8vJWlBEgDfo7VfiD+o5OEwGf4kv5ca8v+R8CWcjEz9TGsAutZIaJW9Up/0z/1QLSZPwtkVIS92OaAmUvf/umoD+PW3sDEGYbIgC/lvn2Pd/U28elS/ZH6VxaS7yotDN0V9F5FKh7RJvIz2+4iHcRHovm+DJbsCHeshFUXq4RQVx6Q+ZwxCSeAw5wk77PA5GgAzo8ubQnRS8c7bEyy8TXNsTG6jkCimhOuJBgItmcJKonhK6rLljqXgzQgcwxEb9x4nnMeeerFaIehEyX+ja1dmxQWXIlpt23TFVFKqdHNON4lJNQm6CxPqhI6E5+Us5Q/L+ybWK4+iuj9LyqbX14BrDORXUC6sUYFlEoiKCcakkaKtjf3o/goTbYrrB+LjhoIcpopbk2KpgUGjNMDzC523zq0zr6+w1edl98Ez5JN5jgX9Jh4E24+zXy1gwCnaEpshnLAjHveRdd0yaIrQEU4jdz6lputfBPftIolYHNNlXmOnb61o0XzniBzUyJkDzkOE7yWX8bKGI/pVBEO9Ino/gU1xI/BBMoTeMxiRhXCjbq9m53YtTgBPHwsnkaH1Ah1iWzquOtZKvL/rbM1NPxSTDIXxZziXK11bjFb/KFLEI4C6rHhI8/0wDIdmUVzjvXSzYZiNdCl9ZZHaCojoz2TuyCPGRaoqgKsXR1RYD/U+H1SYidnR29HBjjZ33VQS5avpJdNH2qUuIk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 495b7315-980c-483b-fd14-08da3d79e1af X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:11.4653 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: utYAxY0Wunpzn17SA4ftSLLTP5KtKvyrOxX4BNti8sN3Byc9ikdq4DlU7HBTPq7qyDuBZyrZQ8Rqz2zSSqTleA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/key.h | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/key.h diff --git a/drivers/net/wireless/celeno/cl8k/key.h b/drivers/net/wireless/celeno/cl8k/key.h new file mode 100644 index 000000000000..3731347f8243 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/key.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_KEY_H +#define CL_KEY_H + +#include "hw.h" +#include "vif.h" + +enum cl_key_pn_valid_state { + CL_PN_VALID_STATE_SUCCESS, + CL_PN_VALID_STATE_FAILED, + CL_PN_VALID_STATE_NOT_NEEDED, + + CL_PN_VALID_STATE_MAX +}; + +struct cl_key_conf { + struct list_head list; + struct ieee80211_key_conf *key_conf; +}; + +void cl_vif_key_init(struct cl_vif *cl_vif); +void cl_vif_key_deinit(struct cl_vif *cl_vif); +int cl_key_set(struct cl_hw *cl_hw, + enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +struct ieee80211_key_conf *cl_key_get(struct cl_sta *cl_sta); +bool cl_key_is_cipher_ccmp_gcmp(struct ieee80211_key_conf *keyconf); +void cl_key_ccmp_gcmp_pn_to_hdr(u8 *hdr, u64 pn, int key_id); +u8 cl_key_get_cipher_len(struct sk_buff *skb); +int cl_key_handle_pn_validation(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_sta *cl_sta); + +#endif /* CL_KEY_H */ From patchwork Tue May 24 11:34:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575969 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 11133C433EF for ; Tue, 24 May 2022 11:39:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236854AbiEXLjc (ORCPT ); Tue, 24 May 2022 07:39:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236855AbiEXLja (ORCPT ); Tue, 24 May 2022 07:39:30 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2041.outbound.protection.outlook.com [40.107.104.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F0654AE15 for ; Tue, 24 May 2022 04:39:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bUKIV3Icd4ypfqNKSctQN27PgrBhVPKD9CGRGnfKUDIJTOaG+JZW9rDaipwWg8H0QsbYdSWuLJhPlJlFWeRCdC3xwcqtDZds6zAWFIJi8wxTrgyC57CH6yGeO2z4w762gQ+I4WzAVqV+y8da4vizdtyHvfiKr6qI/dA5DzyFxEzUBz/QPAaKv7CRFQF8WGWPgP3qoPwnKav+xWN2Ae8yY31Y3TE+FJkaC+QyrR8r/XIjQ/BdY7fhlnCaQbtqzmedM2AZUF6QfLg19wPQRKbu5Op2jssVdaE2fPdw9RsWzlGRkZMoxQD12o4S3lfaVIAvkvkIQPlzfhrgj0JteVOYNA== 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=fIEiirRArSQNK6MsWdZlaogtGlvImxIuKIviQB4lFEQ=; b=UDupZYWCjNr75CpOnMHQ2Iat83dKq3feKmOBIgfgYs7oDR2ZtRe80Rgv1gtkSCQ1+hDqDch3LudMQY/TL5Vqp1i8WckZR+qjoDfr/MIt1YJIGxcLFJWaj5M4Uuiq/YvtFXZ4qJnipKTUl0mlaJy4aSCCkgVita0HxPLzatNW2yMhCHgtrnSGUpbyvhzRrXeD9OuMI1Z/+O23nmm7wA0sU5ueJLM/s3A7rnvUdcLnQtL0cAKteJZZ2+N91uypW3cpiEIYpMoOSvj66VnGqGOy0Knsb1kGlaU6d4xT4Ep+3XCosKFXRI+TTqkwS1gXDOMdMcHncin4rPU3D9ZtsAlDXA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fIEiirRArSQNK6MsWdZlaogtGlvImxIuKIviQB4lFEQ=; b=gp7B0ei+DriB3dOW4Q6mvVHnK0IpQB3bD6ez+DGUpUmmsImElXitaF77IdE1yK6aiS6Ih34krvRIeNNc6bQmpO6kNXfHohAzTeC++c2ICbgVC6AFb5hicGEXXL/WJgstEl8REfPcbssjh4j9u/wJV2JN4nv8YQOecZAb+7hGgyA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:41 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:41 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 38/96] cl8k: add mac80211.c Date: Tue, 24 May 2022 14:34:04 +0300 Message-Id: <20220524113502.1094459-39-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ba3571b7-be4f-49c2-6866-08da3d79e222 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 3L1SN/PmmjRB/N8OiPioPExEewqdmbfgOaTr2Vel7X5WP0YdTYiXGZjVeEOUmFYOj9CNTq9ZTuTidFfqDySPQp90AqJ8acS1Yr259bYFz7JaaRniBnCeGpl9mAx/JhoaTG5hWb2GZ0sJlVlJleQiRiHtqYzM9VoH5vvtMkhtoZuc5YDt2cdR0Pt329PGbVgJaZHLofFFaK2UgnHKlSqjgtp8fo+aXu7vE3/LXJ9ntw6hWXwTlmWpOyVnD6iK3PAyf7LqmXrcyYPiGKg2mda8IWNXaC/Dbph5mF+KZMgLdNLVEj23i2foant7kGQrBcmc9ge2Ljf1pirM/mGKMOKojhWhhcX19qdHM+SvnxTiaVv3todRMwC8R+ZiF86YJZlXkva/ElB9vnwQPnq901TBYyUdy60VlxwFKeM202iTxj2KsURvtAye/2h2LOQ6bQDMDGwdo6u2x8IhYNvzWjLOi3rO49VeNITrhc6TN7Riea0zadtXmHhCN/U88OceECZILYZvyeHfdAqECuiQo78nFZImfgrnMbhe4+vDr5OcNo4q9CO+2GucSgySLCbQPU+UhC+skbpCDZvLGLwyLtKZkGM3O0WfV4xB7UU7lfLy7qU/vmqyds5+GrTC1qatm+EVxG6AOs5KR2/IbZmykbaFuH5tivTG7csvtaa/ysAL8gGymc4JgPCOi2SGPgXvyLsHN6X9l+sAdB/hAmG4GrZfLw7CgqpSBmKHNy4bAfUXMI6KQOUOpGNRrtsrjPxgYqjd X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(45080400002)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001)(579004)(559001)(309714004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ZHCHRX4UgBYm9KGPK2oa+PcyJJS2Ez/Lq3I2jq/W5gaMp5CGYdgjFSkyaJfc56YJAP2w11Mccpiw83MG7GnHqPetZdtsfsIP7INNxek9DnaS3Hby2QwV/2P6AMvD0eFrTJ4wsPzt+ICFgtHBkPsLwtMqnXps7vR3sf7MBOG9+wc2i6uVvdbBVtp+hBinwthz1V0AflCAQbTsz5ytolD7nt2VimR0XWbrybl4XPBvtuyx34CMM/dZpnWtRYDSAuHPR8PVZOKulqm2Jy6ebRliDKbRLAPMLCzVfcy0KY8EIVY2L0c2Wt033liceKcWf++rBpz0A5io1isicb+6nhQ/tgelSwNVrzEzQ0vqyDkIM7T9GtmBwYbSbpO8EBOCgkgdYcwFiqFNasFCBwah85yg5II3wFty0cWmT9DIeELSvdOpAwRCLxnViIgMMVJzclupdKqhu4mlpd25yqQKO+q8kqyuzKPp628J2T9OR3WCnDqPdbkp3c+ZZJlWn4OwqfOm8BOemcqvZn1naCTTLjaJ2Oh+71vzFrWWstzymRsVHiZPR0PRGzH4uLJBpV4J4F3Zkp+X0w+7lKNz5bsdj05lD4X6KqxGHLJCEgk+Ui64ATfEIVHyfv7ZUYsdsNmyI1g3CXoPZvtSIXSTk88UoomPCM22kObePeaw6utHRJfoNFACKfvvTNsgR7P57y2J64YdKyvCE5W936syrgwZl9QZDHM/CgCWr+uNqJFupIoMQsGsNDY2ln50bNKJSdRvzy0BGzmsn0VUpzf+Gga0bkJiSLES9RYzTmniGP31toOZ8CxkM2CUfPnWuavKlnrM4kMfzYAAFfyZgxAco79Frd/jTD7OGHlMYbqs5VIwmQ5waC22ljua2ILwcZL90dmqrjNyOS27qcajA2x75gxbbqQSUVjbiKs8+47H/M1sumOIfA+nS7K8yy7if5c6elVM0wLDK5s8tRsezzTcmfUhByOSazmYXIUSN3C3a8gzGIu0AtVwTbj9dRLp2uUJu2zisD5MHX8TVQEdsfrGfcXePm3Dw/udya/2nJsvyLRvtSuSAfFpPXcWwQFm4miSCDfGxB1LuBD5eTsXqh4GbvCU06C5C89eWbe1jZCvgN7dqoUpE3VFDl3j/iWzLI29O/cSAaC+mDSa5+Pas7aaxuvgfF052cCjnS1q8hbSxVzTub5xYu9FoFBwa7TMlzoVjLJUXvwzf4N9UoFgZoFpbmlYxoaS1F4rgNbIUDLLh3Ym2p387Jjd5G3gSXAWQRM+9hpZnNgnEzAsjPvh4ERvl8hPgrSjv5/An4Ru63W10P2wBMqiRffAVGblF+7VDQirlj0K3+0T+aHeEFMbZdKnaNi+1vEDPxuvYcVptCkurleLadtHcvhkiGdHHJyeUCZQEQv+RNyOHbJv3DenxdSsh5dv7k0kRuu1tsHisHScz7vID6KTtCnHKWZGBYT4nadDpsUygLp2oFdQXTchM9JWlKeFRvZ8Z+t+m0OIydj9qznN8cxZfMSs4u81iGuFeN6QNhfGiU+zamslr1vOAlSZoxgVScj1IWYxZZVRMVUMMxmWGpAAU7twjHjylGBx+ncqG5s5myQzWjA9FCqnPHEhled0jSJDgc5XmxxpozKaGdoUkF2jRq0bvz+DAIFOtCC52vVndKcc6/bdaBQTtM8qK3HX/TeAhPNPYOp6dA8WkWplAAPCxu3opUTLy22mX6JbwqSUw1M0dbxveMh8Keh0ovrDFlnI7aDao1oTG7boIBybXkY7N/E= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ba3571b7-be4f-49c2-6866-08da3d79e222 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:12.4026 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6kOv6oWgUlHIqXgI25U5eIFMex1lMNyh2XSC8P2lqnhF2NxLTdQSIx/Y+ptBc78lB7zbXCFUOJQ7aVcnm6BEVg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/mac80211.c | 2392 +++++++++++++++++++ 1 file changed, 2392 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/mac80211.c diff --git a/drivers/net/wireless/celeno/cl8k/mac80211.c b/drivers/net/wireless/celeno/cl8k/mac80211.c new file mode 100644 index 000000000000..13989327ccdb --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/mac80211.c @@ -0,0 +1,2392 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include + +#include "debug.h" +#include "utils.h" +#include "sta.h" +#include "dfs.h" +#include "regdom.h" +#include "hw.h" +#include "mac80211.h" +#include "ampdu.h" +#include "tx.h" +#include "radio.h" +#include "recovery.h" +#include "rates.h" +#include "temperature.h" +#include "vns.h" +#include "key.h" +#include "version.h" +#include "power.h" +#include "stats.h" +#include "scan.h" +#include "mac_addr.h" +#include "chip.h" + +#define RATE_1_MBPS 10 +#define RATE_2_MBPS 20 +#define RATE_5_5_MBPS 55 +#define RATE_11_MBPS 110 +#define RATE_6_MBPS 60 +#define RATE_9_MBPS 90 +#define RATE_12_MBPS 120 +#define RATE_18_MBPS 180 +#define RATE_24_MBPS 240 +#define RATE_36_MBPS 360 +#define RATE_48_MBPS 480 +#define RATE_54_MBPS 540 + +#define CL_HT_CAPABILITIES \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_1, \ + .mcs = { \ + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ + }, \ +} + +#define CL_VHT_CAPABILITIES \ +{ \ + .vht_supported = false, \ + .cap = 0, \ + .vht_mcs = { \ + .rx_mcs_map = cpu_to_le16( \ + IEEE80211_VHT_MCS_SUPPORT_0_7 << 0 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ + .tx_mcs_map = cpu_to_le16( \ + IEEE80211_VHT_MCS_SUPPORT_0_7 << 0 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | \ + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14), \ + } \ +} + +#define CL_HE_CAP_ELEM_STATION \ +{ \ + .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE, \ + .mac_cap_info[1] = 0, \ + .mac_cap_info[2] = 0, \ + .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2, \ + .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR, \ + .mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX, \ + .phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G, \ + .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A, \ + .phy_cap_info[2] = 0, \ + .phy_cap_info[3] = 0, \ + .phy_cap_info[4] = 0, \ + .phy_cap_info[5] = 0, \ + .phy_cap_info[6] = 0, \ + .phy_cap_info[7] = 0, \ + .phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, \ + .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, \ + .phy_cap_info[10] = 0, \ +} + +#define CL_HE_CAP_ELEM_AP \ +{ \ + .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE, \ + .mac_cap_info[1] = 0, \ + .mac_cap_info[2] = 0, \ + .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2, \ + .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR, \ + .mac_cap_info[5] = 0, \ + .phy_cap_info[0] = 0, \ + .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A, \ + .phy_cap_info[2] = 0, \ + .phy_cap_info[3] = 0, \ + .phy_cap_info[4] = 0, \ + .phy_cap_info[5] = 0, \ + .phy_cap_info[6] = 0, \ + .phy_cap_info[7] = 0, \ + .phy_cap_info[8] = 0, \ + .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, \ + .phy_cap_info[10] = 0, \ +} + +#define CL_HE_CAP_ELEM_MESH_POINT \ +{ \ + .mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE, \ + .mac_cap_info[1] = 0, \ + .mac_cap_info[2] = 0, \ + .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2, \ + .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_BQR, \ + .mac_cap_info[5] = 0, \ + .phy_cap_info[0] = 0, \ + .phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A, \ + .phy_cap_info[2] = 0, \ + .phy_cap_info[3] = 0, \ + .phy_cap_info[4] = 0, \ + .phy_cap_info[5] = 0, \ + .phy_cap_info[6] = 0, \ + .phy_cap_info[7] = 0, \ + .phy_cap_info[8] = 0, \ + .phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, \ + .phy_cap_info[10] = 0, \ +} + +#define CL_HE_MCS_NSS_SUPP \ +{ \ + .rx_mcs_80 = cpu_to_le16(0xff00), \ + .tx_mcs_80 = cpu_to_le16(0xff00), \ + .rx_mcs_160 = cpu_to_le16(0xff00), \ + .tx_mcs_160 = cpu_to_le16(0xff00), \ + .rx_mcs_80p80 = cpu_to_le16(0xffff), \ + .tx_mcs_80p80 = cpu_to_le16(0xffff), \ +} + +#define RATE(_bitrate, _hw_rate, _flags) { \ + .bitrate = (_bitrate), \ + .flags = (_flags), \ + .hw_value = (_hw_rate), \ +} + +#define CHAN(_freq, _idx) { \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 18, \ +} + +static struct ieee80211_sband_iftype_data cl_he_data[] = { + { + .types_mask = BIT(NL80211_IFTYPE_STATION), + .he_cap = { + .has_he = true, + .he_cap_elem = CL_HE_CAP_ELEM_STATION, + .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP, + }, + }, + { + .types_mask = BIT(NL80211_IFTYPE_AP), + .he_cap = { + .has_he = true, + .he_cap_elem = CL_HE_CAP_ELEM_AP, + .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP, + }, + }, + { + .types_mask = BIT(NL80211_IFTYPE_MESH_POINT), + .he_cap = { + .has_he = true, + .he_cap_elem = CL_HE_CAP_ELEM_MESH_POINT, + .he_mcs_nss_supp = CL_HE_MCS_NSS_SUPP, + }, + }, +}; + +static struct ieee80211_rate cl_ratetable[] = { + RATE(10, 0x00, 0), + RATE(20, 0x01, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, 0x02, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, 0x03, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0x04, 0), + RATE(90, 0x05, 0), + RATE(120, 0x06, 0), + RATE(180, 0x07, 0), + RATE(240, 0x08, 0), + RATE(360, 0x09, 0), + RATE(480, 0x0A, 0), + RATE(540, 0x0B, 0), +}; + +/* The channels indexes here are not used anymore */ +static struct ieee80211_channel cl_2ghz_channels[] = { + CHAN(2412, 0), + CHAN(2417, 1), + CHAN(2422, 2), + CHAN(2427, 3), + CHAN(2432, 4), + CHAN(2437, 5), + CHAN(2442, 6), + CHAN(2447, 7), + CHAN(2452, 8), + CHAN(2457, 9), + CHAN(2462, 10), + CHAN(2467, 11), + CHAN(2472, 12), + CHAN(2484, 13), +}; + +static struct ieee80211_channel cl_5ghz_channels[] = { + CHAN(5180, 0), /* 36 - 20MHz */ + CHAN(5200, 1), /* 40 - 20MHz */ + CHAN(5220, 2), /* 44 - 20MHz */ + CHAN(5240, 3), /* 48 - 20MHz */ + CHAN(5260, 4), /* 52 - 20MHz */ + CHAN(5280, 5), /* 56 - 20MHz */ + CHAN(5300, 6), /* 60 - 20MHz */ + CHAN(5320, 7), /* 64 - 20MHz */ + CHAN(5500, 8), /* 100 - 20MHz */ + CHAN(5520, 9), /* 104 - 20MHz */ + CHAN(5540, 10), /* 108 - 20MHz */ + CHAN(5560, 11), /* 112 - 20MHz */ + CHAN(5580, 12), /* 116 - 20MHz */ + CHAN(5600, 13), /* 120 - 20MHz */ + CHAN(5620, 14), /* 124 - 20MHz */ + CHAN(5640, 15), /* 128 - 20MHz */ + CHAN(5660, 16), /* 132 - 20MHz */ + CHAN(5680, 17), /* 136 - 20MHz */ + CHAN(5700, 18), /* 140 - 20MHz */ + CHAN(5720, 19), /* 144 - 20MHz */ + CHAN(5745, 20), /* 149 - 20MHz */ + CHAN(5765, 21), /* 153 - 20MHz */ + CHAN(5785, 22), /* 157 - 20MHz */ + CHAN(5805, 23), /* 161 - 20MHz */ + CHAN(5825, 24), /* 165 - 20MHz */ +}; + +static struct ieee80211_channel cl_6ghz_channels[] = { + CHAN(5955, 1), /* 1 - 20MHz */ + CHAN(5935, 2), /* 2 - 20MHz */ + CHAN(5975, 5), /* 5 - 20MHz */ + CHAN(5995, 9), /* 9 - 20MHz */ + CHAN(6015, 13), /* 13 - 20MHz */ + CHAN(6035, 17), /* 17 - 20MHz */ + CHAN(6055, 21), /* 21 - 20MHz */ + CHAN(6075, 25), /* 25 - 20MHz */ + CHAN(6095, 29), /* 29 - 20MHz */ + CHAN(6115, 33), /* 33 - 20MHz */ + CHAN(6135, 37), /* 37 - 20MHz */ + CHAN(6155, 41), /* 41 - 20MHz */ + CHAN(6175, 45), /* 45 - 20MHz */ + CHAN(6195, 49), /* 49 - 20MHz */ + CHAN(6215, 53), /* 53 - 20MHz */ + CHAN(6235, 57), /* 57 - 20MHz */ + CHAN(6255, 61), /* 61 - 20MHz */ + CHAN(6275, 65), /* 65 - 20MHz */ + CHAN(6295, 69), /* 69 - 20MHz */ + CHAN(6315, 73), /* 73 - 20MHz */ + CHAN(6335, 77), /* 77 - 20MHz */ + CHAN(6355, 81), /* 81 - 20MHz */ + CHAN(6375, 85), /* 85 - 20MHz */ + CHAN(6395, 89), /* 89 - 20MHz */ + CHAN(6415, 93), /* 93 - 20MHz */ + CHAN(6435, 97), /* 97 - 20MHz */ + CHAN(6455, 101), /* 101 - 20MHz */ + CHAN(6475, 105), /* 105 - 20MHz */ + CHAN(6495, 109), /* 109 - 20MHz */ + CHAN(6515, 113), /* 113 - 20MHz */ + CHAN(6535, 117), /* 117 - 20MHz */ + CHAN(6555, 121), /* 121 - 20MHz */ + CHAN(6575, 125), /* 125 - 20MHz */ + CHAN(6595, 129), /* 129 - 20MHz */ + CHAN(6615, 133), /* 133 - 20MHz */ + CHAN(6635, 137), /* 137 - 20MHz */ + CHAN(6655, 141), /* 141 - 20MHz */ + CHAN(6675, 145), /* 145 - 20MHz */ + CHAN(6695, 149), /* 149 - 20MHz */ + CHAN(6715, 153), /* 153 - 20MHz */ + CHAN(6735, 157), /* 157 - 20MHz */ + CHAN(6755, 161), /* 161 - 20MHz */ + CHAN(6775, 165), /* 165 - 20MHz */ + CHAN(6795, 169), /* 169 - 20MHz */ + CHAN(6815, 173), /* 173 - 20MHz */ + CHAN(6835, 177), /* 177 - 20MHz */ + CHAN(6855, 181), /* 181 - 20MHz */ + CHAN(6875, 188), /* 185 - 20MHz */ + CHAN(6895, 189), /* 189 - 20MHz */ + CHAN(6915, 193), /* 193 - 20MHz */ + CHAN(6935, 197), /* 197 - 20MHz */ + CHAN(6955, 201), /* 201 - 20MHz */ + CHAN(6975, 205), /* 205 - 20MHz */ + CHAN(6995, 209), /* 209 - 20MHz */ + CHAN(7015, 213), /* 213 - 20MHz */ + CHAN(7035, 217), /* 217 - 20MHz */ + CHAN(7055, 221), /* 221 - 20MHz */ + CHAN(7075, 225), /* 225 - 20MHz */ + CHAN(7095, 229), /* 229 - 20MHz */ + CHAN(7115, 233), /* 233 - 20MHz */ +}; + +static struct ieee80211_supported_band cl_band_2ghz = { + .channels = cl_2ghz_channels, + .n_channels = ARRAY_SIZE(cl_2ghz_channels), + .bitrates = cl_ratetable, + .n_bitrates = ARRAY_SIZE(cl_ratetable), + .ht_cap = CL_HT_CAPABILITIES, + .vht_cap = CL_VHT_CAPABILITIES, +}; + +static struct ieee80211_supported_band cl_band_5ghz = { + .channels = cl_5ghz_channels, + .n_channels = ARRAY_SIZE(cl_5ghz_channels), + .bitrates = &cl_ratetable[4], + .n_bitrates = ARRAY_SIZE(cl_ratetable) - 4, + .ht_cap = CL_HT_CAPABILITIES, + .vht_cap = CL_VHT_CAPABILITIES, +}; + +static struct ieee80211_supported_band cl_band_6ghz = { + .channels = cl_6ghz_channels, + .n_channels = ARRAY_SIZE(cl_6ghz_channels), + .bitrates = &cl_ratetable[4], + .n_bitrates = ARRAY_SIZE(cl_ratetable) - 4, +}; + +static const struct ieee80211_iface_limit cl_limits[] = { + { + .max = ARRAY_SIZE(((struct cl_hw *)0)->addresses), + .types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_MESH_POINT), + }, +}; + +#define WLAN_EXT_CAPA1_2040_BSS_COEX_MGMT_ENABLED BIT(0) + +static u8 cl_if_types_ext_capa_ap_24g[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, +}; + +static const struct wiphy_iftype_ext_capab cl_iftypes_ext_capa_24g[] = { + { + .iftype = NL80211_IFTYPE_AP, + .extended_capabilities = cl_if_types_ext_capa_ap_24g, + .extended_capabilities_mask = cl_if_types_ext_capa_ap_24g, + .extended_capabilities_len = sizeof(cl_if_types_ext_capa_ap_24g), + }, +}; + +static u8 cl_if_types_ext_capa_ap_5g[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, +}; + +static const struct wiphy_iftype_ext_capab cl_iftypes_ext_capa_5g[] = { + { + .iftype = NL80211_IFTYPE_AP, + .extended_capabilities = cl_if_types_ext_capa_ap_5g, + .extended_capabilities_mask = cl_if_types_ext_capa_ap_5g, + .extended_capabilities_len = sizeof(cl_if_types_ext_capa_ap_5g), + }, +}; + +static u8 cl_if_types_ext_capa_ap_6g[] = { + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, +}; + +static const struct wiphy_iftype_ext_capab cl_iftypes_ext_capa_6g[] = { + { + .iftype = NL80211_IFTYPE_AP, + .extended_capabilities = cl_if_types_ext_capa_ap_6g, + .extended_capabilities_mask = cl_if_types_ext_capa_ap_6g, + .extended_capabilities_len = sizeof(cl_if_types_ext_capa_ap_6g), + }, +}; + +static struct ieee80211_iface_combination cl_combinations[] = { + { + .limits = cl_limits, + .n_limits = ARRAY_SIZE(cl_limits), + .num_different_channels = 1, + .max_interfaces = ARRAY_SIZE(((struct cl_hw *)0)->addresses), + .beacon_int_min_gcd = 100, + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160), + } +}; + +static const int cl_ac2hwq[AC_MAX] = { + [NL80211_TXQ_Q_VO] = CL_HWQ_VO, + [NL80211_TXQ_Q_VI] = CL_HWQ_VI, + [NL80211_TXQ_Q_BE] = CL_HWQ_BE, + [NL80211_TXQ_Q_BK] = CL_HWQ_BK +}; + +static const int cl_ac2edca[AC_MAX] = { + [NL80211_TXQ_Q_VO] = EDCA_AC_VO, + [NL80211_TXQ_Q_VI] = EDCA_AC_VI, + [NL80211_TXQ_Q_BE] = EDCA_AC_BE, + [NL80211_TXQ_Q_BK] = EDCA_AC_BK +}; + +static u8 cl_he_mcs_supp_tx(struct cl_hw *cl_hw, u8 nss) +{ + u8 mcs = cl_hw->conf->ce_he_mcs_nss_supp_tx[nss]; + + switch (mcs) { + case WRS_MCS_7: + return IEEE80211_HE_MCS_SUPPORT_0_7; + case WRS_MCS_9: + return IEEE80211_HE_MCS_SUPPORT_0_9; + case WRS_MCS_11: + return IEEE80211_HE_MCS_SUPPORT_0_11; + } + + cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7, 9 or 11!\n", mcs, nss); + return IEEE80211_HE_MCS_NOT_SUPPORTED; +} + +static u8 cl_he_mcs_supp_rx(struct cl_hw *cl_hw, u8 nss) +{ + u8 mcs = cl_hw->conf->ce_he_mcs_nss_supp_rx[nss]; + + switch (mcs) { + case WRS_MCS_7: + return IEEE80211_HE_MCS_SUPPORT_0_7; + case WRS_MCS_9: + return IEEE80211_HE_MCS_SUPPORT_0_9; + case WRS_MCS_11: + return IEEE80211_HE_MCS_SUPPORT_0_11; + } + + cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7, 9 or 11!\n", mcs, nss); + return IEEE80211_HE_MCS_NOT_SUPPORTED; +} + +static u8 cl_vht_mcs_supp_tx(struct cl_hw *cl_hw, u8 nss) +{ + u8 mcs = cl_hw->conf->ce_vht_mcs_nss_supp_tx[nss]; + + switch (mcs) { + case WRS_MCS_7: + return IEEE80211_VHT_MCS_SUPPORT_0_7; + case WRS_MCS_8: + return IEEE80211_VHT_MCS_SUPPORT_0_8; + case WRS_MCS_9: + return IEEE80211_VHT_MCS_SUPPORT_0_9; + } + + cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7-9!\n", mcs, nss); + return IEEE80211_VHT_MCS_NOT_SUPPORTED; +} + +static u8 cl_vht_mcs_supp_rx(struct cl_hw *cl_hw, u8 nss) +{ + u8 mcs = cl_hw->conf->ce_vht_mcs_nss_supp_rx[nss]; + + switch (mcs) { + case WRS_MCS_7: + return IEEE80211_VHT_MCS_SUPPORT_0_7; + case WRS_MCS_8: + return IEEE80211_VHT_MCS_SUPPORT_0_8; + case WRS_MCS_9: + return IEEE80211_VHT_MCS_SUPPORT_0_9; + } + + cl_dbg_err(cl_hw, "Invalid mcs %u for nss %u. Must be 7-9!\n", mcs, nss); + return IEEE80211_VHT_MCS_NOT_SUPPORTED; +} + +static void cl_set_he_6ghz_capab(struct cl_hw *cl_hw) +{ + struct ieee80211_he_6ghz_capa *he_6ghz_cap0 = &cl_hw->iftype_data[0].he_6ghz_capa; + struct ieee80211_he_6ghz_capa *he_6ghz_cap1 = &cl_hw->iftype_data[1].he_6ghz_capa; + struct ieee80211_he_6ghz_capa *he_6ghz_cap2 = &cl_hw->iftype_data[2].he_6ghz_capa; + + he_6ghz_cap0->capa = cpu_to_le16(IEEE80211_HT_MPDU_DENSITY_1); + + he_6ghz_cap0->capa |= + cpu_to_le16(cl_hw->conf->ci_max_mpdu_len << HE_6GHZ_CAP_MAX_MPDU_LEN_OFFSET); + he_6ghz_cap0->capa |= + cpu_to_le16(IEEE80211_VHT_MAX_AMPDU_1024K << HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP_OFFSET); + + he_6ghz_cap0->capa |= cpu_to_le16(IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS | + IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS); + + he_6ghz_cap1->capa = he_6ghz_cap0->capa; + he_6ghz_cap2->capa = he_6ghz_cap0->capa; +} + +static void _cl_set_he_capab(struct cl_hw *cl_hw, u8 idx) +{ + struct ieee80211_sta_he_cap *he_cap = &cl_hw->iftype_data[idx].he_cap; + struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp = &he_cap->he_mcs_nss_supp; + struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem; + u8 rx_nss = cl_hw->conf->ce_rx_nss; + u8 tx_nss = cl_hw->conf->ce_tx_nss; + int i = 0; + + if (BAND_IS_5G_6G(cl_hw)) { + he_cap_elem->phy_cap_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + + for (i = 0; i < rx_nss; i++) + he_mcs_nss_supp->rx_mcs_160 |= + cpu_to_le16(cl_he_mcs_supp_rx(cl_hw, i) << (i * 2)); + + for (i = 0; i < tx_nss; i++) + he_mcs_nss_supp->tx_mcs_160 |= + cpu_to_le16(cl_he_mcs_supp_tx(cl_hw, i) << (i * 2)); + + he_cap_elem->phy_cap_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; + + for (i = 0; i < rx_nss; i++) + he_mcs_nss_supp->rx_mcs_80 |= + cpu_to_le16(cl_he_mcs_supp_rx(cl_hw, i) << (i * 2)); + + for (i = 0; i < tx_nss; i++) + he_mcs_nss_supp->tx_mcs_80 |= + cpu_to_le16(cl_he_mcs_supp_tx(cl_hw, i) << (i * 2)); + } else { + he_cap_elem->phy_cap_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; + + for (i = 0; i < rx_nss; i++) + he_mcs_nss_supp->rx_mcs_80 |= + cpu_to_le16(cl_he_mcs_supp_rx(cl_hw, i) << (i * 2)); + + for (i = 0; i < tx_nss; i++) + he_mcs_nss_supp->tx_mcs_80 |= + cpu_to_le16(cl_he_mcs_supp_tx(cl_hw, i) << (i * 2)); + } + + for (i = rx_nss; i < 8; i++) { + he_mcs_nss_supp->rx_mcs_80 |= + cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_mcs_nss_supp->rx_mcs_160 |= + cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + } + + for (i = tx_nss; i < 8; i++) { + he_mcs_nss_supp->tx_mcs_80 |= + cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_mcs_nss_supp->tx_mcs_160 |= + cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + } + + if (cl_hw->conf->ci_he_rxldpc_en) + he_cap_elem->phy_cap_info[1] |= + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; + + if (cl_hw->conf->ci_rx_he_mu_ppdu) + he_cap_elem->phy_cap_info[3] |= + IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; + + if (cl_hw->conf->ci_bf_en) { + he_cap_elem->phy_cap_info[3] |= + IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; + he_cap_elem->phy_cap_info[5] |= + IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_4; + } +} + +static void cl_set_he_capab(struct cl_hw *cl_hw) +{ + struct ieee80211_sta_he_cap *he_cap0 = &cl_hw->iftype_data[0].he_cap; + struct ieee80211_he_cap_elem *he_cap_elem = &he_cap0->he_cap_elem; + struct cl_tcv_conf *conf = cl_hw->conf; + u8 tf_mac_pad_dur = conf->ci_tf_mac_pad_dur; + + memcpy(&cl_hw->iftype_data, cl_he_data, sizeof(cl_hw->iftype_data)); + + if (tf_mac_pad_dur == 1) + he_cap_elem->mac_cap_info[1] |= IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US; + else if (tf_mac_pad_dur == 2) + he_cap_elem->mac_cap_info[1] |= IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; + + _cl_set_he_capab(cl_hw, 0); + _cl_set_he_capab(cl_hw, 1); + _cl_set_he_capab(cl_hw, 2); + + if (cl_band_is_6g(cl_hw)) + cl_set_he_6ghz_capab(cl_hw); + + cl_hw->sband.n_iftype_data = ARRAY_SIZE(cl_he_data); + cl_hw->sband.iftype_data = cl_hw->iftype_data; +} + +#define RATE_1_MBPS 10 +#define RATE_2_MBPS 20 +#define RATE_5_5_MBPS 55 +#define RATE_11_MBPS 110 +#define RATE_6_MBPS 60 +#define RATE_9_MBPS 90 +#define RATE_12_MBPS 120 +#define RATE_18_MBPS 180 +#define RATE_24_MBPS 240 +#define RATE_36_MBPS 360 +#define RATE_48_MBPS 480 +#define RATE_54_MBPS 540 + +static u16 cl_cap_convert_rate_to_bitmap(u16 rate) +{ + switch (rate) { + case RATE_1_MBPS: + return BIT(0); + case RATE_2_MBPS: + return BIT(1); + case RATE_5_5_MBPS: + return BIT(2); + case RATE_11_MBPS: + return BIT(3); + case RATE_6_MBPS: + return BIT(4); + case RATE_9_MBPS: + return BIT(5); + case RATE_12_MBPS: + return BIT(6); + case RATE_18_MBPS: + return BIT(7); + case RATE_24_MBPS: + return BIT(8); + case RATE_36_MBPS: + return BIT(9); + case RATE_48_MBPS: + return BIT(10); + case RATE_54_MBPS: + return BIT(11); + default: + return 0; + } +} + +u16 cl_cap_set_mesh_basic_rates(struct cl_hw *cl_hw) +{ + int i; + struct cl_tcv_conf *conf = cl_hw->conf; + u16 basic_rates = 0; + + for (i = 0; i < MESH_BASIC_RATE_MAX; i++) + basic_rates |= cl_cap_convert_rate_to_bitmap(conf->ci_mesh_basic_rates[i]); + + return basic_rates; +} + +void cl_cap_dyn_params(struct cl_hw *cl_hw) +{ + struct ieee80211_hw *hw = cl_hw->hw; + struct wiphy *wiphy = hw->wiphy; + struct cl_tcv_conf *conf = cl_hw->conf; + u8 rx_nss = conf->ce_rx_nss; + u8 tx_nss = conf->ce_tx_nss; + u8 guard_interval = conf->ci_short_guard_interval; + u8 i; + u8 bw = cl_hw->conf->ci_cap_bandwidth; + struct ieee80211_supported_band *sband = &cl_hw->sband; + struct ieee80211_sta_ht_cap *sband_ht_cap = &sband->ht_cap; + struct ieee80211_sta_vht_cap *sband_vht_cap = &sband->vht_cap; + + if (cl_band_is_6g(cl_hw)) { + memcpy(sband, &cl_band_6ghz, sizeof(struct ieee80211_supported_band)); + } else if (cl_band_is_5g(cl_hw)) { + memcpy(sband, &cl_band_5ghz, sizeof(struct ieee80211_supported_band)); + } else { + memcpy(sband, &cl_band_2ghz, sizeof(struct ieee80211_supported_band)); + + if (!conf->ci_vht_cap_24g) + memset(&sband->vht_cap, 0, sizeof(struct ieee80211_sta_vht_cap)); + } + + /* 6GHz doesn't support HT/VHT */ + if (!cl_band_is_6g(cl_hw)) { + if (bw > CHNL_BW_20) + sband_ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + + /* Guard_interval */ + if (guard_interval) { + sband_ht_cap->cap |= IEEE80211_HT_CAP_SGI_20; + + if (bw >= CHNL_BW_40) + sband_ht_cap->cap |= IEEE80211_HT_CAP_SGI_40; + + if (bw >= CHNL_BW_80) + sband_vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_80; + + if (bw == CHNL_BW_160) + sband_vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_160; + } + } + + /* Amsdu */ + cl_rx_amsdu_hw_en(hw, conf->ce_rxamsdu_en); + cl_hw->txamsdu_en = conf->ce_txamsdu_en; + + /* Hw flags */ + ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, QUEUE_CONTROL); + ieee80211_hw_set(hw, WANT_MONITOR_VIF); + ieee80211_hw_set(hw, SPECTRUM_MGMT); + ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, NO_AUTO_VIF); + ieee80211_hw_set(hw, MFP_CAPABLE); + ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK); + ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD); + + wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; + wiphy->features |= NL80211_FEATURE_AP_SCAN; + wiphy->available_antennas_tx = ANT_MASK(cl_hw->max_antennas); + wiphy->available_antennas_rx = ANT_MASK(cl_hw->max_antennas); + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); + + if (conf->ci_fast_rx_en) { + ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); + ieee80211_hw_set(hw, AP_LINK_PS); + } + + if (cl_band_is_6g(cl_hw)) { + hw->wiphy->iftype_ext_capab = cl_iftypes_ext_capa_6g; + hw->wiphy->num_iftype_ext_capab = ARRAY_SIZE(cl_iftypes_ext_capa_6g); + } else if (cl_band_is_5g(cl_hw)) { + hw->wiphy->iftype_ext_capab = cl_iftypes_ext_capa_5g; + hw->wiphy->num_iftype_ext_capab = ARRAY_SIZE(cl_iftypes_ext_capa_5g); + } else if (cl_band_is_24g(cl_hw)) { + /* Turn on "20/40 Coex Mgmt Support" bit (24g only) */ + if (conf->ce_acs_coex_en) { + u8 *ext_cap = (u8 *)cl_iftypes_ext_capa_24g[0].extended_capabilities; + + ext_cap[0] |= WLAN_EXT_CAPA1_2040_BSS_COEX_MGMT_ENABLED; + } + + hw->wiphy->iftype_ext_capab = cl_iftypes_ext_capa_24g; + hw->wiphy->num_iftype_ext_capab = ARRAY_SIZE(cl_iftypes_ext_capa_24g); + } + + /* + * To disable the dynamic PS we say to the stack that we support it in + * HW. This will force mac80211 rely on us to handle this. + */ + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + + if (conf->ci_agg_tx) + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_MESH_POINT); + + wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_IBSS_RSN; + + if (conf->ci_uapsd_en) + wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + + /* Modify MAX BSS num according to the desired config value */ + for (i = 0; i < ARRAY_SIZE(cl_combinations); i++) + cl_combinations[i].max_interfaces = conf->ci_max_bss_num; + wiphy->iface_combinations = cl_combinations; + wiphy->n_iface_combinations = ARRAY_SIZE(cl_combinations); + + /* + * hw_scan ops may ask driver to forge active scan request. So the + * scan capabs are filled in (the are same as inside mac80211). + * However, they are not representing real hw_scan logic, since it will + * fallback to the sw_scan for active scan request. + **/ + wiphy->max_scan_ssids = 4; + wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + + hw->max_rates = IEEE80211_TX_MAX_RATES; + hw->max_report_rates = IEEE80211_TX_MAX_RATES; + hw->max_rate_tries = 1; + + hw->max_tx_aggregation_subframes = conf->ce_max_agg_size_tx; + hw->max_rx_aggregation_subframes = conf->ce_max_agg_size_rx; + + hw->vif_data_size = sizeof(struct cl_vif); + hw->sta_data_size = sizeof(struct cl_sta); + + hw->extra_tx_headroom = 0; + hw->queues = IEEE80211_MAX_QUEUES; + hw->offchannel_tx_hw_queue = CL_HWQ_VO; + + if (!cl_band_is_6g(cl_hw)) { + if (conf->ci_ht_rxldpc_en) + sband_ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; + + sband_ht_cap->cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + sband_vht_cap->cap |= cl_hw->conf->ci_max_mpdu_len; + if (conf->ci_bf_en) { + sband_vht_cap->cap |= + IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + (3 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT) | + (3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); + } + } + + if (cl_band_is_5g(cl_hw) || (cl_band_is_24g(cl_hw) && conf->ci_vht_cap_24g)) { + if (bw == CHNL_BW_160) + sband_vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + + sband_vht_cap->cap |= (conf->ci_max_ampdu_len_exp << + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); + + if (conf->ci_vht_rxldpc_en) + sband_vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + + sband_vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN; + sband_vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; + + sband_vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(0); + sband_vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(0); + + for (i = 0; i < rx_nss; i++) + sband_vht_cap->vht_mcs.rx_mcs_map |= + cpu_to_le16(cl_vht_mcs_supp_rx(cl_hw, i) << (i * 2)); + + for (; i < 8; i++) + sband_vht_cap->vht_mcs.rx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2)); + + for (i = 0; i < tx_nss; i++) + sband_vht_cap->vht_mcs.tx_mcs_map |= + cpu_to_le16(cl_vht_mcs_supp_tx(cl_hw, i) << (i * 2)); + + for (; i < 8; i++) + sband_vht_cap->vht_mcs.tx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2)); + + sband_vht_cap->vht_supported = true; + } + + /* 6GHz band supports HE only */ + if (!cl_band_is_6g(cl_hw)) + for (i = 0; i < rx_nss; i++) + sband_ht_cap->mcs.rx_mask[i] = U8_MAX; + + cl_set_he_capab(cl_hw); + + /* Get channels and power limitations information from ChannelInfo file */ + cl_chan_info_init(cl_hw); + + if (cl_band_is_6g(cl_hw)) { + wiphy->bands[NL80211_BAND_2GHZ] = NULL; + wiphy->bands[NL80211_BAND_5GHZ] = NULL; + wiphy->bands[NL80211_BAND_6GHZ] = sband; + } else if (cl_band_is_5g(cl_hw)) { + wiphy->bands[NL80211_BAND_2GHZ] = NULL; + wiphy->bands[NL80211_BAND_5GHZ] = sband; + wiphy->bands[NL80211_BAND_6GHZ] = NULL; + } else { + wiphy->bands[NL80211_BAND_2GHZ] = sband; + wiphy->bands[NL80211_BAND_5GHZ] = NULL; + wiphy->bands[NL80211_BAND_6GHZ] = NULL; + } +} + +enum he_pkt_ext_constellations { + HE_PKT_EXT_BPSK = 0, + HE_PKT_EXT_QPSK, + HE_PKT_EXT_16QAM, + HE_PKT_EXT_64QAM, + HE_PKT_EXT_256QAM, + HE_PKT_EXT_1024QAM, + HE_PKT_EXT_RESERVED, + HE_PKT_EXT_NONE, +}; + +static u8 mcs_to_constellation[WRS_MCS_MAX_HE] = { + HE_PKT_EXT_BPSK, + HE_PKT_EXT_QPSK, + HE_PKT_EXT_QPSK, + HE_PKT_EXT_16QAM, + HE_PKT_EXT_16QAM, + HE_PKT_EXT_64QAM, + HE_PKT_EXT_64QAM, + HE_PKT_EXT_64QAM, + HE_PKT_EXT_256QAM, + HE_PKT_EXT_256QAM, + HE_PKT_EXT_1024QAM, + HE_PKT_EXT_1024QAM +}; + +#define QAM_THR_1 0 +#define QAM_THR_2 1 +#define QAM_THR_MAX 2 + +static u8 cl_get_ppe_val(u8 *ppe, u8 ppe_pos_bit) +{ + u8 byte_num = ppe_pos_bit / 8; + u8 bit_num = ppe_pos_bit % 8; + u8 residue_bits; + u8 res; + + if (bit_num <= 5) + return (ppe[byte_num] >> bit_num) & + (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE) - 1); + + /* + * If bit_num > 5, we have to combine bits with next byte. + * Calculate how many bits we need to take from current byte (called + * here "residue_bits"), and add them to bits from next byte. + */ + residue_bits = 8 - bit_num; + + res = (ppe[byte_num + 1] & + (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits) - 1)) << + residue_bits; + res += (ppe[byte_num] >> bit_num) & (BIT(residue_bits) - 1); + + return res; +} + +static void cl_set_fixed_ppe_val(u8 pe_dur[CHNL_BW_MAX][WRS_MCS_MAX_HE], u8 dur) +{ + u8 val = ((dur << 6) | (dur << 4) | (dur << 2) | dur); + + memset(pe_dur, val, CHNL_BW_MAX * WRS_MCS_MAX_HE); +} + +void cl_cap_ppe_duration(struct cl_hw *cl_hw, struct ieee80211_sta *sta, + u8 pe_dur[CHNL_BW_MAX][WRS_MCS_MAX_HE]) +{ + /* Force NVRAM parameter */ + if (cl_hw->conf->ci_pe_duration <= PPE_16US) { + cl_set_fixed_ppe_val(pe_dur, cl_hw->conf->ci_pe_duration); + return; + } + + /* + * If STA sets the PPE Threshold Present subfield to 0, + * the value should be set according to the Nominal Packet Padding subfield + */ + if ((sta->he_cap.he_cap_elem.phy_cap_info[6] & + IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0) { + switch (sta->he_cap.he_cap_elem.phy_cap_info[9] & + IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK) { + case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US: + cl_set_fixed_ppe_val(pe_dur, PPE_0US); + break; + case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US: + cl_set_fixed_ppe_val(pe_dur, PPE_8US); + break; + case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US: + default: + cl_set_fixed_ppe_val(pe_dur, PPE_16US); + break; + } + + return; + } + + /* + * struct iwl_he_pkt_ext - QAM thresholds + * The required PPE is set via HE Capabilities IE, per Nss x BW x MCS + * The IE is organized in the following way: + * Support for Nss x BW (or RU) matrix: + * (0=SISO, 1=MIMO2) x (0-20MHz, 1-40MHz, 2-80MHz, 3-160MHz) + * Each entry contains 2 QAM thresholds for 8us and 16us: + * 0=BPSK, 1=QPSK, 2=16QAM, 3=64QAM, 4=256QAM, 5=1024QAM, 6=RES, 7=NONE + * i.e. QAM_th1 < QAM_th2 such if TX uses QAM_tx: + * QAM_tx < QAM_th1 --> PPE=0us + * QAM_th1 <= QAM_tx < QAM_th2 --> PPE=8us + * QAM_th2 <= QAM_tx --> PPE=16us + * @pkt_ext_qam_th: QAM thresholds + * For each Nss/Bw define 2 QAM thrsholds (0..5) + * For rates below the low_th, no need for PPE + * For rates between low_th and high_th, need 8us PPE + * For rates equal or higher then the high_th, need 16us PPE + * Nss (0-siso, 1-mimo2) x BW (0-20MHz, 1-40MHz, 2-80MHz, 3-160MHz) x + * (0-low_th, 1-high_th) + */ + u8 pkt_ext_qam_th[WRS_SS_MAX][CHNL_BW_MAX][QAM_THR_MAX]; + + /* If PPE Thresholds exist, parse them into a FW-familiar format. */ + u8 nss = (sta->he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1; + u8 ru_index_bitmap = u32_get_bits(sta->he_cap.ppe_thres[0], + IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK); + u8 *ppe = &sta->he_cap.ppe_thres[0]; + u8 ppe_pos_bit = 7; /* Starting after PPE header */ + u8 bw, ss, mcs, constellation; + + if (nss > WRS_SS_MAX) + nss = WRS_SS_MAX; + + for (ss = 0; ss < nss; ss++) { + u8 ru_index_tmp = ru_index_bitmap << 1; + + for (bw = 0; bw <= cl_hw->bw; bw++) { + ru_index_tmp >>= 1; + if (!(ru_index_tmp & 1)) + continue; + + pkt_ext_qam_th[ss][bw][QAM_THR_2] = cl_get_ppe_val(ppe, ppe_pos_bit); + ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE; + pkt_ext_qam_th[ss][bw][QAM_THR_1] = cl_get_ppe_val(ppe, ppe_pos_bit); + ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE; + } + } + + /* Reset PE duration before filling it */ + memset(pe_dur, 0, CHNL_BW_MAX * WRS_MCS_MAX_HE); + + for (ss = 0; ss < nss; ss++) { + for (bw = 0; bw <= cl_hw->bw; bw++) { + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) { + constellation = mcs_to_constellation[mcs]; + + if (constellation < pkt_ext_qam_th[ss][bw][QAM_THR_1]) + pe_dur[bw][mcs] |= (PPE_0US << (ss * 2)); + else if (constellation < pkt_ext_qam_th[ss][bw][QAM_THR_2]) + pe_dur[bw][mcs] |= (PPE_8US << (ss * 2)); + else + pe_dur[bw][mcs] |= (PPE_16US << (ss * 2)); + } + } + } +} + +static void cl_ops_tx_agg(struct cl_hw *cl_hw, + struct sk_buff *skb, + struct ieee80211_tx_info *tx_info, + struct cl_sta *cl_sta) +{ + cl_hw->tx_packet_cntr.forward.from_mac_agg++; + + if (!cl_sta) { + struct cl_vif *cl_vif = + (struct cl_vif *)tx_info->control.vif->drv_priv; + u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + u8 ac = tid_to_ac[tid]; + + kfree_skb(skb); + cl_dbg_err(cl_hw, "cl_sta null in agg packet\n"); + cl_hw->tx_packet_cntr.drop.sta_null_in_agg++; + cl_vif->trfc_cntrs[ac].tx_errors++; + return; + } + + /* AMSDU in HW can work only with header conversion. */ + tx_info->control.flags &= ~IEEE80211_TX_CTRL_AMSDU; + cl_tx_agg(cl_hw, cl_sta, skb, false, true); +} + +static void cl_ops_tx_single(struct cl_hw *cl_hw, + struct sk_buff *skb, + struct ieee80211_tx_info *tx_info, + struct cl_sta *cl_sta, + struct ieee80211_sta *sta) +{ + bool is_vns = cl_vns_is_very_near(cl_hw, cl_sta, skb); + + cl_hw->tx_packet_cntr.forward.from_mac_single++; + if (cl_hw->tx_db.block_prob_resp) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (ieee80211_is_probe_resp(hdr->frame_control)) { + struct cl_vif *cl_vif = NETDEV_TO_CL_VIF(skb->dev); + u8 ac = cl_vif->vif->hw_queue[skb_get_queue_mapping(skb)]; + + cl_tx_single_free_skb(cl_hw, skb); + cl_hw->tx_packet_cntr.drop.probe_response++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + } + + if (sta) { + u32 sta_vht_cap = sta->vht_cap.cap; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + + if (!(sta_vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) + goto out_tx; + + if (ieee80211_is_assoc_resp(mgmt->frame_control)) { + int len = skb->len - (mgmt->u.assoc_resp.variable - skb->data); + const u8 *vht_cap_addr = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, + mgmt->u.assoc_resp.variable, + len); + + if (vht_cap_addr) { + struct ieee80211_vht_cap *vht_cap = + (struct ieee80211_vht_cap *)(2 + vht_cap_addr); + + vht_cap->vht_cap_info &= + ~(cpu_to_le32(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK | + IEEE80211_VHT_CAP_SHORT_GI_160)); + } + } + } + +out_tx: + cl_tx_single(cl_hw, cl_sta, skb, is_vns, true); +} + +static u16 cl_ops_recalc_smallest_tbtt(struct cl_hw *cl_hw) +{ + struct wiphy *wiphy = cl_hw->hw->wiphy; + u8 cmb_idx = wiphy->n_iface_combinations - 1; + struct cl_vif *cl_vif = NULL; + u16 ret = 0; + u8 topology = cl_hw_get_iface_conf(cl_hw); + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + if (cl_vif->vif->type == NL80211_IFTYPE_STATION) + continue; + else if (ret == 0) + ret = cl_vif->vif->bss_conf.beacon_int; + else if (cl_vif->vif->bss_conf.beacon_int) + ret = min(ret, cl_vif->vif->bss_conf.beacon_int); + } + read_unlock_bh(&cl_hw->vif_db.lock); + + if (ret == 0) { + WARN_ONCE(topology != CL_IFCONF_STA && topology != CL_IFCONF_MESH_ONLY, + "invalid smallest beacon interval"); + return wiphy->iface_combinations[cmb_idx].beacon_int_min_gcd; + } + return ret; +} + +static void cl_ops_set_mesh_tbtt(struct cl_hw *cl_hw, u16 this_beacon_int, + u16 smallest_beacon_int) +{ + u16 div = this_beacon_int / smallest_beacon_int; + + cl_hw->mesh_tbtt_div = (div > 0) ? div : 1; +} + +void cl_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) +{ + /* + * Almost all traffic passing here is singles. + * Only when opening a BA session some packets with + * IEEE80211_TX_CTL_AMPDU set can pass here. + * All skbs passing here did header conversion. + */ + struct cl_hw *cl_hw = (struct cl_hw *)hw->priv; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = control->sta; + struct cl_sta *cl_sta = NULL; + + if (sta) { + cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + /* + * Prior to STA connection sta can be set but we don't + * want cl_sta to be used since it's not initialized yet + */ + if (cl_sta->sta_idx == STA_IDX_INVALID) + cl_sta = NULL; + } + + if (cl_recovery_in_progress(cl_hw)) { + cl_hw->tx_packet_cntr.drop.in_recovery++; + + if (cl_sta) { + struct cl_vif *cl_vif = cl_sta->cl_vif; + + if (cl_vif) { + struct ieee80211_vif *vif = cl_vif->vif; + u8 hw_queue; + + if (vif) { + hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)]; + cl_vif->trfc_cntrs[hw_queue].tx_dropped++; + } + } + } + + cl_tx_drop_skb(skb); + return; + } + + if (cl_sta && (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + goto fast_tx; + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) + cl_ops_tx_agg(cl_hw, skb, tx_info, cl_sta); + else + cl_ops_tx_single(cl_hw, skb, tx_info, cl_sta, sta); + + return; + +fast_tx: + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) + cl_tx_fast_agg(cl_hw, cl_sta, skb, true); + else + cl_tx_fast_single(cl_hw, cl_sta, skb, true); +} + +int cl_ops_start(struct ieee80211_hw *hw) +{ + /* + * Called before the first netdevice attached to the hardware + * is enabled. This should turn on the hardware and must turn on + * frame reception (for possibly enabled monitor interfaces.) + * Returns negative error codes, these may be seen in userspace, + * or zero. + * When the device is started it should not have a MAC address + * to avoid acknowledging frames before a non-monitor device + * is added. + * Must be implemented and can sleep. + * It does not return until the firmware is up and running. + */ + int error = 0; + struct cl_hw *cl_hw = hw->priv; + struct cl_tcv_conf *conf = cl_hw->conf; + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + + if (!cl_hw->ipc_env) { + CL_DBG_ERROR(cl_hw, "ipc_env is NULL!\n"); + return -ENODEV; + } + + /* Exits if device is already started */ + if (WARN_ON(test_bit(CL_DEV_STARTED, &cl_hw->drv_flags))) + return -EBUSY; + + /* Device is now started. + * Set CL_DEV_STARTED bit before the calls to other messages sent to + * firmware, to prevent them from being blocked* + */ + + set_bit(CL_DEV_STARTED, &cl_hw->drv_flags); + + if (!cl_recovery_in_progress(cl_hw)) { + /* Read version */ + error = cl_version_update(cl_hw); + if (error) + return error; + + error = cl_temperature_diff_e2p_read(cl_hw); + if (error) + return error; + } + + /* Set firmware debug module filter */ + error = cl_msg_tx_dbg_set_ce_mod_filter(cl_hw, conf->ci_fw_dbg_module); + if (error) + return error; + + /* Set firmware debug severity level */ + error = cl_msg_tx_dbg_set_sev_filter(cl_hw, conf->ci_fw_dbg_severity); + if (error) + return error; + + /* Set firmware rate fallbacks */ + error = cl_msg_tx_set_rate_fallback(cl_hw); + if (error) + return error; + + error = cl_msg_tx_ndp_tx_control(cl_hw, + conf->ci_sensing_ndp_tx_chain_mask, + conf->ci_sensing_ndp_tx_bw, + conf->ci_sensing_ndp_tx_format, + conf->ci_sensing_ndp_tx_num_ltf); + if (error) + return error; + + /* Set default, multicast, broadcast rate */ + cl_rate_ctrl_set_default(cl_hw); +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_rate_set(cl_hw); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_set(cl_hw, 0); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + + ieee80211_wake_queues(hw); + + clear_bit(CL_DEV_INIT, &cl_hw->drv_flags); + + cl_edca_hw_conf(cl_hw); + + if (!cl_hw->chip->conf->ce_calib_runtime_en) { + cl_calib_dcoc_init_calibration(cl_hw); + + if (cl_hw->chip->conf->ce_production_mode) + cl_calib_iq_init_production(cl_hw); + else if (!cl_hw_other || test_bit(CL_DEV_STARTED, &cl_hw_other->drv_flags)) + cl_calib_iq_init_calibration(cl_hw); + } + + return error; +} + +void cl_ops_stop(struct ieee80211_hw *hw) +{ + /* + * Called after last netdevice attached to the hardware + * is disabled. This should turn off the hardware (at least + * it must turn off frame reception.) + * May be called right after add_interface if that rejects + * an interface. If you added any work onto the mac80211 workqueue + * you should ensure to cancel it on this callback. + * Must be implemented and can sleep. + */ + struct cl_hw *cl_hw = hw->priv; + + /* Stop mac80211 queues */ + ieee80211_stop_queues(hw); + + /* Go to idle */ + cl_msg_tx_set_idle(cl_hw, MAC_IDLE_SYNC, true); + + /* + * Clear CL_DEV_STARTED to prevent message to be sent (besides reset and start). + * It also blocks transmission of new packets + */ + clear_bit(CL_DEV_STARTED, &cl_hw->drv_flags); + + cl_hw->num_ap_started = 0; + cl_hw->channel = 0; + cl_hw->radio_status = RADIO_STATUS_OFF; +} + +static int cl_add_interface_to_firmware(struct cl_hw *cl_hw, + struct ieee80211_vif *vif, u8 vif_index) +{ + struct mm_add_if_cfm *add_if_cfm; + int ret = 0; + + /* Forward the information to the firmware */ + ret = cl_msg_tx_add_if(cl_hw, vif, vif_index); + if (ret) + return ret; + + add_if_cfm = (struct mm_add_if_cfm *)(cl_hw->msg_cfm_params[MM_ADD_IF_CFM]); + if (!add_if_cfm) + return -ENOMSG; + + if (add_if_cfm->status != 0) { + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", add_if_cfm->status); + ret = -EIO; + } + + cl_msg_tx_free_cfm_params(cl_hw, MM_ADD_IF_CFM); + + return ret; +} + +static enum cl_iface_conf cl_recalc_hw_iface(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif = NULL; + u8 num_ap = 0, num_sta = 0, num_mp = 0; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + switch (cl_vif->vif->type) { + case NL80211_IFTYPE_AP: + num_ap++; + break; + case NL80211_IFTYPE_STATION: + num_sta++; + break; + case NL80211_IFTYPE_MESH_POINT: + num_mp++; + break; + default: + read_unlock_bh(&cl_hw->vif_db.lock); + return CL_IFCONF_MAX; + } + } + read_unlock_bh(&cl_hw->vif_db.lock); + + if (num_ap > 0 && num_sta == 0 && num_mp == 0) + return CL_IFCONF_AP; + if (num_ap == 0 && num_sta == 1 && num_mp == 0) + return CL_IFCONF_STA; + if (num_ap == 1 && num_sta == 1 && num_mp == 0) + return CL_IFCONF_REPEATER; + if (num_ap > 0 && num_sta == 0 && num_mp == 1) + return CL_IFCONF_MESH_AP; + if (num_ap == 0 && num_sta == 0 && num_mp == 1) + return CL_IFCONF_MESH_ONLY; + + return CL_IFCONF_MAX; +} + +int cl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + /* + * Called when a netdevice attached to the hardware is + * enabled. Because it is not called for monitor mode devices, start + * and stop must be implemented. + * The driver should perform any initialization it needs before + * the device can be enabled. The initial configuration for the + * interface is given in the conf parameter. + * The callback may refuse to add an interface by returning a + * negative error code (which will be seen in userspace.) + * Must be implemented and can sleep. + */ + struct cl_hw *cl_hw = hw->priv; + struct cl_chip *chip = cl_hw->chip; + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + struct wireless_dev *wdev = ieee80211_vif_to_wdev(vif); + struct net_device *dev = NULL; + u8 ac; + + if (!wdev) + return -ENODEV; + + dev = wdev->netdev; + if (!dev) + return -ENODEV; + + /* + * In recovery just send the message to firmware and exit + * (also make sure cl_vif already exists). + */ + if (cl_recovery_in_progress(cl_hw) && cl_vif_get_by_dev(cl_hw, dev)) + return cl_add_interface_to_firmware(cl_hw, vif, cl_vif->vif_index); + + cl_vif->cl_hw = cl_hw; + cl_vif->vif = vif; + cl_vif->dev = dev; + cl_vif->vif_index = cl_mac_addr_find_idx(cl_hw, vif->addr); + + /* MAC address not found - invalid address */ + if (cl_vif->vif_index == BSS_INVALID_IDX) { + cl_dbg_err(cl_hw, "Error: Invalid MAC address %pM for vif %s\n", + vif->addr, dev->name); + + return -EINVAL; + } + + if (chip->conf->ce_production_mode || vif->type == NL80211_IFTYPE_STATION) + cl_vif->tx_en = true; + + cl_vif_key_init(cl_vif); + + if (cl_add_interface_to_firmware(cl_hw, vif, cl_vif->vif_index)) + return -EINVAL; + + cl_vif->conn_data = kzalloc(sizeof(*cl_vif->conn_data), GFP_KERNEL); + if (!cl_vif->conn_data) { + cl_dbg_verbose(cl_hw, "Memory allocation for conn_data failed !!!\n"); + return -ENOMEM; + } + + if (vif->type != NL80211_IFTYPE_STATION) + vif->cab_queue = CL_HWQ_VO; + + cl_vif_add(cl_hw, cl_vif); + cl_hw_set_iface_conf(cl_hw, cl_recalc_hw_iface(cl_hw)); + + for (ac = 0; ac < AC_MAX; ac++) + vif->hw_queue[ac] = cl_ac2hwq[ac]; + + if (cl_radio_is_on(cl_hw) && vif->type == NL80211_IFTYPE_AP) + cl_vif->tx_en = true; + + /* Set active state in station mode after ifconfig down and up */ + if (cl_hw->conf->ce_listener_en) + cl_radio_on(cl_hw); + else if (cl_radio_is_on(cl_hw) && vif->type == NL80211_IFTYPE_STATION) + cl_msg_tx_set_idle(cl_hw, MAC_ACTIVE, true); + + if (vif->type == NL80211_IFTYPE_MESH_POINT) { + tasklet_init(&cl_hw->tx_mesh_bcn_task, cl_tx_bcn_mesh_task, + (unsigned long)cl_vif); + cl_radio_on(cl_hw); + cl_vif->tx_en = true; + cl_vif->mesh_basic_rates = cl_cap_set_mesh_basic_rates(cl_hw); + } + + return 0; +} + +void cl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + /* + * Notifies a driver that an interface is going down. + * The stop callback is called after this if it is the last interface + * and no monitor interfaces are present. + * When all interfaces are removed, the MAC address in the hardware + * must be cleared so the device no longer acknowledges packets, + * the mac_addr member of the conf structure is, however, set to the + * MAC address of the device going away. + * Hence, this callback must be implemented. It can sleep. + */ + struct cl_hw *cl_hw = hw->priv; + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + + if (vif->type == NL80211_IFTYPE_MESH_POINT) + tasklet_kill(&cl_hw->tx_mesh_bcn_task); + + if (!cl_recovery_in_progress(cl_hw)) { + kfree(cl_vif->conn_data); + cl_vif_remove(cl_hw, cl_vif); + cl_msg_tx_remove_if(cl_hw, cl_vif->vif_index); + } else { + cl_vif_remove(cl_hw, cl_vif); + } + cl_hw_set_iface_conf(cl_hw, cl_recalc_hw_iface(cl_hw)); + + cl_vif_key_deinit(cl_vif); + + cl_vif->cl_hw = NULL; + cl_vif->vif = NULL; + cl_vif->dev = NULL; +} + +static int cl_ops_conf_change_channel(struct ieee80211_hw *hw) +{ + struct cl_hw *cl_hw = hw->priv; + struct cl_chip *chip = cl_hw->chip; + struct cfg80211_chan_def *chandef = &hw->conf.chandef; + enum nl80211_chan_width width = chandef->width; + u32 primary = chandef->chan->center_freq; + u32 center = chandef->center_freq1; + u32 channel = ieee80211_frequency_to_channel(primary); + u8 bw = cl_width_to_bw(width); + int ret = 0; + + if (!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags)) + return 0; + + /* WA: for the first set-channel in production mode use the nvram values */ + if (cl_hw_is_prod_or_listener(cl_hw) || !IS_REAL_PHY(chip)) { + ret = cl_chandef_get_default(cl_hw, &channel, &bw, + &width, &primary, ¢er); + + if (ret != 0) + return ret; + } + + cl_dbg_trace(cl_hw, + "channel(%u), primary(%u), center(%u), width(%u), bw(%u)\n", + channel, primary, center, width, bw); + + if (cl_hw->channel == channel && + cl_hw->bw == bw && + cl_hw->primary_freq == primary && + cl_hw->center_freq == center) + goto dfs_cac; + + /* + * Flush the pending data to ensure that we will finish the pending + * transmissions before changing the channel + */ + if (IS_REAL_PHY(chip)) + cl_ops_flush(hw, NULL, -1, false); + + if (cl_hw->chip->conf->ce_calib_runtime_en) + ret = cl_calib_runtime_and_switch_channel(cl_hw, channel, bw, primary, center); + else + ret = cl_msg_tx_set_channel(cl_hw, channel, bw, primary, center, + CL_CALIB_PARAMS_DEFAULT_STRUCT); + if (ret) + return -EIO; + + /** + * Set preffered channel type to HT+/- based on current hapd + * configuration. + */ + if (cl_band_is_24g(cl_hw)) { + u8 ct = cfg80211_get_chandef_type(&hw->conf.chandef); + + switch (ct) { + case NL80211_CHAN_HT40PLUS: + case NL80211_CHAN_HT40MINUS: + if (ct != cl_hw->ht40_preffered_ch_type) { + cl_dbg_info(cl_hw, "HT40 preffered channel type=%s\n", + ct == NL80211_CHAN_HT40PLUS ? "HT+" : "HT-"); + cl_hw->ht40_preffered_ch_type = ct; + } + } + } + + cl_wrs_api_bss_set_bw(cl_hw, bw); + +dfs_cac: + /* + * TODO: This callback is being spawned even in STA mode, moreover, + * "start_ap" comes later - it is unclear whether we are an AP at this + * stage. Likely, may be solved by moving "force_cac_*" states to beginning + * of "start_ap", but the request should stay in current callback + */ + if (!cl_band_is_5g(cl_hw)) + return 0; + + /* + * Radar listening may occur at DFS channels during in-service mode, + * so CAC may clear the channels, but radar listening should be + * still active, and should start it as soon as we can. + */ + if (hw->conf.radar_enabled) { + /* If channel policy demans to be in CAC - need to request it */ + if (!cl_dfs_is_in_cac(cl_hw) && + chandef->chan->dfs_state == NL80211_DFS_USABLE) + cl_dfs_request_cac(cl_hw, true); + + if (!cl_dfs_radar_listening(cl_hw)) + cl_dfs_radar_listen_start(cl_hw); + } else { + /* + * No sense to continue be in silent mode if the channel was + * cleared + */ + + if (cl_dfs_is_in_cac(cl_hw) && + chandef->chan->dfs_state == NL80211_DFS_AVAILABLE) + cl_dfs_request_cac(cl_hw, false); + + if (cl_dfs_radar_listening(cl_hw)) + cl_dfs_radar_listen_end(cl_hw); + } + /* + * We have just finished channel switch. + * Now, check what to do with CAC. + */ + if (cl_dfs_requested_cac(cl_hw)) + cl_dfs_force_cac_start(cl_hw); + else if (cl_dfs_is_in_cac(cl_hw)) + cl_dfs_force_cac_end(cl_hw); + + return 0; +} + +int cl_ops_config(struct ieee80211_hw *hw, u32 changed) +{ + /* + * Handler for configuration requests. IEEE 802.11 code calls this + * function to change hardware configuration, e.g., channel. + * This function should never fail but returns a negative error code + * if it does. The callback can sleep + */ + int error = 0; + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) + error = cl_ops_conf_change_channel(hw); + + return error; +} + +/* + * @bss_info_changed: Handler for configuration requests related to BSS + * parameters that may vary during BSS's lifespan, and may affect low + * level driver (e.g. assoc/disassoc status, erp parameters). + * This function should not be used if no BSS has been set, unless + * for association indication. The @changed parameter indicates which + * of the bss parameters has changed when a call is made. The callback + * can sleep. + */ +void cl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed) +{ + struct cl_hw *cl_hw = hw->priv; + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + + if (changed & BSS_CHANGED_ASSOC) { + if (cl_msg_tx_set_associated(cl_hw, info)) + return; + } + + if (changed & BSS_CHANGED_BSSID) { + if (cl_msg_tx_set_bssid(cl_hw, info->bssid, cl_vif->vif_index)) + return; + } + + if (changed & BSS_CHANGED_BEACON_INT) { + u16 smallest_int = cl_ops_recalc_smallest_tbtt(cl_hw); + + cl_hw->smallest_beacon_int = smallest_int; + + if (vif->type == NL80211_IFTYPE_AP || + cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_MESH_ONLY) { + if (cl_msg_tx_set_beacon_int(cl_hw, info->beacon_int, + cl_vif->vif_index)) + return; + if (cl_msg_tx_dtim(cl_hw, info->dtim_period)) + return; + } + + if (vif->type == NL80211_IFTYPE_MESH_POINT && + cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_MESH_AP) { + cl_ops_set_mesh_tbtt(cl_hw, info->beacon_int, smallest_int); + } + } + + if (changed & BSS_CHANGED_BASIC_RATES) { + int shift = hw->wiphy->bands[hw->conf.chandef.chan->band]->bitrates[0].hw_value; + + if (vif->type == NL80211_IFTYPE_MESH_POINT) + if (cl_vif->mesh_basic_rates) + info->basic_rates = cl_vif->mesh_basic_rates; + + if (cl_msg_tx_set_basic_rates(cl_hw, info->basic_rates << shift)) + return; + /* TODO: check if cl_msg_tx_set_mode() should be called */ + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + /* + * We must be in 11g mode here + * TODO: we can add a check on the mode + */ + if (cl_msg_tx_set_slottime(cl_hw, info->use_short_slot)) + return; + } + + if (changed & BSS_CHANGED_BANDWIDTH) + cl_wrs_api_bss_set_bw(cl_hw, cl_width_to_bw(info->chandef.width)); + + if (changed & BSS_CHANGED_TXPOWER) { + if (info->txpower_type == NL80211_TX_POWER_FIXED) { + cl_hw->new_tx_power = info->txpower; + cl_power_tables_update(cl_hw, &cl_hw->phy_data_info.data->pwr_tables); + cl_msg_tx_refresh_power(cl_hw); + } + } + + if (changed & BSS_CHANGED_BEACON) { + struct beacon_data *beacon = NULL; + struct ieee80211_sub_if_data *sdata = + container_of(vif, struct ieee80211_sub_if_data, vif); + struct ieee80211_ht_cap *ht_cap = NULL; + struct ieee80211_vht_cap *vht_cap = NULL; + struct ieee80211_he_cap_elem *he_cap = NULL; + bool sgi_en = false; + u8 hw_mode = cl_hw->hw_mode; + enum cl_wireless_mode wireless_mode = cl_hw->wireless_mode; + + rcu_read_lock(); + + if (sdata->vif.type == NL80211_IFTYPE_AP) + beacon = rcu_dereference(sdata->u.ap.beacon); + else if (ieee80211_vif_is_mesh(&sdata->vif)) + beacon = rcu_dereference(sdata->u.mesh.beacon); + + if (beacon) { + size_t ies_len = beacon->tail_len; + const u8 *ies = beacon->tail; + const u8 *cap = NULL; + int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + int len = beacon->head_len - var_offset; + const u8 *var_pos = beacon->head + var_offset; + const u8 *rate_ie = NULL; + + cl_vif->wmm_enabled = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WMM, + ies, + ies_len); + cl_dbg_info(cl_hw, "vif=%d wmm_enabled=%d\n", + cl_vif->vif_index, + cl_vif->wmm_enabled); + + cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len); + if (cap && cap[1] >= sizeof(*ht_cap)) { + ht_cap = (void *)(cap + 2); + sgi_en |= (le16_to_cpu(ht_cap->cap_info) & + IEEE80211_HT_CAP_SGI_20) || + (le16_to_cpu(ht_cap->cap_info) & + IEEE80211_HT_CAP_SGI_40); + } + + cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len); + if (cap && cap[1] >= sizeof(*vht_cap)) { + vht_cap = (void *)(cap + 2); + sgi_en |= (le32_to_cpu(vht_cap->vht_cap_info) & + IEEE80211_VHT_CAP_SHORT_GI_80) || + (le32_to_cpu(vht_cap->vht_cap_info) & + IEEE80211_VHT_CAP_SHORT_GI_160); + } + + cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len); + if (cap && cap[1] >= sizeof(*he_cap) + 1) + he_cap = (void *)(cap + 3); + + rate_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); + if (rate_ie) { + if (cl_band_is_24g(cl_hw)) + if (cl_is_valid_g_rates(rate_ie)) + hw_mode = cl_hw->conf->ci_cck_in_hw_mode ? + HW_MODE_BG : HW_MODE_G; + else + hw_mode = HW_MODE_B; + else + hw_mode = HW_MODE_A; + } + } else { + cl_dbg_warn(cl_hw, "beacon_data not set!\n"); + } + + rcu_read_unlock(); + + /* + * FIXME: 1. WRS has no VIF-specific capabs settings. + * 2. WRS has no BW-specific SGI configuration support. + **/ + + /* If found any capabs info and state is different - update sgi */ + if ((ht_cap || vht_cap) && (cl_wrs_api_bss_is_sgi_en(cl_hw) != sgi_en)) + cl_wrs_api_bss_set_sgi(cl_hw, sgi_en); + + if (hw_mode != cl_hw->hw_mode) { + cl_hw->hw_mode = hw_mode; + sgi_en = + (ht_cap || vht_cap) ? sgi_en : cl_hw->conf->ci_short_guard_interval; +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_update(cl_hw); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_update(cl_hw); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ + cl_wrs_api_bss_capab_update(cl_hw, cl_hw->bw, sgi_en); + } + + wireless_mode = cl_recalc_wireless_mode(cl_hw, !!ht_cap, !!vht_cap, !!he_cap); + if (wireless_mode != cl_hw->wireless_mode) { + sgi_en = + (ht_cap || vht_cap) ? sgi_en : cl_hw->conf->ci_short_guard_interval; + cl_hw->wireless_mode = wireless_mode; +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_update(cl_hw); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ + cl_wrs_api_bss_capab_update(cl_hw, cl_hw->bw, sgi_en); + } + } +} + +int cl_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct cl_hw *cl_hw = hw->priv; + + set_bit(CL_DEV_AP_STARTED, &cl_hw->drv_flags); + + cl_hw->num_ap_started++; + if (cl_hw->conf->ce_radio_on) { + if (cl_radio_is_off(cl_hw)) + cl_radio_on(cl_hw); + + return 0; + } + + /* + * Set active state when cl_ops_start_ap() is called not during first driver start + * but rather after removing all interfaces and then doing up again to one interface. + */ + if (cl_radio_is_on(cl_hw) && !cl_recovery_in_progress(cl_hw)) + cl_msg_tx_set_idle(cl_hw, MAC_ACTIVE, true); + + return 0; +} + +void cl_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct cl_hw *cl_hw = hw->priv; + + /* + * Unset CL_DEV_AP_STARTED in order to avoid + * calling cl_ops_conf_change_channel after unloading the driver + */ + clear_bit(CL_DEV_AP_STARTED, &cl_hw->drv_flags); + + cl_hw->num_ap_started--; + + if (!cl_hw->num_ap_started) + cl_hw->channel = 0; +} + +u64 cl_ops_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list) +{ + return netdev_hw_addr_list_count(mc_list); +} + +void cl_ops_configure_filter(struct ieee80211_hw *hw, u32 changed_flags, + u32 *total_flags, u64 multicast) +{ + /* + * configure_filter: Configure the device's RX filter. + * See the section "Frame filtering" for more information. + * This callback must be implemented and can sleep. + */ + struct cl_hw *cl_hw = hw->priv; + + cl_dbg_trace(cl_hw, "total_flags = 0x%08x\n", *total_flags); + + /* + * Reset our filter flags since our start/stop ops reset + * the programmed settings + */ + if (!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags)) { + *total_flags = 0; + return; + } + + if (multicast) + *total_flags |= FIF_ALLMULTI; + else + *total_flags &= ~FIF_ALLMULTI; + + /* TODO: optimize with changed_flags vs multicast */ + cl_msg_tx_set_filter(cl_hw, *total_flags, false); + + *total_flags &= ~(1 << 31); +} + +int cl_ops_set_key(struct ieee80211_hw *hw, + enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct cl_hw *cl_hw = hw->priv; + + return cl_key_set(cl_hw, cmd, vif, sta, key); +} + +void cl_ops_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) +{ + struct cl_hw *cl_hw = hw->priv; + + cl_hw->sw_scan_in_progress = 1; + + if (cl_hw->conf->ce_radio_on && + cl_radio_is_off(cl_hw) && + vif->type == NL80211_IFTYPE_STATION) + cl_radio_on(cl_hw); + + if (cl_dfs_is_in_cac(cl_hw)) + cl_dfs_force_cac_end(cl_hw); +} + +void cl_ops_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct cl_hw *cl_hw = hw->priv; + + cl_hw->sw_scan_in_progress = 0; +} + +int cl_ops_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, enum ieee80211_sta_state new_state) +{ + struct cl_hw *cl_hw = hw->priv; + int error = 0; + + if (old_state == new_state) + return 0; + + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) { + cl_sta_init_sta(cl_hw, sta); + } else if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) { + error = cl_sta_add(cl_hw, vif, sta); + } else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) { + cl_sta_remove(cl_hw, vif, sta); + } + + return error; +} + +void cl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta) +{ + struct cl_hw *cl_hw = (struct cl_hw *)hw->priv; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + bool is_ps = (bool)!cmd; + + cl_sta_ps_notify(cl_hw, cl_sta, is_ps); +} + +int cl_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 ac_queue, + const struct ieee80211_tx_queue_params *params) +{ + /* + * Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), + * bursting) for a hardware TX queue. + * Returns a negative error code on failure. + * The callback can sleep. + */ + + /* We only handle STA edca here */ + if (vif->type == NL80211_IFTYPE_STATION) { + struct cl_hw *cl_hw = hw->priv; + struct ieee80211_he_mu_edca_param_ac_rec mu_edca = {0}; + struct edca_params edca_params = { + .aifsn = (u8)(params->aifs), + .cw_min = (u8)(ilog2(params->cw_min + 1)), + .cw_max = (u8)(ilog2(params->cw_max + 1)), + .txop = (u8)(params->txop) + }; + + if (cl_hw->wireless_mode > WIRELESS_MODE_HT_VHT) + memcpy(&mu_edca, ¶ms->mu_edca_param_rec, sizeof(mu_edca)); + + cl_edca_set(cl_hw, cl_ac2edca[ac_queue], &edca_params, &mu_edca); + } + return 0; +} + +void cl_ops_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u32 changed) +{ + struct cl_hw *cl_hw = (struct cl_hw *)hw->priv; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u8 bw = wrs_sta->max_rate_cap.bw; + u8 nss = wrs_sta->max_rate_cap.nss; + + if (changed & IEEE80211_RC_SMPS_CHANGED) + cl_wrs_api_set_smps_mode(cl_hw, sta, sta->bandwidth); + + WARN_ON(sta->rx_nss == 0); + if (changed & IEEE80211_RC_NSS_CHANGED) + nss = min_t(u8, sta->rx_nss, WRS_SS_MAX) - 1; + + if (changed & IEEE80211_RC_BW_CHANGED) + bw = sta->bandwidth; + + if ((changed & IEEE80211_RC_NSS_CHANGED) || (changed & IEEE80211_RC_BW_CHANGED)) + cl_wrs_api_nss_or_bw_changed(cl_hw, sta, nss, bw); +} + +int cl_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + struct cl_hw *cl_hw = (struct cl_hw *)hw->priv; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(params->sta); + int ret = 0; + + switch (params->action) { + case IEEE80211_AMPDU_RX_START: + ret = cl_ampdu_rx_start(cl_hw, cl_sta, params->tid, + params->ssn, params->buf_size); + break; + case IEEE80211_AMPDU_RX_STOP: + cl_ampdu_rx_stop(cl_hw, cl_sta, params->tid); + break; + case IEEE80211_AMPDU_TX_START: + ret = cl_ampdu_tx_start(cl_hw, vif, cl_sta, params->tid, + params->ssn); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + ret = cl_ampdu_tx_operational(cl_hw, cl_sta, params->tid, + params->buf_size, params->amsdu); + break; + case IEEE80211_AMPDU_TX_STOP_CONT: + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + ret = cl_ampdu_tx_stop(cl_hw, vif, params->action, cl_sta, + params->tid); + break; + default: + pr_warn("Error: Unknown AMPDU action (%d)\n", params->action); + } + + return ret; +} + +int cl_ops_post_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + /* TODO: Need to handle post switch */ + return 0; +} + +void cl_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) +{ + struct cl_hw *cl_hw = hw->priv; + int flush_duration; + + if (test_bit(CL_DEV_HW_RESTART, &cl_hw->drv_flags)) { + cl_dbg_verbose(cl_hw, ": bypassing (CL_DEV_HW_RESTART set)\n"); + return; + } + + /* Wait for a maximum time of 200ms until all pending frames are flushed */ + for (flush_duration = 0; flush_duration < 200; flush_duration++) { + if (!cl_txq_frames_pending(cl_hw)) + return; + + /* Lets sleep and hope for the best */ + usleep_range(1000, 2000); + } +} + +bool cl_ops_tx_frames_pending(struct ieee80211_hw *hw) +{ + struct cl_hw *cl_hw = hw->priv; + + return cl_txq_frames_pending(cl_hw); +} + +void cl_ops_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) +{ + struct cl_hw *cl_hw = hw->priv; + + cl_recovery_reconfig_complete(cl_hw); +} + +int cl_ops_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm) +{ + struct cl_hw *cl_hw = hw->priv; + + if (cl_hw->phy_data_info.data) + *dbm = cl_power_get_max(cl_hw); + else + *dbm = 0; + + return 0; +} + +int cl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + /* TODO: Fix this call */ + return 0; +} + +static void cl_ops_mgd_assoc(struct cl_hw *cl_hw, struct ieee80211_vif *vif) +{ + struct ieee80211_sub_if_data *sdata = container_of(vif, struct ieee80211_sub_if_data, vif); + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + struct ieee80211_sta *sta = ieee80211_find_sta(vif, sdata->u.mgd.bssid); + + if (!sta) { + /* Should never happen */ + cl_dbg_verbose(cl_hw, "sta is NULL !!!\n"); + return; + } + + cl_sta_mgd_add(cl_hw, cl_vif, sta); + + if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_REPEATER) { + cl_vif_ap_tx_enable(cl_hw, true); + set_bit(CL_DEV_REPEATER, &cl_hw->drv_flags); + } +} + +static void cl_ops_mgd_disassoc(struct cl_hw *cl_hw) +{ + if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_REPEATER) { + cl_vif_ap_tx_enable(cl_hw, false); + clear_bit(CL_DEV_REPEATER, &cl_hw->drv_flags); + } +} + +void cl_ops_event_callback(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct ieee80211_event *event) +{ + struct cl_hw *cl_hw = hw->priv; + + if (event->type == MLME_EVENT) { + if (event->u.mlme.data == ASSOC_EVENT && + event->u.mlme.status == MLME_SUCCESS) + cl_ops_mgd_assoc(cl_hw, vif); + else if (event->u.mlme.data == DEAUTH_TX_EVENT || + event->u.mlme.data == DEAUTH_RX_EVENT) + cl_ops_mgd_disassoc(cl_hw); + } +} + +/* This function is required for PS flow - do not remove */ +int cl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +{ + return 0; +} + +int cl_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct cl_hw *cl_hw = hw->priv; + + *rx_ant = cl_hw->mask_num_antennas; + *tx_ant = cl_hw->mask_num_antennas; + + return 0; +} + +u32 cl_ops_get_expected_throughput(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + + return cl_sta->wrs_sta.tx_su_params.data_rate; +} + +void cl_ops_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct cl_hw *cl_hw = hw->priv; + struct cl_sta *cl_sta = NULL; + u64 total_tx_success = 0, total_tx_fail = 0; + struct cl_wrs_params *wrs_params = NULL; + + if (!sta) + return; + + cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + /* + * Since cl8k implements rate control algorithm (sets IEEE80211_HW_HAS_RATE_CONTROL) + * it is needed to initialize both rx/tx bitrates manually + */ + cl_wrs_lock_bh(&cl_hw->wrs_db); + wrs_params = &cl_sta->wrs_sta.tx_su_params; + cl_wrs_fill_sinfo_rates(&sinfo->txrate, wrs_params, cl_sta); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + cl_wrs_unlock_bh(&cl_hw->wrs_db); + + /* mac80211 will fill sinfo stats if driver not set sinfo->filled flag */ + if (!cl_hw->conf->ci_stats_en) + return; + + cl_stats_get_tx(cl_hw, cl_sta, &total_tx_success, &total_tx_fail); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + sinfo->tx_packets = total_tx_success; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + sinfo->tx_failed = total_tx_fail; + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); + sinfo->rx_packets = cl_stats_get_rx(cl_hw, cl_sta); + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); + sinfo->tx_bytes = cl_sta->tx_bytes; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); + sinfo->rx_bytes = cl_sta->rx_bytes; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + sinfo->tx_retries = cl_sta->retry_count; + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + sinfo->signal_avg = cl_stats_get_rssi(cl_hw, cl_sta); +} + +int cl_ops_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) +{ + struct ieee80211_conf *conf = &hw->conf; + struct cl_hw *cl_hw = hw->priv; + struct ieee80211_supported_band *sband = hw->wiphy->bands[conf->chandef.chan->band]; + struct cl_chan_scanner *scanner = cl_hw->scanner; + struct cl_channel_stats *scanned_channel = NULL; + int chan_num; + u8 i; + + if (idx >= sband->n_channels) + return -ENOENT; + + survey->channel = &sband->channels[idx]; + chan_num = ieee80211_frequency_to_channel(sband->channels[idx].center_freq); + + for (i = 0; i < scanner->channels_num; i++) { + if (scanner->channels[i].channel == chan_num) { + scanned_channel = &scanner->channels[i]; + break; + } + } + + if (!scanned_channel) { + survey->filled = 0; + return 0; + } + + survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_SCAN | + SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME_TX | + SURVEY_INFO_TIME_RX | SURVEY_INFO_TIME_BUSY | + SURVEY_INFO_TIME_EXT_BUSY; + + survey->noise = scanned_channel->ch_noise; + + survey->time = scanned_channel->scan_time_ms; + survey->time_scan = survey->time; + + survey->time_rx = div64_u64(scanned_channel->util_time_rx, USEC_PER_MSEC); + survey->time_tx = div64_u64(scanned_channel->util_time_tx, USEC_PER_MSEC); + + survey->time_busy = div64_u64(scanned_channel->util_time_busy, USEC_PER_MSEC); + survey->time_ext_busy = survey->time_busy; + + return 0; +} + +static void cl_scan_completion_cb(struct cl_hw *cl_hw, void *arg) +{ + struct cl_chan_scanner *scanner = cl_hw->scanner; + struct cfg80211_scan_info info = { + .aborted = scanner->scan_aborted, + }; + + cl_dbg_trace(cl_hw, "Completed scan request, aborted: %u\n", info.aborted); + + cl_scan_channel_switch(cl_hw, scanner->prescan_channel, scanner->prescan_bw, true); + ieee80211_scan_completed(cl_hw->hw, &info); +} + +int cl_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) +{ + struct cfg80211_scan_request *req = &hw_req->req; + struct cl_hw *cl_hw = hw->priv; + struct cl_chan_scanner *scanner = cl_hw->scanner; + u8 scan_channels[MAX_CHANNELS] = {0}; + u8 i; + int ret = 0; + + cl_dbg_trace(cl_hw, "Hardware scan request: n_channels:%u, n_ssids:%d\n", + req->n_channels, req->n_ssids); + + if (cl_hw->conf->ce_radio_on && cl_radio_is_off(cl_hw)) + cl_radio_on(cl_hw); + + ret = mutex_lock_interruptible(&scanner->cl_hw->set_channel_mutex); + if (ret != 0) + return ret; + scanner->prescan_bw = cl_hw->bw; + scanner->prescan_channel = cl_hw->channel; + mutex_unlock(&scanner->cl_hw->set_channel_mutex); + + if (req->n_ssids > 0) { + /* + * This is active scan request. We do not support it yet, so we + * need to force the mac80211 to fallback to the sw_scan. + */ + cl_dbg_trace(cl_hw, "activating fall-back strategy - sw_scan\n"); + return 1; + } + + if (req->n_channels > ARRAY_SIZE(scan_channels)) { + cl_dbg_warn(cl_hw, "invalid number of channels to scan: %u\n", + req->n_channels); + return -ERANGE; + } + + for (i = 0; i < req->n_channels; ++i) { + if (req->channels[i]->band != cl_hw->nl_band) { + cl_dbg_warn(cl_hw, "band %u is invalid\n", req->channels[i]->band); + return -EINVAL; + } + scan_channels[i] = ieee80211_frequency_to_channel(req->channels[i]->center_freq); + } + + ret = cl_trigger_off_channel_scan(scanner, req->duration, 0, + scan_channels, CHNL_BW_20, req->n_channels, + cl_scan_completion_cb, NULL); + return ret; +} + +void cl_ops_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct cl_hw *cl_hw = hw->priv; + struct cl_chan_scanner *scanner = cl_hw->scanner; + + if (!cl_is_scan_in_progress(scanner)) + return; + + cl_abort_scan(scanner); + wait_event_interruptible_timeout(scanner->wq, + !cl_is_scan_in_progress(scanner), + msecs_to_jiffies(MSEC_PER_SEC)); +} From patchwork Tue May 24 11:34:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576852 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 7A017C433EF for ; Tue, 24 May 2022 11:39:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236845AbiEXLjZ (ORCPT ); Tue, 24 May 2022 07:39:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236843AbiEXLjX (ORCPT ); Tue, 24 May 2022 07:39:23 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2086.outbound.protection.outlook.com [40.107.104.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EC808D6B7 for ; Tue, 24 May 2022 04:39:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ZzzaWOSJ3HdcP0u2o4pJFa6k4qaNUDUl8/IZm78z+BFH6G0rImiS6/xLjEoiKSoIVdKfTC9ytahEbtNfG4ldaSL8iBci9qENEYlzhLnbXm4vFf/3gyeZFQOwacAzthkQ9S8SDVkg+bXTx8xnIEEJk9ZNOcx11qBIr8RL1hNDN4gqfF+aBwQrVf120QcF9SCzv1ZwVyF4eXe/UuNHdSDuMforq6DmZjcIOfwe0YEyOxo6VHV5PJdxqg3GO0RLcTAh7DZSWf4hSFI8fHHyR0lfDemLtcEtCJBjz29xXv1+Afu3ktzIGFRtS51grlSolHG2Aa2YlbPBm1cp+wXbWae5lQ== 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=Y6JZoNFmGNSqyK+7OiN9STKegkIvcAT/apf77LQ7+to=; b=P9gJxFPwdgt0E6UGfrOCnWTGRoEWgj7Se2EkLE7wu91aUFQ1E1749uvkQguPZWJXIEJksUKdrYfNkMZssEBcf4OvXy9RQWoj06s1Zp3jJKqSJJTI/SyRk2znU52sFjRYKIzb7S4K7kqJSG8DxyRr2x+DunsjelM6Hj3s4KYyrDD+oozaMoem9pezmk9Y8ddCLjRqghFV3L9FQJ5UyJ7v57nD3N7XrML36yEBz1n1HPbIkPTKM9wsWBKglRRGAmtj/7pyL4883YH8PN2DU6DQuk+ElNMfF0B/hhmiW/tQLANUiWdXASzdsAeij1MZzsBVtcjpRLTdn5E1csGODBiFKQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Y6JZoNFmGNSqyK+7OiN9STKegkIvcAT/apf77LQ7+to=; b=Q8tNWzdtALG+ifpbX/5ZFgJ3q1o1p14Z3gp3eDIJJqOiXnp8o1W6T35MP7ZGDXlzGNJ2RpQmMJYwjzeQuDlzDI2u8jg6Uj7LPVmt1nMwJ++iqyCOcCk3WZclLdFFW8vCHB7h6GKbwUDrOMT/3mF9hr/1Zx+R0gRw9XxpqUGSHIs= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:41 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:41 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 39/96] cl8k: add mac80211.h Date: Tue, 24 May 2022 14:34:05 +0300 Message-Id: <20220524113502.1094459-40-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 06082275-11e4-4fb3-c8f3-08da3d79e2f6 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 1db7U7nVw5vZV6/kd5r7DK7Ss2PnG6BcXzpr9v/Yc7FKoYL8PYR1ROk0Q1jxB2r7u2GMfOVuWJTsm0r1e3J/8QPZ26s3tlFdUFgkEeX73E8sod7G9k+FmOR4K8oj+7ewCKgR2ak2BuezAbGnLa2yR+hFDynHvKJzJPANVEzfOCstM4DTLX3CAeEfQ8ih6MTglLlROaT2hmMhvOwhCagfPnzrLgrJlpWhYBao8SOkUtozIISbiQDofBEq1Y6LMbgsObyXMz38BenORPseGHk43aPtaspL8KA8hLjLiyl7XO1fdEs88JSdU4ogEnhq79Jm4OsC9leWSQvKmyCqxPUast2hDqS25HFtLyMqwVUVhuy6v6WXyI+LHLxFve9kqR3wwpe3e7N61GFZCmeDfzmjUeBzRdGLQoczW8vp22++7hpiae6Eir16f9jPj+++4XycvYreed8SjHytQ2iiNgRjVKEFGSPSPnXUMOw/VRKgsa9shFGtvkhHuEkHdOGgL5VnJPEGjeAaeRDf8hFfS1WqLQs5O1QP7X8Amg0ovaeevh7mwtzap90LTMIXktnjeXRg0kkiJRga5I7G4sF5w4VQMfnYgpMCpVwf71/Iq/EqGg5SJPKkn/l61gbwKpBwpwu3Bjh9gyinlCMnSveJs4zsIsvvP50tj8iEZ2Sh+ucrxjITkjxwRDHzbMQkUpAiDwa3KhMnwtnQGf+B+Fhhi1jx60B3c2djb+8VZyNvjJCO2Eg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: OCvo8EtcIyZWXrGHdtRNjd6UYfbDTCimwpjP+MiHdYnefCSYNeDlrTifLj5nFWNKaod70haX+l9caXavxTB6S+Onhwqr0ih7T7HB2k5vPi4r3eCB3ioSavHCzRvhD7HRqesnshSxAZEbvFX+xVHplS/G8//9Rf3VmcgUB51ba3yPq0AQftUi5niUSOCncwkDY9T3XlcUtYMaDGABJnHHgHeFZMo3HcUcVZQU6jWa+TJy4N0o1yU1RU+ItJHDoo8J49F7QtxkoK3UbCgqmkO51R8smIg03iAH+ImpRc57lwc/R+gLvBpBRtIcJ9iUP7uUS/WeHCSI5RllxhmQyMYcvVkQ6WV37FHbCSRM0DkzigrY+psSkEjvKzxBB+eLRuzh93VOmtqiGXxBDXETrMqXUnBzCo4kWUHreIE5Vu7CgQiQiBidm+XCb0cydPv4c5QDu2QZbYMA8wWIto0K52NTU6PWONA5W91HkvVFW4NwI8QL5zW55ID8PJ4Vb8l3zIbMF146dbwBYWcB5NiN47nfK4jGs0pIHduTRbSH66JyTmfVj9Iga5PRpHX6UBQRb8/2NFQsDFQbsRuPb8p4XL7DSIHuDnQopIwY3PiWJD3aVqnKN/lX2ArQ53vTstoJhFpsPU8fe8nhrQzepvCOI3OB+q7Jvosn1YTosc/Wasx2/ROQrrb1qOspvnijm79JaRtlMPO3a6D0LNz4nviF8rYaj1vUfhDkGI+CxA53fhNwaBDMUyi0juKUzU53imRxPftTAP7XV7j/LnUoPM3x8Ho14Gm6TSzZwz+FAfBjuFgoAMGJwPIRfYgUive2gRIFSbsQRT8YCD6PzNkSbX2fKOQZHyZ6Dc7RYYSCxsl6WYkTMRJDzsHUo5zPEA58U+g6fxwjeOKjBnW7SD6EqtT5Pi2tfj/2GyVF0a206xn9H2Q7HnCvGsbaUF/2h/i0D1+26EXDxOgjq4d5/4dU5aXrfNxcmb1zEXt93K9u3pkevk/itpnYeEVy/sWlNsu96ublHqcppDy7JybXgrwSSgpd/QnLuHa1SXJATop04ncQkLWd5xluBaMHpFNzUhyv1rHqVwdsXv0tqwsqzC+M470rswpXLrWO440w6jJZ2iQSsjJAMoG0f7LVlSiNIAi0LYfvZIyMa8FQB3HTf993y61h6spx5nRaaEjflPGyP/IwB58V4KQBiG0NWqjAidkgiE5GY6kcg7fONTjIkA1xs+sI79BbscyoeuH/1cv6kHHCiSmdKsTbmRZbz0DJOi/MAVXfl+Mpr9QcyqX64+a0jZ8a3oYiJCB0XRjlsXjKamj0pK0kgcwwHqKl5baAN6/7yaG94xFDe3QQ3/ZNVvM1Ql+dq8f+utIFvY+fDa/KDSwf5eLV2VRDRlRlRhvkaxBEO5ZJuFFL6w6bcKVQaFNFxiPZ8Wmh5xq1Ni8fwU2nt5slT3MGnZjCmHOQjDFbir6Az9uhvsayLNHiaHHT/3w2e6eMcF8nbCbblSpT5dGEGY0aWcYlQGsimY6tsYzdLImUvadqLuCXt6/nYV5ZaPYQxmuE2g1TatPSlhlZcGCkoMgI1/GkIvNWMs565PkNI9OO6gkGZvc2k008TIeGiE3PnmH/0euhgCZC2kGuXTrjR+UUpTtugsmee+jqKE5GCwQEVGv5uuWJmwqzxG5nhfOp7dSVjBQQFAQLdrtiJMxZV074wxRCInCygEsjYKib5x3ChFRaJRVRBlYs0LOHWkKUGrxC6q8r01jfu5W7OZBb53NYrTZHxBk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 06082275-11e4-4fb3-c8f3-08da3d79e2f6 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:13.7163 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2aa4LQWwaXfppPhB2jW8r3JPgyCdlHTmh7Sy6sI0snJIGxSBuQXcARfZFksjQX8ztR2IUujsA18UYMz1iFWO3Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/mac80211.h | 197 ++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/mac80211.h diff --git a/drivers/net/wireless/celeno/cl8k/mac80211.h b/drivers/net/wireless/celeno/cl8k/mac80211.h new file mode 100644 index 000000000000..f76c1a0ad820 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/mac80211.h @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_MAC80211_H +#define CL_MAC80211_H + +#include +#include +#include + +#define PPE_0US 0 +#define PPE_8US 1 +#define PPE_16US 2 + +/* + * Extended Channel Switching capability to be set in the 1st byte of + * the @WLAN_EID_EXT_CAPABILITY information element + */ +#define WLAN_EXT_CAPA1_2040_BSS_COEX_MGMT_ENABLED BIT(0) + +/* WLAN_EID_BSS_COEX_2040 = 72 */ +/* 802.11n 7.3.2.61 */ +struct ieee80211_bss_coex_20_40_ie { + u8 element_id; + u8 len; + u8 info_req : 1; + /* Inter-BSS set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS */ + u8 intolerant40 : 1; + /* Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS */ + u8 bss20_width_req : 1; + u8 obss_scan_exemp_req : 1; + u8 obss_scan_exemp_grant : 1; + u8 rsv : 3; +} __packed; + +/* WLAN_EID_BSS_INTOLERANT_CHL_REPORT = 73 */ +/*802.11n 7.3.2.59 */ +struct ieee80211_bss_intolerant_chl_report_ie { + u8 element_id; + u8 len; + u8 regulatory_class; + u8 ch_list[0]; +} __packed; + +/* Union options that are not included in 'struct ieee80211_mgmt' */ +struct cl_ieee80211_mgmt { + __le16 frame_control; + __le16 duration; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + __le16 seq_ctrl; + union { + struct { + __le16 auth_alg; + __le16 auth_transaction; + __le16 status_code; + /* Possibly followed by Challenge text */ + u8 variable[0]; + } __packed auth; + struct { + __le16 reason_code; + } __packed deauth; + struct { + __le16 capab_info; + __le16 listen_interval; + /* Followed by SSID and Supported rates */ + u8 variable[0]; + } __packed assoc_req; + struct { + __le16 capab_info; + __le16 status_code; + __le16 aid; + /* Followed by Supported rates */ + u8 variable[0]; + } __packed assoc_resp, reassoc_resp; + struct { + __le16 capab_info; + __le16 listen_interval; + u8 current_ap[ETH_ALEN]; + /* Followed by SSID and Supported rates */ + u8 variable[0]; + } __packed reassoc_req; + struct { + __le16 reason_code; + } __packed disassoc; + struct { + __le64 timestamp; + __le16 beacon_int; + __le16 capab_info; + /* + * Followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM + */ + u8 variable[0]; + } __packed beacon; + struct { + /* Only variable items: SSID, Supported rates */ + u8 variable[0]; + } __packed probe_req; + struct { + __le64 timestamp; + __le16 beacon_int; + __le16 capab_info; + /* + * Followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params + */ + u8 variable[0]; + } __packed probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + struct ieee80211_bss_coex_20_40_ie bss_coex_20_40_ie; + /* + * This IE May appear zero or more times, + * that situation wasn't handled here. + */ + struct ieee80211_bss_intolerant_chl_report_ie + bss_intolerant_chl_report_ie; + } __packed coex_2040_mgmt; + } u; + } __packed action; + } u; +} __packed __aligned(2); + +void cl_cap_dyn_params(struct cl_hw *cl_hw); +void cl_cap_ppe_duration(struct cl_hw *cl_hw, struct ieee80211_sta *sta, + u8 pe_dur[CHNL_BW_MAX][WRS_MCS_MAX_HE]); +u16 cl_cap_set_mesh_basic_rates(struct cl_hw *cl_hw); +void cl_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); +void cl_ops_rx_finish(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta); +int cl_ops_start(struct ieee80211_hw *hw); +void cl_ops_stop(struct ieee80211_hw *hw); +int cl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void cl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int cl_ops_config(struct ieee80211_hw *hw, u32 changed); +void cl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed); +int cl_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void cl_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +u64 cl_ops_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list); +void cl_ops_configure_filter(struct ieee80211_hw *hw, u32 changed_flags, + u32 *total_flags, u64 multicast); +int cl_ops_set_key(struct ieee80211_hw *hw, + enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +void cl_ops_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr); +void cl_ops_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int cl_ops_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, enum ieee80211_sta_state new_state); +void cl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta); +int cl_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 ac_queue, + const struct ieee80211_tx_queue_params *params); +void cl_ops_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u32 changed); +int cl_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params); +int cl_ops_post_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void cl_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop); +bool cl_ops_tx_frames_pending(struct ieee80211_hw *hw); +void cl_ops_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type); +int cl_ops_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm); +int cl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); +void cl_ops_event_callback(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct ieee80211_event *event); +int cl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); +int cl_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); +u32 cl_ops_get_expected_throughput(struct ieee80211_hw *hw, struct ieee80211_sta *sta); +void cl_ops_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo); +int cl_ops_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask); +int cl_ops_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey); +int cl_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req); +void cl_ops_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + +#endif /* CL_MAC80211_H */ From patchwork Tue May 24 11:34:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576850 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 11B73C433FE for ; Tue, 24 May 2022 11:39:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236862AbiEXLjf (ORCPT ); Tue, 24 May 2022 07:39:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235357AbiEXLjd (ORCPT ); Tue, 24 May 2022 07:39:33 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2081.outbound.protection.outlook.com [40.107.104.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C11648CB3D for ; Tue, 24 May 2022 04:39:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=USDzTwPt+D6HHAi+FL6nanQKsD1tltugm03Q7IHEmDZEPnMy0GNqnfTO6P2pnLv4jo2rt/10tj75h/5UoZBb7ZbJ3ZyF0VeAl3n5wQ4ELJPcSgS6g24RV1mXqt3BXMogeD7yzr0ycI4B62R0PMC62gBpIZGku12lm7b+8eyvgE000IBWvSRmKLzMCOrojBwsN0DbidSz6TSCXoyHxTT5QzpJUOZ/p36W4CheNIGBsQ98bPcZNatP9RGSTHfZL4X3sxXn+AKlTdJUi7HjE+lwHh96fCKD73DbzJxVnoN5PaIq+9hB/QoTN9hsyecWveHYewBX7L2VWk7ajQnkIRqbOw== 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=73VgtPoBPUHFsPlhN2xY0bBWL2WMKVEtWH8FJesVnzI=; b=Lhy0P9ZlF05ol73QY6t7pNXdnaGHMaROx+8fU4bAxA+FR9UaZrLzLsSYdlKfz6MZrKLkmzTqUQ+nm9jdOf0+gtwVruJ7rltdiZIUW4BzwcjGRAvPoW0IcjiNJfA2SpYaDTUj5YtQLMQUiwvomnrTaR+CfuX+6AnPNZqlr9DXU0vjLYtU5kbDyhSPTRhTF84C3whTvVht+2+2Y8EaPRTF383JJSp+ohoClCo5AAFkjESgoPwvyZpaj1ORUzF5pL3ujYDN8s7NIyN10X06YwyaGiSv0LLyPTHR9k8HJ+Imr8t6DE/RUskQwlGI5A1688yRxPzSTeIKbjVWeHgqrNr+1w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=73VgtPoBPUHFsPlhN2xY0bBWL2WMKVEtWH8FJesVnzI=; b=xtZfEwSw2PC6AkypHUHmZhTA4CgT0VX9FgXxWgFapYIjOv7A0GcGz7O7xDyMNCvG2Gih97uqqC6Vp7+1qDk+pKYuv4FI29BzIBJpY5g0x3uLjjg4LSFtRuKcXLYHbNIDdwPL9s5YXTQ1nii+W1ipxs7AN2ePJY0fr95TKbrjojQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:42 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:42 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 40/96] cl8k: add mac_addr.c Date: Tue, 24 May 2022 14:34:06 +0300 Message-Id: <20220524113502.1094459-41-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a49df5ac-5d19-442f-eb5c-08da3d79e3b9 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: p+u01cIuuSvweBJNdPxvlUoHqOT9kgc/pbUTuOgqrtQmYSEd0SqiIOEKLnqnVc6dLwqsJP2bNjHxDj+QTH9B62qp6BBl6SJqDTSpaSd5mflkn+NmofsdDv+MnC5I+uH53vz57lp1esxSJyjb8e/UVs35K5Esq7MDLkT+51yBuhp1eaIQpROx7E0S9gRBme635lG+OYGPC8P6TMBha727LiAwG6bpjBPo9HB98fIydAt/WR9r/1EPL58hNcMiQqqKu9P0yJCF9lshwhLwHVyw4hK5c1q1SMt4QDTi7QOXW43YFRTe6c1b348Jiezb2Qyvr01HC1UWUSTjaOwuCpDtZioyARPW75wPkapsjwOCIcwfauCqQsZLKjnmLmcBuPSs7ajwHFgGWLbkO0ddupHD3KF0wB7kfi22gtJQEmPPlek6wdarGJZY8BefSRBZ8y3isGUySIbRQ/YXrpby64BqXb+h4Bm93ZZS9j4a8GHCOg0R4dFOZH69ChczFNls6W+i2I6MzST2Sv5RdinFxWX4hbgzBEODXR/LVr1n91I0ZCHzi4R/TbhLXNovm2tmhUa5UPE/eqXjcPk1JOygm6B0hCXvPE3Ii35wZrcr/LAb4mGwPsk8VzUF/TwLV9yfw7/T4dE0gm9r/jgEpllRT3haG1Ar+dfDrRDMJu3AQhc1CGrMD0mwdqaO6gULKjCGKMM18vjUOSoJjWYoLItLYjbgU24WXJMGqgt9laF/1w6Yhus= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: BJRQvrvfO72IGYjiSA7ugVopWGHpH4zq5u5T+KOZ2JAEVZoQiOQv5MDOUFP1xzD1QB6/Fk1YQebZKxsI7Y+Rl4b1bbOMbipuDBu001MxmwZR4G53K8TiBelsL16PRNl+4gNqBDOAmKNjpHvbaQOmn+56P5AnD7HBkrgB6XKGyexpYwROWecRu4x/S0FdZ5aacyf5kvWjOwaoauQlamIohgmgGCN6IG9GilZ4RrvgottAQ2FK4BbLbdLjSm+ja3V/usaHajGyvaNNaPcDz5vWBSn4gDLI0/NNxCPvPl8SqMMfqr2RQk65afTfD315IdRbUBUGMjMVLtGxohaU61gopz4w+bdzJOxUM3SI6HKTM6Ir0iqgZDWF91p/LXhz2VujcjdG00bj+bpS5kAmrERwgKtk/NgRwQOBHXbKXG2t4qJ0Y++02cLR5se0/zYsZaANCtLvbVQNfalOTbFPEPaRskPanGxyKAzceSwIKoBPy1+XP9/ThQQARPd76t5MfeJftgjsLqbB4yrI4QzP+icQUVsbMLQqo6jhcYQUL8fxt3VIHM5cZ2TPFG6wgeFjYjpPRLk5CQXLFXaMcI2SXhytaI539NCxCTFPebA4J3J3DORJ2mp06QMx6QVRzz+yuYQypEQZxPuSVwIvF2NaBvFVfmjU0y+7umfjnQSp1FqdMnL8GUirKc7Bg4+GHFcaHbf95nO3xDksBG0HwCLpdloDFxtOJiwPHNzGzUL4wwRIn8Bs0VUEQYrGb9RO3cK+7qxMux4CnxPRtjzd40fQAxui2Cndp5b07vatAm6z4lCPnmmIfIWCMoV1w+l4C6d00QQWcGresagyvRyuBD4sdcdyr4IB/Qt01FmoQk9Hthv1h0xedptIeVVnQ2lhW7nscJ7UEUv5G+K/kCduzMnWwHT/4h5nAgHrq4XKpsVEdFyXES+clymelBnBdEFRdfObV0OW5tb4E5fKfgw/oEkG27Mk5/9CzPThGYbscPSyGuZilnj9nGAG8tnJjXVQAAe5qweIGXtFmCNMN9/Erd/AAIhsbyVgk3NmQgGG+969tEmkzI33l3xvCV5wymGvi2uiOlAqFYqFeThi5gLDWZPA8dfCqSwM5DsAYOd8jQwLdx5dSc6uQOF58RZUboY4QTvHEpcl50yrsXVarmyLtnUuYpEEOA4d5RUWZGYfhm9JF8lL93WKKMpUNP5ODBeBVMLYok7ujBdT7AVI1tZGwPAGjOkdJOwT5utwjJGDbxXkSNHqVqGISaz+HaRCxAJn7ut5re9pqMAhV8O/vhZgs2eomGr5S6f1ayOlKS8zMNVp6vJehZIARNDHrkc2rHi+iha2sR/1pQwg39WiFSTIFxcwhpt935gXLrzJ1bikew27W5IX5mfALZD5dyvxZIw3FRpH3gmAKhX7hn7GjwOXNeD+dr0807iUjIZq3O98RQJH1SWcj9wAnwsjSx/lpJSHoF5Yo2qhkBYJLEL99Pw2pf/dlzYa2dtPyCPNPx8GZis3tXtUvLygOwExtbrjQz+XMORaRRm0UeDdU1jPUveGNjcJZR9XZG8XBJ/PIPvwsNONgaPsNH2GVJqe4qRLx0hgHm4220yMyXpES7FknbjMEpbna/Q10WnGNM34RQyvVxbvTbQVXIuWxKLRgxI+Mgqt3YIXevQV56o6RsixjED2YbL+lJ1A99A9pICjri7bhlJddyc2ppp7VHbtN9QTnQhqjhTcTakmVR7EHLcqb6FsmirIzcvbUiMRUtef+73q1cchLO8Wp3A= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: a49df5ac-5d19-442f-eb5c-08da3d79e3b9 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:14.9014 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ko093/ZyJ7WM64V1JXp9GMyv36b0lXJFrXFO9Z4JSc3WpptdKx0OBoSg6En4U/xoe/KpafvqMN8GPydyMTs6Ng== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/mac_addr.c | 418 ++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/mac_addr.c diff --git a/drivers/net/wireless/celeno/cl8k/mac_addr.c b/drivers/net/wireless/celeno/cl8k/mac_addr.c new file mode 100644 index 000000000000..be9080564773 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/mac_addr.c @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "mac_addr.h" + +/** DOC: MAC identifier generation + * + * The driver allows to works with multiple MAC indentifiers via one base MAC, + * which it gets from: + * a) EEPROM; + * b) %ce_phys_mac_addr parameter in chip config; + * c) randomly generated address with Celeno's OUI. + * + * All other MAC are generated from base MAC by modyfing specific byte in each + * new address (starting from %ce_first_mask_bit). All addresses should be in + * 4-bit range from each other (HW requirement). + * + * Both tranceivers are sharing MAC addresses pool per same chip, and with LAM + * (=Locally Administered Mac) there is the ability to have up to 16 different + * addrs starting with any base MAC. Otherwise (without LAM), base MAC should + * allow to generate addresses within 4-bit difference at max. + * + * Max addresses count is configurable on per-TCV basis via %ci_max_bss_num + * variable. + * + * If LAM is enabled, TCV0 is getting original MAC for the first interface. All + * another interfaces of the TCV0 and all interfaces of the TCV1 are getting + * LAM-based addresses, which will have 0x02 in the first byte and will have + * dynamic last (depends on %ce_first_mask_bit) byte, which typically is being + * incremented for each new address, but not always (the logic tries to fit + * addresses in 4-bit range, for the sake of this rule new LAM-based address be + * reseted to start from 0. + * + * MAC examples + * Case 1: Typical (with LAM) + * - 00:1C:51:BD:FB:00; -> base MAC (valid with and without LAM) + * - 02:1C:51:BD:FB:00; + * - 02:1C:51:BD:FB:01; + * + * Case 2: Typical (without LAM) + * - 00:1C:51:BD:FB:00; -> base MAC (valid with and without LAM) + * - 00:1C:51:BD:FB:01; + * - 00:1C:51:BD:FB:02; + * + * Case 3: With reset to fit 4-bit rule (with LAM) + * - 00:1C:51:BD:FB:CF; -> base MAC (valid only with LAM) + * - 02:1C:51:BD:FB:CF; + * - 02:1C:51:BD:FB:C0: + * - 02:1C:51:BD:FB:C1; + */ + +#define CL_LAM_INDICATION 0x02 + +static int cl_set_mask_addr_without_zeroing_bits(struct cl_hw *cl_hw, u64 mac64, u8 bss_num, + u8 first_mask_bit, u8 *mask_addr) +{ + u64 mask = mac64; + s8 idx = 0; + + mask >>= first_mask_bit; + mask += (bss_num - 1); + + /* + * After the following line the mask will contain the changed + * bits between the first BSS MAC and the last BSS MAC + */ + mask ^= (mac64 >> first_mask_bit); + + /* Find leftmost set bit */ + for (idx = 47 - first_mask_bit; (idx >= 0) && (!(mask & (1ULL << idx))); idx--) + ; + + if (idx < 0) { + cl_dbg_err(cl_hw, "Invalid mask (mac=0x%02llx, first_mask_bit=%u, bss_num=%u)\n", + mac64, first_mask_bit, bss_num); + mask = 0; + eth_zero_addr(mask_addr); + + return -1; + } + + mask = (1ULL << idx); + mask |= (mask - 1); + mask <<= first_mask_bit; + + for (idx = 0; idx < ETH_ALEN; idx++) { + u8 shift = (BITS_PER_BYTE * (ETH_ALEN - 1 - idx)); + + mask_addr[idx] = (mask & ((u64)0xff << shift)) >> shift; + } + + return 0; +} + +static int cl_mask_mac_by_bss_num(struct cl_hw *cl_hw, u8 *mac_addr, u8 *mask_addr, + bool use_lam, bool random_mac) +{ + u8 bss_num = cl_hw->conf->ci_max_bss_num; + struct cl_hw *cl_hw_tcv0 = cl_hw->chip->cl_hw_tcv0; + u8 first_mask_bit = cl_hw->chip->conf->ce_first_mask_bit; + u8 i; + /* Determine the bits necessary to cover the number of BSSIDs. */ + u8 num_bits_to_mask[ARRAY_SIZE(cl_hw->addresses) * TCV_MAX] = { + 0, /* 0 : 00:1C:51:BD:FB:(0b 0000 0000) -> 0-bit diff (no LAM, original MAC) */ + 0, /* 1 : 02:1C:51:BD:FB:(0b 0000 0000) -> 0-bit diff (LAM) */ + + 1, /* 2 : 02:1C:51:BD:FB:(0b 0000 0001) -> 1-bit diff (LAM, between address #1) */ + + 2, /* 3 : 02:1C:51:BD:FB:(0b 0000 0011) -> 2-bit diff (LAM) */ + 2, /* 4 : 02:1C:51:BD:FB:(0b 0000 0010) -> 2-bit diff (LAM) */ + + 3, /* 5 : 02:1C:51:BD:FB:(0b 0000 0111) -> 3-bit diff (LAM) */ + 3, /* 6 : 02:1C:51:BD:FB:(0b 0000 0100) -> 3-bit diff (LAM) */ + 3, /* 7 : 02:1C:51:BD:FB:(0b 0000 0101) -> 3-bit diff (LAM) */ + 3, /* 8 : 02:1C:51:BD:FB:(0b 0000 0110) -> 3-bit diff (LAM) */ + + 4, /* 9 : 02:1C:51:BD:FB:(0b 0000 1111) -> 4-bit diff (LAM) */ + 4, /* 10: 02:1C:51:BD:FB:(0b 0000 1000) -> 4-bit diff (LAM) */ + 4, /* 11: 02:1C:51:BD:FB:(0b 0000 1001) -> 4-bit diff (LAM) */ + 4, /* 12: 02:1C:51:BD:FB:(0b 0000 1010) -> 4-bit diff (LAM) */ + 4, /* 13: 02:1C:51:BD:FB:(0b 0000 1100) -> 4-bit diff (LAM) */ + 4, /* 14: 02:1C:51:BD:FB:(0b 0000 1110) -> 4-bit diff (LAM) */ + 4, /* 15: 02:1C:51:BD:FB:(0b 0000 1011) -> 4-bit diff (LAM) */ + }; + + u8 mask_size = 0; + u8 byte_num = ETH_ALEN - 1 - (first_mask_bit / BITS_PER_BYTE); + u8 bit_in_byte = first_mask_bit % BITS_PER_BYTE; /* Referring to the index of the bit */ + + if ((first_mask_bit + num_bits_to_mask[bss_num]) > BITS_PER_TYPE(struct mac_address)) { + cl_dbg_err(cl_hw, "Invalid combination of first_mask_bit + bss_num. " + "must be lower than 48 bit in total\n"); + return -EINVAL; + } + + if (cl_hw_is_first_tcv(cl_hw)) { + mask_size = num_bits_to_mask[bss_num - 1]; + } else { + u64 mac64 = ether_addr_to_u64(mac_addr); + u8 tcv0_bss_num = cl_hw_tcv0 ? cl_hw_tcv0->conf->ci_max_bss_num : 0; + u8 bit_mask = (1 << num_bits_to_mask[bss_num + tcv0_bss_num - 1]) - 1; + + /* + * If we need to zero bits due to lack of room for the MAC addresses + * of all BSSs of TCV1, then the mask is the number of zeroed bits + */ + if (((u64)bit_mask - ((mac64 >> first_mask_bit) & (u64)bit_mask) + 1) < bss_num) { + mask_size = num_bits_to_mask[bss_num + tcv0_bss_num - 1]; + } else { + /* + * Otherwise the mask is the different bits between the + * addresses of the first and the last BSSs + */ + cl_set_mask_addr_without_zeroing_bits(cl_hw, mac64, bss_num, + first_mask_bit, mask_addr); + return 0; + } + } + + /* Build mac and mask addr */ + for (i = 0; i < mask_size; i++) { + /* + * Build mask - Convert to "1" the relevant bits in the mask + * addr in order to support the desired number of BSSIDs + */ + mask_addr[byte_num] |= (0x01 << bit_in_byte); + + /* + * Build mac -convert to "0" the relevant bits in the mac addr + * in order to support the desired number of BSSIDs + */ + if (random_mac && !use_lam) + mac_addr[byte_num] &= ~(0x01 << bit_in_byte); + + bit_in_byte++; + + /* Support cases where the mask bits are not at the same byte. */ + if (bit_in_byte == BITS_PER_BYTE) { + byte_num--; + bit_in_byte = 0; + } + } + + if (use_lam) { + /* Mask LAM bit (Locally Administered Mac) */ + if (cl_hw_is_first_tcv(cl_hw)) + mask_addr[0] |= CL_LAM_INDICATION; + } else { + /* + * When not using LAM we do not zero the MAC address of the second BSS, + * so the mask (the modified bits between the first and last BSS) depends + * on initial MAC + */ + u64 mac64 = ether_addr_to_u64(mac_addr); + + cl_set_mask_addr_without_zeroing_bits(cl_hw, mac64, bss_num, + first_mask_bit, mask_addr); + } + + return 0; +} + +#define MAC_FILTER_BITS 4 +#define MAC_FILTER_MASK ((1 << MAC_FILTER_BITS) - 1) + +static bool cl_is_valid_mac_addr(u64 mac64, u8 first_mask_bit, u8 bss_num) +{ + u8 mac_bits = (mac64 >> first_mask_bit) & MAC_FILTER_MASK; + u8 mac_diff = 0; + u8 i; + + for (i = 0; i < bss_num; i++) { + mac_diff |= mac_bits; + mac_bits++; + } + + return hweight8(mac_diff) <= MAC_FILTER_BITS; +} + +static int cl_mac_addr_set_addresses(struct cl_hw *cl_hw, bool use_lam, + u8 *mask_addr) +{ + u8 first_mask_bit = cl_hw->chip->conf->ce_first_mask_bit; + int i = 0; + u8 bss_num = min_t(u8, cl_hw->conf->ci_max_bss_num, ARRAY_SIZE(cl_hw->addresses)); + u64 mac64 = ether_addr_to_u64(cl_hw->hw->wiphy->perm_addr); + u64 mask64 = 0; + u8 new_addr[ETH_ALEN] = {0}; + + if (!use_lam && !cl_is_valid_mac_addr(mac64, first_mask_bit, bss_num)) { + cl_dbg_err(cl_hw, + "perm_addr %pM is invalid for bss_num %d without LAM\n", + cl_hw->hw->wiphy->perm_addr, bss_num); + return -1; + } + + cl_mac_addr_copy(cl_hw->addresses[i].addr, + cl_hw->hw->wiphy->perm_addr); + for (i = 1; i < bss_num; i++) { + u8 *prev_addr = cl_hw->addresses[i - 1].addr; + + if (use_lam) { + mac64 = ether_addr_to_u64(prev_addr); + mask64 = ether_addr_to_u64(mask_addr); + if (cl_hw_is_first_tcv(cl_hw)) { + if (i == 1) + mac64 &= ~mask64; + else + mac64 += 1 << first_mask_bit; + u64_to_ether_addr(mac64, new_addr); + new_addr[0] |= CL_LAM_INDICATION; + } else { + if ((mac64 & mask64) == mask64) + mac64 &= ~mask64; + else + mac64 += 1 << first_mask_bit; + u64_to_ether_addr(mac64, new_addr); + } + cl_mac_addr_copy(cl_hw->addresses[i].addr, new_addr); + } else { + mac64 = ether_addr_to_u64(prev_addr); + mac64 += 1 << first_mask_bit; + u64_to_ether_addr(mac64, cl_hw->addresses[i].addr); + } + } + cl_hw->n_addresses = bss_num; + + return 0; +} + +static int cl_mac_addr_set_first_tcv(struct cl_hw *cl_hw, u8 *dflt_mac, + bool *random_mac) +{ + struct cl_chip *chip = cl_hw->chip; + + if (!cl_mac_addr_is_zero(chip->conf->ce_phys_mac_addr)) { + /* Read MAC from NVRAM file */ + cl_mac_addr_copy(dflt_mac, chip->conf->ce_phys_mac_addr); + cl_dbg_verbose(cl_hw, "Read MAC address from NVRAM [%pM]\n", dflt_mac); + } else { + /* Read MAC from EEPROM */ + if (chip->eeprom_read_block(chip, ADDR_GEN_MAC_ADDR, + ETH_ALEN, dflt_mac) != ETH_ALEN) { + CL_DBG_ERROR(cl_hw, "Error reading MAC address from EEPROM\n"); + return -1; + } + + cl_dbg_verbose(cl_hw, "Read MAC address from EEPROM [%pM]\n", dflt_mac); + } + + /* Test if the new mac address is 00:00:00:00:00:00 or ff:ff:ff:ff:ff:ff */ + if (cl_mac_addr_is_zero(dflt_mac) || cl_mac_addr_is_broadcast(dflt_mac)) { + /* Set celeno oui */ + dflt_mac[0] = 0x00; + dflt_mac[1] = 0x1c; + dflt_mac[2] = 0x51; + get_random_bytes(&dflt_mac[3], 3); + cl_dbg_verbose(cl_hw, "Random MAC address [%pM]\n", dflt_mac); + *random_mac = true; + } + + return 0; +} + +static void cl_mac_addr_set_second_tcv(struct cl_hw *cl_hw, u8 *dflt_mac) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + u8 tcv0_bss_num = cl_hw_tcv0->conf->ci_max_bss_num; + u8 first_mask_bit = chip->conf->ce_first_mask_bit; + u64 mac64; + u8 idx; + u8 bss_num = cl_hw->conf->ci_max_bss_num; + u8 lam_bit_mask[ARRAY_SIZE(cl_hw->addresses) * TCV_MAX] = { + 0b0000, /* 1 addr, 0-bit diff between MAC addrs, LAM is not affecting it */ + 0b0000, /* 2 addrs, 0-bit diff between MAC addrs, first differs by LAM !!! */ + 0b0001, /* 3 addrs, 1-bit diff */ + 0b0011, /* 4 addrs, 2-bit diff */ + 0b0011, /* 5 addrs, 2-bit diff */ + + 0b0111, /* 6 addrs, 3-bit diff */ + 0b0111, /* 7 addrs, 3-bit diff */ + 0b0111, /* 8 addrs, 3-bit diff */ + 0b0111, /* 9 addrs, 3-bit diff */ + + 0b1111, /* 10 addrs, 4-bit diff */ + 0b1111, /* 11 addrs, 4-bit diff */ + 0b1111, /* 12 addrs, 4-bit diff */ + 0b1111, /* 13 addrs, 4-bit diff */ + 0b1111, /* 14 addrs, 4-bit diff */ + 0b1111, /* 15 addrs, 4-bit diff */ + 0b1111, /* 16 addrs, 4-bit diff */ + }; + + mac64 = ether_addr_to_u64(cl_hw_tcv0->hw->wiphy->perm_addr); + + if (chip->conf->ce_lam_enable) { + /* Find the first address of TCV1 */ + if (tcv0_bss_num == 1) { + /* + * For tcv0 bss num = 1, we have to zero the necessary bits + * since it hasn't been done in TCV0 + */ + mac64 &= ~((u64)lam_bit_mask[bss_num] << first_mask_bit); + } else { + u8 total_bss_to_mask = bss_num + tcv0_bss_num - 1; + + mac64 &= ~((u64)lam_bit_mask[tcv0_bss_num - 1] << first_mask_bit); + /* + * Get the first MAC address of TCV1 by incrementing the MAC + * address of the last BSS of TCV0. + * After the instruction below mac64 will hold the MAC of TCV0's + * last BSS. + */ + mac64 += ((u64)(tcv0_bss_num - 2) << first_mask_bit); + /* + * If there is no more room for another address in TCV0's mask + * address then we have to zero bits else increment the last + * address of TCV0 + */ + if (((mac64 >> first_mask_bit) & (u64)lam_bit_mask[total_bss_to_mask]) == + (u64)lam_bit_mask[total_bss_to_mask]) + mac64 &= ~((u64)lam_bit_mask[total_bss_to_mask] << first_mask_bit); + else + mac64 += (1ULL << first_mask_bit); + } + + /* Enable LAM bit */ + mac64 += (0x2ULL << 40); + } else { + mac64 += ((u64)tcv0_bss_num << first_mask_bit); + } + + for (idx = 0; idx < ETH_ALEN; idx++) { + u8 shift = (8 * (ETH_ALEN - 1 - idx)); + + dflt_mac[idx] = (mac64 & ((u64)0xFF << shift)) >> shift; + } +} + +int cl_mac_addr_set(struct cl_hw *cl_hw) +{ + bool random_mac = false; + u8 dflt_mac[ETH_ALEN] = {0x00, 0x1c, 0x51, 0x51, 0x51, 0x51}; + u8 dflt_mask[ETH_ALEN] = {0}; + bool use_lam = cl_hw->chip->conf->ce_lam_enable; + struct wiphy *wiphy = cl_hw->hw->wiphy; + + if (cl_hw_is_first_tcv(cl_hw)) { + if (cl_mac_addr_set_first_tcv(cl_hw, dflt_mac, &random_mac)) + return -1; + } else { + cl_mac_addr_set_second_tcv(cl_hw, dflt_mac); + } + + if (cl_mask_mac_by_bss_num(cl_hw, dflt_mac, dflt_mask, use_lam, random_mac)) + return -1; + + /* Permanent address MAC (the MAC of the first BSS) */ + SET_IEEE80211_PERM_ADDR(cl_hw->hw, dflt_mac); + + /* + * Addresses count must be power of 2 + * mac80211 doesn't handle non-contiguous masks + */ + BUILD_BUG_ON_NOT_POWER_OF_2(ARRAY_SIZE(cl_hw->addresses)); + + cl_mac_addr_array_to_nxmac(dflt_mask, &cl_hw->mask_low, &cl_hw->mask_hi); + + if (cl_mac_addr_set_addresses(cl_hw, use_lam, dflt_mask)) + return -1; + + wiphy->addresses = cl_hw->addresses; + wiphy->n_addresses = cl_hw->n_addresses; + + return 0; +} From patchwork Tue May 24 11:34:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575967 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 0012DC433EF for ; Tue, 24 May 2022 11:39:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236858AbiEXLjo (ORCPT ); Tue, 24 May 2022 07:39:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236865AbiEXLjm (ORCPT ); Tue, 24 May 2022 07:39:42 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2086.outbound.protection.outlook.com [40.107.104.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CCCA8D6A6 for ; Tue, 24 May 2022 04:39:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cM/gDrFOkcCnrQWdb8RJHU24WJFG4R5mO9j2n0RahXi2IGjndMRqY74vk7pC0qTs6b7Y49wCOlFnvmrqLXVRLOt6SxX8LPZuk/KGg+XagSaqkwg7JYowVkPEr3mzv2BIfbzI/fEUKl74n723NIhmGHNXvBl3RJqzCoxtJScC3vd1oM4J7RUxRPrmgB0bOTZPSAl4lE0+iBeO15+l8EQhxezj5EKa4iJSvyJybVu8ZnWm2kOFiBLVzht98hP1EpgMZNpgPo5IUDnKD8Lf+HJzDAh8P5pCTaDmMf4RtNNYgAMpPstAn8bzUjURnNvkvbIRIM1XFP7g1OVIpB2ymO3QKA== 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=hnf0lzHhXiJjUj1mEj2y01uHUt7I+1E59uqvq5alXWk=; b=ljMa/EO4OY6JwLR/6zOiGPcb+WfbOyNOQFE5nwEc/cA7FgP2U/TfazYFN8/RsKsmcf0UyiGWsTuDCcL/m7sYsaaz5lavcMguOmns3zHSTEqLaJo4A6yIMhHxD8IVHTDCwknyYbeD/zGsXQrNJldUIwXQkd58tiXRgr8BTpWbfe2oynUb8YXx9gqRClPL/TSczefGPWPZGjfnXRxDXb0aS6jMZwWpjYUT2WiYP28guYliJi23AIosRAMF5/fTAFJCnJjYzhqRVcX8rcbKukaNdu5zR+Jxx2LpVa+SoAOI5LXqRR+REw4BQRFa+uISFbWApPOLYxaUgvUXYDDi9I6D7w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hnf0lzHhXiJjUj1mEj2y01uHUt7I+1E59uqvq5alXWk=; b=lc8csV5g0nPVlRu7FRXS5Glm9zP822/jKCBTh2x8rn6Hb1KQZ8RqXhkTUsFQBHrDAbHxPDUQmAZcKnV/PTC5PQw9kr/6vW7bEBJ0IhBwUqMF80vERExUCEG0XM31lA8co8DoGqSQ42KCyn4se+MUgTbFASL0cDa+Tdl5XbZrxtQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:43 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:43 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 41/96] cl8k: add mac_addr.h Date: Tue, 24 May 2022 14:34:07 +0300 Message-Id: <20220524113502.1094459-42-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: dd35cfe9-dbf1-46c8-630f-08da3d79e439 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2jBSUMEayaFCDgl1Dd+tVjeIvhCzRSIm51cOvZQfkj4l635sQehCDbeETGgBIytOKj/CtmeSosQeOWbvwXySltXFizVGfw3Jo0xfmBMfaQZFnz3zQwa7roQ+iel/xsj50IzSqOdIHS0R7/V4v9f1CEykeqZlq9fLObLgUJqbcWF6dU4+89yH3K1UZq8U9kl4KEELZMNHziQsYEqye6ekS7KqyzhbJAQjBtG26pBKCQ8fF4obmTWSBkSNygNscRFXUBDjftwyn0XN9JrDhBLHDdqhkhffZLDp9SJ6ppYEh97R7+4mtTCX0bydYAbF6FsO/l3kM1/TGDp8sMp6Y2qpzFArFeeQ94iXL/re3J4trUIUz90Xwl4AQ9D2Xdjli33fGNHYH//OmHwBW7cRy9ydYMWh1inyUC32V68WR1HkGXm4bok9nyhg3hBrCSImOnU2LpKk/iLhh4sSh+T7W8CxjnAqXJV3kPaPtUVFPDDGMl04qICpez99CeV+6E7Bj8/qFTn0BWNsUGiwF5axugJPeB7ykfKctF2prWNKHkQnDQEc3zeDY+bdSFRhAeiRdbKpXF6XA0SPZUerw48Bt6A97tBaG2pVLk6x7RYvcV6E/9Flzwe0CWVvIBw7f89HoHYf/L2CECnF22jcTXXtNNYc7BBuwvbNPqVcjyr96uDhhx+Sf1kazKsRlf2OB6p0WPjcmWrToTYJSABPotKCZLw7iOXb9FJQ8yrK8DXfUN8raSg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: /fcuxp7QqnREZYphLyxIiMu8uAy0Da55ZDrdOnri2wxdYHOEZZYMXHfz63lRKypKDWhrRhT8zyD2O9Sh80cU5rTuy4kasBZoOLdHaY5zlcR0zucUn5zUUhDifoBPBe+bmINCK8YbIrRQLIad3N+m+dcY+PYCmkW26OQhINLhgP9OOA33O2P77vq2n2GOVFZV0vRLamyVwmk6uU3oHt4lWi0ZNbqTxijfG8zR/Wj9kBlTuGSLesEj71S6f4TY9LtZXE2UepDeJkSfpthqIg35/MRw1/IIvGmX7yKu2COLuElJKG0zYLG/v3OStn7BsQIIw7JGDZF1+bdVkfbRawdU6zIfPjeznzwSl2uI1XIpL539ybB5+EyWUQTbNjTPh7KTDWf+VxPLyJQRsgd0KZ5A/P4Aut5h+7T4TQNur0yB9ZwMkWbvUTbLm9un0p8hAqB8takJwEbboAAayUkr+hj1nj8UIZjXkW/eT4H+iTUlMzaChpKzxJUsnWB3TcCzz11DDo6KlxQOwZuRt/7wcyN8FXnQKi3WscYGZRTurJFacKEFIcHr7QZVfIoHi7yOr3SUqOuhPcGhyU/wdNd2mr4QGPL/+D76Hh2GCcjhqF7E7ZAI8mMxKKaZm9f/qmxwXyxYJpSIJ3Be/gJlfcJfTIXZROSFOnlyxaRz7wa7y1e1Lj0U6nfQEjvvqaONNeTs5ixzgGi+mliSn7P6B3kqUDZVP5C35ladR3jm+UU2WAVZ8kTHQysGFpjY5hzUi54UYBb+FAodrQe97QX/zRmpWbfVosVa2f6HVadGoBO55AOIlCVhABWRt36HYR7UJizx8xKsRfExk+tj102tAPuuO4+KsD5VmDQp/bc3sJFKuOLV14jjWny+/FAQOUO/VtrE3Ssj6AtwWUVdCJx1LpI4xlEzfRjOiG9qVhhHRuyZCdYD/T3CU4F8r2/RvvkD6oZSzd6/s1L+yX/oQNSxpLG4mpd5vVuTbiw1sGVAr+JbjqpVgvAQ3qDtVkB/nOuuFoytQzAZ/0fSr0xSZwblMr41ZgCqhorJcmQ14DRhgdSkQjiSqrYonsc+TBkOYglA3fMn9xxGD6EZjpMk1YnF2r7DajbSFfFciXZPOWwR6Mj5xSA2ITxuPhy+4PnFlUnHV4FI6+dhhd8eVI7hOIh5DiTPbOZ9pyHqfqg6eWgZQ4Om99OdbWZG09gLfn/FF0OkbKEahZJ3jK8bPjhAAQROJz/aDuOwuj9ws7cH6szvKjbQo7j25j0ZA5NrgED5cDKpuwewXC4Mex0H0R8w1qxDO4MFZXMfJo1ICENPoZS0PlxoHwpJuXAC+/LBXoi4E2RVJzbyrfS7+ygWPugeqT8TG1gegXJPoxLu3OJWM3MDAh0ZjB5omKnw9RIa2IVToBgcPbkTrPj5jQAQn9vlOUUtOAmGc+vlUrETQRrRA1pT1DK7Qm7wKco7Lr7LNpGUf1ckykeK19OJjjWfEo+cgtpq+Y2YMF4eurjxMASrx8zhvpEGiib35/yqm9a4nr9BVF2hEZCXB/7/A7k4/mkpI+kCQARakjQC7oLxzr5I7N8mTFJFC6sS4t4DJLcGuBCdj9zeJdcUW//ypIglfi4iFE7c6zS/HATOKuYdQ6njyhpVefGjwqY16mOQSMeRbtH0dKPQEmwNSpeuhSEa0uPUEse0/HvAqt4PLF/qfAqDFnZWNR2gTb0yLikM4RXfujzOhdxXFXQIdf+JVIbseJnrgNWIZTLfcicPGQMyEJRABxThzGa7wXYYA0k= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: dd35cfe9-dbf1-46c8-630f-08da3d79e439 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:15.8617 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 15nYMeIYFXuxk7pU8fWzuGa4v5yC7X/oE3/E5xBr2HJPi96jLzwNohAdsW8eUat/b5s9XcnuY9uRKcI6Uj5e7Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/mac_addr.h | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/mac_addr.h diff --git a/drivers/net/wireless/celeno/cl8k/mac_addr.h b/drivers/net/wireless/celeno/cl8k/mac_addr.h new file mode 100644 index 000000000000..3f916f2b7f7b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/mac_addr.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_MAC_ADDR_H +#define CL_MAC_ADDR_H + +#include "hw.h" + +int cl_mac_addr_set(struct cl_hw *cl_hw); + +static inline void cl_mac_addr_copy(u8 *dest_addr, const u8 *src_addr) +{ + memcpy(dest_addr, src_addr, ETH_ALEN); +} + +static inline bool cl_mac_addr_compare(const u8 *addr1, const u8 *addr2) +{ + return !memcmp(addr1, addr2, ETH_ALEN); +} + +static inline bool cl_mac_addr_is_zero(const u8 *addr) +{ + const u8 addr_zero[ETH_ALEN] = {0}; + + return !memcmp(addr, addr_zero, ETH_ALEN); +} + +static inline bool cl_mac_addr_is_broadcast(const u8 *addr) +{ + const u8 addr_bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + return !memcmp(addr, addr_bcast, ETH_ALEN); +} + +static inline void cl_mac_addr_array_to_nxmac(u8 *array, u32 *low, u32 *high) +{ + /* Convert mac address (in a form of array) to a C nxmac form. + * Input: array - MAC address + * Output: low - array[0..3], high - array[4..5] + */ + u8 i; + + for (i = 0; i < 4; i++) + *low |= (u32)(((u32)array[i]) << (i * 8)); + + for (i = 0; i < 2; i++) + *high |= (u32)(((u32)array[i + 4]) << (i * 8)); +} + +static inline u8 cl_mac_addr_find_idx(struct cl_hw *cl_hw, u8 *addr) +{ + u8 i; + + for (i = 0; i < cl_hw->n_addresses; i++) + if (cl_mac_addr_compare(cl_hw->addresses[i].addr, addr)) + return i; + + return BSS_INVALID_IDX; +} + +#endif /* CL_MAC_ADDR_H */ From patchwork Tue May 24 11:34:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575965 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 033E5C433FE for ; Tue, 24 May 2022 11:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236885AbiEXLj6 (ORCPT ); Tue, 24 May 2022 07:39:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236865AbiEXLjx (ORCPT ); Tue, 24 May 2022 07:39:53 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2041.outbound.protection.outlook.com [40.107.104.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 968E592D01 for ; Tue, 24 May 2022 04:39:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=L7qmBNmVmwiqbfmqOZsHc+q/SG5L0AtqXvQVx22ya6Z18iQHF5V564ExiuHxrL6YF/8sbdJvJcne8bnplraZk2kNDZpT38U/oHEq74OXv+h6cqrJ3+yo8Vr0zcM6H/kqzB1N3E8hA26AKzHlS+/spqd5szNTe60dqrXsL7CeZM6123Md+KwLuAYucggrphpgrwXdOu3n2kJNoAIUAopnLep5HvcHfJKDJ9pZFr/xBbNYs9VwGbR5CS+DRk1TQQHkT/sFHOzHd+UdgTyiXUNab004lMva1ywpdzxOs/YhY93vbtGFgCX6RB717tITynDfrYC457EUAZXSvQt8S/Vtsw== 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=SZPsCcruYG+xAKUQN6WMYvyDcG+9g1RmeHUitee3gb8=; b=n9u2ZhGuE0cZrSG7NI2jtUeE4PX0C60vjTkp3fwxal3s6+r2TtSW+1t5ZYYVYXdy/sEAZFcriw5P5rhOoexF2O+mclFOEPj40hTZW1EvlW0HipYhw4pibsakqUi7f3BX6ovLZqsO9P6sRkzOJxNjZc80k4Jv5PiKEZCacA7bSEjhMpHWXv3k17reCuUK+tW366ahplGAzhEV/kGUJ4CZv4GW0FarvkFnjkxjvpFtiuxb/mFT6h+dk4iQTVViOKsP6QR67Be9+0KhC3bDdpFgIAOJff6YZe1Zuda5O/jXue1c+nDdT/9+r+jYh7SBvcNKsOkihhaikHCrVRhgvFL16g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=SZPsCcruYG+xAKUQN6WMYvyDcG+9g1RmeHUitee3gb8=; b=YlZkoynsCC2l3uC27RlFZeovrhyVj6HwR/Wzb6OiIKaECBQi0biiZj+MpNh50dwCyVN5cUJdDwvFRSl8fxLtTMK4JgpgaowmbA/msY/pnaUeQKESpAZSNTYpglQnsPAPFpa6s15/vrI1RNQ8ibW0Bl4Sdp13CthD59tQMcU5R6M= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:43 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:43 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 42/96] cl8k: add main.c Date: Tue, 24 May 2022 14:34:08 +0300 Message-Id: <20220524113502.1094459-43-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b9763b2e-2eac-47fc-4e23-08da3d79e6fa X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 23pZcr0HmpL1WXaVh3238s5Y1bl2nAN2OZR3FX7BF7POnxjNUjMzZDGhzY7RnceGS3Xgz6YwpaK9kN6z568lOtTkuwJXsocSSS5Itr0/asiUvaHpqPoE7oSercIvak5diA2ujNAtx6ZkCJ+jVHw4nvHUsAp2Jp0ipouVLkIPLe40oMZGLCszO8xsY00w9f21tg6FhJP6gHT5ZaqH/z6uBcSxpFEnTw2slhfsyzeWsLfe5SE3JpMq57bSrs5F0VeqZSwn7wwVOm98FCs3vfuk18xs0rkjnhTEQu/OwQX0Zgi5bmURoG8yY2pxVYXo1/fYg8OQzGcq+pZRzrcjAX3EDQTLGP7Ln5nRg0OFmCrA90dPLoNuLFUpvOc7hsp/1z7MuJB3ahHEfgAG0pAQwxnPY40Oox2J5wMoSA6RiyyboaRWHhW9lKkOnXDofrVohotzFXUZwy8RwaDN6p/uJfElmWDPHr15PiK0G5gCQ13RPXVATJeFUNyhIn7fm+Kj7zRUDbjI6jP/h3XVh15mbWzNucqbUMjUfvPjlDE/ajb6eFPQ4YOKK0KwWwcslhFnC9fc89DncpSMZMLl3Y816Bzk9PlDOC4RpqetgsttlTAX8O26vivHZQheIsJSB7Qa3Iy0pU8g6Hp1sm5rVahd0dzk+6SEU2hIXNciNMKWprojMlodQPB3vLXABuJbQ0MzwC4/YqNE66RKOnVU8yqBwBVAtLqIdj70GnOeKG7yIcrD5n8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(30864003)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: BWxOvb9jUKBknoWDm9KT0FSeNV7rto1Ku3se8+2IjZLoN5IRIcx2QtCwGnIS+5nvvIIZI7e2DLfEkGzgyq7g4S6PRaBGyE0P4SpK2BtnkKuQAt+LOPXpogxj++9ZsrZqICg1tTrfO5giY0JBixheUl55w+kHCdzcMq9YLY9JpvHq8lAznTc0P/H8HDs+q9tHeEy2TRpQDQIp+WA0wri1ulBdIaJ8wUgJ9391aURGsVfibLp5E0nd4dCi7ilVMqIZBMUXrWPG8y8qgbVEyCWwBwencda3+SAHVHZXGHLLEp19cKK/kmGuxlVawriC4UoH4BuTE+fwOmggGqDZGkOT9hPxrr3xAqQdUkbzQWcyrh9LirErmyiAuZF2l5UT3v5bPyGAMT61yHiBRViIY5OiXhSORgsG5yNfPahgml3/M2nk8eohnboNH9jy8aNDoijSilHkgXAA1CRMxRaQ/jrsQl1xahOBLZtCSeMI72RVJ1vypK8p0v8bqfaqHcd6qZlb8C1fY4DVNVTHmypVkWD/6mqhG9e0xqL95WvSd6XKsY8UODp9hpfWJ5ZPnTbbdIZAnjxHv1sluUy+7baAmzx8DHhULwptWlC1EMmxFGjiiytFz21algupBvjnmJzxc6mKBnIVeGBq4+cxOl3jZYSKR/XKscbfoGiLMsfAYddfheo/9SFj3mBCr9uuCwd/Nw+aQD3X/zXZdyaXwUypDFDT2Z6NjzvUsat3rAD8DLm+EhSf0V+O8B4BG+0yEs/aYPkmLNwpEhvlDdGoOBjlTdB76DFzWCMpMJnJ2ZRPnat5aBFEZlMWwFu0Def1ZAGUX0xKMbYai2590PWTDRMVCczegPsjc3ArY1JENHOpb0fHrsDSuZyz5nzx4PxJplH5WCPh56H7WeVgLxHhVcPuig0rn8dKTtl33ZwVnSDp7nyewEh2BVccERV+YUjLsio4LRoVlFn+ZOAkJTDrA86Cv/TFVQesRTkFj0eKu7gn5boqu22x6P8UqpHYoDb0e2Fx71f79Up8g1jXEltGVcY+obYdEMn6XqbX+2a8TzzLpCwqwWiXOH/mjO04K6vNfsOG13Ny16UYxPlr/vWip8ON9nFudXYrdjawz1JkPNUBiQ+iXzZKOxYMUDpRMuiaWJuXMcARsOGFzjLNHBOV9lXbSX/Urzln2H8NW7IixHTHcWFzJNGtPQZt0V5D0TCtAU0XC32QTBd/J151o6NmFYEYrpIhLzsM+A6BNFdO9n7EoANzVlLXfaAkyDAb52TWw+DkK4sbMPvLP1ej6hcyUZfVonufd6V108kxM1p/aHUEqQiJnJI/d9nzEWIdF3lZ4I9DGXldWrdM1dH8Ah4h7Z2QqAl5AQJ5WAipel04y9LLjzR9o2FEMhAGGx2HxbTqu3zIFRpHCOWInMKW+jHLXwsret1DM8iBWFJO5GyoSbT3ih958vT3RdYEJssZrjlnDsthTf9gDTXv8JMjHl3Nk7MsThZnMTe2ui65tmcXo8BT6d4U6SYYlLQJ9HlmN+CPbX/8C1Ym6K/MMDvyL9KyNQ2yfley7WIwy/ErMprmKbijpFQIUumIYPlvGpUbs+yT+KcntQXsXaHrRp1W1IMtbXhDwoB8u4WNbM1zPWD4upQQSWVpH7y8rZV6iYbtvMEgUGqJD+NGUaW7hyeap7PCfhJQpZGIb6ZL8g1IQh/kFDEMBZQV/bl2EHz9w0gaJ1vCvq4dARC7EZFyNUyYKHisXtwa9yTPoSIzgvMBm9XJaFkW6xwH33E= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9763b2e-2eac-47fc-4e23-08da3d79e6fa X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:20.5596 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: DBagqrBLBL0Db/Z5IfN0CqQABpsknEITZ0iarbH2fpbRBYF1AuANbCSmJooCdAbKN6cUwPBPCYQ1+9dth7SEIQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/main.c | 603 ++++++++++++++++++++++++ 1 file changed, 603 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/main.c diff --git a/drivers/net/wireless/celeno/cl8k/main.c b/drivers/net/wireless/celeno/cl8k/main.c new file mode 100644 index 000000000000..08abb16987ef --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/main.c @@ -0,0 +1,603 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "tx.h" +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "stats.h" +#include "maintenance.h" +#include "vns.h" +#include "traffic.h" +#include "sounding.h" +#include "recovery.h" +#include "rates.h" +#include "utils.h" +#include "phy.h" +#include "radio.h" +#include "dsp.h" +#include "dfs.h" +#include "tcv.h" +#include "mac_addr.h" +#include "bf.h" +#include "rfic.h" +#include "e2p.h" +#include "chip.h" +#include "regdom.h" +#include "platform.h" +#include "mac80211.h" +#include "main.h" + +MODULE_DESCRIPTION("Celeno 11ax driver for Linux"); +MODULE_VERSION(CONFIG_CL8K_VERSION); +MODULE_AUTHOR("Copyright(c) 2022 Celeno Communications Ltd"); +MODULE_LICENSE("Dual BSD/GPL"); + +static struct ieee80211_ops cl_ops = { + .tx = cl_ops_tx, + .start = cl_ops_start, + .stop = cl_ops_stop, + .add_interface = cl_ops_add_interface, + .remove_interface = cl_ops_remove_interface, + .config = cl_ops_config, + .bss_info_changed = cl_ops_bss_info_changed, + .start_ap = cl_ops_start_ap, + .stop_ap = cl_ops_stop_ap, + .prepare_multicast = cl_ops_prepare_multicast, + .configure_filter = cl_ops_configure_filter, + .set_key = cl_ops_set_key, + .sw_scan_start = cl_ops_sw_scan_start, + .sw_scan_complete = cl_ops_sw_scan_complete, + .sta_state = cl_ops_sta_state, + .sta_notify = cl_ops_sta_notify, + .conf_tx = cl_ops_conf_tx, + .sta_rc_update = cl_ops_sta_rc_update, + .ampdu_action = cl_ops_ampdu_action, + .post_channel_switch = cl_ops_post_channel_switch, + .flush = cl_ops_flush, + .tx_frames_pending = cl_ops_tx_frames_pending, + .reconfig_complete = cl_ops_reconfig_complete, + .get_txpower = cl_ops_get_txpower, + .set_rts_threshold = cl_ops_set_rts_threshold, + .event_callback = cl_ops_event_callback, + .set_tim = cl_ops_set_tim, + .get_antenna = cl_ops_get_antenna, + .get_expected_throughput = cl_ops_get_expected_throughput, + .sta_statistics = cl_ops_sta_statistics, + .get_survey = cl_ops_get_survey, + .hw_scan = cl_ops_hw_scan, + .cancel_hw_scan = cl_ops_cancel_hw_scan +}; + +static void cl_drv_workqueue_create(struct cl_hw *cl_hw) +{ + if (!cl_hw->drv_workqueue) + cl_hw->drv_workqueue = create_singlethread_workqueue("drv_workqueue"); +} + +static void cl_drv_workqueue_destroy(struct cl_hw *cl_hw) +{ + if (cl_hw->drv_workqueue) { + destroy_workqueue(cl_hw->drv_workqueue); + cl_hw->drv_workqueue = NULL; + } +} + +static int cl_main_alloc(struct cl_hw *cl_hw) +{ + int ret = 0; + + ret = cl_phy_data_alloc(cl_hw); + if (ret) + return ret; + + ret = cl_calib_common_tables_alloc(cl_hw); + if (ret) + return ret; + + ret = cl_power_table_alloc(cl_hw); + if (ret) + return ret; + + return ret; +} + +static void cl_main_free(struct cl_hw *cl_hw) +{ + cl_phy_data_free(cl_hw); + cl_calib_common_tables_free(cl_hw); + cl_power_table_free(cl_hw); +} + +static void cl_free_hw(struct cl_hw *cl_hw) +{ + if (!cl_hw) + return; + + cl_temperature_wait_for_measurement(cl_hw->chip, cl_hw->tcv_idx); + + cl_tcv_config_free(cl_hw); + + if (cl_hw->hw->wiphy->registered) + ieee80211_unregister_hw(cl_hw->hw); + + cl_chip_unset_hw(cl_hw->chip, cl_hw); + ieee80211_free_hw(cl_hw->hw); +} + +static void cl_free_chip(struct cl_chip *chip) +{ + cl_free_hw(chip->cl_hw_tcv0); + cl_free_hw(chip->cl_hw_tcv1); +} + +static int cl_prepare_hw(struct cl_chip *chip, u8 tcv_idx, + const struct cl_driver_ops *drv_ops) +{ + struct cl_hw *cl_hw = NULL; + struct ieee80211_hw *hw; + int ret = 0; + + hw = ieee80211_alloc_hw(sizeof(struct cl_hw), &cl_ops); + if (!hw) { + cl_dbg_chip_err(chip, "ieee80211_alloc_hw failed\n"); + return -ENOMEM; + } + + cl_hw_init(chip, hw->priv, tcv_idx); + + cl_hw = hw->priv; + cl_hw->hw = hw; + cl_hw->tcv_idx = tcv_idx; + cl_hw->sx_idx = chip->conf->ci_tcv1_chains_sx0 ? 0 : tcv_idx; + cl_hw->chip = chip; + + /* + * chip0, tcv0 --> 0 + * chip0, tcv1 --> 1 + * chip1, tcv0 --> 2 + * chip1, tcv1 --> 3 + */ + cl_hw->idx = chip->idx * CHIP_MAX + tcv_idx; + + cl_hw->drv_ops = drv_ops; + + SET_IEEE80211_DEV(hw, chip->dev); + + ret = cl_tcv_config_alloc(cl_hw); + if (ret) + goto out_free_hw; + + ret = cl_tcv_config_read(cl_hw); + if (ret) + goto out_free_hw; + + cl_chip_set_hw(chip, cl_hw); + + ret = cl_mac_addr_set(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_mac_addr_set failed\n"); + goto out_free_hw; + } + + if (cl_band_is_6g(cl_hw)) + cl_hw->nl_band = NL80211_BAND_6GHZ; + else if (cl_band_is_5g(cl_hw)) + cl_hw->nl_band = NL80211_BAND_5GHZ; + else + cl_hw->nl_band = NL80211_BAND_2GHZ; + + if (cl_band_is_24g(cl_hw)) + cl_hw->hw_mode = HW_MODE_BG; + else + cl_hw->hw_mode = HW_MODE_A; + + cl_hw->wireless_mode = WIRELESS_MODE_HT_VHT_HE; + + cl_cap_dyn_params(cl_hw); + + cl_dbg_verbose(cl_hw, "cl_hw created\n"); + + return 0; + +out_free_hw: + cl_free_hw(cl_hw); + + return ret; +} + +void cl_main_off(struct cl_hw *cl_hw) +{ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.all); + cl_ipc_stop(cl_hw); + + if (!test_bit(CL_DEV_INIT, &cl_hw->drv_flags)) { + cl_tx_off(cl_hw); + cl_rx_off(cl_hw); + cl_msg_rx_flush_all(cl_hw); + } + + cl_fw_file_cleanup(cl_hw); +} + +static void _cl_main_deinit(struct cl_hw *cl_hw) +{ + if (!cl_hw) + return; + + ieee80211_unregister_hw(cl_hw->hw); + + /* Send reset message to firmware */ + cl_msg_tx_reset(cl_hw); + + cl_hw->is_stop_context = true; + + cl_drv_workqueue_destroy(cl_hw); + + cl_scanner_deinit(cl_hw); + + cl_noise_close(cl_hw); + cl_maintenance_close(cl_hw); + cl_vns_close(cl_hw); + cl_rssi_assoc_exit(cl_hw); + cl_radar_close(cl_hw); + cl_sounding_close(cl_hw); + cl_chan_info_deinit(cl_hw); + cl_wrs_api_close(cl_hw); + cl_main_off(cl_hw); + /* These 2 must be called after cl_tx_off() (which is called from cl_main_off) */ + cl_tx_amsdu_txhdr_deinit(cl_hw); + cl_sw_txhdr_deinit(cl_hw); + cl_fw_dbg_trigger_based_deinit(cl_hw); + cl_stats_deinit(cl_hw); + cl_main_free(cl_hw); + cl_fw_file_release(cl_hw); + + cl_ipc_deinit(cl_hw); + cl_hw_deinit(cl_hw, cl_hw->tcv_idx); + vfree(cl_hw->tx_queues); +} + +void cl_main_deinit(struct cl_chip *chip) +{ + struct cl_chip_conf *conf = chip->conf; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + + if (cl_chip_is_tcv1_enabled(chip) && cl_hw_tcv1) + _cl_main_deinit(cl_hw_tcv1); + + if (cl_chip_is_tcv0_enabled(chip) && cl_hw_tcv0) + _cl_main_deinit(cl_hw_tcv0); + + if (conf->ci_phy_dev != PHY_DEV_DUMMY) { + if (!conf->ci_phy_load_bootdrv) + cl_phy_off(cl_hw_tcv1); + + cl_phy_off(cl_hw_tcv0); + } + + cl_platform_dealloc(chip); + + cl_free_chip(chip); +} + +static struct cl_controller_reg all_controller_reg = { + .breset = XMAC_BRESET, + .debug_enable = XMAC_DEBUG_ENABLE, + .dreset = XMAC_DRESET, + .ocd_halt_on_reset = XMAC_OCD_HALT_ON_RESET, + .run_stall = XMAC_RUN_STALL +}; + +void cl_main_reset(struct cl_chip *chip, struct cl_controller_reg *controller_reg) +{ + /* Release TRST & BReset to enable JTAG connection to FPGA A */ + u32 regval; + + /* 1. return to reset value */ + regval = macsys_gcu_xt_control_get(chip); + regval |= controller_reg->ocd_halt_on_reset; + regval &= ~(controller_reg->dreset | controller_reg->run_stall | controller_reg->breset); + macsys_gcu_xt_control_set(chip, regval); + + regval = macsys_gcu_xt_control_get(chip); + regval |= controller_reg->dreset; + macsys_gcu_xt_control_set(chip, regval); + + /* 2. stall xtensa & release ocd */ + regval = macsys_gcu_xt_control_get(chip); + regval |= controller_reg->run_stall; + regval &= ~controller_reg->ocd_halt_on_reset; + macsys_gcu_xt_control_set(chip, regval); + + /* 3. breset release & debug enable */ + regval = macsys_gcu_xt_control_get(chip); + regval |= (controller_reg->debug_enable | controller_reg->breset); + macsys_gcu_xt_control_set(chip, regval); + + msleep(100); +} + +int cl_main_on(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + int ret; + u32 regval; + + cl_hw->fw_active = false; + + cl_txq_init(cl_hw); + + cl_hw_assert_info_init(cl_hw); + + if (cl_recovery_in_progress(cl_hw)) + cl_main_reset(chip, &cl_hw->controller_reg); + + ret = cl_fw_file_load(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_fw_file_load failed %d\n", ret); + return ret; + } + + /* Clear CL_DEV_FW_ERROR after firmware loaded */ + clear_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags); + + if (cl_recovery_in_progress(cl_hw)) + cl_ipc_recovery(cl_hw); + + regval = macsys_gcu_xt_control_get(chip); + + /* Set fw to run */ + if (cl_hw->fw_active) + regval &= ~cl_hw->controller_reg.run_stall; + + /* Set umac to run */ + if (chip->umac_active) + regval &= ~UMAC_RUN_STALL; + + /* Ack all possibly pending IRQs */ + ipc_xmac_2_host_ack_set(chip, cl_hw->ipc_e2a_irq.all); + macsys_gcu_xt_control_set(chip, regval); + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.all); + /* + * cl_irq_status_sync will set CL_DEV_FW_SYNC when fw raises IPC_IRQ_E2A_SYNC + * (indicate its ready to accept interrupts) + */ + ret = wait_event_interruptible_timeout(cl_hw->fw_sync_wq, + test_and_clear_bit(CL_DEV_FW_SYNC, + &cl_hw->drv_flags), + msecs_to_jiffies(5000)); + + if (ret == 0) { + pr_err("[%s]: FW synchronization timeout.\n", __func__); + cl_hw_assert_check(cl_hw); + ret = -ETIMEDOUT; + goto out_free_cached_fw; + } else if (ret == -ERESTARTSYS) { + goto out_free_cached_fw; + } + + return 0; + +out_free_cached_fw: + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.all); + cl_fw_file_release(cl_hw); + return ret; +} + +static int __cl_main_init(struct cl_hw *cl_hw) +{ + int ret; + + if (!cl_hw) + return 0; + + if (cl_regd_init(cl_hw, cl_hw->hw->wiphy)) + cl_dbg_err(cl_hw, "regulatory failed\n"); + + /* + * ieee80211_register_hw() will take care of calling wiphy_register() and + * also ieee80211_if_add() (because IFTYPE_STATION is supported) + * which will internally call register_netdev() + */ + ret = ieee80211_register_hw(cl_hw->hw); + if (ret) { + cl_dbg_err(cl_hw, "ieee80211_register_hw failed\n"); + cl_main_deinit(cl_hw->chip); + + return ret; + } + + return ret; +} + +static int _cl_main_init(struct cl_hw *cl_hw) +{ + int ret = 0; + + if (!cl_hw) + return 0; + + set_bit(CL_DEV_INIT, &cl_hw->drv_flags); + + /* By default, set FEM mode to opertional mode. */ + cl_hw->fem_mode = FEM_MODE_OPERETIONAL; + + cl_vif_init(cl_hw); + + cl_drv_workqueue_create(cl_hw); + + init_waitqueue_head(&cl_hw->wait_queue); + init_waitqueue_head(&cl_hw->fw_sync_wq); + init_waitqueue_head(&cl_hw->radio_wait_queue); + + mutex_init(&cl_hw->dbginfo.mutex); + mutex_init(&cl_hw->msg_tx_mutex); + mutex_init(&cl_hw->set_channel_mutex); + + spin_lock_init(&cl_hw->tx_lock_agg); + spin_lock_init(&cl_hw->tx_lock_cfm_agg); + spin_lock_init(&cl_hw->tx_lock_single); + spin_lock_init(&cl_hw->tx_lock_bcmc); + spin_lock_init(&cl_hw->channel_info_lock); + + ret = cl_ipc_init(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_ipc_init failed %d\n", ret); + return ret; + } + + cl_chip_set_rfic_version(cl_hw); + + /* Validate calib params should be called after setting the rfic version */ + cl_tcv_config_validate_calib_params(cl_hw); + + cl_hw->tx_queues = vzalloc(sizeof(*cl_hw->tx_queues)); + if (!cl_hw->tx_queues) { + cl_ipc_deinit(cl_hw); + return -ENOMEM; + } + + ret = cl_main_on(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_main_on failed %d\n", ret); + cl_ipc_deinit(cl_hw); + vfree(cl_hw->tx_queues); + + return ret; + } + + ret = cl_main_alloc(cl_hw); + if (ret) + goto out_free; + + /* Reset firmware */ + ret = cl_msg_tx_reset(cl_hw); + if (ret) + goto out_free; + + cl_calib_power_read(cl_hw); + cl_sta_init(cl_hw); + cl_sw_txhdr_init(cl_hw); + cl_tx_amsdu_txhdr_init(cl_hw); + cl_rx_init(cl_hw); + cl_prot_mode_init(cl_hw); + cl_radar_init(cl_hw); + cl_sounding_init(cl_hw); + cl_traffic_init(cl_hw); + ret = cl_vns_init(cl_hw); + if (ret) + goto out_free; + + cl_maintenance_init(cl_hw); + cl_rssi_assoc_init(cl_hw); + cl_agg_cfm_init(cl_hw); + cl_single_cfm_init(cl_hw); + cl_bcmc_cfm_init(cl_hw); +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_rate_init(cl_hw); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_init(cl_hw); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + cl_wrs_api_init(cl_hw); + cl_dfs_init(cl_hw); + cl_noise_init(cl_hw); + ret = cl_fw_dbg_trigger_based_init(cl_hw); + if (ret) + goto out_free; + + cl_stats_init(cl_hw); + cl_cca_init(cl_hw); + cl_bf_init(cl_hw); + + ret = cl_scanner_init(cl_hw); + if (ret) + goto out_free; + + /* Start firmware */ + ret = cl_msg_tx_start(cl_hw); + if (ret) + goto out_free; + + return 0; + +out_free: + cl_main_free(cl_hw); + vfree(cl_hw->tx_queues); + + return ret; +} + +int cl_main_init(struct cl_chip *chip, const struct cl_driver_ops *drv_ops) +{ + int ret = 0; + struct cl_chip_conf *conf = chip->conf; + + /* All cores needs to be reset first (once per chip) */ + cl_main_reset(chip, &all_controller_reg); + + /* Prepare HW for TCV0 */ + if (cl_chip_is_tcv0_enabled(chip)) { + ret = cl_prepare_hw(chip, TCV0, drv_ops); + + if (ret) { + cl_dbg_chip_err(chip, "Prepare HW for TCV0 failed %d\n", ret); + return ret; + } + } + + /* Prepare HW for TCV1 */ + if (cl_chip_is_tcv1_enabled(chip)) { + ret = cl_prepare_hw(chip, TCV1, drv_ops); + + if (ret) { + cl_dbg_chip_err(chip, "Prepare HW for TCV1 failed %d\n", ret); + cl_free_hw(chip->cl_hw_tcv0); + return ret; + } + } + + if (!conf->ci_phy_load_bootdrv && + conf->ci_phy_dev != PHY_DEV_DUMMY) { + ret = cl_radio_boot(chip); + if (ret) { + cl_dbg_chip_err(chip, "RF boot failed %d\n", ret); + return ret; + } + + ret = cl_dsp_load_regular(chip); + if (ret) { + cl_dbg_chip_err(chip, "DSP load failed %d\n", ret); + return ret; + } + } + + ret = _cl_main_init(chip->cl_hw_tcv0); + if (ret) { + cl_free_chip(chip); + return ret; + } + + ret = _cl_main_init(chip->cl_hw_tcv1); + if (ret) { + _cl_main_deinit(chip->cl_hw_tcv0); + cl_free_chip(chip); + return ret; + } + + ret = __cl_main_init(chip->cl_hw_tcv0); + if (ret) + return ret; + + ret = __cl_main_init(chip->cl_hw_tcv1); + if (ret) + return ret; + +#ifdef CONFIG_CL8K_EEPROM_STM24256 + if (conf->ci_calib_eeprom_en && conf->ce_production_mode && conf->ce_calib_runtime_en) + cl_e2p_read_eeprom_start_work(chip); +#endif + + return ret; +} From patchwork Tue May 24 11:34:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576845 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 534C8C433F5 for ; Tue, 24 May 2022 11:40:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236881AbiEXLkC (ORCPT ); Tue, 24 May 2022 07:40:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236876AbiEXLj5 (ORCPT ); Tue, 24 May 2022 07:39:57 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2081.outbound.protection.outlook.com [40.107.104.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D7E692D0C for ; Tue, 24 May 2022 04:39:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Td2vUgGpUfgSykCi3d4XL/e1CWc2IaIYbaXPiWZa6X+OIpY6YJACG6bFk1JSQIGvBfNCYhuPOfTXXQEZWk6GdtvykMXDEv8suby2sXhkDor1uvmQYEJ0daRJ5ibPtXB2uiSHxONdS1IGIxM6yrwutdGOTX5ozmacy6Tb0mvdTt309hdgClQC/7Q3bz3HMOk3zrm/eo5fKjMlrh8UMZZdM/i3259eI+AwBjT8Hun0vyMH+OD4LmiZpN8WiyHR9wCHF5eBV8oZzMfqE0tVaFnDQA1Y4gJYcs/2Bn5ifcPg3c/63Cav+bRg2T/sRfD+o9z18NxqEm0DJvx3QgbgoUfTOA== 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=MuEiQ2he2/khl9KjB3d8Z7ABA1d6Vd6a9zGKnnkZSxs=; b=Ib3dgMM9gxfJp2xS5rUR6VWsYtdbBEeRoDMBVRDU6VC9LNXjb3HlwWUTg7zBCdVJeQhW5XWCIkHT6+C8X2FCc/1Yv5JCQF4j2W1G8/4+sJKo0c6uHdRnjQKQEEz12EAf4OnE/YREf0z39+IxG8brHvR3HS18+1BYNsrrLUNdxDvBydiycMKTQusz1ucE0xwWK2gSnuv98ee0GAPmZO9n7GHsM38bUo0yugI1aTydDSnMiE1BATYlFQ6UShC4I8Vwr/14cCH+6W5jaqrH5h+N6VwkAT8o3iuCcy1XlJ1ulQV3jmxuUMCq5csApJwwjSn3l/oYQ5FdJIx+EAS+55tJgw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MuEiQ2he2/khl9KjB3d8Z7ABA1d6Vd6a9zGKnnkZSxs=; b=fX2FtrGdRTsvWmkj/lY+0g76fbouPtRiZHDB2DrjTPlj3pz3HVQC4OuDBNoor8rWxXX8II50zeqGoaNUL3izAkX8j+hNcbnPBBT06YpriOITGlYxncrQUhCxHYBeCn9zxgq+3hZujSjs6sY8GvZjZWhBy2ctjaj0w7NXO94g/PM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:44 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:44 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 43/96] cl8k: add main.h Date: Tue, 24 May 2022 14:34:09 +0300 Message-Id: <20220524113502.1094459-44-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b38815b4-1411-47af-ba79-08da3d79e789 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: icbzC1DDtLNYv1NJW0bgiscXtwOOUE/VPesUwPO5kvImA6pJ7F8e9S04yedlgOM7TopN958Uv4Dc8WML/h4pudnSsda87n+KYsgs0uO7OuCdhq5SFORz0KIISHN+VLFWFQKVvs43T0Jxq6DU0hjBbDC3RAfsvaW+lcE8xHkdrZZqqe62Jt3v2kTmN4qv/AzBkSKTeVYwalHIioMJSKD3quFMzXKUUhnRq7lY6cv4gNq57TqgarFqvwDflCMVK9CxhepRt4I8wyc/AecChd4SC4DCYuwAWIVHbSdMaiMVZWV7tix/zP2skbDmZCYSF2xG8CRQ4ej5kZaQm+sjowyMG1U2H48/LlOoHDfLRL1Z9paJAl1M6BkArL45FaXv4+7S+1VcLmcvLLdINbtMc+veCQG1xAyYDnnT9aIL5Ua9qjgHBfgyvzm7ZFsWjXX2qymQAKTEIjrkv596/7vTq68QtPKEGX5/fLwnslfYmzaIvdRCj5IzvxoCPCrPMgsRk8vALHH8GX56YjCzP8vXXVuqoDJu+nELiVRogY5pw0YSFIfMhDifvPOJZLqdO1Jmm1WhR/jdqBUj+X8NGGgG9Hxto0KJHh5Yo2JnMP/xELZDZmZNakqrjdk2KJuwacFy+CuELKJNTL6EdzfnhrUc+6IwoFXXFDUZbiN3NtNrRxPSehv25b8z5pvEUMsSAF4l+1BlMTbcflX29jWAQ0rMhjMTsDJ57rbyuReJ8ZpX7xxqajs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: psmvP3r4FfDKHiXNYwHo++r8H9ho4TltJ13yaH2pqgJ8NhqeN3ZkJP2Uv0KoWroONogHN6u+NPj+f1cQFsCSm0pE0uUqvEJa596+J3QGLJFXrcK6bLZOwRvQyLL/Vd2KuSRzKbfmwZ/WKeQnrzwyrO1n2uoZCs2lAvlo408+lA02qGyLK2gLXvuJawl4A3oyLEugjthJENM78ejX0+9odMgi0a19h0Vlq6uzOSVJjHki5qMUcAUwfoi8/VOagKE8OIyqcpFP7U65OK9wztG6n1NXPxMUZKyYcV7to0aB3DGcn0C3Mt6A7NbHLgUKDLNpn444K9hddhB9KBdw5ZDnM8aYeYYJ9r5g0U5sn2U19Kca3MlStE3C2IOm9LrOJEn6LrAEcMkSadU70pKv9Vm5m3PiVV8l/acSRosdkPpRPQsn5m2QcsQE5Pksgc9a47BY37h7f4kGRkOC8vACPHdUgfJ41kw7y37mIwqysKOp7yggkY0oz5QV9PqR+yyPch66cIsKc8OZXtTbGCaE0EyqcJwjraFP0GrJedjVccBV5U0RNh8TL8BZLbcg5stMb/zvhzuu14j5DOcKSsjXi0r1BJ44PUwjM6Mw7ziP2SlEz7m/6V6TIaAjL1t7HmWKEisF4GFXAEaE/9SzqwmcwCFhqoEGbZgymIVH2lcUWkEn+CFPFKHTKxOoMVdQR75+tC6ziP5frkZ6YnezxX2xd4ZeBx4d/E09c4RO3D+rZwjt/IVKlpJ9kcO1RWbFpBPXVlRoZuDCcGebUDK/lcUXjrgFg5RzDCd5q6boOJDikhsnBjto/kiG16oe9vTTLND6iSydu2YfhBAmyDBLngpWspVfK0YJSmYdEMfM8x/ohN85Zrsln/4FsxDIqPkOiS8mo9D3CvzHqT1pvjOtGUOkZRUZ0lF6fJ9zlQ5/DwUGhAoLCoynBj5npL4Abr9rtKtP0YaLjQxQbGMpM0QpLtvUHIsESolabZ38BO1xci1mHG3di0m12SOcSAKsg0eOilBAne1tH5dN0vj3UAA7eLmzBY/VKB7U4w1IVkH6NnxoW4TvAaqEozI6H9AUJ2bMS/ecRgkLgAbbkY9BBPMkv8e2vWo1HAHlcgRqsBs8ASdniqiFAU7venvS/KgMGl5hyWhLKzTRU7s3t0ELDoATe4UbxRplICjup3powLDVjx1BKVaxnMZ2TC2Cn8w2Ye/c21SiR/6Suyj2HU6vMvbXuUSCxEvG/Js0Oye2htRD4MD9PnPhRezKKBT51kdp9GVxzJhup0B+o9IgytHz7nK3J2gtWC4XvnTJOV7nM88h/CFgGLhsZxsAdcZeIvya9Ge8I/uksjEkQ1nm8jYrHkDwej97PlmjcdlIhrVcRl5/NS1TNz3M9FWspZBIccbctesR2ohukP0DHJdqoc3QSCvwT+el6+i0txfvseA17mf/fY+VActpz6s2Iz9zhrmDez15zQ+Q8BCnV0TnbG38A2IhVOcT5cg/POWdamiHtvC4Vp8sMX+acKuUmluRxT3fm1Xc0sUSziRFG+RWfSnUDO2IE02cdWBkTqAwHIUlpkWHiemPxllNWgAjX9V53zm+E4LMrjm4hHI1wDIXtzqPQzZvyM/kb2A2J99Ggdbi3264okQFnY6/J+NEm5ukdMIEfmLEpbdT4ZrWobRZuew246mrp2sC85gBl3Yqzol2Vlu9s/GG7YIw9S4Eqt/FfnlI41mnKm5eUeqfJkw7gFwbrbyld/QdC+YtA70RrIjOn8+ZOMx1rVE6ybs= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b38815b4-1411-47af-ba79-08da3d79e789 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:21.2496 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: NSrHzDeRc1Gz4AJDdU3dPkC22QzsUY4NzWuCaB4qodxsmrxVfQsS9CyOgjZDvj0alhk0YroFw4NQxldFQ0KQWg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/main.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/main.h diff --git a/drivers/net/wireless/celeno/cl8k/main.h b/drivers/net/wireless/celeno/cl8k/main.h new file mode 100644 index 000000000000..69f4ae599902 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/main.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_MAIN_H +#define CL_MAIN_H + +#include "chip.h" +#include "hw.h" + +int cl_main_init(struct cl_chip *chip, const struct cl_driver_ops *drv_ops); +void cl_main_deinit(struct cl_chip *chip); +void cl_main_reset(struct cl_chip *chip, struct cl_controller_reg *controller_reg); +int cl_main_on(struct cl_hw *cl_hw); +void cl_main_off(struct cl_hw *cl_hw); + +#endif /* CL_MAIN_H */ From patchwork Tue May 24 11:34:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575961 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 97F8DC433EF for ; Tue, 24 May 2022 11:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236891AbiEXLkK (ORCPT ); Tue, 24 May 2022 07:40:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232631AbiEXLkK (ORCPT ); Tue, 24 May 2022 07:40:10 -0400 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2086.outbound.protection.outlook.com [40.107.104.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 416CB8D687 for ; Tue, 24 May 2022 04:39:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MBASZrGq1K+ppZhgduow5hsabj7ZbwehywFrYSIt0zoj+QXRKAKNNTxTwOG+0yDtBbEaUuyRP5lIt+E4ID/+zM84DB9RP2hWVit90KXZDwbeD6LbplyCE4zFKTtQhkB5LbxbjW3s/x+6oZ8cr2ae4OpiOOtd6lVmWpVkwhIRajlo5sGoaOCEh1FuzquClZwjE6+UM909Je4zEc19JP6i522ZDBbC0TyQfHmhWkmspTIAfcuOGUUIJ0Ayghr8FwqRhH2dPODazEF0ZC3CUs4LXV8Fx3/sgoCrHwL0LLR3hnswDIrWh9tPSyS5bAVxtMyfuc9WwBjOchZuAHBQTrLexw== 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=4AiHYJ0zvtX6Pwkzdn/mSLyHwqah32921ts8a1DgqoA=; b=IT+uz84JIqdrHXepiQlcAqAgSfEWTngxixBo+4ppKzaLQCKd2tAjgTdL9WU0oxuSKVb9ia42AVJeFA5+ZWio51VNj/AMT8LBYZTj3BD30nn7i5eN8FSkG22cZGClKAEt3FaT6jUlNbo2RBGnQ+fjJH7kL0gYfXxikiZL0neHHs1OV3gB0wNY8GgxFRWBZe3S/7WSRAIyZ17xa6YNW9ZmAlwDsK3OTcw0nhbilFwZRX8NnzigXkRZFGEtPJtgE7wfS6wVmVAROUVnLXDpMkrgqaYC0GT2i0HVv3zKXTk14PRofuE6EvnnJVYpXKF/yeooboI6GqJF3tMrIg2sl+k2qg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4AiHYJ0zvtX6Pwkzdn/mSLyHwqah32921ts8a1DgqoA=; b=HNYBg21E6AElPLS5tvbXQNP+M/3VMvqc+HPmLX9n7+yQIlHzH8de2ZL+NnD1aKNyqwlbBgeQijBE156P5ZhknETBGmvkuJb7LzeQE5C1CwGgbVo9vp6EGIJ7wWMjaYmrtEzwJB38ZZLsSRCReXagWY9zA9w9IF6dDygZW/U2bPg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VI1P192MB0384.EURP192.PROD.OUTLOOK.COM (2603:10a6:803:34::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:38:45 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:44 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 44/96] cl8k: add maintenance.c Date: Tue, 24 May 2022 14:34:10 +0300 Message-Id: <20220524113502.1094459-45-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 44863fd3-71ae-48a9-9cdf-08da3d79e7f2 X-MS-TrafficTypeDiagnostic: VI1P192MB0384:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fSMRHICxRnHZjViLTa+CnGlKxFvEfrHd1tRx/EMJpLGMAd9EuxLZx+7sDem40mw8/ecS6AdlB7Yeb+3eCXVnaImFrcYwjOIpXPCYW2emeGkXwmCLv4Y3IU2ThL8H3e8ipZMC7PpTs3AwxfnvHRMzTtTE+ly43J2AbmFF5SOS3n8w3uJH2o6PpnifRzpWqZWETn7zojZofyVem1ezflvfzPjUZcuQH/1tWRP4BFjoHRcLI7mmgfGmL/nPMYBnFxUDSWDW2RVzo5AANGd6iq/mZEfjNZkCcdnoZtNj7uFlRNRTsUfDtYLwjZ8kDZn58tN215RGf8GfWahASL3Q9D6RGXQruDupiZvYylRelSN6fTDeVEHAMQGZaKbHiJZGukXSdlpngZ7wxYrCLRkqB63Dlg4TIencDhFS8uW3/aF8E9i/1GBXloh9+Jwd3h6rlsqLjqs06w0tbo6/OL89FJWOUde2lpvGTMaWlR62PazIg6NY6nqy0PKSgS5gcEU0Cog5vXa4PG2mP/bkpD2ulIRlgIKzNZzIrhJdtzvdJz7ZYmNacjE45R/dRspeN7E7DM2PP6bAG967kINnv0jATEd10OQa9f0FqJnC/H6c8SUktI//+99+5DDLjncB4g62g3pw7vTnWYHqmSLAQS2V+cUwR84woBxbqa3OFxVsbqCOAedlRpsZN+zwUqWs3iFW+YMV4Leesj4fFLxAoWS8N426l3yXAaFabCmRHwQR3a9os0U= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(346002)(39850400004)(376002)(41300700001)(36756003)(6666004)(8936002)(508600001)(186003)(83380400001)(6486002)(6506007)(38100700002)(2906002)(38350700002)(6512007)(107886003)(5660300002)(2616005)(1076003)(66946007)(4326008)(8676002)(26005)(52116002)(316002)(6916009)(9686003)(66556008)(66476007)(86362001)(54906003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: MM8CgWkOoHMzY/ei9Wtu3QOTuILaQgEJvHsy9yjNhhsHGf6hIjqJVHFUl9vi2xQYAkHrlAA+BvUD/84CkzDdU/tVWYumRn+8G8vpVhXQjN8p3NifsHBmU3xFgN3gmZIjzFkiRo2xaW3rhHhgV9B6UBeNyCt5GpdQEvqOEWxesOAQadYtXUVXpU0gZRNOmkBeV8Dr8ys3Z4Shouxew9vIeuHdbZa79mgq/To6ycRVriuY2V07X6CVP3SzlrBY6fTYbvfTQUMDe6qncekev4s6KDagNcG+NF2S+NTiUUOejkQcdSAst33r/O3BlidSYWE83XkjzxjFAA81EesrS2DTb8SeFL51IvIJ1K4E3btmTa3q7zkEwVsA3cyVc1fZop4cCq3NAcjrsnhQIyJnMLPHANa6RebKDy6ckWGHHTSAYkg0MGh3fkRC7tLcYviJ3Bksj6PO7n2CgAt6WH0DT7AWYD5IzvGcZm+m484Zp2qqSDirRs+MYxsVymoC1pF/yXJIDpGLZhXRZWbbkesx3USrwrCV6xJe1tFErlbvGhE/VTet5DY7AkacPtdLvSkSqttc9mI00G7GCw8Lp7icv3cmRQ4xThPReNZgjZYzsyP+ZB7B5rgzxKMooUyGFwsstaEfY3FF0fLAL50FCfS1wGr/muJoeLejjs2KIfdYIm9wAYxUE/TFFhRwrEy4fQMCNwbrYbXso/rHTswkXZ2skPbRHyk6hyb3cFMdRazmhL9+eELscsggA6KDT2yGAhQrlepen512Zk50Lx1Aao2nPQzYUYGGc5spuOenQwh9zbX5MJk1g3Wczqo+ez7tX9EFvODKtVhhGAhf+yT1asX+hNsWXJVdlXD4/WCRRNtxI+O04Vl78oEPFO5B2mUVYn6HsOrlW6yaYno+c2C1/w6cuYfaG2YaCSi8K6JgGTAut1XjuKxDAmBgcKyCy857xjJNE4l9SgC2ZORLOLwQ4Qx8wI4dP1fWPulh07W9dQfGjFhepHoLEjSSbV7jIxjWqJZ1d40ZfgCotHQjQ8q1P+T2IsWmtGHOLbIW9aSGmY9lnLdMQOBe78Jp3LtukPveIbwRtfsEeY0uhaohj7HSYKwB6xc5ek/UU1KADW27sjv2ffrBM2P6qeJUD/8v07NSmEVnWBKxyuEN6uIR0plqplptgEb9tZ8AXwycyQXqMy9yCmOTjfNZOKmLTtCVPJCUBIsECopz7wOwncN/QlbLgPxjJelJOe/lge5VMIEJAFK6Ty/fA5MAPbnYWSXfiz4og/IQfYoQGdsxS75dIBtbncESDe1XJEl+3/TGA86SmjSsDKPR9TWj2Aw/xWjtAlN1kImaNZXGGRxWqJSsIly/ZFbmzho3o/gvUdDLwChPpjfVuGb6c/BZJ5fKOQaXJDykRHewJiMrcDwutXcbqO3jMsjTumrYKPhb3YTiY3E1APEexiTfJMTviZ1x9JPZTpLFyys4Vl9UIWiYeq8C2V/TOoIT8774em5bZdpx7WQ52OoZHFC6pNpsR/5l9+NzeVI5DAbTc6o8doGEd/d9D9cJLkCHKr+zwFa7NG5XVv7/x2p62LzMsBuL3L3FzQHO2Bg34nJa8OQCl35CzAhCwFYoVMQ5hcGdy63250XLsVrDIz58VJQS62c2RqeGFu6NZRhkV7UTR8wbwZql1spPJLLBoSOALAm6cw/IKl0gqChvnxlb0lifeO/e3Iy5RYhlOUKBgX55h073fW3vFrGVKrACrhglfPGq5HShzQqoC1weKegq7gEGQpA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 44863fd3-71ae-48a9-9cdf-08da3d79e7f2 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:21.9526 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: gP26ajJORhCfhK3jDZazC5bG9J/1hfBgU5wlRS7xSVP0Q9vANVI7CvkOdss5N0NmeT5lAUMw3d75s8H66z3UOQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P192MB0384 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/maintenance.c | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/maintenance.c diff --git a/drivers/net/wireless/celeno/cl8k/maintenance.c b/drivers/net/wireless/celeno/cl8k/maintenance.c new file mode 100644 index 000000000000..3230757edacc --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/maintenance.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "maintenance.h" +#include "traffic.h" +#include "vns.h" +#include "reg/reg_access.h" +#include "sounding.h" +#include "sta.h" +#include "motion_sense.h" +#include "radio.h" + +static void cl_maintenance_callback_slow(struct timer_list *t) +{ + struct cl_hw *cl_hw = from_timer(cl_hw, t, maintenance_slow_timer); + + cl_cca_maintenance(cl_hw); + cl_noise_maintenance(cl_hw); + + if (cl_hw_is_prod_or_listener(cl_hw)) + goto reschedule_timer; + + cl_vns_maintenance(cl_hw); + + if (cl_hw->conf->ci_traffic_mon_en) + cl_sta_loop(cl_hw, cl_traffic_mon_sta_maintenance); + + if (cl_sta_num(cl_hw) == 0) + goto reschedule_timer; + + cl_motion_sense_maintenance(cl_hw); + cl_sounding_maintenance(cl_hw); + +reschedule_timer: + mod_timer(&cl_hw->maintenance_slow_timer, + jiffies + msecs_to_jiffies(CL_MAINTENANCE_PERIOD_SLOW_MS)); +} + +static void cl_maintenance_callback_fast(struct timer_list *t) +{ + struct cl_hw *cl_hw = from_timer(cl_hw, t, maintenance_fast_timer); + + if (cl_sta_num(cl_hw) == 0) + goto reschedule_timer; + + cl_traffic_maintenance(cl_hw); + +reschedule_timer: + mod_timer(&cl_hw->maintenance_fast_timer, + jiffies + msecs_to_jiffies(CL_MAINTENANCE_PERIOD_FAST_MS)); +} + +void cl_maintenance_init(struct cl_hw *cl_hw) +{ + timer_setup(&cl_hw->maintenance_slow_timer, cl_maintenance_callback_slow, 0); + timer_setup(&cl_hw->maintenance_fast_timer, cl_maintenance_callback_fast, 0); + + cl_maintenance_start(cl_hw); +} + +void cl_maintenance_close(struct cl_hw *cl_hw) +{ + del_timer_sync(&cl_hw->maintenance_slow_timer); + del_timer_sync(&cl_hw->maintenance_fast_timer); +} + +void cl_maintenance_stop(struct cl_hw *cl_hw) +{ + del_timer(&cl_hw->maintenance_slow_timer); + del_timer(&cl_hw->maintenance_fast_timer); +} + +void cl_maintenance_start(struct cl_hw *cl_hw) +{ + mod_timer(&cl_hw->maintenance_slow_timer, + jiffies + msecs_to_jiffies(CL_MAINTENANCE_PERIOD_SLOW_MS)); + + if (!cl_hw_is_prod_or_listener(cl_hw)) + mod_timer(&cl_hw->maintenance_fast_timer, + jiffies + msecs_to_jiffies(CL_MAINTENANCE_PERIOD_FAST_MS)); +} From patchwork Tue May 24 11:34:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575975 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 D0641C433EF for ; Tue, 24 May 2022 11:39:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236826AbiEXLjH (ORCPT ); Tue, 24 May 2022 07:39:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41404 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236835AbiEXLjG (ORCPT ); Tue, 24 May 2022 07:39:06 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50045.outbound.protection.outlook.com [40.107.5.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74A9241316 for ; Tue, 24 May 2022 04:38:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Yx7rtHvw5u8hyWQvQ5SGDv5ye/BW3Ol8SE1KnsTOhgtc5fEAYMe0IrGO6SOzks2gyq1FuV8Hkh1Hg3tHmwMujCNKrtJtRHfpbkW05+BI/CTwNBhaN/pr0jUcyBn3x/UVNvnYGtLfhS9O4rK5qAn/sttHcSmIv0wZDDG9DZ/fpYRt0Uz4/7ig7uXZ8+9233U5Y730mhYbyX3dR+0WM53VFU84XDKCITYo8DdvT3qRoCR6C77aR4U9CqnTIazgE8ZladGeWb0hh/Fg8nQVLIeaUGXBqitg8b3QeqPw9Vw0iMm84Lu+ieDzqEmohtGKRDjZUxqcD6SUfvs4aucEi82klg== 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=LcuVxWpRuXCPem6tX4JQD9O4XBSTxEsEXwKxJMuu2TA=; b=fWjP/RFGlh8Jrcskn3VbvS3Ck8ixEJ9BVV9K5HjQ/o1ceYe5cV4PRKwG7iYEJVga+h/akZASsUfMx/fXXhKv93PuTKbGwtZt3FUKTX8jdm/uaj9MNfMXH1ZivMKKunxe2Rp8/WP4be/rjSzSbHoLDYs+8whUX63DS0B07jTOn7+hfoveJaSPkySuXQjOsTHx7q4Tv/MRjYA2R8y3ajeFqtcdjVWdQn1eO0V7QTmSuINRaVyDnrWjVSrunFsI+LTsgcyjTWtc1vdGASdo+BZk9xcxDWcO167gCFalZbRxvC+KlrN+Wg/0hjDIF1T3JuaqRrxDB+gfLyU+pI83tc5Ksg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LcuVxWpRuXCPem6tX4JQD9O4XBSTxEsEXwKxJMuu2TA=; b=0kNvuujvhmdJorNcH4FuTYByprM09z3sJAG9UIbEoYG657UnojcY3muhd8CsJ5dQAxhAScgMYjqu94Ci1haOAPh3KJSlA/e82RdhUrzqCHpafYK8xT5vS7XD/xupKmRnyJpjUlwd5Bqu6ez/56IUI7agtcT7At17Jgftt97AZCM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:45 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:45 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 45/96] cl8k: add maintenance.h Date: Tue, 24 May 2022 14:34:11 +0300 Message-Id: <20220524113502.1094459-46-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d3a1b938-733b-497c-476d-08da3d79e860 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: W4aBZcKpw5tvMVT5Qc5UMkra7htnSVguOlgZ5A2PHKUd0L2+4EH6g8NH6iTRAiVnlqUA3IwvAibQAoDtQo+gvZwfYsDVCZU3Pvz+i9fOZVru8J5ZYPDn5gDrJNgtLkayxrg9lwEZuBVLtiI90WCePke0WxI0Ztx/lUBUzyn9Piq2Ym17Q1W8tJheo8+0Ss8pWQwPRsEYLLxVt4YWE34PF7jp+IkB4TVBsM9ng/kZMLlUUEJ6O53XseRMcVArfSBXWL0xGdfJTYX8JYP0nm2MoApq/D4AHDbL8EtLLHiY8rhzz8/xmx7nj9NoL9Q+LRBQUjbQhWqblUPdlbc5zD21MVUenvL1D+zLttHBDRPlCJSdu32kdxsm+yHnodDRT6AR3uxTykxRPhlIr3uzo9nOU6vapVhqHjUwD1D9IoUS98A8P5uNEp9occULmENlfTDKKySJzxGi+Ao0o8W3UptJMmHhO7EjOBhPd3sPqXHJCCAwOINe8jQO0JvO8hmTNTuNMoW7IFfaSpUbKOqKxghQrtNpZ0G61WfKFHtBMwkptCadFAJ6C041vquPVSponASTmaj3j7emIwLm6Btc0BLwzmlCIKxN6t4uVrVPD+RAT24mahThnqvOwt1ICxHfTsyE+76t4AJ+38Ljgs63O/+AdPPNys1cVfk5jIL3drCO2mng8glIkGm77pMK6CXesSxzwxq6/85MeD2YC/UdKqaZIXgY9BsoFf8jWfFCJDD1FXE= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: JiWf7+ExVPJrXeYrDnUNT6c4xOld8H74u+H2aIGIu1RYzRVy07yjXD866HdwWWHW5a1Cug7/SvfIL2JTntrbyJKe69CZkCZk4wUIHqvjLJZAIE+0qgvJNBmhvfCYIHFpxlCWL0cGFMJxPYPZe5SSAhjO0Aomcv7y4ItyvPjD+ETucUUw0QWH6idys2Ke6ePlIRc6OjKqMcmOKjCbXM1+BNV9AmQw8u33JJL3JwCAtvIOfDN4HgUOgmHv+wEm8OkR89ksrqFDpuqzlBK9CLVrjzvJoyO7ikPbuAXkByO/XAufUCa8e6TOkkD5ZuGxvab0lA4Vfxs+0YXIwUCeo3W1f5+2WAEf5G8IqjYs5lv0kBPd8LEK7qjiLzTEVxc2E2f6Z/CICNl0Czfal63n7d1RG8fdI2wxbhB63uqaixzOio0TZoP8NgAbLO4i8ENhiK7ymWERc266YMSSee8hQM1MOxl+gpxDyMUb6i6vB99TKjmhl7Bq9g0u4Hd8mZ+gaymWxsnODRBnjQt/XkWGhVeHizAz5ghMGUux0vC2Cxh51zEbuH6YlF4GmBcSzPuGL+8OuTirb91sH9IBEMfoBC9qlW6ZvugeE9Acvf1nslMubIGWGUT6A0yIfJT5DCIfLUs6c0eEPGB2VYQSFYFRrL0WmDmmyxYIJuVzX7gg6opGGSOXMIslYOMGYb6Y0UaXxp7/MZP12KNEa0zsXrzXe+npR/25xxN5yNORcq6RZXH74BFaUlVAFqxPcDKMHkv5U/P0Rbmueah6QviyN0VwgxdWZNNYBS99oeW1pYOm8lgYbWe4bsdvHVmW0jqb6xCiKHkGp1YYRIPveRENaB82prAbve6P7osD6lmys/UrDB4/QWkoMS3MimyLdi/1EQ0hjEDGlqBRaYpi5gk3ehvKQp1R1PDwwVURUrxh6PXu0jBAWN3ftXa+xHfjk8g1BMnXvxW3k7orSJJ7y8T9TnrBlocibNmeeYtAuvIGxbIe5YPV3QtnQXm8nJEF3mIilGYwB2DOVQlCau5n3s2VCoVtYAmgNBVkxImFBCZlCQnu3SB+6//uXotkr/75ZqDhzzfQIXdzLH7bBCmtrFRZcNxVqjdUuwx67e0Sjqk4TISkl1Vbe/RUbpkNmZbwhINccgod2tEYLTp/zqOhSZ+FbySdyHjPaVy3boUdKyhL2KSWFQzlfP1rxKip5p/NkUnjjxd/jMYbUFXASvsQB+Q6rlrz/b27u348FwyfDFJhbX3VmmSMBfWsBPzxcWC5yhyL4p8oh07H253cf7vI1YyGs5+8Zo0mTnaqJ6WisMIqX45yWeXfW84S/6EXssywBY3EX9Tg4z7W2mmi0EtXXQ5+KHYu7EKGr6EWFd7NO2ojCEIj9WFRazVfTmkr4/Rse8CG6pkbHfDx9I/J2jdkWf3fKAeNJXin76zFKxa6NkV6DYdHVvnLZT1ZlyiAPiOijpzzi8eSZ1N2f/46DP9ECvqkHWNWTjEPmk9msZZWRUl9srNEpszDsFtv3YVI8YR9nrIyis1GBn0O/W9UlbyQ9cqy8jqNaT4fmy7i46ere6ogUAkJ8SGmybuISuLTYO6D3OZQtXwA8QqZvfYargo/iuDA5Ay1+rozqozE75imWg4AM05bcCcoiHfHNJ0eQ26kGPzRGY4yhvbu6n+LFLwljyuulFDFHk51isCJMYVsHVaKjzt/No5SczHPbN5+2BvFT8+GwjmNvTKKxoyu7wRmEIsAVKYHZtuvMuGfmaMPMmgG6YPizxTLPvo= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d3a1b938-733b-497c-476d-08da3d79e860 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:22.6868 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: q+gcFr2f9ckt4zsWN/GIxpSB9zukMiZomrxF7aBgizS3oUnE4d12Iik16z0KglKETkipY/Bx4jGAvA4lXUN4hQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/maintenance.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/maintenance.h diff --git a/drivers/net/wireless/celeno/cl8k/maintenance.h b/drivers/net/wireless/celeno/cl8k/maintenance.h new file mode 100644 index 000000000000..c9d1526a47a0 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/maintenance.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_MAINTENANCE_H +#define CL_MAINTENANCE_H + +#include "hw.h" + +#define CL_MAINTENANCE_PERIOD_SLOW_MS 1000 +#define CL_MAINTENANCE_PERIOD_FAST_MS 100 + +void cl_maintenance_init(struct cl_hw *cl_hw); +void cl_maintenance_close(struct cl_hw *cl_hw); +void cl_maintenance_stop(struct cl_hw *cl_hw); +void cl_maintenance_start(struct cl_hw *cl_hw); + +#endif /* CL_MAINTENANCE_H */ From patchwork Tue May 24 11:34:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576853 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 BE308C433FE for ; Tue, 24 May 2022 11:39:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236841AbiEXLjT (ORCPT ); Tue, 24 May 2022 07:39:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236843AbiEXLjR (ORCPT ); Tue, 24 May 2022 07:39:17 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50088.outbound.protection.outlook.com [40.107.5.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E3B58D680 for ; Tue, 24 May 2022 04:39:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ikFNIDc7AG6/kDiN3FSu3RQYUl2AWWIAZTTvIZ49Bc57+9SXNLusCVcB5ivMjtmvsb0sfuIZk52WCPyn2JXvexCBgCPYFSjoF358MuhvJbHzdLwf/oppLFbDj2zl+gTZtd71jfbr7DKQa41DgNWNdFOl1C0OXGinCd5g76czj4T5nJhrg/7dt6xFw9v4MCob7uAntkCSHEsqdWSkB5I3rQYem+iGsPVi21DXighrHFMWLyQtyV6x6jdKVsln3WI9yEox3cwOFD8yL+4amNzDbPuK1zCj1H+Gd/cNr0Z9b9e+E6CstqqIg6VE9WThSt1hAr9uGHM3BnG3KfvPQHNuGg== 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=VgfD6rYdhGban4wtkPkLuL+pvxsH4gSyKEI47Rt1HZc=; b=nrJkqRi19knXgmGOh1dRmxerF6PMpKlI4iJPGUef1ck2zZ3P5XvPNWwuPtY7F5MxBOAsQhsH5N29ALqvU0U57NR5lRn9DAVM/afI5RgO5DrcThA+MG0XixdXJF6mm4B8YNjAPGC8QVqgwgNAUR36vdYAt0VTB32z+NsL7dxOQoTMh3UCO5x76JR0h4pRfVWzRLkhi1MmC5OTzaHvZHOEopu1P4OTZiTLb54J1UK60JRbgPLs+q/Dpx5XOmY+MjkpKAv6Ucm6ETgkgYiWJEVdYdOGmo4KGh+PeZeDyMPLJiTmjSFfsSvjDmY7T+LeuJbCinUmfs/9OeflwPNqv+pwAg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VgfD6rYdhGban4wtkPkLuL+pvxsH4gSyKEI47Rt1HZc=; b=lz1p7GbHpCuctGjdJ9pfFd4CEv9KrUjWfVGgg/0OF64eweg+e+Sleo2WUAH2MNroeAvMWPvtQuvq3yjAnd5yIyXjvyTjeHAmSNkGWz55UT4ODfmKXESqPUElrBMI5v4GvuYgLj8DXVz3exZMUM1I1OJ+MzDwH33HvmfdC1tqP2I= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:45 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:45 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 46/96] cl8k: add motion_sense.c Date: Tue, 24 May 2022 14:34:12 +0300 Message-Id: <20220524113502.1094459-47-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 25a5d643-7ead-49b4-ede8-08da3d79e9a1 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: sNoxbOm0gAJ8DG3aGeix3675Q4YJ4Vhp87zUsvPq/D0+HtWbne06kwwkBClDo3visSESoeuzb3gQ/NMZMMW4Bk+7oQqQ/oH8fD+XJ7M00qCLJnVF+oYhwI8bNsrOmmBmaDHsMRt5X5RzCoF8nNT/uONMgQZYucdaNISww64xNS0SMKCxZVXfhrHYjjJgX/PWGa5ZXyMAQVaLCQw639pzUDy03gAHqkL2sufoBrfJzpAFZl88OU/98bPRxmJRYJQD6sSwxPaEmyuYicdYYjGO9TivC/TdOubAbU+Qpv/5szetl7yNah4DBji9CQvAnxGH7rLKkEdWe2S4sanJxCujifRdxAXZRWfxqKnpe6Ffu3QDpCGMeBfQ+L5Na4qdd4iF1JTQf2jy+3f6nN8dSoEcBOLKPFwYLJ3gV493Br/CWpDeIKs+gazLYdaG6HfA23yGfFQ8dGc1qPx0957CJolJw6vqN4xjw8VDyoXISuye3Q+prnSHes7G7MQx0IXTs+dwIv1ACAxmTBLRpP9U7SnCu4MbXLkkorRIU3BeZXfXVDFLENmRa43AZPFfzBVDdtwpzozbvGPcUfQuYvMaVlZ7AawyvxgiYyxk6b1Fa/C6ybCjuuAElcRXNw1EgEmgZXj4Bb1U4TnhFxr/Cx+X8C0VLrsv9i3DHgtBayPqXOOgwERQdA1m8IMg+tK1ddHsWMwt90irMlKrvBtnBmb/GCvXyFlZmI+Y/veKg3TQtGPTd/Y= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: MjJCMR+hRsUjVAb6p2IINNJ5lRKBqNTjX96o6ZvrwWMtr8O5kxDAaAWzxC7Bcgj0S/SuWcfG6ZasKfbFuYRdLM8Vat8Ru0vsL7tsZb7bUkS+rHO8FnIeGPa39cOhTc3qM/S+SmyKCk7qM46tCrguDLGofzQnFu73axpjhH7k/nKZKZF2uh1MO9yxeDXlqtncFixt/Q1jLW+3IsJjDxiLXRJfc05nk4twSDbbSgZsvgviwEykARwuNJYCZNVHEeAL7utPo0z5l9FZ0syTeAnZOGXZznqdFR0vYBY+f1X3XFKl0tUmhf/FZCLVe3Gf9gCPTTuWM3e2LgUHaDAeDHUb+IlVSK9xZX1h9qk8akmrHTjoU5gj3h+ww0Dw6FwfHHcNhH2TuyQvRJfqexA3+zw60C34xSfvlDiwEwG6YLVXoFfYLQzhxAgzezaKE0UeSoITR4+VBgwNsVxyEcRbDW52WavJ7gAYHWaRWZBvpS7NFCtA7pwqiFvzPiUBaqHOmVV976UV5wVDj3uNC+oJUgyp7G8Z40Dl/C+DCuwXuZSaieKR032NHWkeyTqEGkTPzRlqb97iRrkBeBnH4Fih3fYCYpAbN43DwnVsjuUCUsfjXASOOGeF+H5Kn5+KTTtaDZlRzg8va+BTSJlKD/7GU3O/nxlWSCUZChbXM8YpfxXVaSWiYMmiZ9rNEOqq8cEg7seJkiRfG0zomaeUSbm5XtbdlBMZVYQaKFMkjTNve4BDRgjOs7tnzzTrIxq2VF5EGTqu7LBth5P5SwEtglYqq2g+LLiLUSooHWCxi/GBwR5WxiHDvKXnKpEU29Wg+qmIU1trDiH/7jQBuOGQ8ktD/3AC2aXDmOPFwiAdfmKiobR74H4Wxis4kpq4Lx/wp7kM+Zs2yaLdaOze5FsfZDxjSwG5p+pesy/+tEifeloFyE1cYlWECOOwe1tR0JOL4NcCnh3RAorqPBO9cMxOdFlXWc2h7FDkCFK9AVWWe+/p6nicUhci0I0LlEHqLV17lv/bXU5+SZGG+taFDUBB+fhj/58AOgHEGvuDZ2igVlLPyFh/fuT0jW2xXPBlMWJy4mHdKgGX83ET2B2ARISxa8WBaFK0u3AJ60IhJhyPLzLlBZevJ3NtJvyOT+4l8ThEKDeGPysJPL4m7LTNcKpL1Vm2ShdpUJD6yrX+bL37L0gpWVOGzSSKY7FaeyU8JoINZUsu61IUB9FSJigQazxFITEQMaiHFX2Sn73+Iq4yqjAxpLL+kzP+j5YcoUTIwrevkzdWsGP+wbg0/Z1eyPUsqSCgzd+v8+rKgtLxVi/gmhRDQR1cfKZLdo1EzL0FDW0635veWK4rFs2NtAsln8qvFYM6fV3J1JVYJWhO2BiY4JsKbZriPlU5X3OG70OOW1i5BIKZPf9tZ/bhKlmz4eB9KB89+T5Q71ea8Q2a6TzI+NwEVdPQRJ+t9Gkx0Zw5phSd/lZYh9mpHBl5yMOBsjEuJI1JCGMGK5ZaMHOnkPsGD4Sr4MvWidSYyfquUtYORh+XUjrhVMM17NedX9yF5eqGhUWbz4y4jODDuTQukHLTs45pQ5V50iAc4fT5opU3HjizGUv1XM/ObBtkuNJ0KVUM72QpGQWjqAcWDTFS0muxjsuBrgbTpgxNPrg8oi+ulRn9xw64rY67fVHtdlUgIeYY7IVSCKvxTa2jhEgtv3NvqeiBn8ydYKp/AluNJl/B+q1ccN+YWliI/TO34Uxr5A/z5xLh5eHGEZdmZkP0pG4Bxb2Q5LwRNYU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 25a5d643-7ead-49b4-ede8-08da3d79e9a1 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:24.8730 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2419UE0Go/DQ9aCicU3yZKQtB14/cCxceabYXMiP2IKGJyCVUtSnXGaxMgcHwb12twPu7ACNAo3Ozzlql5baKA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/motion_sense.c | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/motion_sense.c diff --git a/drivers/net/wireless/celeno/cl8k/motion_sense.c b/drivers/net/wireless/celeno/cl8k/motion_sense.c new file mode 100644 index 000000000000..2e4c05564900 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/motion_sense.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "hw.h" +#include "debug.h" +#include "motion_sense.h" + +#define motion_pr(...) \ + do { \ + if (cl_hw->motion_sense_dbg) \ + pr_debug("[MOTION SENSE]" __VA_ARGS__); \ + } while (0) + +/* Minimum time (+1) for taking a decison */ +#define MOTION_SENSE_MIN_DECISION_MGMT_CTL 4 +#define MOTION_SENSE_MIN_DECISION_DATA 9 +#define MOTION_SENSE_MIN_DECISION_BA 9 + +static void _cl_motion_sense_sta_add(struct cl_motion_rssi *motion_rssi) +{ + motion_rssi->max = S8_MIN; + motion_rssi->min = S8_MAX; +} + +void cl_motion_sense_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + _cl_motion_sense_sta_add(&cl_sta->motion_sense.rssi_mgmt_ctl); + _cl_motion_sense_sta_add(&cl_sta->motion_sense.rssi_data); + _cl_motion_sense_sta_add(&cl_sta->motion_sense.rssi_ba); +} + +static void cl_motion_sense_rssi_handler(struct cl_hw *cl_hw, + struct cl_motion_rssi *motion_rssi, + s8 rssi[MAX_ANTENNAS]) +{ + u8 i; + + motion_rssi->cnt++; + + for (i = 0; i < cl_hw->num_antennas; i++) + motion_rssi->sum[i] += rssi[i]; +} + +void cl_motion_sense_rssi_mgmt_ctl(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr) +{ + /* RSSI of mgmt and ctl packets */ + if (cl_hw->conf->ci_motion_sense_en) { + s8 rssi[MAX_ANTENNAS] = RX_HDR_RSSI(rxhdr); + u8 i; + + if (!IS_REAL_PHY(cl_hw->chip)) + for (i = 0; i < cl_hw->num_antennas; i++) + if (rssi[i] == 0) + return; + + cl_motion_sense_rssi_handler(cl_hw, &cl_sta->motion_sense.rssi_mgmt_ctl, rssi); + } +} + +void cl_motion_sense_rssi_data(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr) +{ + /* RSSI of data packets */ + s8 rssi[MAX_ANTENNAS] = RX_HDR_RSSI(rxhdr); + + if (!cl_hw->conf->ci_motion_sense_en) + return; + + if (!IS_REAL_PHY(cl_hw->chip) && rssi[0] == 0) + return; + + cl_motion_sense_rssi_handler(cl_hw, &cl_sta->motion_sense.rssi_data, rssi); +} + +void cl_motion_sense_rssi_ba(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]) +{ + /* RSSI of block-acks */ + if (cl_hw->conf->ci_motion_sense_en) + cl_motion_sense_rssi_handler(cl_hw, &cl_sta->motion_sense.rssi_ba, rssi); +} + +static s8 cl_motion_sense_calc_new_rssi(struct cl_hw *cl_hw, struct cl_motion_rssi *motion_rssi) +{ + u8 i = 0; + s8 rssi_avg[MAX_ANTENNAS] = {0}; + + /* Calculate average rssi */ + for (i = 0; i < cl_hw->num_antennas; i++) + rssi_avg[i] = (s8)(motion_rssi->sum[i] / motion_rssi->cnt); + + /* Reset rssi sum for next maintenance cycle */ + memset(motion_rssi->sum, 0, sizeof(motion_rssi->sum)); + motion_rssi->cnt = 0; + + return cl_rssi_calc_equivalent(cl_hw, rssi_avg); +} + +static void cl_motion_sense_state(struct cl_hw *cl_hw, struct cl_motion_rssi *motion_rssi, + u8 sta_idx, u8 min_history, const s8 *type) +{ + u8 i = 0; + s8 rssi_new = 0, rssi_old = 0; + + if (motion_rssi->cnt == 0) + return; + + /* Get new and old rssi */ + rssi_new = cl_motion_sense_calc_new_rssi(cl_hw, motion_rssi); + rssi_old = motion_rssi->history[motion_rssi->idx]; + + /* Add new rssi to history and increase history index */ + motion_rssi->history[motion_rssi->idx] = rssi_new; + + motion_rssi->idx++; + if (motion_rssi->idx == MOTION_SENSE_SIZE) + motion_rssi->idx = 0; + + /* Check if new rssi is max or min */ + if (rssi_new > motion_rssi->max) { + motion_rssi->max = rssi_new; + goto out; + } else if (rssi_new < motion_rssi->min) { + motion_rssi->min = rssi_new; + goto out; + } + + /* + * Check if old rssi was max or min. + * If so, go over history and find new max/min + */ + if (rssi_old == motion_rssi->max) { + motion_rssi->max = S8_MIN; + + for (i = 0; i < MOTION_SENSE_SIZE; i++) { + if (motion_rssi->history[i] == 0) + break; + + if (motion_rssi->history[i] > motion_rssi->max) + motion_rssi->max = motion_rssi->history[i]; + } + } else if (rssi_old == motion_rssi->min) { + motion_rssi->min = S8_MAX; + + for (i = 0; i < MOTION_SENSE_SIZE; i++) { + if (motion_rssi->history[i] == 0) + break; + + if (motion_rssi->history[i] < motion_rssi->min) + motion_rssi->min = motion_rssi->history[i]; + } + } + +out: + /* Wait X second after connection, before making first decision */ + if (motion_rssi->history[min_history] == 0) + return; + + /* According to delta decide if station is STATIC or in MOTION */ + if ((motion_rssi->max - motion_rssi->min) < cl_hw->conf->ci_motion_sense_rssi_thr) { + if (motion_rssi->state == STATE_STATIC) + return; + + motion_rssi->state = STATE_STATIC; + + motion_pr("%s - sta_idx=%u, min=%d, max=%d, state=STATIC\n", + type, sta_idx, motion_rssi->min, motion_rssi->max); + } else { + if (motion_rssi->state == STATE_MOVING) + return; + + motion_rssi->state = STATE_MOVING; + + motion_pr("%s - sta_idx=%u, min=%d, max=%d, state=MOVING\n", + type, sta_idx, motion_rssi->min, motion_rssi->max); + } +} + +static void cl_motion_sense_moving(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_motion_sense *motion_sense) +{ + if (motion_sense->combined_state != STATE_MOVING) { + motion_sense->combined_state = STATE_MOVING; + motion_pr("sta_idx = %u, combined_state = MOVING\n", + cl_sta->sta_idx); + } +} + +static void cl_motion_sense_static(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_motion_sense *motion_sense) +{ + if (motion_sense->combined_state != STATE_STATIC) { + motion_sense->combined_state = STATE_STATIC; + motion_pr("sta_idx = %u, combined_state = STATIC\n", + cl_sta->sta_idx); + } +} + +static void cl_motion_sense_combined_state(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_motion_sense *motion_sense = &cl_sta->motion_sense; + + if (motion_sense->rssi_mgmt_ctl.history[MOTION_SENSE_MIN_DECISION_MGMT_CTL] == 0 && + motion_sense->rssi_data.history[MOTION_SENSE_MIN_DECISION_DATA] == 0 && + motion_sense->rssi_ba.history[MOTION_SENSE_MIN_DECISION_BA] == 0) + return; + + if (motion_sense->rssi_mgmt_ctl.state == STATE_MOVING || + motion_sense->rssi_data.state == STATE_MOVING || + motion_sense->rssi_ba.state == STATE_MOVING) + cl_motion_sense_moving(cl_hw, cl_sta, motion_sense); + else + cl_motion_sense_static(cl_hw, cl_sta, motion_sense); +} + +static void cl_motion_sense_maintenance_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + u8 sta_idx = cl_sta->sta_idx; + struct cl_motion_sense *motion_sense = &cl_sta->motion_sense; + + cl_motion_sense_state(cl_hw, &motion_sense->rssi_mgmt_ctl, sta_idx, + MOTION_SENSE_MIN_DECISION_MGMT_CTL, "mgmt/ctl"); + cl_motion_sense_state(cl_hw, &motion_sense->rssi_data, sta_idx, + MOTION_SENSE_MIN_DECISION_DATA, "data"); + cl_motion_sense_state(cl_hw, &motion_sense->rssi_ba, sta_idx, + MOTION_SENSE_MIN_DECISION_BA, "ba"); + + if (motion_sense->forced_state != STATE_NULL) + return; + + cl_motion_sense_combined_state(cl_hw, cl_sta); +} + +void cl_motion_sense_maintenance(struct cl_hw *cl_hw) +{ + cl_sta_loop(cl_hw, cl_motion_sense_maintenance_sta); +} + +bool cl_motion_sense_is_static(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + return (cl_sta->motion_sense.combined_state == STATE_STATIC); +} + From patchwork Tue May 24 11:34:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576855 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 55490C433F5 for ; Tue, 24 May 2022 11:39:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234374AbiEXLjL (ORCPT ); Tue, 24 May 2022 07:39:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236831AbiEXLjJ (ORCPT ); Tue, 24 May 2022 07:39:09 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EEC084C798 for ; Tue, 24 May 2022 04:38:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=P2AV93BXhaOcjxhghbc1YFiVqj6LZih9teOdGGeZG9IPz7BrF0GjCPK8esax1TzEkcvkGkKXklBN1j4uPtWrTPXmQRkS0oFpg4VFYke/Spp771UsyuYW5rOvYSv+uAu3dc0TLxkdGrORhMsM0zizf/iMdLfkRnd+b+2JTJHa8EQXOpgbAjU/SIouRbaC081QT4TR6CASUJvH2N6xFbPGV7Xbm13tgjM8ksboYtGjqgVJQNtM3PlpX8zcuQ/P0gIhx8+voe3OEWp4B0l5OG/VEVh515M72oEDXAaJ/ruA2UYce3z6XWLJVlkRieYBjDZ0+zfSkStQJwcM/PIAAMsgwg== 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=ANHk5HwYOQqmnM3pCOWHh74wQPfY+TLoRLdTniWTask=; b=hGpBBdOq7uh1zQmqp5SNzpvNQ95O52F7TaqkWwUg9aQZwiM7UT1N8uwJHTxmWTUMEemKGYEqZGlCx4zlnjmnt56EUYK3/jWurOjIifEM8pqTkqXN8j6N8LTsOQcip3Udp6jw4B5o9W11jJ1eFbiF08AsQU+4zvEdEAR0/JG3G85hiLuKdbBQn0XWb3EK35CjC6QRglVltgqAJxS+zAa5wfEN6NEpokyRfF9N7mllHwPlQtYUYf8GElDyVIJ4ijKXO4N/ujQlbgxTHDFw4R3VUTE60YRcPhbzBeRA6SPv2yMKQgRaJZ+4I32T4fPLoeimc9Muyp1vqe+iG7m/ASgk+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ANHk5HwYOQqmnM3pCOWHh74wQPfY+TLoRLdTniWTask=; b=s5PLvf/k0nJswuArXQbuuhpCGVFbzAiMpqLO+9jk7MHfqsruhy35ZH6AzULCQw5vTt0UmQABylsxOAauspwvT8YC/6pbnGOEbOK45ky9GWo8x2CbBIg+F2mP8hBthPBPdjNsp8yhN9XKPTBBKN7VquHzcyqAn9FhxJAi3mRxbeg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:46 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:46 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 47/96] cl8k: add motion_sense.h Date: Tue, 24 May 2022 14:34:13 +0300 Message-Id: <20220524113502.1094459-48-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8152312f-340d-48f3-3594-08da3d79ea25 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wzh7l82O5QR+TBKka9ZGiSkWCnFXINeYTdOugOcTfevHjsa1c9dMloj++lrim0Pqlg30wZVBR0vbC1/CGmT7T4dhT76h05unaF96mwJDDJvzLNp1869SswXFfyZCHH7a0zRTGlU7IR1x0mVyCjQwrKmDGAjPvCWENHw2BVNVnmr81QLUQNyQ/em/xMo2gHUMAvCJzcOirpFzhPWH3WeQgy2tM8eM7tvSXr/XyGHpX84czo9jm+UMusquWstbsIwHs8fV5c4FRHcn2YgEkYkp1Cgyo9TgS5ohqowheuNdQRFXXuuUunktEWYqQBZXxnuibhjyaq9TL7SxLY8Ej78AxgtbnYzvRXZExXiLi1o/YQdn3CtOxgD55AI1s2ZJSpjpnvG9ere482YejtC46n4gqhQDqG73vuS5qfttmRXEyXA7vxMF8OLymnm2dZIZlNK+4l1yf59x770sU5dUDMBXt+H7ZoXB88Tlo7Q4q7Ee1MGd7H96Dkaoa70c0bj/q7rr4I1TUTdEmFQB3B73iHDr9jCBF0ABrrYvPkESbaeDJRrJCzl+oWG5Ocg4dM3HvviSkAAGGRBY7a2KN7Xhhoxd8hjQ3moI1+v94Pyi7QZw8W+WjiTeAqXnclRQe2H9m3oc9VptuC3jcbK0M3DiI4CfzKN6YfTohyc5PX8qeuRu3fJ/MAZH+oLGpHro63yIKnkOdRbGZf4tR3R5wjNHuBr/+PHzcwJbb7ORLa6SgQuBaxA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 6mhSwmdXo1uuRr9t4QdDAeIkJfpE5dqiRt84t9f6mcKKfdvN/YbIgCFLEUs11U5+uJeG0DGdY4t5apWXBJxLWYmFkhQx1ePtYXyc2071QfsAamXNVqR8IpcuhmJMLHHQ8tPpUY2aaCF0Cnu+MkYnIDM1zt+5RIqjjP+z7BdEIxoQUt3osAq2UOmjV8N+/AxfD0ktDaimLlwFCWNkXzq30ENFp1I9lIOvUWjfqr9lrvIsCwN2967ghkAmypS+Wv1z0IMxNz1DL3gdEj5ecmsZETysycIjl+yj3iqFGavzBJaX+vXGVULaTTX4g5g+xIkE02pRO0i3jAFyrSZnI+FKAg6MWfQkQAL8lV15Hdadh7zERLPzuq6wt1xylvm/cHjTaxQUI6m72HzjztTlMD3xYBiEP0jfDdpE6PDhYnWV3/pt97xzUkepsqMz3AGfJH1nNtYFMXLfE0hTIGnR2ScPULe1lmP07d6iBDUJV7J2zfRzoBa0YEeKZTsIiUzqWjkvUZZ+xHJbmqaZ+fyd7gj9Kd0s80647HdVvw/0GRJ9zUk+upkZbsQ/4DrjBCJR4hmhocd0kHyZJAw/mb4J/2q9okDhAr964kM8bQhsHOTXg4YxumqWkubZLn2TcpNwIFVF9ZmV9YnrfQ/40F1lsXCZWMfRMBoqs7vgSRG82xcnIjDwONQYAQhb1RDcnP7fkxMPmB06YJ8WubL1TXEsFhWYMxKlvC+2s34H0thzZoWNjl+2nrXnQSLAlCI5qr20u9tiMRmmgPXtTUvBEPXp/GtJ5jgXbrtLGml45hS9qAL+OngjHxFWgMAF3scrZ745BgHfBbYscrwtyqdM5BCZBIWGB8VngMz9VE+7VkwyRcs3fxbmrAkhOfLlP8mDEU5yjk4UULLycfXaDNc2j2xdRC7XDkx3LsdjPmnrdtgd1XsazyhmIoiaiwcaamPSm4XH78Io81vdiNOTzeolPmSbhLEtKTmtlAHnr20RRVL+/BXmxifD1ynBX8CT+la9B4zfu5igy+4UXKyC6SkdYH6XTSd7HZbZNlLUTV69CnlV2IWzHEyw4eFIWLCEJsDJ8i8ptMsLwPelANzT250yJ90ZCAYhxsTRk8tWCI49EJxpnfzph+szNznESZqxahEoGaC04AG0YYFrkdzM8JbyKvTIRyLxnXifgwgfmTQ+chP3I1MVQybcMhVlbZAk8xm+ibJM+NoQhZGMMjYNtF+l0xVhLowpXeneCefZ+IthCcQ3FNnzCpd9rXJcPpoCzwtnQ9tHGKUQQkZ922n6MpdAX78A+os2fWrnm5rD/DxmdPNeGdJlio98VAzpv2cvpWB6Nlcaw5tuHwykxHPj3qcnRWvFohyblzduQd6xn+9nnHzyRbTL97yGp1OAkByCEC+MOeWpTeBymJfX8kd5xjQpj+OSCJgQZbf0j8O8w6BZw+CRlWR2Ey9yXlaorRXgwbsCoTaaJV9Sh5R2rLc4oq2+92OW9KlJpdbZjxO66VoS9Tu2z/RhoNby2zabkyoi1+bwAl8YL0DuRvh0BdCPPETdJGKPHI7EfXQvumyzmixUrPaO118PEIVUS0RmvKiZPj41ePHo4LcJdPjEDvxPuimcCddhGBVZZsw4N2zoOfXZ1LenohS+nBZT6BuEyTXJblFC7Krmf34oXz3nk7Efl8iRDyU5oNwRLYJW8WzkpdvocE6zeVZ1L2Vz3cbOc1XVhsN7YGpYEXMaNRgsjER6sAgqlwaldmIil+p5UAoJJDeFXjigWPFDOM8= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8152312f-340d-48f3-3594-08da3d79ea25 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:25.6396 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2viNaYwBKBArlWYoz1gqILrB61H+xz3GLeT8sho9vIdaFGzMop4mQnJbRTzofKMlrP9EOdCp7ZDlnW/PHIenhQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/motion_sense.h | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/motion_sense.h diff --git a/drivers/net/wireless/celeno/cl8k/motion_sense.h b/drivers/net/wireless/celeno/cl8k/motion_sense.h new file mode 100644 index 000000000000..9ea63f561a92 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/motion_sense.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_MOTION_SENSE_H +#define CL_MOTION_SENSE_H + +#include + +#include "rx.h" + +#define MOTION_SENSE_SIZE 30 + +enum cl_motion_state { + STATE_NULL, + STATE_MOVING, + STATE_STATIC +}; + +struct cl_motion_rssi { + s32 sum[MAX_ANTENNAS]; + s32 cnt; + s8 history[MOTION_SENSE_SIZE]; + u8 idx; + s8 max; + s8 min; + enum cl_motion_state state; +}; + +struct cl_motion_sense { + struct cl_motion_rssi rssi_mgmt_ctl; + struct cl_motion_rssi rssi_data; + struct cl_motion_rssi rssi_ba; + enum cl_motion_state combined_state; + enum cl_motion_state forced_state; +}; + +void cl_motion_sense_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_motion_sense_rssi_mgmt_ctl(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr); +void cl_motion_sense_rssi_data(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr); +void cl_motion_sense_rssi_ba(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]); +void cl_motion_sense_maintenance(struct cl_hw *cl_hw); +bool cl_motion_sense_is_static(struct cl_hw *cl_hw, struct cl_sta *cl_sta); + +#endif /* CL_MOTION_SENSE_H */ From patchwork Tue May 24 11:34:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576851 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 CF8C5C433F5 for ; Tue, 24 May 2022 11:39:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236851AbiEXLj3 (ORCPT ); Tue, 24 May 2022 07:39:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236852AbiEXLj0 (ORCPT ); Tue, 24 May 2022 07:39:26 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7BA98DDC7 for ; Tue, 24 May 2022 04:39:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kBOGImi9UM2vRNZz9Nqw4SUBzW8wtNtmjrGGhPjY2WlfQGK7DL4s+sK6zlA+5vzbsGNeUu+6sf8Ic1dWtN70l7D9ddpI/EnwUssWK8V6vR82QoGVpIlqUcNrtfVmKRHOH2we+62GpKFxD9dP/niv3GkPQ9gmZGsO0DQGLfYUoXBTfKSq2v6cIscXn1xPu0UzzWdcUVcw3hcnSHL1/fcbLYDTDhO3Sptshr1Od4OZJ21pCayrdDOWvLDDaCCyxdSm6FQynrXdLG9cCMDLRQGQ9ZIvxgmvAIQP4WZG3+SwsKFLh0ULfd6bPUFXTLlm81chvLy1YA3AUiZ7XS4q91TcfQ== 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=zhK8McDfVqVGnvitP3Yvl4/xJgXhlC7tw2eQuJnKCAI=; b=XzS7kZ7+7ehK1ngM/qsFR6Vj+gPOnnFFvQ+psgzhvlVuDoVhRabUrFy5PKG+xbQBCIlCu86EBkCkTpo/jkczpd8h+fAeoi6OTD9MmJ28H10ItWBvtb9tCvlAGDnIhRPlQVAIZQuSZU49Cbn35Sg5MkzD6oiTGqOspdplaftSpfWL1GW2tQXdeAcE6KtqmrcWzWHc1ZEF8nWk33vwtJEjpOrzshDe9eD5ivCB2EITLNma5CFKLj1/abwjB0VAcSMX9S//oG5I8hoeOoVCYv3knQKaAsYC9c/p3gJyPS9sGL4i5bY9pIQmpi+IajC/fglZehBkTju69jx4mqerOM8Vaw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zhK8McDfVqVGnvitP3Yvl4/xJgXhlC7tw2eQuJnKCAI=; b=TcTT9PkD6lyz282M3X28kli2Rthmvv+EolpvFnmEvoNPb6JKnH+mNMYYzX+D+zICO26RuNTHlrg+KqFXmpKCXsyjjNsTdO/zzI9qPwIWhYiypzmpFBeU+ioqC0PiP5CL8OIKnecb+PqJbmnFBp68CoOh0YpiHwzfKQCiqZBqfYI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:46 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:46 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 48/96] cl8k: add pci.c Date: Tue, 24 May 2022 14:34:14 +0300 Message-Id: <20220524113502.1094459-49-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1e6c3c16-9c69-4be0-7c3f-08da3d79ea90 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2q4Hd0kFuuBBAEyvUE2Za44EDfVpQz3DvOTMs+1a5Ww6k+LDrr4Apv9W4JH4h9ScevlRSBuzXkfpewP2pzytNnPWuIpsA9ve/uL1bSXvAzRWbjubT6SQIIbvEw2e0ftpwv1BH8/2KGcH8MhIX9Nku/D7tPUxbX6f3YRZZxg95PD6cYHsmHnSY/UvmVQhFiayZTlyxWlwQ6YTrgj+0bRaYUt4D7gi+st2TBZMZXbEVdSvuTPdA4wED9Loqx/WGW73HNIC11c+023blIZIwnsHVf9WESypLPTaJ1n/xZ/67NbR65CvzgaOfU7By+Ach9JDbfF8ODAbzflf5UEHJqdQNTZB3oL1tvVENhMHHAH5LRsYgBEw39ElDuozhkuR2X2Rj82zW5P8ylETuXT/AFg+PPChf+BvGRDpRP4bngPCnE+qa2OEaziPVMOIKgsbAvONnyfVeVS/ALXp3GYx2Ijk6XZluy1PUmDktPpAlOH5vsNCbwuxiYuauh9bGXUqubbE2AVVZonwXMDWQs1RJ/ZrBjrJX098uMa6qZg8N8vldr9ig3nyvqHujXMxOwlSxbu7XmA0KUrm2gDjZCYaLkAITS2kk+zpqhmaTT+yXClLyQOwtAM4X4W6UmOoGDKJPVNsTl/yIvok+4mtgcJaLBseVCjcUIi5hu81XTR7yyToRvZcfq7voLZg0n9gt87PvacRKdffmJP9bD7lJgkiV5cLcs5vqSObksYA14YIB89dUS0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: +74waqGjs1SQfZEasvVJrSnC+2PSI2t3zxAA1YDHZRltGDEhfW6VxyxQr1moMWtAzeFjYpC6ctBnEQVFKGlCHXjjXkvW/NJoP7moCCmdphnV8Oq42zuKVipVhum0qMLCF81bW971gMtxdBjGsz9Eb4+fM4LlewZ7Ockmy9Dvwo0REwiOlVqTBj04fzr91JDbrVrhfY/C+VNvta9QTU7BpOUX6eeAfKRKdbTuSLnlzY7PMFNlPBriLH5zx4tcX4u1C6P8GnTRfl7klesty6Fjqt1Mm72zGKTUj74x3JVMAzbO4lTeVSobqImbeajmR68AcDX9qeloWT0nJE08vcRQl9xiyEt5/ozHYfIPNSUXZwEMWDZWjqWt4J4PuBBw8gD9o9uYVB+j8pdtTKLcLJBN/DdMd/Nn4x7Jly+O0M4fWyM9A/mzV9u4pClrb6a0ls831Lz4HUuESl21UA9TX4wBI3PjyqaTZsz/rXJwelaW1+3rSnHJZQ3ssBi6WpsV9mX0nYZCF8tpqkMqYUwZFEmCraFUq2ssGNbdrgdi9f1ejjsfqewUchETMVkVZiuc0owiU9aN7ryt4ebrdKL0vb4YHbkWcSeQ0LnWZFzuZHOY9HTx0SDUV/ihVFq/SNTmYEy75/LWVXBAv1fdxKSS4fKeglZ9kQirso5Iy9+PoAydAjtmJp+Rrh8oGKeVaOuj4ufE7yYjZCLo5Sq4Zm692UJApuo8iIJiVjDHuSmA7m/ueQUJEYG4JMNb23ftqegnBmmeu8vPPOgiKACvTcxr8koXFpKwoGCSThFB664rhxafJdTRUkfoVCTXq3IrIsLoFlC3ozax51MIVPSpdMvx4t4jFkKI2C405itiHpMJfliZyzGswD3V08SZP4mbBztSK5kLTQDVFfRkAXesmw5XvkA2AE0lZgsyqKT6rJSP1SWAHY2nXSPi9NgUCMthclQ/SG78JvRlKCj6XDhqYFh2AMIVjZYIEasC2xRs3fpgY9jBPMJk4ZajScEatmtgr3hSms2xTqvOwgYQ1HDZxkl0tVcGgwpcGt2AWQ8YYPrIOzL8OrHWeTxab5v9molf+Xstu2WY2gQMcph9Bl3zMfAdALbYypw6rboA4vzoqbWr/4gYQh6hrhBkLntyh1KkthtXdhkbdXvPszIHTZXX92YBcXj3t1Bd1D5SEe1D1Yumnercv+9PgIxowlsC7gRV+wiEO3tK3o37eo0VnUDZzHgeLeOshj19sP+RGCJoKCxpEMkLX4922y2wb/5qQ1rdB8PUUyHVOz3+ci2FRgjtxFmIqmkN92EGmh96+YzDDqBz2MaZgcl2B70k/Q0LFIVENUhe+yG0xNi1NbuRiLX6JfmPVrNUfBU43LB5ZC/rjs0ah3/ZVQr5vr7ufzDW949qbrcHji4/n1UDtaDv2MM6VoIMQBrW3aRW7KiwU9vaudNVRbdwdp/waEhVBS0TsE+D5Hqx3FB9kcXYrxXrh6mGKQSutOdDDcmTnQe5QeLI8gS1Jv+lwqikYEaFqBd/S4cp5K/eLHTgxYvJKZ0VYGRMVg113OtlNcjbKXMm60c9s7pe1FSlpQZsT52WC0XGyh+Pi/XRGh8hreUF4PY1uEkh1jMxrMQajPd2xwT37f2Tr1wxTcqxDBjKxAWfrz0jEYYEcNCsZLUCdOQhbGe9RzldZxTn2voaFpfmsDNoDpa41YcIyZ/FUaWpHgxIvPKsuQcVw/fr7QQq3VsVXH46BB6HDGBancZ37mv0ngBPzNWVTs+pDhJKYXQ= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1e6c3c16-9c69-4be0-7c3f-08da3d79ea90 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:26.7644 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2cIn/xZYcf7Z4qs9/okrP9UMgoFJtv+omTM44DqnZUeojexSCGO3dPDxERo8aCQGIbQy+LKZvNEyPmkLI7TYoA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/pci.c | 2468 ++++++++++++++++++++++++ 1 file changed, 2468 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/pci.c diff --git a/drivers/net/wireless/celeno/cl8k/pci.c b/drivers/net/wireless/celeno/cl8k/pci.c new file mode 100644 index 000000000000..dffbcc9478ee --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/pci.c @@ -0,0 +1,2468 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "chip.h" +#include "hw.h" +#include "main.h" +#include "ela.h" +#include "debug.h" +#include "reg/reg_defs.h" +#include "enhanced_tim.h" +#include "pci.h" + +#define DMA_CFM_QUEUE_SIZE 1024 +#define DMA_CFM_TOTAL_SIZE (8 * sizeof(struct cl_ipc_cfm_msg) * DMA_CFM_QUEUE_SIZE) + +static void cl_ipc_env_free(struct cl_hw *cl_hw) +{ + kfree(cl_hw->ipc_env); + cl_hw->ipc_env = NULL; +} + +static void cl_ipc_ring_indices_dealloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + if (!ipc_env->ring_indices_elem) + return; + + memset(ipc_env->ring_indices_elem->indices, 0, sizeof(struct cl_ipc_ring_indices)); + ipc_env->ring_indices_elem->indices = NULL; + kfree(ipc_env->ring_indices_elem); + ipc_env->ring_indices_elem = NULL; +} + +static void _cl_ipc_txdesc_dealloc(struct cl_hw *cl_hw, + struct txdesc *txdesc, + __le32 dma_addr, + u32 desc_num) +{ + dma_addr_t phys_dma_addr = le32_to_cpu(dma_addr); + u32 size = (desc_num * sizeof(struct txdesc)); + + if (size < PAGE_SIZE) + dma_pool_free(cl_hw->txdesc_pool, txdesc, phys_dma_addr); + else + dma_free_coherent(cl_hw->chip->dev, size, txdesc, phys_dma_addr); +} + +static void cl_ipc_txdesc_dealloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_tx_queues *tx_queues = &cl_hw->ipc_env->tx_queues; + struct tx_queues_dma_addr *queues_dma_addr = tx_queues->queues_dma_addr; + u32 i; + + if (queues_dma_addr->bcmc) { + _cl_ipc_txdesc_dealloc(cl_hw, tx_queues->ipc_txdesc_bcmc, + queues_dma_addr->bcmc, IPC_TXDESC_CNT_BCMC); + queues_dma_addr->bcmc = 0; + } + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + if (queues_dma_addr->single[i]) { + _cl_ipc_txdesc_dealloc(cl_hw, tx_queues->ipc_txdesc_single[i], + queues_dma_addr->single[i], + IPC_TXDESC_CNT_SINGLE); + queues_dma_addr->single[i] = 0; + } + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + if (queues_dma_addr->agg[i]) { + _cl_ipc_txdesc_dealloc(cl_hw, tx_queues->ipc_txdesc_agg[i], + queues_dma_addr->agg[i], + TXDESC_AGG_Q_SIZE_MAX); + queues_dma_addr->agg[i] = 0; + } + + dma_pool_destroy(cl_hw->txdesc_pool); + cl_hw->txdesc_pool = NULL; +} + +static void cl_ipc_tx_queues_dealloc(struct cl_hw *cl_hw) +{ + u32 len = sizeof(struct tx_queues_dma_addr); + dma_addr_t phys_dma_addr = cl_hw->ipc_env->tx_queues.dma_addr; + + if (!cl_hw->ipc_env->tx_queues.queues_dma_addr) + return; + + dma_free_coherent(cl_hw->chip->dev, len, + (void *)cl_hw->ipc_env->tx_queues.queues_dma_addr, + phys_dma_addr); + cl_hw->ipc_env->tx_queues.queues_dma_addr = NULL; +} + +static void cl_ipc_rx_dealloc_skb(struct cl_hw *cl_hw, struct cl_rx_elem *rx_elem, + u16 len) +{ + dma_unmap_single(cl_hw->chip->dev, rx_elem->dma_addr, len, + DMA_FROM_DEVICE); + kfree_skb(rx_elem->skb); + rx_elem->skb = NULL; +} + +static void _cl_ipc_rx_dealloc_buff(struct cl_hw *cl_hw, + u32 *rxbuf, + __le32 dma_addr, + u32 desc_num) +{ + dma_addr_t phys_dma_addr = le32_to_cpu(dma_addr); + u32 size = (desc_num * sizeof(u32)); + + dma_free_coherent(cl_hw->chip->dev, size, rxbuf, phys_dma_addr); +} + +static void cl_ipc_rx_dealloc_buff(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_host_rxbuf *rxbuf_rxm = &ipc_env->rx_hostbuf_array[CL_RX_BUF_RXM]; + struct cl_ipc_host_rxbuf *rxbuf_fw = &ipc_env->rx_hostbuf_array[CL_RX_BUF_FW]; + + if (rxbuf_rxm->dma_payload_base_addr) + _cl_ipc_rx_dealloc_buff(cl_hw, + rxbuf_rxm->dma_payload_addr, + rxbuf_rxm->dma_payload_base_addr, + IPC_RXBUF_CNT_RXM); + + if (rxbuf_fw->dma_payload_base_addr) + _cl_ipc_rx_dealloc_buff(cl_hw, + rxbuf_fw->dma_payload_addr, + rxbuf_fw->dma_payload_base_addr, + IPC_RXBUF_CNT_FW); +} + +static void cl_ipc_rx_dealloc(struct cl_hw *cl_hw) +{ + struct cl_rx_elem *rx_elem = cl_hw->rx_elems; + u16 rxbuf_size_rxm = cl_hw->conf->ci_ipc_rxbuf_size[CL_RX_BUF_RXM]; + u16 rxbuf_size_fw = cl_hw->conf->ci_ipc_rxbuf_size[CL_RX_BUF_FW]; + int i; + + if (!cl_hw->rx_elems) + return; + + for (i = 0; i < IPC_RXBUF_CNT_RXM; i++, rx_elem++) + if (rx_elem->skb && !rx_elem->passed) + cl_ipc_rx_dealloc_skb(cl_hw, rx_elem, rxbuf_size_rxm); + + for (i = 0; i < IPC_RXBUF_CNT_FW; i++, rx_elem++) + if (rx_elem->skb && !rx_elem->passed) + cl_ipc_rx_dealloc_skb(cl_hw, rx_elem, rxbuf_size_fw); + + kfree(cl_hw->rx_elems); + cl_hw->rx_elems = NULL; + + cl_ipc_rx_dealloc_buff(cl_hw); +} + +static void cl_ipc_msg_dealloc(struct cl_hw *cl_hw) +{ + struct cl_e2a_msg_elem *msg_elem; + int i; + + if (!cl_hw->e2a_msg_elems || !cl_hw->e2a_msg_pool) + return; + + for (i = 0, msg_elem = cl_hw->e2a_msg_elems; + i < IPC_E2A_MSG_BUF_CNT; i++, msg_elem++) { + if (msg_elem->msgbuf_ptr) { + dma_pool_free(cl_hw->e2a_msg_pool, msg_elem->msgbuf_ptr, + msg_elem->dma_addr); + msg_elem->msgbuf_ptr = NULL; + } + } + + dma_pool_destroy(cl_hw->e2a_msg_pool); + cl_hw->e2a_msg_pool = NULL; + + kfree(cl_hw->e2a_msg_elems); + cl_hw->e2a_msg_elems = NULL; +} + +static void cl_ipc_radar_dealloc(struct cl_hw *cl_hw) +{ + struct cl_radar_elem *radar_elem; + int i; + + if (!cl_hw->radar_pool || !cl_hw->radar_elems) + return; + + for (i = 0, radar_elem = cl_hw->radar_elems; + i < IPC_RADAR_BUF_CNT; i++, radar_elem++) { + if (radar_elem->radarbuf_ptr) { + dma_pool_free(cl_hw->radar_pool, radar_elem->radarbuf_ptr, + radar_elem->dma_addr); + radar_elem->radarbuf_ptr = NULL; + } + } + + dma_pool_destroy(cl_hw->radar_pool); + cl_hw->radar_pool = NULL; + + kfree(cl_hw->radar_elems); + cl_hw->radar_elems = NULL; +} + +static void cl_ipc_dbg_dealloc(struct cl_hw *cl_hw) +{ + struct cl_dbg_elem *dbg_elem; + int i; + + if (!cl_hw->dbg_pool || !cl_hw->dbg_elems) + return; + + for (i = 0, dbg_elem = cl_hw->dbg_elems; + i < IPC_DBG_BUF_CNT; i++, dbg_elem++) { + if (dbg_elem->dbgbuf_ptr) { + dma_pool_free(cl_hw->dbg_pool, dbg_elem->dbgbuf_ptr, + dbg_elem->dma_addr); + dbg_elem->dbgbuf_ptr = NULL; + } + } + + dma_pool_destroy(cl_hw->dbg_pool); + cl_hw->dbg_pool = NULL; + + kfree(cl_hw->dbg_elems); + cl_hw->dbg_elems = NULL; +} + +static void cl_ipc_cfm_dealloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + dma_free_coherent(cl_hw->chip->dev, + DMA_CFM_TOTAL_SIZE, + ipc_env->cfm_virt_base_addr, + ipc_env->cfm_dma_base_addr); + + ipc_env->cfm_dma_base_addr = 0; + ipc_env->cfm_virt_base_addr = NULL; +} + +static void cl_ipc_dbg_info_dealloc(struct cl_hw *cl_hw) +{ + if (!cl_hw->dbginfo.buf) + return; + + dma_free_coherent(cl_hw->chip->dev, + cl_hw->dbginfo.bufsz, + cl_hw->dbginfo.buf, + cl_hw->dbginfo.dma_addr); + + cl_hw->dbginfo.buf = NULL; +} + +static void cl_ipc_elems_dealloc(struct cl_hw *cl_hw) +{ + cl_ipc_ring_indices_dealloc(cl_hw); + cl_ipc_txdesc_dealloc(cl_hw); + cl_ipc_tx_queues_dealloc(cl_hw); + cl_ipc_rx_dealloc(cl_hw); + cl_ipc_msg_dealloc(cl_hw); + cl_ipc_radar_dealloc(cl_hw); + cl_ipc_dbg_dealloc(cl_hw); + cl_ipc_cfm_dealloc(cl_hw); + cl_ipc_dbg_info_dealloc(cl_hw); +} + +static int cl_ipc_ring_indices_alloc(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + ipc_env->ring_indices_elem = kzalloc(sizeof(*ipc_env->ring_indices_elem), GFP_KERNEL); + + if (!ipc_env->ring_indices_elem) + return -ENOMEM; + + if (cl_hw_is_tcv0(cl_hw)) { + ipc_env->ring_indices_elem->indices = chip->ring_indices.params; + ipc_env->ring_indices_elem->dma_addr = chip->ring_indices.dma_addr; + } else { + ipc_env->ring_indices_elem->indices = chip->ring_indices.params + 1; + ipc_env->ring_indices_elem->dma_addr = + (u32)chip->ring_indices.dma_addr + sizeof(struct cl_ipc_ring_indices); + } + + memset(ipc_env->ring_indices_elem->indices, 0, sizeof(struct cl_ipc_ring_indices)); + + return 0; +} + +static int cl_ipc_tx_queues_alloc(struct cl_hw *cl_hw) +{ + struct tx_queues_dma_addr *buf = NULL; + u32 size = sizeof(struct tx_queues_dma_addr); + dma_addr_t phys_dma_addr; + + buf = dma_alloc_coherent(cl_hw->chip->dev, size, &phys_dma_addr, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + cl_hw->ipc_env->tx_queues.queues_dma_addr = buf; + cl_hw->ipc_env->tx_queues.dma_addr = phys_dma_addr; + + return 0; +} + +static int __cl_ipc_txdesc_alloc(struct cl_hw *cl_hw, + struct txdesc **txdesc, + __le32 *dma_addr, + u32 desc_num) +{ + dma_addr_t phys_dma_addr; + u32 size = (desc_num * sizeof(struct txdesc)); + + if (size < PAGE_SIZE) { + *txdesc = dma_pool_alloc(cl_hw->txdesc_pool, GFP_KERNEL, &phys_dma_addr); + + if (!(*txdesc)) { + cl_dbg_err(cl_hw, "dma_pool_alloc failed size=%d\n", size); + return -ENOMEM; + } + } else { + *txdesc = dma_alloc_coherent(cl_hw->chip->dev, size, &phys_dma_addr, GFP_KERNEL); + + if (!(*txdesc)) { + cl_dbg_err(cl_hw, "dma_alloc_coherent failed size=%d\n", size); + return -ENOMEM; + } + } + + *dma_addr = cpu_to_le32(phys_dma_addr); + memset(*txdesc, 0, size); + + return 0; +} + +static int _cl_ipc_txdesc_alloc(struct cl_hw *cl_hw) +{ + /* + * Allocate ipc txdesc for each queue, map the base + * address to the DMA and set the queues size + */ + struct cl_ipc_tx_queues *tx_queues = &cl_hw->ipc_env->tx_queues; + struct tx_queues_dma_addr *queues_dma_addr = tx_queues->queues_dma_addr; + u32 i; + int ret = 0; + + ret = __cl_ipc_txdesc_alloc(cl_hw, &tx_queues->ipc_txdesc_bcmc, + &queues_dma_addr->bcmc, IPC_TXDESC_CNT_BCMC); + if (ret) + return ret; + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) { + ret = __cl_ipc_txdesc_alloc(cl_hw, &tx_queues->ipc_txdesc_single[i], + &queues_dma_addr->single[i], + IPC_TXDESC_CNT_SINGLE); + if (ret) + return ret; + } + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) { + ret = __cl_ipc_txdesc_alloc(cl_hw, &tx_queues->ipc_txdesc_agg[i], + &queues_dma_addr->agg[i], + TXDESC_AGG_Q_SIZE_MAX); + if (ret) + return ret; + } + + return 0; +} + +static int cl_ipc_txdesc_alloc(struct cl_hw *cl_hw) +{ + u32 pool_size = IPC_TXDESC_CNT_SINGLE * sizeof(struct txdesc); + + cl_hw->txdesc_pool = dma_pool_create("cl_txdesc_pool", cl_hw->chip->dev, + pool_size, cache_line_size(), 0); + + if (!cl_hw->txdesc_pool) { + cl_dbg_verbose(cl_hw, "dma_pool_create failed !!!\n"); + return -ENOMEM; + } + + return _cl_ipc_txdesc_alloc(cl_hw); +} + +static int cl_ipc_rx_skb_alloc(struct cl_hw *cl_hw) +{ + /* + * This function allocates Rx elements for DMA + * transfers and pushes the DMA address to FW. + */ + struct cl_rx_elem *rx_elem = cl_hw->rx_elems; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + int i = 0; + u16 rxbuf_size_rxm = cl_hw->conf->ci_ipc_rxbuf_size[CL_RX_BUF_RXM]; + u16 rxbuf_size_fw = cl_hw->conf->ci_ipc_rxbuf_size[CL_RX_BUF_FW]; + + /* Allocate and push RXM buffers */ + for (i = 0; i < IPC_RXBUF_CNT_RXM; rx_elem++, i++) { + if (cl_ipc_rx_elem_alloc(cl_hw, rx_elem, rxbuf_size_rxm)) { + cl_dbg_verbose(cl_hw, "RXM rx_elem allocation failed !!!\n"); + return -ENOMEM; + } + cl_ipc_rxbuf_push(ipc_env, rx_elem, i, i, CL_RX_BUF_RXM); + } + + /* Allocate and push FW buffers */ + for (i = 0; i < IPC_RXBUF_CNT_FW; rx_elem++, i++) { + if (cl_ipc_rx_elem_alloc(cl_hw, rx_elem, rxbuf_size_fw)) { + cl_dbg_verbose(cl_hw, "FW rx_elem allocation failed !!!\n"); + return -ENOMEM; + } + cl_ipc_rxbuf_push(ipc_env, rx_elem, i, i, CL_RX_BUF_FW); + } + + return 0; +} + +static int _cl_ipc_rx_buf_alloc(struct cl_hw *cl_hw, u32 **rxbuf, __le32 *dma_addr, u32 desc_num) +{ + dma_addr_t phys_dma_addr; + u32 size = (desc_num * sizeof(u32)); + + *rxbuf = dma_alloc_coherent(cl_hw->chip->dev, + size, + &phys_dma_addr, + GFP_KERNEL); + + if (!(*rxbuf)) + return -ENOMEM; + + *dma_addr = cpu_to_le32(phys_dma_addr); + memset(*rxbuf, 0, size); + + return 0; +} + +static int cl_ipc_rx_buf_alloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_host_rxbuf *rxbuf_rxm = &ipc_env->rx_hostbuf_array[CL_RX_BUF_RXM]; + struct cl_ipc_host_rxbuf *rxbuf_fw = &ipc_env->rx_hostbuf_array[CL_RX_BUF_FW]; + int ret = 0; + + rxbuf_rxm->ipc_host_rxdesc_ptr = ipc_env->ipc_host_rxdesc_rxm; + rxbuf_fw->ipc_host_rxdesc_ptr = ipc_env->ipc_host_rxdesc_fw; + + /* Allocate RXM RX write/read indexes */ + ret = _cl_ipc_rx_buf_alloc(cl_hw, + (u32 **)&rxbuf_rxm->dma_payload_addr, + &rxbuf_rxm->dma_payload_base_addr, + IPC_RXBUF_CNT_RXM); + if (ret) + return ret; + + /* Allocate FW RX write/read indexes */ + ret = _cl_ipc_rx_buf_alloc(cl_hw, + (u32 **)&rxbuf_fw->dma_payload_addr, + &rxbuf_fw->dma_payload_base_addr, + IPC_RXBUF_CNT_FW); + if (ret) + return ret; + + return 0; +} + +static int cl_ipc_rx_alloc(struct cl_hw *cl_hw) +{ + u32 total_rx_elems = IPC_RXBUF_CNT_RXM + IPC_RXBUF_CNT_FW; + u32 alloc_size = total_rx_elems * sizeof(struct cl_rx_elem); + int ret = cl_ipc_rx_buf_alloc(cl_hw); + + if (ret) + return ret; + + cl_hw->rx_elems = kzalloc(alloc_size, GFP_KERNEL); + + if (!cl_hw->rx_elems) + return -ENOMEM; + + return cl_ipc_rx_skb_alloc(cl_hw); +} + +static int _cl_ipc_msg_alloc(struct cl_hw *cl_hw, struct cl_e2a_msg_elem *msg_elem) +{ + dma_addr_t dma_addr; + struct cl_ipc_e2a_msg *msg; + + /* Initialize the message pattern to NULL */ + msg = dma_pool_alloc(cl_hw->e2a_msg_pool, GFP_KERNEL, &dma_addr); + if (!msg) + return -ENOMEM; + + msg->pattern = 0; + + /* Save the msg pointer (for deallocation) and the dma_addr */ + msg_elem->msgbuf_ptr = msg; + msg_elem->dma_addr = dma_addr; + + return 0; +} + +static int cl_ipc_msg_alloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_e2a_msg_elem *msg_elem; + u32 alloc_size = IPC_E2A_MSG_BUF_CNT * sizeof(struct cl_e2a_msg_elem); + u32 i; + + cl_hw->e2a_msg_elems = kzalloc(alloc_size, GFP_KERNEL); + + if (!cl_hw->e2a_msg_elems) + return -ENOMEM; + + cl_hw->e2a_msg_pool = dma_pool_create("dma_pool_msg", + cl_hw->chip->dev, + sizeof(struct cl_ipc_e2a_msg), + cache_line_size(), + 0); + + if (!cl_hw->e2a_msg_pool) { + cl_dbg_verbose(cl_hw, "dma_pool_create failed !!!\n"); + return -ENOMEM; + } + + /* Initialize the msg buffers in the global IPC array. */ + for (i = 0, msg_elem = cl_hw->e2a_msg_elems; + i < IPC_E2A_MSG_BUF_CNT; msg_elem++, i++) { + if (_cl_ipc_msg_alloc(cl_hw, msg_elem)) { + cl_dbg_verbose(cl_hw, "msg allocation failed !!!\n"); + return -ENOMEM; + } + + cl_ipc_msgbuf_push(ipc_env, (ptrdiff_t)msg_elem, msg_elem->dma_addr); + } + + return 0; +} + +static int _cl_ipc_radar_alloc(struct cl_hw *cl_hw, struct cl_radar_elem *radar_elem) +{ + dma_addr_t dma_addr; + struct cl_radar_pulse_array *radar; + + /* Initialize the message pattern to NULL */ + radar = dma_pool_alloc(cl_hw->radar_pool, GFP_KERNEL, &dma_addr); + if (!radar) + return -ENOMEM; + + radar->cnt = 0; + + /* Save the msg pointer (for deallocation) and the dma_addr */ + radar_elem->radarbuf_ptr = radar; + radar_elem->dma_addr = dma_addr; + + return 0; +} + +static int cl_ipc_radar_alloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_radar_elem *radar_elem; + u32 alloc_size = IPC_RADAR_BUF_CNT * sizeof(struct cl_radar_elem); + u32 i; + + cl_hw->radar_elems = kzalloc(alloc_size, GFP_KERNEL); + + if (!cl_hw->radar_elems) + return -ENOMEM; + + cl_hw->radar_pool = dma_pool_create("dma_pool_radar", + cl_hw->chip->dev, + sizeof(struct cl_radar_pulse_array), + cache_line_size(), + 0); + + if (!cl_hw->radar_pool) { + cl_dbg_verbose(cl_hw, "dma_pool_create failed !!!\n"); + return -ENOMEM; + } + + /* Initialize the radar buffers in the global IPC array. */ + for (i = 0, radar_elem = cl_hw->radar_elems; + i < IPC_RADAR_BUF_CNT; radar_elem++, i++) { + if (_cl_ipc_radar_alloc(cl_hw, radar_elem)) { + cl_dbg_verbose(cl_hw, "radar allocation failed !!!\n"); + return -ENOMEM; + } + + cl_ipc_radarbuf_push(ipc_env, (ptrdiff_t)radar_elem, radar_elem->dma_addr); + } + + return 0; +} + +static int _cl_ipc_dbg_alloc(struct cl_hw *cl_hw, struct cl_dbg_elem *dbg_elem) +{ + dma_addr_t dma_addr; + struct cl_ipc_dbg_msg *dbg_msg; + + dbg_msg = dma_pool_alloc(cl_hw->dbg_pool, GFP_KERNEL, &dma_addr); + if (!dbg_msg) + return -ENOMEM; + + dbg_msg->pattern = 0; + + /* Save the Debug msg pointer (for deallocation) and the dma_addr */ + dbg_elem->dbgbuf_ptr = dbg_msg; + dbg_elem->dma_addr = dma_addr; + + return 0; +} + +static int cl_ipc_dbg_alloc(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_dbg_elem *dbg_elem; + u32 alloc_size = IPC_DBG_BUF_CNT * sizeof(struct cl_dbg_elem); + u32 i; + + cl_hw->dbg_elems = kzalloc(alloc_size, GFP_KERNEL); + + if (!cl_hw->dbg_elems) + return -ENOMEM; + + cl_hw->dbg_pool = dma_pool_create("dma_pool_dbg", + cl_hw->chip->dev, + sizeof(struct cl_ipc_dbg_msg), + cache_line_size(), + 0); + + if (!cl_hw->dbg_pool) { + cl_dbg_verbose(cl_hw, "dma_pool_create failed !!!\n"); + return -ENOMEM; + } + + /* Initialize the dbg buffers in the global IPC array. */ + for (i = 0, dbg_elem = cl_hw->dbg_elems; + i < IPC_DBG_BUF_CNT; dbg_elem++, i++) { + if (_cl_ipc_dbg_alloc(cl_hw, dbg_elem)) { + cl_dbg_verbose(cl_hw, "dbgelem allocation failed !!!\n"); + return -ENOMEM; + } + + cl_ipc_dbgbuf_push(ipc_env, (ptrdiff_t)dbg_elem, dbg_elem->dma_addr); + } + + return 0; +} + +static int cl_ipc_cfm_alloc(struct cl_hw *cl_hw) +{ + dma_addr_t dma_addr; + u8 *host_virt_addr; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + host_virt_addr = dma_alloc_coherent(cl_hw->chip->dev, + DMA_CFM_TOTAL_SIZE, + &dma_addr, + GFP_KERNEL); + + if (!host_virt_addr) + return -ENOMEM; + + memset(host_virt_addr, 0, DMA_CFM_TOTAL_SIZE); + ipc_env->cfm_dma_base_addr = dma_addr; + ipc_env->cfm_virt_base_addr = host_virt_addr; + + memset(ipc_env->cfm_virt_base_addr, 0, IPC_CFM_SIZE); + + return 0; +} + +static int _cl_ipc_dbg_info_alloc(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + struct dbg_info *buf; + dma_addr_t dma_addr; + u32 len = sizeof(struct dbg_info); + + if (!chip->conf->ci_la_mirror_en) + len -= sizeof_field(struct dbg_dump_info, la_mem); + + buf = dma_alloc_coherent(chip->dev, len, &dma_addr, GFP_KERNEL); + + if (!buf) { + cl_dbg_verbose(cl_hw, "buffer alloc of size %u failed\n", len); + return -ENOMEM; + } + + memset(buf, 0, len); + buf->u.type = DBG_INFO_UNSET; + + cl_hw->dbginfo.buf = buf; + cl_hw->dbginfo.dma_addr = dma_addr; + cl_hw->dbginfo.bufsz = len; + + return 0; +} + +static int cl_ipc_dbg_info_alloc(struct cl_hw *cl_hw) +{ + /* Initialize the debug information buffer */ + if (_cl_ipc_dbg_info_alloc(cl_hw)) { + cl_dbg_verbose(cl_hw, "dbginfo allocation failed !!!\n"); + return -ENOMEM; + } + + cl_ipc_dbginfobuf_push(cl_hw->ipc_env, cl_hw->dbginfo.dma_addr); + + return 0; +} + +static int cl_ipc_elems_alloc(struct cl_hw *cl_hw) +{ + /* Allocate all the elements required for communications with firmware */ + if (cl_ipc_ring_indices_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_tx_queues_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_txdesc_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_rx_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_msg_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_radar_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_dbg_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_cfm_alloc(cl_hw)) + goto out_err; + + if (cl_ipc_dbg_info_alloc(cl_hw)) + goto out_err; + + return 0; + +out_err: + cl_ipc_elems_dealloc(cl_hw); + return -ENOMEM; +} + +static u8 cl_ipc_dbgfile_handler(struct cl_hw *cl_hw, ptrdiff_t hostid) +{ + struct cl_dbg_elem *dbg_elem = (struct cl_dbg_elem *)hostid; + struct cl_ipc_dbg_msg *dbg_msg; + u8 ret = 0; + + /* Retrieve the message structure */ + dbg_msg = (struct cl_ipc_dbg_msg *)dbg_elem->dbgbuf_ptr; + + if (!dbg_msg) { + ret = -1; + cl_dbg_err(cl_hw, "dbgbuf_ptr is NULL!!!!\n"); + goto dbg_push; + } + + /* Look for pattern which means that this hostbuf has been used for a MSG */ + if (le32_to_cpu(dbg_msg->pattern) != IPC_DBG_VALID_PATTERN) { + ret = -1; + goto dbg_no_push; + } + + /* Reset the msg element and re-use it */ + dbg_msg->pattern = 0; + + /* Display the firmware string */ + cl_dbgfile_print_fw_str(cl_hw, dbg_msg->string, IPC_DBG_PARAM_SIZE); + +dbg_push: + /* make sure memory is written before push to HW */ + wmb(); + + /* Push back the buffer to the firmware */ + cl_ipc_dbgbuf_push(cl_hw->ipc_env, (ptrdiff_t)dbg_elem, dbg_elem->dma_addr); + +dbg_no_push: + return ret; +} + +static void cl_ipc_dbgfile_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_hostbuf *dbg_array = ipc_env->dbg_hostbuf_array; + int dbg_handled = 0; + + while (!cl_ipc_dbgfile_handler(cl_hw, dbg_array[ipc_env->dbg_host_idx].hostid)) + dbg_handled++; + + /* Enable the DBG interrupt */ + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.dbg); +} + +static void cl_ipc_tasklet_init(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + tasklet_init(&ipc_env->rxdesc_tasklet, + cl_rx_pci_desc_tasklet, + (unsigned long)cl_hw); + tasklet_init(&ipc_env->tx_single_cfm_tasklet, + cl_tx_pci_single_cfm_tasklet, + (unsigned long)cl_hw); + tasklet_init(&ipc_env->tx_agg_cfm_tasklet, + cl_tx_pci_agg_cfm_tasklet, + (unsigned long)cl_hw); + tasklet_init(&ipc_env->msg_tasklet, + cl_msg_rx_tasklet, + (unsigned long)cl_hw); + tasklet_init(&ipc_env->dbg_tasklet, + cl_ipc_dbgfile_tasklet, + (unsigned long)cl_hw); + tasklet_init(&ipc_env->bcn_tasklet, + cl_tx_bcns_tasklet, + (unsigned long)cl_hw); +} + +static int cl_ipc_env_init(struct cl_hw *cl_hw) +{ + u32 *dst; + u32 i; + + BUILD_BUG_ON_NOT_POWER_OF_2(IPC_RXBUF_CNT_RXM); + BUILD_BUG_ON_NOT_POWER_OF_2(IPC_RXBUF_CNT_FW); + + /* Allocate the IPC environment */ + cl_hw->ipc_env = kzalloc(sizeof(*cl_hw->ipc_env), GFP_KERNEL); + + if (!cl_hw->ipc_env) + return -ENOMEM; + + dst = (u32 *)(cl_hw->ipc_env); + + /* + * Reset the IPC Host environment. + * Perform the reset word per word because memset() does + * not correctly reset all (due to misaligned accesses) + */ + for (i = 0; i < sizeof(struct cl_ipc_host_env); i += sizeof(u32)) + *dst++ = 0; + + return 0; +} + +static bool cl_pci_is_la_enabled(struct cl_chip *chip) +{ + s8 *ela_mode = chip->conf->ce_ela_mode; + + return (!strcmp(ela_mode, "default") || + !strncmp(ela_mode, "lcu_mac", 7) || + !strncmp(ela_mode, "lcu_phy", 7)); +} + +static void cl_ipc_shared_env_init(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_shared_env __iomem *shared_env = + (struct cl_ipc_shared_env __iomem *)(chip->pci_bar0_virt_addr + + SHARED_RAM_START_ADDR); + u32 i; + u16 max_retry = cl_hw_is_prod_or_listener(cl_hw) ? + 0 : cl_hw->conf->ce_max_retry; + bool first_tcv = cl_hw_is_first_tcv(cl_hw) && + !cl_recovery_in_progress(cl_hw); + void __iomem *dst; + + /* The shared environment of TCV1 is located after the shared environment of TCV0. */ + if (cl_hw_is_tcv1(cl_hw)) + shared_env++; + + dst = (void __iomem *)(shared_env); + + /* Reset the shared environment */ + for (i = 0; i < sizeof(struct cl_ipc_shared_env); i += sizeof(u32), + dst += sizeof(u32)) + iowrite32(0, dst); + + iowrite8(cl_pci_is_la_enabled(chip), (void __iomem *)&shared_env->la_enable); + iowrite16(max_retry, (void __iomem *)&shared_env->max_retry); + iowrite16(CL_TX_LIFETIME_MS, (void __iomem *)&shared_env->lft_limit_ms); + iowrite16(chip->conf->ci_phy_dev, (void __iomem *)&shared_env->phy_dev); + iowrite8(first_tcv, (void __iomem *)&shared_env->first_tcv); + iowrite8(chip->conf->ci_la_mirror_en, + (void __iomem *)&shared_env->la_mirror_enable); + + /* Initialize the shared environment pointer */ + ipc_env->shared = shared_env; +} + +static void cl_ipc_e2a_irq_init(struct cl_hw *cl_hw) +{ + struct cl_ipc_e2a_irq *ipc_e2a_irq = &cl_hw->ipc_e2a_irq; + + if (cl_hw_is_tcv0(cl_hw)) { + ipc_e2a_irq->dbg = IPC_IRQ_L2H_DBG; + ipc_e2a_irq->msg = IPC_IRQ_L2H_MSG; + ipc_e2a_irq->rxdesc = IPC_IRQ_L2H_RXDESC; + ipc_e2a_irq->txcfm = IPC_IRQ_L2H_TXCFM; + ipc_e2a_irq->radar = IPC_IRQ_L2H_RADAR; + ipc_e2a_irq->txdesc_ind = IPC_IRQ_L2H_TXDESC_IND; + ipc_e2a_irq->tbtt = IPC_IRQ_L2H_TBTT; + ipc_e2a_irq->sync = IPC_IRQ_L2H_SYNC; + ipc_e2a_irq->all = IPC_IRQ_L2H_ALL; + } else { + ipc_e2a_irq->dbg = IPC_IRQ_S2H_DBG; + ipc_e2a_irq->msg = IPC_IRQ_S2H_MSG; + ipc_e2a_irq->rxdesc = IPC_IRQ_S2H_RXDESC; + ipc_e2a_irq->txcfm = IPC_IRQ_S2H_TXCFM; + ipc_e2a_irq->radar = IPC_IRQ_S2H_RADAR; + ipc_e2a_irq->txdesc_ind = IPC_IRQ_S2H_TXDESC_IND; + ipc_e2a_irq->tbtt = IPC_IRQ_S2H_TBTT; + ipc_e2a_irq->sync = IPC_IRQ_S2H_SYNC; + ipc_e2a_irq->all = IPC_IRQ_S2H_ALL; + } +} + +int cl_ipc_init(struct cl_hw *cl_hw) +{ + /* + * This function initializes IPC interface by registering callbacks, setting + * shared memory area and calling IPC Init function. + * This function should be called only once during driver's lifetime. + */ + int ret = cl_ipc_env_init(cl_hw); + + if (ret) + return ret; + + cl_ipc_e2a_irq_init(cl_hw); + if (cl_hw_is_tcv0(cl_hw)) + cl_hw->ipc_host2xmac_trigger_set = ipc_host_2_lmac_trigger_set; + else + cl_hw->ipc_host2xmac_trigger_set = ipc_host_2_smac_trigger_set; + + cl_ipc_shared_env_init(cl_hw); + + ret = cl_ipc_elems_alloc(cl_hw); + if (ret) { + cl_ipc_env_free(cl_hw); + return ret; + } + + cl_ipc_tasklet_init(cl_hw); + + return ret; +} + +static void cl_ipc_ring_indices_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + memset(ipc_env->ring_indices_elem->indices, 0, sizeof(struct cl_ipc_ring_indices)); + + /* Reset host desc read idx follower */ + ipc_env->host_rxdesc_read_idx[CL_RX_BUF_RXM] = 0; + ipc_env->host_rxdesc_read_idx[CL_RX_BUF_FW] = 0; +} + +static void _cl_ipc_txdesc_reset(struct txdesc **txdesc, u32 desc_num) +{ + u32 size = (desc_num * sizeof(struct txdesc)); + + memset(*txdesc, 0, size); +} + +static void cl_ipc_txdesc_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_tx_queues *tx_queues = &cl_hw->ipc_env->tx_queues; + u32 i; + + _cl_ipc_txdesc_reset(&tx_queues->ipc_txdesc_bcmc, IPC_TXDESC_CNT_BCMC); + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + _cl_ipc_txdesc_reset(&tx_queues->ipc_txdesc_single[i], IPC_TXDESC_CNT_SINGLE); + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + _cl_ipc_txdesc_reset(&tx_queues->ipc_txdesc_agg[i], TXDESC_AGG_Q_SIZE_MAX); +} + +static void cl_ipc_rx_skb_reset(struct cl_hw *cl_hw) +{ + /* + * This function allocates Rx elements for DMA + * transfers and pushes the DMA address to FW. + */ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_rx_elem *rx_elem = cl_hw->rx_elems; + int i = 0; + + /* Push RXM buffers */ + for (i = 0; i < IPC_RXBUF_CNT_RXM; rx_elem++, i++) + cl_ipc_rxbuf_push(ipc_env, rx_elem, i, i, CL_RX_BUF_RXM); + + /* Push FW buffers */ + for (i = 0; i < IPC_RXBUF_CNT_FW; rx_elem++, i++) + cl_ipc_rxbuf_push(ipc_env, rx_elem, i, i, CL_RX_BUF_FW); +} + +static void _cl_ipc_rx_buf_reset(u32 **rxbuf, u32 desc_num) +{ + u32 size = (desc_num * sizeof(u32)); + + memset(*rxbuf, 0, size); +} + +static void cl_ipc_rx_buf_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_host_rxbuf *rxbuf_rxm = &ipc_env->rx_hostbuf_array[CL_RX_BUF_RXM]; + struct cl_ipc_host_rxbuf *rxbuf_fw = &ipc_env->rx_hostbuf_array[CL_RX_BUF_FW]; + + /* Reset RXM RX buffer */ + _cl_ipc_rx_buf_reset((u32 **)&rxbuf_rxm->dma_payload_addr, + IPC_RXBUF_CNT_RXM); + + /* Reset FW RX buffer */ + _cl_ipc_rx_buf_reset((u32 **)&rxbuf_fw->dma_payload_addr, + IPC_RXBUF_CNT_FW); +} + +static void cl_ipc_rx_reset(struct cl_hw *cl_hw) +{ + cl_ipc_rx_buf_reset(cl_hw); + cl_ipc_rx_skb_reset(cl_hw); +} + +static void cl_ipc_msg_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_e2a_msg_elem *msg_elem; + u32 i; + + ipc_env->e2a_msg_host_idx = 0; + + /* Initialize the msg buffers in the global IPC array. */ + for (i = 0, msg_elem = cl_hw->e2a_msg_elems; + i < IPC_E2A_MSG_BUF_CNT; msg_elem++, i++) { + msg_elem->msgbuf_ptr->pattern = 0; + cl_ipc_msgbuf_push(ipc_env, (ptrdiff_t)msg_elem, msg_elem->dma_addr); + } +} + +static void cl_ipc_radar_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_radar_elem *radar_elem; + u32 i; + + ipc_env->radar_host_idx = 0; + + /* Initialize the radar buffers in the global IPC array. */ + for (i = 0, radar_elem = cl_hw->radar_elems; + i < IPC_RADAR_BUF_CNT; radar_elem++, i++) { + radar_elem->radarbuf_ptr->cnt = 0; + cl_ipc_radarbuf_push(ipc_env, (ptrdiff_t)radar_elem, radar_elem->dma_addr); + } +} + +static void cl_ipc_dbg_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_dbg_elem *dbg_elem; + u32 i; + + ipc_env->dbg_host_idx = 0; + + /* Initialize the dbg buffers in the global IPC array. */ + for (i = 0, dbg_elem = cl_hw->dbg_elems; + i < IPC_DBG_BUF_CNT; dbg_elem++, i++) { + dbg_elem->dbgbuf_ptr->pattern = 0; + cl_ipc_dbgbuf_push(ipc_env, (ptrdiff_t)dbg_elem, dbg_elem->dma_addr); + } +} + +static void cl_ipc_cfm_reset(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + ipc_env->cfm_used_idx = 0; + memset(ipc_env->cfm_virt_base_addr, 0, IPC_CFM_SIZE); +} + +static void cl_ipc_dbg_info_reset(struct cl_hw *cl_hw) +{ + struct dbg_info *buf = cl_hw->dbginfo.buf; + struct cl_chip *chip = cl_hw->chip; + u32 len = sizeof(struct dbg_info); + + if (!chip->conf->ci_la_mirror_en) + len -= sizeof_field(struct dbg_dump_info, la_mem); + + memset(buf, 0, len); + buf->u.type = DBG_INFO_UNSET; + + cl_ipc_dbginfobuf_push(cl_hw->ipc_env, cl_hw->dbginfo.dma_addr); +} + +static void cl_ipc_elems_reset(struct cl_hw *cl_hw) +{ + cl_ipc_ring_indices_reset(cl_hw); + cl_ipc_txdesc_reset(cl_hw); + cl_ipc_rx_reset(cl_hw); + cl_ipc_msg_reset(cl_hw); + cl_ipc_radar_reset(cl_hw); + cl_ipc_dbg_reset(cl_hw); + cl_ipc_cfm_reset(cl_hw); + cl_ipc_dbg_info_reset(cl_hw); + cl_enhanced_tim_reset(cl_hw); +} + +void cl_ipc_recovery(struct cl_hw *cl_hw) +{ + cl_ipc_shared_env_init(cl_hw); + cl_ipc_elems_reset(cl_hw); +} + +void cl_ipc_deinit(struct cl_hw *cl_hw) +{ + cl_ipc_elems_dealloc(cl_hw); + cl_ipc_env_free(cl_hw); +} + +void cl_ipc_stop(struct cl_hw *cl_hw) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + tasklet_kill(&ipc_env->bcn_tasklet); + tasklet_kill(&ipc_env->rxdesc_tasklet); + tasklet_kill(&ipc_env->tx_single_cfm_tasklet); + tasklet_kill(&ipc_env->tx_agg_cfm_tasklet); + tasklet_kill(&ipc_env->msg_tasklet); + tasklet_kill(&ipc_env->dbg_tasklet); +} + +int cl_ipc_rx_elem_alloc(struct cl_hw *cl_hw, struct cl_rx_elem *rx_elem, u32 size) +{ + struct sk_buff *skb; + dma_addr_t dma_addr; + struct hw_rxhdr *rxhdr; + + rx_elem->passed = 0; + + skb = dev_alloc_skb(size); + + if (unlikely(!skb)) { + cl_dbg_verbose(cl_hw, "skb alloc failed (size %u)\n", size); + rx_elem->dma_addr = (dma_addr_t)0; + return -ENOMEM; + } + + rxhdr = (struct hw_rxhdr *)skb->data; + rxhdr->pattern = 0; + + dma_addr = dma_map_single(cl_hw->chip->dev, skb->data, size, DMA_FROM_DEVICE); + + if (unlikely(dma_mapping_error(cl_hw->chip->dev, dma_addr))) { + cl_dbg_verbose(cl_hw, "dma_mapping_error\n"); + kfree_skb(skb); + return -1; + } + + rx_elem->skb = skb; + rx_elem->dma_addr = dma_addr; + + cl_rx_skb_alloc_handler(skb); + + return 0; +} + +void cl_ipc_msgbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf) +{ + /* + * Push a pre-allocated buffer descriptor for MSGs + * This function is only called at Init time since the MSGs will be handled directly + * and buffer can be re-used as soon as the message is handled, no need to re-allocate + * new buffers in the meantime. + */ + struct cl_ipc_shared_env __iomem *shared_env = ipc_env->shared; + u8 e2a_msg_host_idx = ipc_env->e2a_msg_host_idx; + + /* Save the hostid and the hostbuf in global array */ + ipc_env->e2a_msg_hostbuf_array[e2a_msg_host_idx].hostid = hostid; + ipc_env->e2a_msg_hostbuf_array[e2a_msg_host_idx].dma_addr = hostbuf; + + /* Copy the hostbuf (DMA address) in the ipc shared memory */ + iowrite32(hostbuf, (void __iomem *)&shared_env->e2a_msg_hostbuf_addr[e2a_msg_host_idx]); + + /* Increment the array index */ + ipc_env->e2a_msg_host_idx = (e2a_msg_host_idx + 1) % IPC_E2A_MSG_BUF_CNT; +} + +void cl_ipc_rxbuf_push(struct cl_ipc_host_env *ipc_env, struct cl_rx_elem *rx_elem, + u32 rxdesc_read_idx, u32 host_read_idx, enum rx_buf_type type) +{ + /* + * Push a pre-allocated buffer descriptor for Rx packet. + * This function is called to supply the firmware with new empty buffer. + */ + struct cl_ipc_ring_indices *indices = ipc_env->ring_indices_elem->indices; + struct cl_ipc_host_rxbuf *host_rxbuf = &ipc_env->rx_hostbuf_array[type]; + + /* Save the hostid and the hostbuf in global array */ + host_rxbuf->ipc_host_rxdesc_ptr[host_read_idx] = (ptrdiff_t *)rx_elem; + host_rxbuf->dma_payload_addr[host_read_idx] = rx_elem->dma_addr; + + /* Update rxbuff metadata */ + indices->rxdesc_read_idx[type] = cpu_to_le32(rxdesc_read_idx + 1); +} + +void cl_ipc_radarbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf) +{ + /* + * Push a pre-allocated radar event buffer descriptor. + * This function should be called by the host IRQ handler to supply the embedded + * side with new empty buffer. + */ + struct cl_ipc_shared_env __iomem *shared_env = ipc_env->shared; + u8 radar_host_idx = ipc_env->radar_host_idx; + + /* Save the hostid and the hostbuf in global array */ + ipc_env->radar_hostbuf_array[radar_host_idx].hostid = hostid; + ipc_env->radar_hostbuf_array[radar_host_idx].dma_addr = hostbuf; + + /* Copy the hostbuf (DMA address) in the ipc shared memory */ + iowrite32(hostbuf, (void __iomem *)&shared_env->radarbuf_hostbuf[radar_host_idx]); + + /* Increment the array index */ + ipc_env->radar_host_idx = (radar_host_idx + 1) % IPC_RADAR_BUF_CNT; +} + +void cl_ipc_dbgbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf) +{ + /* + * Push a pre-allocated buffer descriptor for Debug messages. + * This function is only called at Init time since the Debug messages will be + * handled directly and buffer can be re-used as soon as the message is handled, + * no need to re-allocate new buffers in the meantime. + */ + struct cl_ipc_shared_env __iomem *shared_env = ipc_env->shared; + u8 dbg_host_idx = ipc_env->dbg_host_idx; + + /* Save the hostid and the hostbuf in global array */ + ipc_env->dbg_hostbuf_array[dbg_host_idx].hostid = hostid; + ipc_env->dbg_hostbuf_array[dbg_host_idx].dma_addr = hostbuf; + + /* Copy the hostbuf (DMA address) in the ipc shared memory */ + iowrite32(hostbuf, (void __iomem *)&shared_env->dbg_hostbuf_addr[dbg_host_idx]); + + /* Increment the array index */ + ipc_env->dbg_host_idx = (dbg_host_idx + 1) % IPC_DBG_BUF_CNT; +} + +void cl_ipc_dbginfobuf_push(struct cl_ipc_host_env *ipc_env, dma_addr_t infobuf) +{ + /*Push the pre-allocated logic analyzer and debug information buffer */ + struct cl_ipc_shared_env __iomem *shared_env = ipc_env->shared; + + /* Copy the hostbuf (DMA address) in the ipc shared memory */ + iowrite32(infobuf, (void __iomem *)&shared_env->dbginfo_addr); + /* Copy the hostbuf size in the ipc shared memory */ + iowrite32(DBG_DUMP_BUFFER_SIZE, (void __iomem *)&shared_env->dbginfo_size); +} + +static void cl_irq_status_rxdesc(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* + * Handle the reception of a Rx Descriptor. + * + * Disable the RX interrupt until rxelement/skb handled + * this would avoid redundant context switch + redundant tasklet scheduling + */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.rxdesc); + + /* Acknowledge the interrupt BEFORE handling the packet */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.rxdesc); + + /* + * If more than 50% of buffer are populated handle them in the interrupt, + * otherwise schedule a tasklet to handle the buffers. + */ + if (cl_rx_process_in_irq(cl_hw)) + cl_rx_pci_desc_handler(cl_hw); + else + tasklet_schedule(&ipc_env->rxdesc_tasklet); +} + +static void cl_irq_status_txcfm(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* + * Disable the TXCFM interrupt bit - will be enabled + * at the end of cl_tx_pci_single_cfm_tasklet() + */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.txcfm); + + /* Acknowledge the TXCFM interrupt */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.txcfm); + + /* Schedule tasklet to handle the TXCFM */ + tasklet_schedule(&ipc_env->tx_single_cfm_tasklet); +} + +static void cl_irq_status_tbtt(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + unsigned long tbtt_diff_msec = jiffies_to_msecs(jiffies - cl_hw->last_tbtt_irq); + + /* Acknowledge the interrupt BEFORE handling the request */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.tbtt); + + cl_hw->last_tbtt_irq = jiffies; + cl_hw->tbtt_cnt++; + + /* + * Send beacon only if radio is on, there is at least one AP interface + * up, we aren't in the middle of recovery, and user didn't disable them. + */ + if (unlikely(!cl_is_tx_allowed(cl_hw))) + return; + + if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_MESH_ONLY) { + tasklet_hi_schedule(&cl_hw->tx_mesh_bcn_task); + return; + } else if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_MESH_AP && cl_hw->mesh_tbtt_div >= 1 && + ((cl_hw->tbtt_cnt % cl_hw->mesh_tbtt_div) == 0)) { + tasklet_hi_schedule(&cl_hw->tx_mesh_bcn_task); + } else if (IS_REAL_PHY(cl_hw->chip) && cl_hw->smallest_beacon_int > 0) { + /* + * More than 2 times the beacon interval passed between beacons - WARNING + * More than 3 times the beacon interval passed between beacons - ERROR + */ + if (tbtt_diff_msec > (cl_hw->smallest_beacon_int * 3)) + cl_dbg_err(cl_hw, "last_tbtt_irq=%lu, curr_time=%lu, diff=%lu\n", + cl_hw->last_tbtt_irq, jiffies, tbtt_diff_msec); + else if (tbtt_diff_msec > (cl_hw->smallest_beacon_int * 2)) + cl_dbg_warn(cl_hw, "last_tbtt_irq=%lu, curr_time=%lu, diff=%lu\n", + cl_hw->last_tbtt_irq, jiffies, tbtt_diff_msec); + } + + tasklet_hi_schedule(&ipc_env->bcn_tasklet); +} + +static void cl_irq_status_msg(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* Acknowledge the interrupt BEFORE handling the request */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.msg); + + /* Schedule tasklet to handle the messages */ + tasklet_schedule(&ipc_env->msg_tasklet); +} + +static u8 cl_radar_handler(struct cl_hw *cl_hw, ptrdiff_t hostid) +{ + struct cl_radar_elem *radar_elem = (struct cl_radar_elem *)hostid; + u8 ret = 0; + struct cl_radar_pulse_array *pulses; + + /* Retrieve the radar pulses structure */ + pulses = (struct cl_radar_pulse_array *)radar_elem->radarbuf_ptr; + + /* Look for pulse count meaning that this hostbuf contains RADAR pulses */ + if (pulses->cnt == 0) { + ret = -1; + goto radar_no_push; + } + + /* Push pulse information to queue and schedule a tasklet to handle it */ + cl_radar_push(cl_hw, radar_elem); + + /* Reset the radar element and re-use it */ + pulses->cnt = 0; + + /* Make sure memory is written before push to HW */ + wmb(); + + /* Push back the buffer to the firmware */ + cl_ipc_radarbuf_push(cl_hw->ipc_env, (ptrdiff_t)radar_elem, radar_elem->dma_addr); + +radar_no_push: + return ret; +} + +static void cl_irq_status_radar(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* + * Firmware has triggered an IT saying that a radar event has been sent to upper layer. + * Then we first need to check the validity of the current msg buf, and the validity + * of the next buffers too, because it is likely that several buffers have been + * filled within the time needed for this irq handling + */ + + /* Disable the RADAR interrupt bit - will be enabled at the end of cl_radar_tasklet() */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.radar); + + /* Acknowledge the RADAR interrupt */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.radar); + + /* Push all new radar pulses to queue */ + while (cl_radar_handler(cl_hw, + ipc_env->radar_hostbuf_array[ipc_env->radar_host_idx].hostid) == 0) + ; + + /* Schedule tasklet to handle the radar pulses */ + cl_radar_tasklet_schedule(cl_hw); +} + +static void cl_irq_status_dbg(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* Disable the DBG interrupt bit - will be enabled at the end of cl_dbgfile_tasklet() */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.dbg); + + /* Acknowledge the DBG interrupt */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.dbg); + + /* Schedule tasklet to handle the debug */ + tasklet_schedule(&ipc_env->dbg_tasklet); +} + +static void cl_irq_status_txdesc_ind(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* + * Disable the TXDESC_IND interrupt bit - + * will be enabled at the end of cl_tx_pci_agg_cfm_tasklet() + */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.txdesc_ind); + + /* Acknowledge the TXDESC_IND interrupt */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.txdesc_ind); + + tasklet_schedule(&ipc_env->tx_agg_cfm_tasklet); + tasklet_schedule(&cl_hw->tx_task); +} + +static void cl_irq_status_sync(struct cl_hw *cl_hw, struct cl_ipc_host_env *ipc_env) +{ + /* Acknowledge the interrupt BEFORE handling the request */ + ipc_xmac_2_host_ack_set(cl_hw->chip, cl_hw->ipc_e2a_irq.sync); + + set_bit(CL_DEV_FW_SYNC, &cl_hw->drv_flags); + wake_up_interruptible(&cl_hw->fw_sync_wq); +} + +void cl_irq_status(struct cl_hw *cl_hw, u32 status) +{ + /* Handle all IPC interrupts on the host side */ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + + if (status & cl_hw->ipc_e2a_irq.rxdesc) + cl_irq_status_rxdesc(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.txcfm) + cl_irq_status_txcfm(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.tbtt) + cl_irq_status_tbtt(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.msg) + cl_irq_status_msg(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.radar) + cl_irq_status_radar(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.dbg) + cl_irq_status_dbg(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.txdesc_ind) + cl_irq_status_txdesc_ind(cl_hw, ipc_env); + + if (status & cl_hw->ipc_e2a_irq.sync) + cl_irq_status_sync(cl_hw, ipc_env); +} + +static void cl_irq_handler(struct cl_chip *chip) +{ + /* Interrupt handler */ + u32 status, statuses = 0; + unsigned long now = jiffies; + struct cl_irq_stats *irq_stats = &chip->irq_stats; + + while ((status = ipc_xmac_2_host_status_get(chip))) { + statuses |= status; + + if (status & IPC_IRQ_L2H_ALL) + cl_irq_status(chip->cl_hw_tcv0, status); + + if (status & IPC_IRQ_S2H_ALL) + cl_irq_status(chip->cl_hw_tcv1, status); + } + + if (statuses & (IPC_IRQ_L2H_RXDESC | IPC_IRQ_S2H_RXDESC)) + irq_stats->last_rx = now; + + if (statuses & (IPC_IRQ_L2H_TXCFM | IPC_IRQ_S2H_TXCFM)) + irq_stats->last_tx = now; + + irq_stats->last_isr = now; + irq_stats->last_isr_statuses = statuses; +} + +static irqreturn_t cl_irq_request_handler(int irq, void *dev_id) +{ + struct cl_chip *chip = (struct cl_chip *)dev_id; + + cl_irq_handler(chip); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_SMP +static void cl_irq_set_affinity(struct cl_chip *chip, struct pci_dev *pci_dev) +{ + s32 irq_smp_affinity = chip->conf->ce_irq_smp_affinity; + + if (irq_smp_affinity != -1) { + struct irq_data *data = irq_get_irq_data(pci_dev->irq); + + if (data) { + static struct cpumask mask; + + cpumask_clear(&mask); + cpumask_set_cpu(irq_smp_affinity, &mask); + + if (data->chip->irq_set_affinity) { + data->chip->irq_set_affinity(data, &mask, false); + pr_debug("irq=%d, affinity=%d\n", pci_dev->irq, irq_smp_affinity); + } + } + } +} +#endif /* CONFIG_SMP */ + +int cl_irq_request(struct cl_chip *chip) +{ + /* + * Allocate host irq line. + * Enable PCIe device interrupts + */ + int ret; + unsigned long flags = IRQF_SHARED; + struct pci_dev *pci_dev = chip->pci_dev; + + ret = request_irq(pci_dev->irq, cl_irq_request_handler, flags, "cl", chip); + + if (ret) { + pr_err("ERROR: could not assign interrupt %d, err=%d\n", pci_dev->irq, ret); + return ret; + } + +#ifdef CONFIG_SMP + cl_irq_set_affinity(chip, pci_dev); +#endif /* CONFIG_SMP */ + + return ret; +} + +void cl_irq_free(struct cl_chip *chip) +{ + struct pci_dev *pci_dev = chip->pci_dev; + /* Disable PCI device interrupt and release irq line */ + free_irq(pci_dev->irq, chip); +} + +void cl_irq_enable(struct cl_hw *cl_hw, u32 value) +{ + /* Enable IPC interrupts */ + ipc_xmac_2_host_enable_set_set(cl_hw->chip, value); +} + +void cl_irq_disable(struct cl_hw *cl_hw, u32 value) +{ + /* Disable IPC interrupts */ + ipc_xmac_2_host_enable_clear_set(cl_hw->chip, value); +} + +static void cl_msg_pci_fw_push(struct cl_hw *cl_hw, void *msg_buf, u16 len) +{ + /* Send a message to the embedded side */ + int i; + u32 *src; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + void __iomem *dst = (void __iomem *)&ipc_env->shared->a2e_msg_buf; + + /* Copy the message into the IPC MSG buffer */ + src = (u32 *)msg_buf; + + /* + * Move the destination pointer forward by one word + * (due to the format of the firmware kernel messages) + */ + dst += sizeof(u32); + + /* Align length of message to 4 */ + len = ALIGN(len, sizeof(u32)); + + /* Copy the message in the IPC queue */ + for (i = 0; i < len; i += sizeof(u32), dst += sizeof(u32)) + iowrite32(*src++, dst); + + /* Trigger the irq to send the message to EMB */ + cl_hw->ipc_host2xmac_trigger_set(cl_hw->chip, IPC_IRQ_A2E_MSG); +} + +int cl_msg_pci_msg_fw_send(struct cl_hw *cl_hw, const void *msg_params, + bool background) +{ + struct cl_fw_msg *msg = container_of((void *)msg_params, struct cl_fw_msg, param); + u16 req_id = le16_to_cpu(msg->msg_id); + u16 cfm_bit = cl_msg_cfm_set_bit(req_id); + int length = sizeof(struct cl_fw_msg) + le16_to_cpu(msg->param_len); + int error = 0; + + if (!cl_hw->fw_active) { + cl_dbg_verbose(cl_hw, "Bypass %s (firmware not loaded)\n", MSG_ID_STR(req_id)); + /* Free the message */ + kfree(msg); + return -EBUSY; + } + + if (test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)) { + cl_dbg_verbose(cl_hw, "Bypass %s (CL_DEV_FW_ERROR is set)\n", MSG_ID_STR(req_id)); + /* Free the message */ + kfree(msg); + return -EBUSY; + } + + if (!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) && + req_id != MM_RESET_REQ && + req_id != MM_START_REQ) { + cl_dbg_verbose(cl_hw, "Bypass %s (CL_DEV_STARTED not set)\n", MSG_ID_STR(req_id)); + /* Free the message */ + kfree(msg); + return -EBUSY; + } + + /* Lock msg tx of the correct msg buffer. */ + error = mutex_lock_interruptible(&cl_hw->msg_tx_mutex); + if (error != 0) { + cl_dbg_verbose(cl_hw, "Bypass %s (mutex error %d)\n", MSG_ID_STR(req_id), error); + /* Free the message */ + kfree(msg); + return error; + } + + cl_hw->msg_background = background; + + CFM_SET_BIT(cfm_bit, &cl_hw->cfm_flags); + + cl_dbg_trace(cl_hw, "%s\n", MSG_ID_STR(req_id)); + + /* Push the message in the IPC */ + cl_msg_pci_fw_push(cl_hw, msg, length); + + /* Free the message */ + kfree(msg); + + return cl_msg_cfm_wait(cl_hw, cfm_bit, req_id); +} + +static DEFINE_PER_CPU(struct tasklet_struct, rx_remote_tasklet_drv[TCV_TOTAL]); + +static void cl_rx_pci_stats_rxm(struct cl_hw *cl_hw, u16 bucket_idx) +{ + if (bucket_idx < IPC_RXBUF_NUM_BUCKETS_RXM) + cl_hw->rx_info.pkt_handle_bucket_rxm[bucket_idx]++; + else + cl_hw->rx_info.pkt_handle_bucket_rxm[IPC_RXBUF_NUM_BUCKETS_RXM - 1]++; +} + +static void cl_rx_pci_stats_fw(struct cl_hw *cl_hw, u16 bucket_idx) +{ + if (bucket_idx < IPC_RXBUF_NUM_BUCKETS_FW) + cl_hw->rx_info.pkt_handle_bucket_fw[bucket_idx]++; + else + cl_hw->rx_info.pkt_handle_bucket_fw[IPC_RXBUF_NUM_BUCKETS_FW - 1]++; +} + +static void cl_rx_pci_stats(struct cl_hw *cl_hw, u16 pkt_cnt, enum rx_buf_type type) +{ + /* Collect stats - fill the bucket stats */ + if (pkt_cnt) { + u16 bucket_idx = pkt_cnt >> IPC_RXBUF_BUCKET_POW_SIZE; + + if (type == CL_RX_BUF_RXM) + cl_rx_pci_stats_rxm(cl_hw, bucket_idx); + else + cl_rx_pci_stats_fw(cl_hw, bucket_idx); + } +} + +static int _cl_rx_pci_start(struct cl_hw *cl_hw, u32 rxdesc_read_idx, u32 host_read_idx, + enum rx_buf_type type) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_host_rxbuf *rx_hostbuf = &ipc_env->rx_hostbuf_array[type]; + struct cl_rx_elem *rxelem = + (struct cl_rx_elem *)rx_hostbuf->ipc_host_rxdesc_ptr[host_read_idx]; + struct sk_buff *skb; + int ret = 0; + dma_addr_t dma_addr; + u32 size = cl_hw->conf->ci_ipc_rxbuf_size[type]; + + cl_hw->rx_info.rx_desc[type]++; + + /* Copy the current skb buffer & dma_addr. */ + skb = rxelem->skb; + dma_addr = rxelem->dma_addr; + + /* Try to populate the rxelem with new skb */ + if (cl_ipc_rx_elem_alloc(cl_hw, rxelem, size)) { + cl_hw->rx_info.elem_alloc_fail++; + /* Restore skb and dma_addr value */ + rxelem->skb = skb; + rxelem->dma_addr = dma_addr; + ret = -ENOMEM; + goto handle_done; + } + + /* Release dma virtual memory early */ + dma_unmap_single(cl_hw->chip->dev, dma_addr, size, DMA_FROM_DEVICE); + + if (!skb) { + cl_hw->rx_info.skb_null++; + cl_rx_skb_error(cl_hw); + cl_dbg_verbose(cl_hw, "skb is NULL\n"); + goto handle_done; + } + + cl_ipc_rxbuf_push(ipc_env, rxelem, rxdesc_read_idx, host_read_idx, type); + + cl_rx_push_queue(cl_hw, skb); + +handle_done: + return ret; +} + +static void cl_rx_pci_start(struct cl_hw *cl_hw, enum rx_buf_type type, u16 rx_buf_cnt) +{ + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_ring_indices *indices = ipc_env->ring_indices_elem->indices; + u16 buf_cnt_mask = rx_buf_cnt - 1; + u16 pkt_cnt = 0; + u32 rxdesc_read_idx = le32_to_cpu(indices->rxdesc_read_idx[type]); + u32 host_read_idx = 0; + u32 rxdesc_write_idx = le32_to_cpu(indices->rxdesc_write_idx[type]); + u32 host_write_idx = 0; + + /* + * Firmware has triggered an interrupt saying that a reception has occurred. + * Iterate over all valid rxdesc pushed by embedded. + * The read index is incremented once the callback function finishes meaning + * a new allocated skb pushed the rxbuff. + * The write index is incremented in direct write by the embedded layer, + * indicating that allocated skb was populated with packet data. + */ + + do { + host_write_idx = rxdesc_write_idx; + + while (ipc_env->host_rxdesc_read_idx[type] != host_write_idx) { + host_read_idx = rxdesc_read_idx & buf_cnt_mask; + + if (_cl_rx_pci_start(cl_hw, rxdesc_read_idx, host_read_idx, type) == 0) { + /* Local application follower of embedded read idx */ + ipc_env->host_rxdesc_read_idx[type]++; + rxdesc_read_idx++; + pkt_cnt++; + } else { + /* + * Replacing old skb with new allocated skb failed + * (should not happen). Postpone the handle of the + * old skb until this function is reschduled again. + */ + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + tasklet_schedule(&ipc_env->rxdesc_tasklet); + goto out; + } + } + + /* Check if firmware pushed new descriptors */ + rxdesc_write_idx = le32_to_cpu(indices->rxdesc_write_idx[type]); + } while (host_write_idx != rxdesc_write_idx); + +out: + cl_rx_pci_stats(cl_hw, pkt_cnt, type); +} + +static void cl_rx_pci_remote_tasklet_handler(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + + cl_rx_remote_cpu_info(cl_hw); + cl_rx_pci_desc_handler(cl_hw); +} + +static call_single_data_t csd_rx_pci_remote_cpu_sched[TCV_TOTAL]; +static void cl_rx_pci_remote_cpu_sched(struct cl_hw *cl_hw) +{ + int cpu = cl_hw->conf->ci_rx_remote_cpu_drv; + struct tasklet_struct *t = csd_rx_pci_remote_cpu_sched[cl_hw->idx].info; + + if (!test_bit(TASKLET_STATE_SCHED, &t->state)) + smp_call_function_single_async(cpu, &csd_rx_pci_remote_cpu_sched[cl_hw->idx]); +} + +void cl_rx_pci_init(struct cl_hw *cl_hw) +{ + s8 cpu = cl_hw->conf->ci_rx_remote_cpu_drv; + + if (cpu >= 0) { + struct tasklet_struct *t = &per_cpu(rx_remote_tasklet_drv[cl_hw->idx], cpu); + + tasklet_init(t, + cl_rx_pci_remote_tasklet_handler, + (unsigned long)cl_hw); + + csd_rx_pci_remote_cpu_sched[cl_hw->idx].func = cl_rx_remote_tasklet_sched; + csd_rx_pci_remote_cpu_sched[cl_hw->idx].info = t; + } +} + +void cl_rx_pci_deinit(struct cl_hw *cl_hw) +{ + s8 cpu = cl_hw->conf->ci_rx_remote_cpu_drv; + + if (cpu >= 0) + tasklet_kill(&per_cpu(rx_remote_tasklet_drv[cl_hw->idx], cpu)); +} + +void cl_rx_pci_desc_handler(struct cl_hw *cl_hw) +{ + /* Handle all RXM rx elements */ + cl_rx_pci_start(cl_hw, CL_RX_BUF_RXM, IPC_RXBUF_CNT_RXM); + /* Handle all FW rx elements */ + cl_rx_pci_start(cl_hw, CL_RX_BUF_FW, IPC_RXBUF_CNT_FW); + + /* Initiate interrupt to embbeded when all rx elements were handled */ + if (!test_bit(CL_DEV_HW_RESTART, &cl_hw->drv_flags)) + cl_hw->ipc_host2xmac_trigger_set(cl_hw->chip, IPC_IRQ_A2E_RXBUF_BACK); + + /* + * Finished handle all valid rx elements, restore the RX interrupt + * to enable handling new populated rx elements + */ + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.rxdesc); +} + +void cl_rx_pci_desc_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + + if (cl_hw->conf->ci_rx_remote_cpu_drv == -1) + cl_rx_pci_desc_handler(cl_hw); + else + cl_rx_pci_remote_cpu_sched(cl_hw); +} + +static void cl_tx_ipc_txdesc_populate(struct cl_hw *cl_hw, struct txdesc *txdesc, + u8 queue_type, u32 ipc_queue_idx) +{ + /* + * 1) Request allocation of txdesc associated with queue type and index from the ipc layer. + * 2) Populate ipc-txdesc with the received txdesc. + * 3) Increase write index - (must be last action since FW fetch WR idx first). + */ + __le32 *write_idx_ptr = NULL; + struct txdesc *ipc_txdesc = NULL; + struct cl_ipc_ring_indices *indices = cl_hw->ipc_env->ring_indices_elem->indices; + struct cl_ipc_txdesc_write_idx *txdesc_write_idx = + (struct cl_ipc_txdesc_write_idx *)&indices->txdesc_write_idx; + u32 write_idx = 0; + u32 masked_write_idx = 0; + + switch (queue_type) { + case QUEUE_TYPE_AGG: + ipc_txdesc = cl_hw->ipc_env->tx_queues.ipc_txdesc_agg[ipc_queue_idx]; + write_idx = le32_to_cpu(txdesc_write_idx->agg[ipc_queue_idx]); + write_idx_ptr = &txdesc_write_idx->agg[ipc_queue_idx]; + masked_write_idx = write_idx & (TXDESC_AGG_Q_SIZE_MAX - 1); + break; + case QUEUE_TYPE_SINGLE: + ipc_txdesc = cl_hw->ipc_env->tx_queues.ipc_txdesc_single[ipc_queue_idx]; + write_idx = le32_to_cpu(txdesc_write_idx->single[ipc_queue_idx]); + write_idx_ptr = &txdesc_write_idx->single[ipc_queue_idx]; + masked_write_idx = write_idx & (IPC_TXDESC_CNT_SINGLE - 1); + break; + case QUEUE_TYPE_BCMC: + ipc_txdesc = cl_hw->ipc_env->tx_queues.ipc_txdesc_bcmc; + write_idx = le32_to_cpu(txdesc_write_idx->bcmc); + write_idx_ptr = &txdesc_write_idx->bcmc; + masked_write_idx = write_idx & (IPC_TXDESC_CNT_BCMC - 1); + break; + default: + cl_dbg_verbose(cl_hw, "undefined queue type %u\n", queue_type); + WARN_ON(true); + } + + ipc_txdesc += masked_write_idx; + + memcpy(ipc_txdesc, txdesc, sizeof(struct txdesc)); + + /* + * Update write pointer only after new txdesc copy is done since FW + * fetch WR pointer first, if not, FW might read and old txdesc since + * WR index indicate txdesc is valid. + */ + *write_idx_ptr = cpu_to_le32(write_idx + 1); +} + +int cl_tx_release_skbs_from_cfm(struct cl_hw *cl_hw, u8 queue_idx, u16 new_ssn) +{ + struct cl_agg_cfm_queue *cfm_queue = NULL; + struct cl_tx_queue *tx_queue = NULL; + int free_space_add = 0; + u16 prev_ssn = 0; + + if (new_ssn == CE_INVALID_SN) + return free_space_add; + + cfm_queue = &cl_hw->agg_cfm_queues[queue_idx]; + tx_queue = cfm_queue->tx_queue; + + /* + * Continue to free skb's until: + * 1. list is empty. + * 2. agg ssn is equal to new ssn received from ssn. + */ + + spin_lock(&cl_hw->tx_lock_cfm_agg); + prev_ssn = cfm_queue->ssn; + while (!list_empty(&cfm_queue->head) && (cfm_queue->ssn != new_ssn)) { + cl_agg_cfm_free_head_skb(cl_hw, cfm_queue, queue_idx); + free_space_add++; + cfm_queue->ssn = ((cfm_queue->ssn + 1) & 0xFFF); + } + + /* Sanity check. test if all skb's marked to be free. */ + if (unlikely(cfm_queue->ssn != new_ssn)) + cl_dbg_err(cl_hw, "ssn diff - queue idx=%u, new ssn=%u, prev ssn=%u, cfm ssn=%u\n", + queue_idx, new_ssn, prev_ssn, cfm_queue->ssn); + + spin_unlock(&cl_hw->tx_lock_cfm_agg); + + if (free_space_add > 0) { + if (tx_queue) { + spin_lock(&cl_hw->tx_lock_agg); + tx_queue->fw_free_space += free_space_add; + tx_queue->total_fw_cfm += free_space_add; + + /* + * If FW used all packets that driver pushed to him, + * clear the enhanced TIM bit. + */ + if (cl_txq_is_fw_empty(tx_queue)) + cl_enhanced_tim_clear_tx_agg(cl_hw, queue_idx, + tx_queue->hw_index, tx_queue->cl_sta, + tx_queue->tid); + spin_unlock(&cl_hw->tx_lock_agg); + } + } + + return free_space_add; +} + +static int cl_tx_pci_agg_cfm_handler(struct cl_hw *cl_hw) +{ + struct cl_ipc_ring_indices *indices = cl_hw->ipc_env->ring_indices_elem->indices; + int total_cfm_handled = 0; + u16 new_ssn; + u8 used_cntr = 0; + u8 ba_queue_idx; + + for (ba_queue_idx = 0; ba_queue_idx < IPC_MAX_BA_SESSIONS; ba_queue_idx++) { + new_ssn = (u16)le32_to_cpu(indices->new_ssn_idx[ba_queue_idx]); + total_cfm_handled += cl_tx_release_skbs_from_cfm(cl_hw, ba_queue_idx, new_ssn); + + /* Optimization - avoid running the for loop IPC_MAX_BA_SESSIONS times */ + used_cntr++; + if (used_cntr == cl_hw->used_agg_queues) + break; + } + + return total_cfm_handled; +} + +void cl_tx_pci_agg_cfm_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + + cl_tx_pci_agg_cfm_handler(cl_hw); + + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.txdesc_ind); +} + +static void cl_tx_pci_single_cfm_handler(struct cl_hw *cl_hw, u32 cfm_status, + u32 dma_addr, u32 single_queue_idx) +{ + struct sk_buff *skb = NULL; + struct ieee80211_tx_info *tx_info = NULL; + struct cl_hw_tx_status *status = (struct cl_hw_tx_status *)&cfm_status; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct cl_tx_queue *tx_queue = NULL; + struct cl_sta *cl_sta = NULL; + u8 hw_queue; + bool is_bcn; + + if (status->is_bcmc) { + spin_lock_bh(&cl_hw->tx_lock_bcmc); + sw_txhdr = cl_bcmc_cfm_find(cl_hw, dma_addr, status->keep_skb); + tx_queue = &cl_hw->tx_queues->bcmc; + } else { + spin_lock_bh(&cl_hw->tx_lock_single); + sw_txhdr = cl_single_cfm_find(cl_hw, single_queue_idx, dma_addr); + tx_queue = &cl_hw->tx_queues->single[single_queue_idx]; + } + + if (!sw_txhdr) { + cl_dbg_trace(cl_hw, "Failed to find CFM for single_queue_idx %u status 0x%x\n", + single_queue_idx, cfm_status); + goto out; + } + + skb = sw_txhdr->skb; + tx_info = IEEE80211_SKB_CB(skb); + hw_queue = sw_txhdr->hw_queue; + is_bcn = sw_txhdr->is_bcn; + + /* + * Used for beacon frames only !! + * if skb was already confirmed we do not need to inc FwFreeSpace counter + */ + if (likely(!status->freespace_inc_skip)) { + tx_queue->total_fw_cfm++; + tx_queue->fw_free_space++; + + /* Clear the TIM element if assoicated IPC queue is empty */ + if (!is_bcn && cl_txq_is_fw_empty(tx_queue)) { + bool no_ps_buffer = + (tx_info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER); + + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, sw_txhdr->sta_idx); + cl_enhanced_tim_clear_tx_single(cl_hw, single_queue_idx, hw_queue, + no_ps_buffer, cl_sta, sw_txhdr->tid); + cl_sta_unlock(cl_hw); + } + } else if (!is_bcn) { + cl_dbg_verbose(cl_hw, "should no be here - is_bcn=%d hw_queue=%d\n", + is_bcn, hw_queue); + } + + /* + * Used for beacon frames only !! + * if this flag is set, it means FW still need this beacon skb, therefore + * we do not free this skb. + */ + if (unlikely(status->keep_skb)) { + if (!is_bcn) + cl_dbg_verbose(cl_hw, "should not be here - is_bcn=%d hw_queue=%d\n", + is_bcn, hw_queue); + goto out; + } + + dma_unmap_single(cl_hw->chip->dev, dma_addr, sw_txhdr->map_len, DMA_TO_DEVICE); + + /* + * If queue is not empty call cl_txq_sched() to + * transfer packets from the queue to firmware + */ + if (!list_empty(&tx_queue->hdrs)) + cl_txq_sched(cl_hw, tx_queue); + + if (status->is_bcmc) + spin_unlock_bh(&cl_hw->tx_lock_bcmc); + else + spin_unlock_bh(&cl_hw->tx_lock_single); + + if (is_bcn) { + struct ieee80211_vif *vif = sw_txhdr->cl_vif->vif; + + if (vif) { + if (vif->csa_active && + ieee80211_beacon_cntdwn_is_complete(vif)) + ieee80211_csa_finish(vif); + } + + consume_skb(skb); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + return; + } + + if (status->frm_successful && !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, sw_txhdr->sta_idx); + + if (cl_sta) { + if (tx_queue->type != QUEUE_TYPE_BCMC && + ieee80211_is_data(sw_txhdr->fc) && + !cl_tx_ctrl_is_eapol(tx_info)) + cl_agg_tx_report_simulate_for_single(cl_hw, cl_sta, status); + + cl_tx_check_start_ba_session(cl_hw, cl_sta->sta, skb); + } + + cl_sta_unlock(cl_hw); + + if (tx_info->ack_frame_id) + ieee80211_tx_status(cl_hw->hw, skb); + else + consume_skb(skb); + + cl_sw_txhdr_free(cl_hw, sw_txhdr); + return; + +out: + if (status->is_bcmc) + spin_unlock_bh(&cl_hw->tx_lock_bcmc); + else + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +void cl_tx_pci_single_cfm_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct cl_ipc_host_env *ipc_env = cl_hw->ipc_env; + struct cl_ipc_cfm_msg *msg = NULL; + + msg = (struct cl_ipc_cfm_msg *)(ipc_env->cfm_virt_base_addr) + + (ipc_env->cfm_used_idx % IPC_CFM_CNT); + + while (msg && msg->dma_addr) { + u32 cfm_used_idx = ipc_env->cfm_used_idx++; + + cl_tx_pci_single_cfm_handler(cl_hw, + le32_to_cpu(msg->status), + le32_to_cpu(msg->dma_addr), + le32_to_cpu(msg->single_queue_idx)); + msg->dma_addr = 0; + iowrite32(cfm_used_idx, (void __iomem *)&ipc_env->shared->cfm_read_pointer); + msg = (struct cl_ipc_cfm_msg *)(ipc_env->cfm_virt_base_addr) + + (ipc_env->cfm_used_idx % IPC_CFM_CNT); + } + + /* Enable the Tx CFM interrupt bit */ + if (!test_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags)) + cl_irq_enable(cl_hw, cl_hw->ipc_e2a_irq.txcfm); +} + +void cl_tx_pci_pkt_fw_send(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + struct cl_tx_queue *tx_queue) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + struct txdesc *txdesc = &sw_txhdr->txdesc; + struct tx_host_info *host_info = &txdesc->host_info; + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + struct cl_vif *cl_vif = sw_txhdr->cl_vif; + u8 hw_queue = sw_txhdr->hw_queue; + u16 a2e_trigger_bit_pos; + u8 tid = sw_txhdr->tid; + u8 queue_type = tx_queue->type; + bool no_ps_buffer = !!(tx_info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER); + u16 ipc_queue_idx = tx_queue->index; + bool is_mgmt = ieee80211_is_mgmt(sw_txhdr->fc); + u8 i = 0; + u8 *cpu_addr = (u8 *)sw_txhdr->skb->data - + ((host_info->host_padding & 1) * 2); + dma_addr_t dma_addr = dma_map_single(cl_hw->chip->dev, cpu_addr, + sw_txhdr->map_len, DMA_TO_DEVICE); + + if (WARN_ON(dma_mapping_error(cl_hw->chip->dev, dma_addr))) { + tx_queue->dump_dma_map_fail++; + + if (queue_type == QUEUE_TYPE_SINGLE) { + if (!is_mgmt) + cl_vif->sequence_number = DEC_SN(cl_vif->sequence_number); + + cl_tx_single_free_skb(cl_hw, sw_txhdr->skb); + } else { + if (queue_type == QUEUE_TYPE_AGG) { + struct cl_baw *baw = &cl_sta->baws[tid]; + + baw->tid_seq = DEC_SN(baw->tid_seq); + } + + dev_kfree_skb_any(sw_txhdr->skb); + } + + cl_sw_txhdr_free(cl_hw, sw_txhdr); + return; + } + + txdesc->umacdesc.packet_addr[0] = cpu_to_le32(dma_addr); + + cl_tx_ipc_txdesc_populate(cl_hw, txdesc, queue_type, ipc_queue_idx); + + /* make sure memory is written before push to HW */ + wmb(); + + /* + * 1) Notify firmware on new buffered traffic by updating the enhanced tim. + * 2) Push sw_txhdr to confirmation list + */ + if (queue_type == QUEUE_TYPE_AGG) { + a2e_trigger_bit_pos = IPC_IRQ_A2E_TXDESC_AGG_MAP(hw_queue); + cl_agg_cfm_add(cl_hw, sw_txhdr, ipc_queue_idx); + cl_enhanced_tim_set_tx_agg(cl_hw, ipc_queue_idx, hw_queue, + no_ps_buffer, cl_sta, tid); + } else if (queue_type == QUEUE_TYPE_SINGLE) { + a2e_trigger_bit_pos = IPC_IRQ_A2E_TXDESC_SINGLE_MAP(hw_queue); + cl_single_cfm_add(cl_hw, sw_txhdr, ipc_queue_idx); + cl_enhanced_tim_set_tx_single(cl_hw, ipc_queue_idx, hw_queue, + no_ps_buffer, cl_sta, tid); + } else { + a2e_trigger_bit_pos = IPC_IRQ_A2E_TXDESC_SINGLE_MAP(hw_queue); + cl_bcmc_cfm_add(cl_hw, sw_txhdr); + } + + if (cl_hw->conf->ci_tx_delay_tstamp_en) + cl_tx_update_hist_tstamp(tx_queue, sw_txhdr->skb, tx_queue->hist_xmit_to_push, + true); + + /* Tx_queue counters */ + tx_queue->fw_free_space--; + tx_queue->total_fw_push_desc++; + tx_queue->total_fw_push_skb += host_info->packet_cnt; + + /* VIF statistics */ + cl_vif->trfc_cntrs[sw_txhdr->ac].tx_packets += host_info->packet_cnt; + + for (i = 0; i < host_info->packet_cnt; i++) + cl_vif->trfc_cntrs[sw_txhdr->ac].tx_bytes += + le16_to_cpu(txdesc->umacdesc.packet_len[i]); + + /* Trigger interrupt to firmware so that it will know that a new descriptor is ready */ + cl_hw->ipc_host2xmac_trigger_set(cl_hw->chip, BIT(a2e_trigger_bit_pos)); +} + +struct cl_pci_db { + u8 device_cntr; + struct pci_dev *dev[CHIP_MAX]; +}; + +static struct cl_pci_db pci_db; + +static void cl_pci_get_celeno_device(void) +{ + /* + * Search the PCI for all Celeno devices. + * If there are two devices sort them in ascending order. + */ + struct pci_dev *dev = NULL; + + while ((dev = pci_get_device(CL_VENDOR_ID, PCI_ANY_ID, dev))) { + pci_db.dev[pci_db.device_cntr] = dev; + pci_db.device_cntr++; + + if (pci_db.device_cntr == CHIP_MAX) { + if (pci_db.dev[CHIP0]->device > pci_db.dev[CHIP1]->device) + swap(pci_db.dev[CHIP0], pci_db.dev[CHIP1]); + + break; + } + } +} + +static u8 cl_pci_chip_idx(struct pci_dev *pci_dev) +{ + if (pci_db.device_cntr == 0) + cl_pci_get_celeno_device(); + + if (pci_db.device_cntr == 1) + return CHIP0; + + return (pci_db.dev[CHIP0] == pci_dev) ? CHIP0 : CHIP1; +} + +static const struct cl_driver_ops drv_ops = { + .msg_fw_send = cl_msg_pci_msg_fw_send, + .pkt_fw_send = cl_tx_pci_pkt_fw_send, +}; + +static int cl_pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) +{ + u16 pci_cmd; + int ret; + u8 step_id; + u8 chip_idx = cl_pci_chip_idx(pci_dev); + struct cl_chip *chip = cl_chip_alloc(chip_idx); + + if (!chip) { + pr_err("Chip [%u] alloc failed\n", chip_idx); + ret = -ENOMEM; + goto out; + } + + chip->pci_dev = pci_dev; + chip->dev = &pci_dev->dev; + chip->bus_type = CL_BUS_TYPE_PCI; + + ret = cl_chip_config_read(chip); + if (ret) { + cl_chip_dealloc(chip); + return 0; + } + + pci_set_drvdata(pci_dev, chip); + + /* Hotplug fixups */ + pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd); + pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd); + pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2); + + ret = pci_enable_device(pci_dev); + if (ret) { + cl_dbg_chip_err(chip, "pci_enable_device failed\n"); + goto out; + } + + if (!dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) { + cl_dbg_chip_verbose(chip, "Using 32bit DMA\n"); + } else { + cl_dbg_chip_verbose(chip, "No suitable DMA available\n"); + goto out_disable_device; + } + + pci_set_master(pci_dev); + + ret = pci_request_regions(pci_dev, chip->pci_drv.name); + if (ret) { + cl_dbg_chip_verbose(chip, "pci_request_regions failed\n"); + goto out_disable_device; + } + + chip->pci_bar0_virt_addr = pci_ioremap_bar(pci_dev, 0); + if (!chip->pci_bar0_virt_addr) { + cl_dbg_chip_verbose(chip, "pci_ioremap_bar 0 failed\n"); + ret = -ENOMEM; + goto out_release_regions; + } + +#ifdef CONFIG_PCI_MSI + if (chip->conf->ci_pci_msi_enable) { + ret = pci_enable_msi(pci_dev); + if (ret) + cl_dbg_chip_err(chip, "pci_enable_msi failed (%d)\n", ret); + } +#endif + + step_id = macsys_gcu_chip_version_step_id_getf(chip); + if (step_id != 0xB) { + cl_dbg_chip_err(chip, "Invalid Step ID: 0x%X\n", step_id); + ret = -EOPNOTSUPP; + goto out_release_regions; + } + + ret = cl_chip_init(chip); + if (ret) + goto out_chip_deinit; + + ret = cl_main_init(chip, &drv_ops); + if (ret) + goto out_chip_deinit; + + if (cl_ela_init(chip)) + cl_dbg_chip_info(chip, "Non-critical: cl_ela_init failed\n"); + + return 0; + +out_chip_deinit: + cl_chip_deinit(chip); +#ifdef CONFIG_PCI_MSI + if (chip->conf->ci_pci_msi_enable) + pci_disable_msi(pci_dev); +#endif + iounmap(chip->pci_bar0_virt_addr); +out_release_regions: + pci_release_regions(pci_dev); +out_disable_device: + pci_disable_device(pci_dev); +out: + + return ret; +} + +static void cl_pci_remove(struct pci_dev *pci_dev) +{ + struct cl_chip *chip = pci_get_drvdata(pci_dev); + + if (!chip) { + pr_err("%s: failed to find chip\n", __func__); + return; + } + + cl_ela_deinit(chip); + + cl_main_deinit(chip); + + cl_chip_deinit(chip); + +#ifdef CONFIG_PCI_MSI + if (chip->conf->ci_pci_msi_enable) { + pci_disable_msi(pci_dev); + pr_debug("pci_disable_msi\n"); + } +#endif + + iounmap(chip->pci_bar0_virt_addr); + cl_chip_dealloc(chip); + pci_release_regions(pci_dev); + pci_disable_device(pci_dev); +} + +static const struct pci_device_id cl_pci_id_table[] = { + { PCI_DEVICE(CL_VENDOR_ID, 0x8000) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8001) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8040) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8060) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8080) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8046) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8066) }, + { PCI_DEVICE(CL_VENDOR_ID, 0x8086) }, + { }, +}; + +static struct pci_driver cl_pci_driver = { + .name = "cl_pci", + .id_table = cl_pci_id_table, + .probe = cl_pci_probe, + .remove = cl_pci_remove, +}; + +static int cl_pci_init(void) +{ + int ret; + + ret = pci_register_driver(&cl_pci_driver); + if (ret) + pr_err("failed to register cl pci driver: %d\n", ret); + + return ret; +} +module_init(cl_pci_init); + +static void cl_pci_exit(void) +{ + pci_unregister_driver(&cl_pci_driver); +} +module_exit(cl_pci_exit); From patchwork Tue May 24 11:34:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575971 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 B20A4C433EF for ; Tue, 24 May 2022 11:39:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236842AbiEXLjW (ORCPT ); Tue, 24 May 2022 07:39:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41708 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236484AbiEXLjV (ORCPT ); Tue, 24 May 2022 07:39:21 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50045.outbound.protection.outlook.com [40.107.5.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81D758D6AA for ; Tue, 24 May 2022 04:39:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IldXWNZLxYKBUWCD7Iht9R4/YAAAyk8bTsrGGMd+fv1w66uDD6hz4IItEFCZTr/wmBQNQYUYGqwyNQWcyDZdrB7F3Ui1yzWDFt1DAA/ROrDUoSLolEuxTtCoDVcYLfq1437A7TvPH2MIlZzMdgUf2hznWrcP0NHPYfuvRKJZjMSy4OgCTvhoFTsrUgR01HzuKfnPWq/z0fIDlslm60ix8gYkvgb52iQIS6ETL/1Cox1XdY1cxyx6eTaqwb9mohXzncXBmTvlqk2oVZDxU9sKKmRPctJZ+opK8MvuHGCuhJpCQavqbkUjlQ6TF41aWXF3o/dGhrlLYdINe8CA9Hq41g== 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=TUNOsgahF0ygfpFr46DzooupHPF69b3OG2NWm7Y0k/M=; b=gB3s9lgmuhHJc1wxRs5PN2DFj4cZeH/KCullyP/5KDUP8tA+nrkk3iLgL06epvhV+Zfcq8NbtjSv/S73nzgGPa/fgxjomPZ+BgDoYI9ozO/Pr+6SNqsmPznC2InTNQhCKpJ39QsF5HEcicfEwKqzUQJetOZKlm4lIQt52Mep+e32nz8u+JybBRDPWbgO5u6RVGEQ9gquRs24u7HS3fpyRUgB3zcsMN7k3soCzbvp73QIPHasaHhQPHcz70LcBMgm/8FNQqQDlqcfOeC7ocRDaCX0M60N/EsP9nky8lHFmmM3JsQhEA9DQ05t2m8KPGJpOy51GDDa1hGzATjfjyr1yw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=TUNOsgahF0ygfpFr46DzooupHPF69b3OG2NWm7Y0k/M=; b=nU8OHuoFCiXIUtmzWcyAqveFhQYbUwux7sqCx3P+T8+srpL/tytVzqgxqQPHucEMCYH71NqMV5M/A6FDxV3HA1au7xEHWkZciAcCP3l6+Cevt4RD6XictwobrvOUNljApsxcZLbJVbPJX5uxj/Ljb2teFlxBbji+VRrK9BSDqXM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:47 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:47 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 49/96] cl8k: add pci.h Date: Tue, 24 May 2022 14:34:15 +0300 Message-Id: <20220524113502.1094459-50-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 013455a5-ee21-4fdd-2191-08da3d79eb54 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: nq2IcfymgyNE+vZ4JDj/iWGok4iBX7LFC8RyxmspRpSjOCEV2D3VoXPYrvzZW+8JhntyJ9hTkkXHLxqtwkoYmYzn00iRg/AUsBkg/Hx0qIFuW6kNq24bB48OuH6AX9AdhkQzyrXyi49Fmr+00W3N2nby/hWLRpMa+/ci78SfkV7uZtFlcsnXX/rvxShiiicaWxCJRFHkU6VngQgBol3xhTivrwiZSy3rF03RU2Bjw7IUAOVTibIeDwd1aslOAUaAadMacC0kKVq6KZ7FodIGoqvcE30WoMWdcrbiC+8HPVd0z78O3Mck9zdznfh0bq/mAnzGA+YEg1YLs9dqgDnZ2Gz3X7Fx/EVY4C8eCrzy46uxEoFk9+95omdRBd1sqgb+fhWGF/cBxc4gLz7NhpvM5riYz+oDZBZ3Ses5E2zpLCU/fpdaaz5WcMPRaM8cwHqhdYAEYp9nrSX1M7+FmwKCuag+RVWl+2DoGAbn5PMUQHfURrc9yFCKe+pudLziRYT3cMuhPjyx94l+hGXEv1M8gWB0e8eMKo6mHeuIKfvrMwI7ZKxMiUKy01zNGfBxqzMALuqo0WyMi7pASMMxzghlPRiwez99O8Iz+wXKW3N8f62VHoH3WPnC0E8CSTa4ksDajAGkjNdy26GEI1/xzbFsftXpuzcivv7To3QY3CB1zcv8z3yv7KbY40jEiPvWAxeeNaIcLzLKruy6s0Gl5jyQETlUItpP2w/SaYQnHkj3e/w= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: IDWPJ0XE5HMwnCuenIxG3e6v6533suDzokySeds8LhmMAHZDlXc6TKmd2ufcnTmUKWVSbt8NfTZB4JG2uowiBR0ydNfdtJN+kYa4PomD5rKyBVhKIdWJMD9X5c+r+MatyOjCwXAt2+GeqDMyoEivBX36g2SOIXmrwKmMrsQX44xRNb8l5xC6ty32FYlf6VxLwAOPyQGsKQrcYSHP72etOD49/ccruODrXIXakkKH39+XMBOgSoJS7bVSktuT1o1NuDToX3QLbuoDlocN3Zl0KsbA7LpMez0zn7oAOwlx2xD+6h6YQURy7t7ysjSk8LjtzkyU8fhn/76TXKnweh2rrvovdhee1oogxLox0Z/VF5ariIvKqKJNyLHoWV74T8Rwx2kc2jIUKGqc4E512mtU4i6vO6jK9FQfXIEI/YBFPiJw3UrT9241Pig2hymJpArRL6KZ3gBWf/gU19ciYJJbf/hw960nJ5G2ONEzF5J7MoffOjvvPbaSQ1IWgl+IcrhaPhAcZefGYMgb7OVsx/zXE+xDS9je1nxusjDXbCJyWol7v09afyeq9u96Ac2g8pL+KrY+St0zn7TxVbb/SZbgtytt+lrOFGAuL5iTgppYOpXWhFTfWB4clT7LqkFyp6oA2DD8/no0Peerr9RQ68WhT6hnsXEQOZCnoUv2xWTjRvSC4SDIjvjGy3vStSYK5pgB8Va98epI7y/5j5BqmlpLBUlr5kiNsOB0/6iFp9RLCyTq0WTVo6HtSLybW376rWBHp53QP/ZRdwJ5zwNTR+9iFjgxGV1/EgFRqrS6tdyaTyvwDpjRfNUJyiOHlKUQyt3ycb8svb9sohmPjpUkvHEk+fQVjt8Q/50/QXdbmGUeNzKHp31aRmDLcGtmeAaprc8mVa6ZSSe00uLuXXsV02VH6zergN7imf9YpCQwP2D008Bbnni5KsNecvTvkyACkn0+JT+369F62KDOhA4Ni+t8SBdusIq0YyfmxD9wVvOmUyZGNeHLKYOWXtOefItORyDuFbeO9p6s6lJC+F90nZvrU5AmnIw5FUNaIN7yKEumW12/nv1yWNJwcEGJQaG27Hx0PvzaHOS55T2N+nVNkPS1+rcz+gYD742xD+wkos+g5oUqbp/eLTNMtqY9Sn6NTa4j0eXbDVKBQdPVv1XT0vlOgOilNOoXLW6fdpirrAo8AJJvxdHlLny9lrhs0gcZcV71xLoJC1vwBiH1tZP+9sv1d1lQ8vylvKTZcSL5BsV9m6EgCDK2ma3b/wg0AfIdLdnYqI+z13mfKluejG/Wu415nZW8TPP3lzvTQ+ZH5JJSdgEp1mAoEVz+UT5IggOZH5Xv43Jzle6dYJ3uJmhGiLC7zvjv9IUklSlYhi+9qK8bw+s/EgV+CngPoBvnnpQXwygmt1vteVhiEJr6z13t8z9jFkUtzNB8barOcInnudKiPT5pYuWFbIiAR190rytLGX1+U5+N1cdRDIXCe+NdMJEc3g7pGFS474Osc02tSNQoFgkzoIGQcCRdHtbolHK3tKzJWW5KdRw26vf425Oe8sdLqsGckqu8AnYrhgFW466NiLKl72FMFKUZSyDt/RudLqUQBlhTa7H4E2nTgWm71YjDPwmtzaOBjgKl3ApUH3wFwsErVo0U0w/HAXfWaql5uScUI1xF83FJ4NaY7kqtDD7CJqoOTpHh9qkUPo0vpQ2Cr2gbnreLal+hs46pw6kD5ckjPtmzHA3S6jMuoVxoSWRKDgbcs1OVH+04XEYNgGhUDjk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 013455a5-ee21-4fdd-2191-08da3d79eb54 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:27.6249 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0QJe7EmaVozbCke14cycxubnYMy2LmBBJfD2pEd+HbFoCJq5KcpDtgk5skYl5KPr9Qe6WJkcvujalIcDMa5MTQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/pci.h | 194 +++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/pci.h diff --git a/drivers/net/wireless/celeno/cl8k/pci.h b/drivers/net/wireless/celeno/cl8k/pci.h new file mode 100644 index 000000000000..ec6801c7c71b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/pci.h @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_PCI_H +#define CL_PCI_H + +#include "tx.h" + +#define CE_INVALID_SN 0xFFFF + +struct cl_chip; + +enum cl_bus_type { + CL_BUS_TYPE_PCI, +}; + +struct cl_driver_ops { + int (*msg_fw_send)(struct cl_hw *cl_hw, const void *msg_params, bool background); + void (*pkt_fw_send)(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + struct cl_tx_queue *tx_queue); +}; + +/* Struct used to store information about host buffers (DMA Address and local pointer) */ +struct cl_ipc_hostbuf { + ptrdiff_t hostid; /* Ptr to hostbuf client (ipc_host client) structure */ + dma_addr_t dma_addr; /* Ptr to real hostbuf dma address */ +}; + +/* + * Index in txdesc - updated by host on every push, used by firmware side + * Keep this structure aligned to 4-byte + */ +struct cl_ipc_txdesc_write_idx { + __le32 agg[IPC_MAX_BA_SESSIONS]; + __le32 single[MAX_SINGLE_QUEUES]; + __le32 bcmc; +}; + +struct cl_ipc_ring_indices { + /* Last copy of ipc txdesc write desc right after DMA push operation */ + volatile struct cl_ipc_txdesc_write_idx txdesc_write_idx; + /* + * new start sn - equal to last acknowledged sequence number + 1. + * Updated by firmware and used by host. + */ + volatile __le32 new_ssn_idx[IPC_MAX_BA_SESSIONS]; + volatile __le32 dtim_count[MAX_BSS_NUM]; + /* Index in rxdesc array, updated by firmware on every payload push, used by host */ + volatile __le32 rxdesc_write_idx[CL_RX_BUF_MAX]; + /* Index in rxdesc array, updated by host on rxdesc copy completion, used by firmware */ + volatile __le32 rxdesc_read_idx[CL_RX_BUF_MAX]; + /* BSR data counters */ + volatile __le32 bsr_data_ctrs[TID_MAX]; +}; + +/* Structure used to store Shared Txring indices */ +struct cl_ipc_ring_indices_elem { + struct cl_ipc_ring_indices *indices; + dma_addr_t dma_addr; +}; + +struct cl_ipc_host_rxbuf { + /* Array of drv desc which holds the skb and additional data */ + ptrdiff_t **ipc_host_rxdesc_ptr; + /* Address of payload for embedded push operation (part of rxdesc data) */ + u32 *dma_payload_addr; + /* Dma pointer to array of DMA payload addresses */ + __le32 dma_payload_base_addr; +}; + +/* + * struct tx_queues_dma_addr - ipc layer queues addresses casted to DMA addresses + * + * The ipc layer points to array of txdesc, there are: + * 'IPC_MAX_BA_SESSIONS' arrays for aggregation queues + * 'MAX_SINGLE_QUEUES' arrayes for singletons queues + * '1' arrays for broadcast/unicast queue + * + * Each one of this arrays should be copied compeletly to the FW, therefore we should + * cast all of the arrays to dma addresses. + */ +struct tx_queues_dma_addr { + __le32 agg[IPC_MAX_BA_SESSIONS]; + __le32 single[MAX_SINGLE_QUEUES]; + __le32 bcmc; +}; + +/* struct cl_ipc_tx_queues - ipc layer tx queues */ +struct cl_ipc_tx_queues { + struct txdesc *ipc_txdesc_agg[IPC_MAX_BA_SESSIONS]; + struct txdesc *ipc_txdesc_single[MAX_SINGLE_QUEUES]; + struct txdesc *ipc_txdesc_bcmc; + /* Mapping of the TXQ's addresses to DMA addresses */ + struct tx_queues_dma_addr *queues_dma_addr; + /* DMA address of tx_queues_dma_addr */ + u32 dma_addr; +}; + +struct cl_ipc_host_env { + /* Pointer to the shared environment */ + struct cl_ipc_shared_env __iomem *shared; + /* TX ring indices (RD, WR idx & new_ssn) */ + struct cl_ipc_ring_indices_elem *ring_indices_elem; + /* RX buffers (rxdesc & dma_addr) */ + ptrdiff_t *ipc_host_rxdesc_rxm[IPC_RXBUF_CNT_RXM]; + ptrdiff_t *ipc_host_rxdesc_fw[IPC_RXBUF_CNT_FW]; + struct cl_ipc_host_rxbuf rx_hostbuf_array[CL_RX_BUF_MAX]; + /* Host last read idx */ + u32 host_rxdesc_read_idx[CL_RX_BUF_MAX]; + /* Fields for Radar events handling */ + struct cl_ipc_hostbuf radar_hostbuf_array[IPC_RADAR_BUF_CNT]; + u8 radar_host_idx; + /* Fields for Emb->App MSGs handling */ + struct cl_ipc_hostbuf e2a_msg_hostbuf_array[IPC_E2A_MSG_BUF_CNT]; + u8 e2a_msg_host_idx; + /* Fields for Debug MSGs handling */ + struct cl_ipc_hostbuf dbg_hostbuf_array[IPC_DBG_BUF_CNT]; + u8 dbg_host_idx; + /* IPC queues */ + struct cl_ipc_tx_queues tx_queues; + struct cl_ipc_enhanced_tim enhanced_tim; + /* Fields for single confirmation handling */ + u8 *cfm_virt_base_addr; + dma_addr_t cfm_dma_base_addr; + /* Index used that points to the first used CFM */ + u32 cfm_used_idx; + /* Tasklets */ + struct tasklet_struct rxdesc_tasklet; + struct tasklet_struct tx_single_cfm_tasklet; + struct tasklet_struct tx_agg_cfm_tasklet; + struct tasklet_struct msg_tasklet; + struct tasklet_struct dbg_tasklet; + struct tasklet_struct bcn_tasklet; +}; + +/* Structure used to store information regarding Debug msg buffers in the driver */ +struct cl_dbg_elem { + struct cl_ipc_dbg_msg *dbgbuf_ptr; + dma_addr_t dma_addr; +}; + +struct cl_debug_info { + struct mutex mutex; + struct dbg_info *buf; + dma_addr_t dma_addr; + int bufsz; + struct timespec64 trigger_tstamp; +}; + +struct cl_rx_elem { + int passed; + struct sk_buff *skb; + dma_addr_t dma_addr; +}; + +int cl_ipc_init(struct cl_hw *cl_hw); +void cl_ipc_recovery(struct cl_hw *cl_hw); +void cl_ipc_deinit(struct cl_hw *cl_hw); +void cl_ipc_stop(struct cl_hw *cl_hw); +int cl_ipc_rx_elem_alloc(struct cl_hw *cl_hw, struct cl_rx_elem *rx_elem, u32 size); +void cl_ipc_msgbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf); +void cl_ipc_rxbuf_push(struct cl_ipc_host_env *ipc_env, struct cl_rx_elem *rx_elem, + u32 rxdesc_read_idx, u32 host_read_idx, enum rx_buf_type type); +void cl_ipc_radarbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf); +void cl_ipc_dbgbuf_push(struct cl_ipc_host_env *ipc_env, ptrdiff_t hostid, dma_addr_t hostbuf); +void cl_ipc_dbginfobuf_push(struct cl_ipc_host_env *ipc_env, dma_addr_t infobuf); + +struct cl_irq_stats { + unsigned long last_rx; + unsigned long last_tx; + unsigned long last_isr; + u32 last_isr_statuses; + u32 count_irq; + u32 ipc_success; +}; + +int cl_irq_request(struct cl_chip *chip); +void cl_irq_free(struct cl_chip *chip); +void cl_irq_status(struct cl_hw *cl_hw, u32 status); +void cl_irq_enable(struct cl_hw *cl_hw, u32 value); +void cl_irq_disable(struct cl_hw *cl_hw, u32 value); +int cl_msg_pci_msg_fw_send(struct cl_hw *cl_hw, const void *msg_params, + bool background); +void cl_rx_pci_init(struct cl_hw *cl_hw); +void cl_rx_pci_deinit(struct cl_hw *cl_hw); +void cl_rx_pci_desc_handler(struct cl_hw *cl_hw); +void cl_rx_pci_desc_tasklet(unsigned long data); +int cl_tx_release_skbs_from_cfm(struct cl_hw *cl_hw, u8 queue_idx, u16 new_ssn); +void cl_tx_pci_single_cfm_tasklet(unsigned long data); +void cl_tx_pci_agg_cfm_tasklet(unsigned long data); +void cl_tx_pci_pkt_fw_send(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + struct cl_tx_queue *tx_queue); + +#endif /* CL_PCI_H */ From patchwork Tue May 24 11:34:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576466 Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E42A4C43219 for ; Tue, 24 May 2022 11:40:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236924AbiEXLk2 (ORCPT ); Tue, 24 May 2022 07:40:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236903AbiEXLkY (ORCPT ); Tue, 24 May 2022 07:40:24 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97B8D8D69B for ; Tue, 24 May 2022 04:40:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=egHt71pOFCE7KfUquA3H3was06BG1oHgMd5t+5o9qlnRb8twrpuWnIN1sRmaz8nczHHbp4+/HqCtePtRmfsvdpsxRaHFAopH7saKyfXSBOv2xoCFqwBTHevai772dJ7vAhj9oyScCtCLdJI4iW9WqeFXkzRyBMSMoHry/oz8qekZPAOMwAyr+e7Og4FQiV1gG+0JNMzwc8tPKs183LBdp+5q30sf1Iv3e5ZaJPpqKeOSmxSDJer40b1b7K3IYSY3P6YuKrdezmwyh0mHs9QrIe9gC4f2TH45GddMm/80ChqVK8gilFO3qEDVkmWbsfFjWs5oYaMW85UPxKkGF5Nk6A== 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=qwUP1zcekZ8m5/SjYCvzSHSJyj+yKYu7jfCO0f58O1Y=; b=DlKm3dna+tyN2fBrOr31szKn2LwwzKy34l7XZKtq+uqccktaGGzYXTDiodH1wzkgog6qkMR4W1C4tH76WDdmJxPGTFalBlJBkdophi7Ig6N81MGO6MV5WDcynJReOp01ScXFBVhg37N/hA01DlQO6E+ilotmPZKLjdjXj15+mJFCdLJzlyy1meUO2DWGO380ZaVEnEfv11iFe31im4cWe2yACi3obsAcyb8HOEx5By9cHG4j468P2IACzluSs7Qn3vGH0jx3BdD4XA38wKlLpnjnolNAMfPEjTSGeKk0nXweczp8Kb1mUs0DSPGWpTOAfSUp9Y6KjfvY+9m7VYGwlg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qwUP1zcekZ8m5/SjYCvzSHSJyj+yKYu7jfCO0f58O1Y=; b=omUHrvBaTELaRcxZUtR//O4hwfjmCCijpmRktzogedkQY93bThM+Bp32xE91/B5MjvzJqjI3adh96tR9Hg4Mf8ErZZ7bbhBqKo29z7zY6k8VB6gUJUCkLhiq/CpX3VkVfWRhDe7ieTNMNp41l+XZ6XfnykwsXbA8qbE6e0D1GEE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:47 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:47 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 50/96] cl8k: add phy.c Date: Tue, 24 May 2022 14:34:16 +0300 Message-Id: <20220524113502.1094459-51-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 5c76894e-c358-4f04-2aa4-08da3d79ebc4 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: dOnk/txhB4s/To/646l8+u81Lkk/FqQXYe+h4bj6z/zQOTNER1BZzLryms/wb/I/aD9Did1xUtuEKA13nqAczpmHmlEbLS75SQd+pnqGBokRbyQTy9cyfSQ6Ds2EK8Oj69Cr8gwLdFK0uBL/Pcs9HraO/cIrUCSEg9gckwQ45I07+7mtKo0JbuxwvBb+1vqKV7uv4aakLaSy8Xub5ltKcmZWP0M/wCJ6KvraLBkEn9CpfaMEV3MZ0OUbXBcMib99oOtJavCOulO6zFBKnUeRls0Id2ajJbyZDUArJojBa+1E9Fw0ci143c0/fWfQrl22bDpw9v9XnF4vwjVQyEDsr6Xze8Wh4eZfozjUfvLBH0UJmCbYtPRXNHAQdxNfCIoqU+Yrz1hpyzIBk1aUm7VyUmZQYPY9m856CHO5HnEup+bPNfnu1loEm77P84mb4PH+xJWBujDejnKyIuvY1lBP29g7HqAjBDHB2nJBZtuL85nDFWW5mJ8NqFKjjPfvQ0hiag2U92FpqHXDLaAwOSdAUWYMAIQwJiKnFHVoP1levtUetsqGA3qPPq1w0Ace7K03CDjeR736ipSZqYm/QnMSSwZH7LAylKXs/rUDImwY6/XAvW0pFnSjDL4P0LhjN+wrqT7N3sOffmeJ9SxvkjJiZKxd3jMQZIWhJ+zx/QxKf5tSQimMHG0L/HH7uzY5dDjPX175SScc14hhlcoOhxOXzyWYgMYeV8YUHgP3jnjtYI8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(66574015)(32563001)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: EBNNZMvCPgCDyzAYr4i75ZEyHj5/pFsf8Ti/IuAwQqO1fxgrB/+URm3bMFXOOqQQEUfFAmawGzPa/TMCyUOIFJbrNe0Q0cnqh0BCJeUMlM9pZGJSf5PsnSFfzpsPUj72H+IsRQSFJzddf4YBf7KkLJhMp8ChFuWdoUyX4DsyZ7fvRqQLVlOoc+7oqQ9w9aZCFr+ULCcM46FLLTtUOQW7cx3BsXmpTW/LRGRshab71dHIMK4Y9LshBZT532NH5qPBZlc/robaPrErM84Swarbm10O/EaWf/OY31H6waLltKgGF2dkfuAweL+2CczMdemtzAuNBGdT61UsIbdQpSXI8bxEWeIaxVEnZsZD58Y3sJ153TM1JZygkrlpaOYdvks3fJHkiJkF/mwuZ8rKbKBb4fJmvi0cHLE2T49+ewA4nQP6toxQTFY331TXvOMatntLerUkiOAM/B2VhMy7y1Bn2noNLRPOjtka++IVzZ3GUdsLP8ZNC8SnN0Rwn2QjDYMUJ6AyqXfAO3ddffyDKGjnU5FVLdQMKXhq7BepZ1fziyA11VsNciGgH3iRKyDWPyVSNgI+9ij62uQ+ZBN33LAmqa2RJNUObY8gP5XjZak/MbvYE72/fv/gd5niEzws2otpUXX7P1aOtNpyY0WshQ04AqiYbzpUHRblludpd4n4x0wnnnIk22pYUKg/wMftQVYAkWAhol93AkKiBaTfkMNG0RQKCx5XrsMEHrHoZI1lv7ewgRe9kIivXwj+pd6ZkrmMfm8iDExUF4fhzVmvpmK7uBAzUDQhDkxhjx7Fbbv25pfq4kcpvmp48u9KMIGEvTFDhi/Hgo0XgKXG63JxGje6/IW3D2/+aIHsOadyDqp3bPQhFhMjHxq+eMO6dWBiGMT2/pv6RY+9wKHRmj5eXLCnOpu0Fka6acQG6fVy98vbODECuj56abSMNim8sN4uUXDCHKyUUlEF20XHFC7jijJm312DcfRtHs0S5Jk2htJFzSGS7moI1XGJ5ZC9tRq1e5hZ2AJuwaUza3aXVIXiRwnh1bW6OWJ84Ir3u+RnWhwTEiTNK67u321lD2accZiwp/hj0MEOIxOAqB/E0YEbPclIyZw1ilnT62i/aqE+GsA6iEdriVeel38I7Krdoey2JptEWRWicUzWsXUKkBVjNMNY3DIH+ooahFDqSZ+WmGK2fZUP9ys40yA7zM9BMDJ/BtNF/O6f0TX7mSsvv11DRwJYbVzAzwJSJkkE0G74Jnvep0x2HIffwrAwbTkPhIdiBiXdCDAGwx72qUWTL5+NdNr5EBSYCyGW65KMuaol33KZJrKJKtDI2pbC5TSS61NOeW2Iqqp2ZlNXUb7YkW8WTuiGaNmb36MmwhW70/IK3zaIifNrAFBVoNwRylNK/aqbzpqkBSxNErjUUy0s/YJGJdre8M1PQOgz4sGKRvDvUYxNzgzkqZ0iZG6G4arOwEzZGD13Ahrg7vK8f4AvPut9+v+ecqBqlcKzYI/wd/EOdqg11t5qFzSFWy+FzJv/cBeB0lNZC3NSHi13qjvVJTuLcU9qk8QEiBFaW8dqg9bNgKcyTFqiUpOo1acBiqpW28sg/BY7kZYy89r51bygSvVuBsNlpp4xBwmZKq9raDbPIYJjxQG5t5pExZah7GhuPd46KncVZJbJ8mTTDCQcjUMKFEYt17HpTysR0mLdGYovvK2B2B8h/edQozbHCkrrFoAsJP3RMrua6SddJuuPgsV5ByomW8x23D5F2sBWmxSslPBLMog= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5c76894e-c358-4f04-2aa4-08da3d79ebc4 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:29.5784 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: YU/C/0sdkqAqyNzrjNufP/DvYedbnUZgniN4pmIw6lv0YuiC4ZqFNGXJIt5tq3KBR1RxBxbzlUM++Q8XVP7K7Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/phy.c | 9648 ++++++++++++++++++++++++ 1 file changed, 9648 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/phy.c diff --git a/drivers/net/wireless/celeno/cl8k/phy.c b/drivers/net/wireless/celeno/cl8k/phy.c new file mode 100644 index 000000000000..dfc7f5a95d3d --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/phy.c @@ -0,0 +1,9648 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "tx.h" +#include "reg/reg_defs.h" +#include "radio.h" +#include "dsp.h" +#include "rfic.h" +#include "e2p.h" +#include "phy.h" + +#define FEM_LUT_EMPTY 0x0 + +const struct common_lut_line athos_lut_6g_40_mhz[ATHOS_LUT_CHAN_6G_MAX] = { + [ATHOS_LUT_CHAN_593000_IDX] = { 23720, 0x0, 0x62, 0x1AAAAB, 0x7B9 }, + [ATHOS_LUT_CHAN_593125_IDX] = { 23725, 0x0, 0x62, 0x1B5555, 0x7B9 }, + [ATHOS_LUT_CHAN_593250_IDX] = { 23730, 0x0, 0x62, 0x1C0000, 0x7BA }, + [ATHOS_LUT_CHAN_593375_IDX] = { 23735, 0x0, 0x62, 0x1CAAAB, 0x7BA }, + [ATHOS_LUT_CHAN_593500_IDX] = { 23740, 0x0, 0x62, 0x1D5555, 0x7BA }, + [ATHOS_LUT_CHAN_593625_IDX] = { 23745, 0x0, 0x62, 0x1E0000, 0x7BB }, + [ATHOS_LUT_CHAN_593750_IDX] = { 23750, 0x0, 0x62, 0x1EAAAB, 0x7BB }, + [ATHOS_LUT_CHAN_593875_IDX] = { 23755, 0x0, 0x62, 0x1F5555, 0x7BC }, + [ATHOS_LUT_CHAN_594000_IDX] = { 23760, 0x0, 0x63, 0x0, 0x7BC }, + [ATHOS_LUT_CHAN_594125_IDX] = { 23765, 0x0, 0x63, 0xAAAB, 0x7BC }, + [ATHOS_LUT_CHAN_594250_IDX] = { 23770, 0x0, 0x63, 0x15555, 0x7BD }, + [ATHOS_LUT_CHAN_594375_IDX] = { 23775, 0x0, 0x63, 0x20000, 0x7BD }, + [ATHOS_LUT_CHAN_594500_IDX] = { 23780, 0x0, 0x63, 0x2AAAB, 0x7BE }, + [ATHOS_LUT_CHAN_594625_IDX] = { 23785, 0x0, 0x63, 0x35555, 0x7BE }, + [ATHOS_LUT_CHAN_594750_IDX] = { 23790, 0x0, 0x63, 0x40000, 0x7BF }, + [ATHOS_LUT_CHAN_594875_IDX] = { 23795, 0x0, 0x63, 0x4AAAB, 0x7BF }, + [ATHOS_LUT_CHAN_595000_IDX] = { 23800, 0x0, 0x63, 0x55555, 0x7BF }, + [ATHOS_LUT_CHAN_595125_IDX] = { 23805, 0x0, 0x63, 0x60000, 0x7C0 }, + [ATHOS_LUT_CHAN_595250_IDX] = { 23810, 0x0, 0x63, 0x6AAAB, 0x7C0 }, + [ATHOS_LUT_CHAN_595375_IDX] = { 23815, 0x0, 0x63, 0x75555, 0x7C1 }, + [ATHOS_LUT_CHAN_595500_IDX] = { 23820, 0x0, 0x63, 0x80000, 0x7C1 }, + [ATHOS_LUT_CHAN_595625_IDX] = { 23825, 0x0, 0x63, 0x8AAAB, 0x7C1 }, + [ATHOS_LUT_CHAN_595750_IDX] = { 23830, 0x0, 0x63, 0x95555, 0x7C2 }, + [ATHOS_LUT_CHAN_595875_IDX] = { 23835, 0x0, 0x63, 0xA0000, 0x7C2 }, + [ATHOS_LUT_CHAN_596000_IDX] = { 23840, 0x0, 0x63, 0xAAAAB, 0x7C3 }, + [ATHOS_LUT_CHAN_596125_IDX] = { 23845, 0x0, 0x63, 0xB5555, 0x7C3 }, + [ATHOS_LUT_CHAN_596250_IDX] = { 23850, 0x0, 0x63, 0xC0000, 0x7C4 }, + [ATHOS_LUT_CHAN_596375_IDX] = { 23855, 0x0, 0x63, 0xCAAAB, 0x7C4 }, + [ATHOS_LUT_CHAN_596500_IDX] = { 23860, 0x0, 0x63, 0xD5555, 0x7C4 }, + [ATHOS_LUT_CHAN_596625_IDX] = { 23865, 0x0, 0x63, 0xE0000, 0x7C5 }, + [ATHOS_LUT_CHAN_596750_IDX] = { 23870, 0x0, 0x63, 0xEAAAB, 0x7C5 }, + [ATHOS_LUT_CHAN_596875_IDX] = { 23875, 0x0, 0x63, 0xF5555, 0x7C6 }, + [ATHOS_LUT_CHAN_597000_IDX] = { 23880, 0x0, 0x63, 0x100000, 0x7C6 }, + [ATHOS_LUT_CHAN_597125_IDX] = { 23885, 0x0, 0x63, 0x10AAAB, 0x7C6 }, + [ATHOS_LUT_CHAN_597250_IDX] = { 23890, 0x0, 0x63, 0x115555, 0x7C7 }, + [ATHOS_LUT_CHAN_597375_IDX] = { 23895, 0x0, 0x63, 0x120000, 0x7C7 }, + [ATHOS_LUT_CHAN_597500_IDX] = { 23900, 0x0, 0x63, 0x12AAAB, 0x7C8 }, + [ATHOS_LUT_CHAN_597625_IDX] = { 23905, 0x0, 0x63, 0x135555, 0x7C8 }, + [ATHOS_LUT_CHAN_597750_IDX] = { 23910, 0x0, 0x63, 0x140000, 0x7C9 }, + [ATHOS_LUT_CHAN_597875_IDX] = { 23915, 0x0, 0x63, 0x14AAAB, 0x7C9 }, + [ATHOS_LUT_CHAN_598000_IDX] = { 23920, 0x0, 0x63, 0x155555, 0x7C9 }, + [ATHOS_LUT_CHAN_598125_IDX] = { 23925, 0x0, 0x63, 0x160000, 0x7CA }, + [ATHOS_LUT_CHAN_598250_IDX] = { 23930, 0x0, 0x63, 0x16AAAB, 0x7CA }, + [ATHOS_LUT_CHAN_598375_IDX] = { 23935, 0x0, 0x63, 0x175555, 0x7CB }, + [ATHOS_LUT_CHAN_598500_IDX] = { 23940, 0x0, 0x63, 0x180000, 0x7CB }, + [ATHOS_LUT_CHAN_598625_IDX] = { 23945, 0x0, 0x63, 0x18AAAB, 0x7CB }, + [ATHOS_LUT_CHAN_598750_IDX] = { 23950, 0x0, 0x63, 0x195555, 0x7CC }, + [ATHOS_LUT_CHAN_598875_IDX] = { 23955, 0x0, 0x63, 0x1A0000, 0x7CC }, + [ATHOS_LUT_CHAN_599000_IDX] = { 23960, 0x0, 0x63, 0x1AAAAB, 0x7CD }, + [ATHOS_LUT_CHAN_599125_IDX] = { 23965, 0x0, 0x63, 0x1B5555, 0x7CD }, + [ATHOS_LUT_CHAN_599250_IDX] = { 23970, 0x0, 0x63, 0x1C0000, 0x7CE }, + [ATHOS_LUT_CHAN_599375_IDX] = { 23975, 0x0, 0x63, 0x1CAAAB, 0x7CE }, + [ATHOS_LUT_CHAN_599500_IDX] = { 23980, 0x0, 0x63, 0x1D5555, 0x7CE }, + [ATHOS_LUT_CHAN_599625_IDX] = { 23985, 0x0, 0x63, 0x1E0000, 0x7CF }, + [ATHOS_LUT_CHAN_599750_IDX] = { 23990, 0x0, 0x63, 0x1EAAAB, 0x7CF }, + [ATHOS_LUT_CHAN_599875_IDX] = { 23995, 0x0, 0x63, 0x1F5555, 0x7D0 }, + [ATHOS_LUT_CHAN_600000_IDX] = { 24000, 0x0, 0x64, 0x0, 0x7D0 }, + [ATHOS_LUT_CHAN_600125_IDX] = { 24005, 0x0, 0x64, 0xAAAB, 0x7D0 }, + [ATHOS_LUT_CHAN_600250_IDX] = { 24010, 0x0, 0x64, 0x15555, 0x7D1 }, + [ATHOS_LUT_CHAN_600375_IDX] = { 24015, 0x0, 0x64, 0x20000, 0x7D1 }, + [ATHOS_LUT_CHAN_600500_IDX] = { 24020, 0x0, 0x64, 0x2AAAB, 0x7D2 }, + [ATHOS_LUT_CHAN_600625_IDX] = { 24025, 0x0, 0x64, 0x35555, 0x7D2 }, + [ATHOS_LUT_CHAN_600750_IDX] = { 24030, 0x0, 0x64, 0x40000, 0x7D3 }, + [ATHOS_LUT_CHAN_600875_IDX] = { 24035, 0x0, 0x64, 0x4AAAB, 0x7D3 }, + [ATHOS_LUT_CHAN_601000_IDX] = { 24040, 0x0, 0x64, 0x55555, 0x7D3 }, + [ATHOS_LUT_CHAN_601125_IDX] = { 24045, 0x0, 0x64, 0x60000, 0x7D4 }, + [ATHOS_LUT_CHAN_601250_IDX] = { 24050, 0x0, 0x64, 0x6AAAB, 0x7D4 }, + [ATHOS_LUT_CHAN_601375_IDX] = { 24055, 0x0, 0x64, 0x75555, 0x7D5 }, + [ATHOS_LUT_CHAN_601500_IDX] = { 24060, 0x0, 0x64, 0x80000, 0x7D5 }, + [ATHOS_LUT_CHAN_601625_IDX] = { 24065, 0x0, 0x64, 0x8AAAB, 0x7D5 }, + [ATHOS_LUT_CHAN_601750_IDX] = { 24070, 0x0, 0x64, 0x95555, 0x7D6 }, + [ATHOS_LUT_CHAN_601875_IDX] = { 24075, 0x0, 0x64, 0xA0000, 0x7D6 }, + [ATHOS_LUT_CHAN_602000_IDX] = { 24080, 0x0, 0x64, 0xAAAAB, 0x7D7 }, + [ATHOS_LUT_CHAN_602125_IDX] = { 24085, 0x0, 0x64, 0xB5555, 0x7D7 }, + [ATHOS_LUT_CHAN_602250_IDX] = { 24090, 0x0, 0x64, 0xC0000, 0x7D8 }, + [ATHOS_LUT_CHAN_602375_IDX] = { 24095, 0x0, 0x64, 0xCAAAB, 0x7D8 }, + [ATHOS_LUT_CHAN_602500_IDX] = { 24100, 0x0, 0x64, 0xD5555, 0x7D8 }, + [ATHOS_LUT_CHAN_602625_IDX] = { 24105, 0x0, 0x64, 0xE0000, 0x7D9 }, + [ATHOS_LUT_CHAN_602750_IDX] = { 24110, 0x0, 0x64, 0xEAAAB, 0x7D9 }, + [ATHOS_LUT_CHAN_602875_IDX] = { 24115, 0x0, 0x64, 0xF5555, 0x7DA }, + [ATHOS_LUT_CHAN_603000_IDX] = { 24120, 0x0, 0x64, 0x100000, 0x7DA }, + [ATHOS_LUT_CHAN_603125_IDX] = { 24125, 0x0, 0x64, 0x10AAAB, 0x7DA }, + [ATHOS_LUT_CHAN_603250_IDX] = { 24130, 0x0, 0x64, 0x115555, 0x7DB }, + [ATHOS_LUT_CHAN_603375_IDX] = { 24135, 0x0, 0x64, 0x120000, 0x7DB }, + [ATHOS_LUT_CHAN_603500_IDX] = { 24140, 0x0, 0x64, 0x12AAAB, 0x7DC }, + [ATHOS_LUT_CHAN_603625_IDX] = { 24145, 0x0, 0x64, 0x135555, 0x7DC }, + [ATHOS_LUT_CHAN_603750_IDX] = { 24150, 0x0, 0x64, 0x140000, 0x7DD }, + [ATHOS_LUT_CHAN_603875_IDX] = { 24155, 0x0, 0x64, 0x14AAAB, 0x7DD }, + [ATHOS_LUT_CHAN_604000_IDX] = { 24160, 0x0, 0x64, 0x155555, 0x7DD }, + [ATHOS_LUT_CHAN_604125_IDX] = { 24165, 0x0, 0x64, 0x160000, 0x7DE }, + [ATHOS_LUT_CHAN_604250_IDX] = { 24170, 0x0, 0x64, 0x16AAAB, 0x7DE }, + [ATHOS_LUT_CHAN_604375_IDX] = { 24175, 0x0, 0x64, 0x175555, 0x7DF }, + [ATHOS_LUT_CHAN_604500_IDX] = { 24180, 0x0, 0x64, 0x180000, 0x7DF }, + [ATHOS_LUT_CHAN_604625_IDX] = { 24185, 0x0, 0x64, 0x18AAAB, 0x7DF }, + [ATHOS_LUT_CHAN_604750_IDX] = { 24190, 0x0, 0x64, 0x195555, 0x7E0 }, + [ATHOS_LUT_CHAN_604875_IDX] = { 24195, 0x0, 0x64, 0x1A0000, 0x7E0 }, + [ATHOS_LUT_CHAN_605000_IDX] = { 24200, 0x0, 0x64, 0x1AAAAB, 0x7E1 }, + [ATHOS_LUT_CHAN_605125_IDX] = { 24205, 0x0, 0x64, 0x1B5555, 0x7E1 }, + [ATHOS_LUT_CHAN_605250_IDX] = { 24210, 0x0, 0x64, 0x1C0000, 0x7E2 }, + [ATHOS_LUT_CHAN_605375_IDX] = { 24215, 0x0, 0x64, 0x1CAAAB, 0x7E2 }, + [ATHOS_LUT_CHAN_605500_IDX] = { 24220, 0x0, 0x64, 0x1D5555, 0x7E2 }, + [ATHOS_LUT_CHAN_605625_IDX] = { 24225, 0x0, 0x64, 0x1E0000, 0x7E3 }, + [ATHOS_LUT_CHAN_605750_IDX] = { 24230, 0x0, 0x64, 0x1EAAAB, 0x7E3 }, + [ATHOS_LUT_CHAN_605875_IDX] = { 24235, 0x0, 0x64, 0x1F5555, 0x7E4 }, + [ATHOS_LUT_CHAN_606000_IDX] = { 24240, 0x0, 0x65, 0x0, 0x7E4 }, + [ATHOS_LUT_CHAN_606125_IDX] = { 24245, 0x0, 0x65, 0xAAAB, 0x7E4 }, + [ATHOS_LUT_CHAN_606250_IDX] = { 24250, 0x0, 0x65, 0x15555, 0x7E5 }, + [ATHOS_LUT_CHAN_606375_IDX] = { 24255, 0x0, 0x65, 0x20000, 0x7E5 }, + [ATHOS_LUT_CHAN_606500_IDX] = { 24260, 0x0, 0x65, 0x2AAAB, 0x7E6 }, + [ATHOS_LUT_CHAN_606625_IDX] = { 24265, 0x0, 0x65, 0x35555, 0x7E6 }, + [ATHOS_LUT_CHAN_606750_IDX] = { 24270, 0x0, 0x65, 0x40000, 0x7E7 }, + [ATHOS_LUT_CHAN_606875_IDX] = { 24275, 0x0, 0x65, 0x4AAAB, 0x7E7 }, + [ATHOS_LUT_CHAN_607000_IDX] = { 24280, 0x0, 0x65, 0x55555, 0x7E7 }, + [ATHOS_LUT_CHAN_607125_IDX] = { 24285, 0x0, 0x65, 0x60000, 0x7E8 }, + [ATHOS_LUT_CHAN_607250_IDX] = { 24290, 0x0, 0x65, 0x6AAAB, 0x7E8 }, + [ATHOS_LUT_CHAN_607375_IDX] = { 24295, 0x0, 0x65, 0x75555, 0x7E9 }, + [ATHOS_LUT_CHAN_607500_IDX] = { 24300, 0x0, 0x65, 0x80000, 0x7E9 }, + [ATHOS_LUT_CHAN_607625_IDX] = { 24305, 0x0, 0x65, 0x8AAAB, 0x7E9 }, + [ATHOS_LUT_CHAN_607750_IDX] = { 24310, 0x0, 0x65, 0x95555, 0x7EA }, + [ATHOS_LUT_CHAN_607875_IDX] = { 24315, 0x0, 0x65, 0xA0000, 0x7EA }, + [ATHOS_LUT_CHAN_608000_IDX] = { 24320, 0x0, 0x65, 0xAAAAB, 0x7EB }, + [ATHOS_LUT_CHAN_608125_IDX] = { 24325, 0x0, 0x65, 0xB5555, 0x7EB }, + [ATHOS_LUT_CHAN_608250_IDX] = { 24330, 0x0, 0x65, 0xC0000, 0x7EC }, + [ATHOS_LUT_CHAN_608375_IDX] = { 24335, 0x0, 0x65, 0xCAAAB, 0x7EC }, + [ATHOS_LUT_CHAN_608500_IDX] = { 24340, 0x0, 0x65, 0xD5555, 0x7EC }, + [ATHOS_LUT_CHAN_608625_IDX] = { 24345, 0x0, 0x65, 0xE0000, 0x7ED }, + [ATHOS_LUT_CHAN_608750_IDX] = { 24350, 0x0, 0x65, 0xEAAAB, 0x7ED }, + [ATHOS_LUT_CHAN_608875_IDX] = { 24355, 0x0, 0x65, 0xF5555, 0x7EE }, + [ATHOS_LUT_CHAN_609000_IDX] = { 24360, 0x0, 0x65, 0x100000, 0x7EE }, + [ATHOS_LUT_CHAN_609125_IDX] = { 24365, 0x0, 0x65, 0x10AAAB, 0x7EE }, + [ATHOS_LUT_CHAN_609250_IDX] = { 24370, 0x0, 0x65, 0x115555, 0x7EF }, + [ATHOS_LUT_CHAN_609375_IDX] = { 24375, 0x0, 0x65, 0x120000, 0x7EF }, + [ATHOS_LUT_CHAN_609500_IDX] = { 24380, 0x0, 0x65, 0x12AAAB, 0x7F0 }, + [ATHOS_LUT_CHAN_609625_IDX] = { 24385, 0x0, 0x65, 0x135555, 0x7F0 }, + [ATHOS_LUT_CHAN_609750_IDX] = { 24390, 0x0, 0x65, 0x140000, 0x7F1 }, + [ATHOS_LUT_CHAN_609875_IDX] = { 24395, 0x0, 0x65, 0x14AAAB, 0x7F1 }, + [ATHOS_LUT_CHAN_610000_IDX] = { 24400, 0x1, 0x65, 0x155555, 0x7F1 }, + [ATHOS_LUT_CHAN_610125_IDX] = { 24405, 0x1, 0x65, 0x160000, 0x7F2 }, + [ATHOS_LUT_CHAN_610250_IDX] = { 24410, 0x1, 0x65, 0x16AAAB, 0x7F2 }, + [ATHOS_LUT_CHAN_610375_IDX] = { 24415, 0x1, 0x65, 0x175555, 0x7F3 }, + [ATHOS_LUT_CHAN_610500_IDX] = { 24420, 0x1, 0x65, 0x180000, 0x7F3 }, + [ATHOS_LUT_CHAN_610625_IDX] = { 24425, 0x1, 0x65, 0x18AAAB, 0x7F3 }, + [ATHOS_LUT_CHAN_610750_IDX] = { 24430, 0x1, 0x65, 0x195555, 0x7F4 }, + [ATHOS_LUT_CHAN_610875_IDX] = { 24435, 0x1, 0x65, 0x1A0000, 0x7F4 }, + [ATHOS_LUT_CHAN_611000_IDX] = { 24440, 0x1, 0x65, 0x1AAAAB, 0x7F5 }, + [ATHOS_LUT_CHAN_611125_IDX] = { 24445, 0x1, 0x65, 0x1B5555, 0x7F5 }, + [ATHOS_LUT_CHAN_611250_IDX] = { 24450, 0x1, 0x65, 0x1C0000, 0x7F6 }, + [ATHOS_LUT_CHAN_611375_IDX] = { 24455, 0x1, 0x65, 0x1CAAAB, 0x7F6 }, + [ATHOS_LUT_CHAN_611500_IDX] = { 24460, 0x1, 0x65, 0x1D5555, 0x7F6 }, + [ATHOS_LUT_CHAN_611625_IDX] = { 24465, 0x1, 0x65, 0x1E0000, 0x7F7 }, + [ATHOS_LUT_CHAN_611750_IDX] = { 24470, 0x1, 0x65, 0x1EAAAB, 0x7F7 }, + [ATHOS_LUT_CHAN_611875_IDX] = { 24475, 0x1, 0x65, 0x1F5555, 0x7F8 }, + [ATHOS_LUT_CHAN_612000_IDX] = { 24480, 0x1, 0x66, 0x0, 0x7F8 }, + [ATHOS_LUT_CHAN_612125_IDX] = { 24485, 0x1, 0x66, 0xAAAB, 0x7F8 }, + [ATHOS_LUT_CHAN_612250_IDX] = { 24490, 0x1, 0x66, 0x15555, 0x7F9 }, + [ATHOS_LUT_CHAN_612375_IDX] = { 24495, 0x1, 0x66, 0x20000, 0x7F9 }, + [ATHOS_LUT_CHAN_612500_IDX] = { 24500, 0x1, 0x66, 0x2AAAB, 0x7FA }, + [ATHOS_LUT_CHAN_612625_IDX] = { 24505, 0x1, 0x66, 0x35555, 0x7FA }, + [ATHOS_LUT_CHAN_612750_IDX] = { 24510, 0x1, 0x66, 0x40000, 0x7FB }, + [ATHOS_LUT_CHAN_612875_IDX] = { 24515, 0x1, 0x66, 0x4AAAB, 0x7FB }, + [ATHOS_LUT_CHAN_613000_IDX] = { 24520, 0x1, 0x66, 0x55555, 0x7FB }, + [ATHOS_LUT_CHAN_613125_IDX] = { 24525, 0x1, 0x66, 0x60000, 0x7FC }, + [ATHOS_LUT_CHAN_613250_IDX] = { 24530, 0x1, 0x66, 0x6AAAB, 0x7FC }, + [ATHOS_LUT_CHAN_613375_IDX] = { 24535, 0x1, 0x66, 0x75555, 0x7FD }, + [ATHOS_LUT_CHAN_613500_IDX] = { 24540, 0x1, 0x66, 0x80000, 0x7FD }, + [ATHOS_LUT_CHAN_613625_IDX] = { 24545, 0x1, 0x66, 0x8AAAB, 0x7FD }, + [ATHOS_LUT_CHAN_613750_IDX] = { 24550, 0x1, 0x66, 0x95555, 0x7FE }, + [ATHOS_LUT_CHAN_613875_IDX] = { 24555, 0x1, 0x66, 0xA0000, 0x7FE }, + [ATHOS_LUT_CHAN_614000_IDX] = { 24560, 0x1, 0x66, 0xAAAAB, 0x7FF }, + [ATHOS_LUT_CHAN_614125_IDX] = { 24565, 0x1, 0x66, 0xB5555, 0x7FF }, + [ATHOS_LUT_CHAN_614250_IDX] = { 24570, 0x1, 0x66, 0xC0000, 0x800 }, + [ATHOS_LUT_CHAN_614375_IDX] = { 24575, 0x1, 0x66, 0xCAAAB, 0x800 }, + [ATHOS_LUT_CHAN_614500_IDX] = { 24580, 0x1, 0x66, 0xD5555, 0x800 }, + [ATHOS_LUT_CHAN_614625_IDX] = { 24585, 0x1, 0x66, 0xE0000, 0x801 }, + [ATHOS_LUT_CHAN_614750_IDX] = { 24590, 0x1, 0x66, 0xEAAAB, 0x801 }, + [ATHOS_LUT_CHAN_614875_IDX] = { 24595, 0x1, 0x66, 0xF5555, 0x802 }, + [ATHOS_LUT_CHAN_615000_IDX] = { 24600, 0x1, 0x66, 0x100000, 0x802 }, + [ATHOS_LUT_CHAN_615125_IDX] = { 24605, 0x1, 0x66, 0x10AAAB, 0x802 }, + [ATHOS_LUT_CHAN_615250_IDX] = { 24610, 0x1, 0x66, 0x115555, 0x803 }, + [ATHOS_LUT_CHAN_615375_IDX] = { 24615, 0x1, 0x66, 0x120000, 0x803 }, + [ATHOS_LUT_CHAN_615500_IDX] = { 24620, 0x1, 0x66, 0x12AAAB, 0x804 }, + [ATHOS_LUT_CHAN_615625_IDX] = { 24625, 0x1, 0x66, 0x135555, 0x804 }, + [ATHOS_LUT_CHAN_615750_IDX] = { 24630, 0x1, 0x66, 0x140000, 0x805 }, + [ATHOS_LUT_CHAN_615875_IDX] = { 24635, 0x1, 0x66, 0x14AAAB, 0x805 }, + [ATHOS_LUT_CHAN_616000_IDX] = { 24640, 0x1, 0x66, 0x155555, 0x805 }, + [ATHOS_LUT_CHAN_616125_IDX] = { 24645, 0x1, 0x66, 0x160000, 0x806 }, + [ATHOS_LUT_CHAN_616250_IDX] = { 24650, 0x1, 0x66, 0x16AAAB, 0x806 }, + [ATHOS_LUT_CHAN_616375_IDX] = { 24655, 0x1, 0x66, 0x175555, 0x807 }, + [ATHOS_LUT_CHAN_616500_IDX] = { 24660, 0x1, 0x66, 0x180000, 0x807 }, + [ATHOS_LUT_CHAN_616625_IDX] = { 24665, 0x1, 0x66, 0x18AAAB, 0x807 }, + [ATHOS_LUT_CHAN_616750_IDX] = { 24670, 0x1, 0x66, 0x195555, 0x808 }, + [ATHOS_LUT_CHAN_616875_IDX] = { 24675, 0x1, 0x66, 0x1A0000, 0x808 }, + [ATHOS_LUT_CHAN_617000_IDX] = { 24680, 0x1, 0x66, 0x1AAAAB, 0x809 }, + [ATHOS_LUT_CHAN_617125_IDX] = { 24685, 0x1, 0x66, 0x1B5555, 0x809 }, + [ATHOS_LUT_CHAN_617250_IDX] = { 24690, 0x1, 0x66, 0x1C0000, 0x80A }, + [ATHOS_LUT_CHAN_617375_IDX] = { 24695, 0x1, 0x66, 0x1CAAAB, 0x80A }, + [ATHOS_LUT_CHAN_617500_IDX] = { 24700, 0x1, 0x66, 0x1D5555, 0x80A }, + [ATHOS_LUT_CHAN_617625_IDX] = { 24705, 0x1, 0x66, 0x1E0000, 0x80B }, + [ATHOS_LUT_CHAN_617750_IDX] = { 24710, 0x1, 0x66, 0x1EAAAB, 0x80B }, + [ATHOS_LUT_CHAN_617875_IDX] = { 24715, 0x1, 0x66, 0x1F5555, 0x80C }, + [ATHOS_LUT_CHAN_618000_IDX] = { 24720, 0x1, 0x67, 0x0, 0x80C }, + [ATHOS_LUT_CHAN_618125_IDX] = { 24725, 0x1, 0x67, 0xAAAB, 0x80C }, + [ATHOS_LUT_CHAN_618250_IDX] = { 24730, 0x1, 0x67, 0x15555, 0x80D }, + [ATHOS_LUT_CHAN_618375_IDX] = { 24735, 0x1, 0x67, 0x20000, 0x80D }, + [ATHOS_LUT_CHAN_618500_IDX] = { 24740, 0x1, 0x67, 0x2AAAB, 0x80E }, + [ATHOS_LUT_CHAN_618625_IDX] = { 24745, 0x1, 0x67, 0x35555, 0x80E }, + [ATHOS_LUT_CHAN_618750_IDX] = { 24750, 0x1, 0x67, 0x40000, 0x80F }, + [ATHOS_LUT_CHAN_618875_IDX] = { 24755, 0x1, 0x67, 0x4AAAB, 0x80F }, + [ATHOS_LUT_CHAN_619000_IDX] = { 24760, 0x1, 0x67, 0x55555, 0x80F }, + [ATHOS_LUT_CHAN_619125_IDX] = { 24765, 0x1, 0x67, 0x60000, 0x810 }, + [ATHOS_LUT_CHAN_619250_IDX] = { 24770, 0x1, 0x67, 0x6AAAB, 0x810 }, + [ATHOS_LUT_CHAN_619375_IDX] = { 24775, 0x1, 0x67, 0x75555, 0x811 }, + [ATHOS_LUT_CHAN_619500_IDX] = { 24780, 0x1, 0x67, 0x80000, 0x811 }, + [ATHOS_LUT_CHAN_619625_IDX] = { 24785, 0x1, 0x67, 0x8AAAB, 0x811 }, + [ATHOS_LUT_CHAN_619750_IDX] = { 24790, 0x1, 0x67, 0x95555, 0x812 }, + [ATHOS_LUT_CHAN_619875_IDX] = { 24795, 0x1, 0x67, 0xA0000, 0x812 }, + [ATHOS_LUT_CHAN_620000_IDX] = { 24800, 0x1, 0x67, 0xAAAAB, 0x813 }, + [ATHOS_LUT_CHAN_620125_IDX] = { 24805, 0x1, 0x67, 0xB5555, 0x813 }, + [ATHOS_LUT_CHAN_620250_IDX] = { 24810, 0x1, 0x67, 0xC0000, 0x814 }, + [ATHOS_LUT_CHAN_620375_IDX] = { 24815, 0x1, 0x67, 0xCAAAB, 0x814 }, + [ATHOS_LUT_CHAN_620500_IDX] = { 24820, 0x1, 0x67, 0xD5555, 0x814 }, + [ATHOS_LUT_CHAN_620625_IDX] = { 24825, 0x1, 0x67, 0xE0000, 0x815 }, + [ATHOS_LUT_CHAN_620750_IDX] = { 24830, 0x1, 0x67, 0xEAAAB, 0x815 }, + [ATHOS_LUT_CHAN_620875_IDX] = { 24835, 0x1, 0x67, 0xF5555, 0x816 }, + [ATHOS_LUT_CHAN_621000_IDX] = { 24840, 0x1, 0x67, 0x100000, 0x816 }, + [ATHOS_LUT_CHAN_621125_IDX] = { 24845, 0x1, 0x67, 0x10AAAB, 0x816 }, + [ATHOS_LUT_CHAN_621250_IDX] = { 24850, 0x1, 0x67, 0x115555, 0x817 }, + [ATHOS_LUT_CHAN_621375_IDX] = { 24855, 0x1, 0x67, 0x120000, 0x817 }, + [ATHOS_LUT_CHAN_621500_IDX] = { 24860, 0x1, 0x67, 0x12AAAB, 0x818 }, + [ATHOS_LUT_CHAN_621625_IDX] = { 24865, 0x1, 0x67, 0x135555, 0x818 }, + [ATHOS_LUT_CHAN_621750_IDX] = { 24870, 0x1, 0x67, 0x140000, 0x819 }, + [ATHOS_LUT_CHAN_621875_IDX] = { 24875, 0x1, 0x67, 0x14AAAB, 0x819 }, + [ATHOS_LUT_CHAN_622000_IDX] = { 24880, 0x1, 0x67, 0x155555, 0x819 }, + [ATHOS_LUT_CHAN_622125_IDX] = { 24885, 0x1, 0x67, 0x160000, 0x81A }, + [ATHOS_LUT_CHAN_622250_IDX] = { 24890, 0x1, 0x67, 0x16AAAB, 0x81A }, + [ATHOS_LUT_CHAN_622375_IDX] = { 24895, 0x1, 0x67, 0x175555, 0x81B }, + [ATHOS_LUT_CHAN_622500_IDX] = { 24900, 0x1, 0x67, 0x180000, 0x81B }, + [ATHOS_LUT_CHAN_622625_IDX] = { 24905, 0x1, 0x67, 0x18AAAB, 0x81B }, + [ATHOS_LUT_CHAN_622750_IDX] = { 24910, 0x1, 0x67, 0x195555, 0x81C }, + [ATHOS_LUT_CHAN_622875_IDX] = { 24915, 0x1, 0x67, 0x1A0000, 0x81C }, + [ATHOS_LUT_CHAN_623000_IDX] = { 24920, 0x1, 0x67, 0x1AAAAB, 0x81D }, + [ATHOS_LUT_CHAN_623125_IDX] = { 24925, 0x1, 0x67, 0x1B5555, 0x81D }, + [ATHOS_LUT_CHAN_623250_IDX] = { 24930, 0x1, 0x67, 0x1C0000, 0x81E }, + [ATHOS_LUT_CHAN_623375_IDX] = { 24935, 0x1, 0x67, 0x1CAAAB, 0x81E }, + [ATHOS_LUT_CHAN_623500_IDX] = { 24940, 0x1, 0x67, 0x1D5555, 0x81E }, + [ATHOS_LUT_CHAN_623625_IDX] = { 24945, 0x1, 0x67, 0x1E0000, 0x81F }, + [ATHOS_LUT_CHAN_623750_IDX] = { 24950, 0x1, 0x67, 0x1EAAAB, 0x81F }, + [ATHOS_LUT_CHAN_623875_IDX] = { 24955, 0x1, 0x67, 0x1F5555, 0x820 }, + [ATHOS_LUT_CHAN_624000_IDX] = { 24960, 0x1, 0x68, 0x0, 0x820 }, + [ATHOS_LUT_CHAN_624125_IDX] = { 24965, 0x1, 0x68, 0xAAAB, 0x820 }, + [ATHOS_LUT_CHAN_624250_IDX] = { 24970, 0x1, 0x68, 0x15555, 0x821 }, + [ATHOS_LUT_CHAN_624375_IDX] = { 24975, 0x1, 0x68, 0x20000, 0x821 }, + [ATHOS_LUT_CHAN_624500_IDX] = { 24980, 0x1, 0x68, 0x2AAAB, 0x822 }, + [ATHOS_LUT_CHAN_624625_IDX] = { 24985, 0x1, 0x68, 0x35555, 0x822 }, + [ATHOS_LUT_CHAN_624750_IDX] = { 24990, 0x1, 0x68, 0x40000, 0x823 }, + [ATHOS_LUT_CHAN_624875_IDX] = { 24995, 0x1, 0x68, 0x4AAAB, 0x823 }, + [ATHOS_LUT_CHAN_625000_IDX] = { 25000, 0x1, 0x68, 0x55555, 0x823 }, + [ATHOS_LUT_CHAN_625125_IDX] = { 25005, 0x1, 0x68, 0x60000, 0x824 }, + [ATHOS_LUT_CHAN_625250_IDX] = { 25010, 0x1, 0x68, 0x6AAAB, 0x824 }, + [ATHOS_LUT_CHAN_625375_IDX] = { 25015, 0x1, 0x68, 0x75555, 0x825 }, + [ATHOS_LUT_CHAN_625500_IDX] = { 25020, 0x1, 0x68, 0x80000, 0x825 }, + [ATHOS_LUT_CHAN_625625_IDX] = { 25025, 0x1, 0x68, 0x8AAAB, 0x825 }, + [ATHOS_LUT_CHAN_625750_IDX] = { 25030, 0x1, 0x68, 0x95555, 0x826 }, + [ATHOS_LUT_CHAN_625875_IDX] = { 25035, 0x1, 0x68, 0xA0000, 0x826 }, + [ATHOS_LUT_CHAN_626000_IDX] = { 25040, 0x1, 0x68, 0xAAAAB, 0x827 }, + [ATHOS_LUT_CHAN_626125_IDX] = { 25045, 0x1, 0x68, 0xB5555, 0x827 }, + [ATHOS_LUT_CHAN_626250_IDX] = { 25050, 0x1, 0x68, 0xC0000, 0x828 }, + [ATHOS_LUT_CHAN_626375_IDX] = { 25055, 0x1, 0x68, 0xCAAAB, 0x828 }, + [ATHOS_LUT_CHAN_626500_IDX] = { 25060, 0x1, 0x68, 0xD5555, 0x828 }, + [ATHOS_LUT_CHAN_626625_IDX] = { 25065, 0x1, 0x68, 0xE0000, 0x829 }, + [ATHOS_LUT_CHAN_626750_IDX] = { 25070, 0x1, 0x68, 0xEAAAB, 0x829 }, + [ATHOS_LUT_CHAN_626875_IDX] = { 25075, 0x1, 0x68, 0xF5555, 0x82A }, + [ATHOS_LUT_CHAN_627000_IDX] = { 25080, 0x1, 0x68, 0x100000, 0x82A }, + [ATHOS_LUT_CHAN_627125_IDX] = { 25085, 0x1, 0x68, 0x10AAAB, 0x82A }, + [ATHOS_LUT_CHAN_627250_IDX] = { 25090, 0x1, 0x68, 0x115555, 0x82B }, + [ATHOS_LUT_CHAN_627375_IDX] = { 25095, 0x1, 0x68, 0x120000, 0x82B }, + [ATHOS_LUT_CHAN_627500_IDX] = { 25100, 0x1, 0x68, 0x12AAAB, 0x82C }, + [ATHOS_LUT_CHAN_627625_IDX] = { 25105, 0x1, 0x68, 0x135555, 0x82C }, + [ATHOS_LUT_CHAN_627750_IDX] = { 25110, 0x1, 0x68, 0x140000, 0x82D }, + [ATHOS_LUT_CHAN_627875_IDX] = { 25115, 0x1, 0x68, 0x14AAAB, 0x82D }, + [ATHOS_LUT_CHAN_628000_IDX] = { 25120, 0x1, 0x68, 0x155555, 0x82D }, + [ATHOS_LUT_CHAN_628125_IDX] = { 25125, 0x1, 0x68, 0x160000, 0x82E }, + [ATHOS_LUT_CHAN_628250_IDX] = { 25130, 0x1, 0x68, 0x16AAAB, 0x82E }, + [ATHOS_LUT_CHAN_628375_IDX] = { 25135, 0x1, 0x68, 0x175555, 0x82F }, + [ATHOS_LUT_CHAN_628500_IDX] = { 25140, 0x1, 0x68, 0x180000, 0x82F }, + [ATHOS_LUT_CHAN_628625_IDX] = { 25145, 0x1, 0x68, 0x18AAAB, 0x82F }, + [ATHOS_LUT_CHAN_628750_IDX] = { 25150, 0x1, 0x68, 0x195555, 0x830 }, + [ATHOS_LUT_CHAN_628875_IDX] = { 25155, 0x1, 0x68, 0x1A0000, 0x830 }, + [ATHOS_LUT_CHAN_629000_IDX] = { 25160, 0x1, 0x68, 0x1AAAAB, 0x831 }, + [ATHOS_LUT_CHAN_629125_IDX] = { 25165, 0x1, 0x68, 0x1B5555, 0x831 }, + [ATHOS_LUT_CHAN_629250_IDX] = { 25170, 0x1, 0x68, 0x1C0000, 0x832 }, + [ATHOS_LUT_CHAN_629375_IDX] = { 25175, 0x1, 0x68, 0x1CAAAB, 0x832 }, + [ATHOS_LUT_CHAN_629500_IDX] = { 25180, 0x1, 0x68, 0x1D5555, 0x832 }, + [ATHOS_LUT_CHAN_629625_IDX] = { 25185, 0x1, 0x68, 0x1E0000, 0x833 }, + [ATHOS_LUT_CHAN_629750_IDX] = { 25190, 0x1, 0x68, 0x1EAAAB, 0x833 }, + [ATHOS_LUT_CHAN_629875_IDX] = { 25195, 0x1, 0x68, 0x1F5555, 0x834 }, + [ATHOS_LUT_CHAN_630000_IDX] = { 25200, 0x1, 0x69, 0x0, 0x834 }, + [ATHOS_LUT_CHAN_630125_IDX] = { 25205, 0x1, 0x69, 0xAAAB, 0x834 }, + [ATHOS_LUT_CHAN_630250_IDX] = { 25210, 0x1, 0x69, 0x15555, 0x835 }, + [ATHOS_LUT_CHAN_630375_IDX] = { 25215, 0x1, 0x69, 0x20000, 0x835 }, + [ATHOS_LUT_CHAN_630500_IDX] = { 25220, 0x1, 0x69, 0x2AAAB, 0x836 }, + [ATHOS_LUT_CHAN_630625_IDX] = { 25225, 0x1, 0x69, 0x35555, 0x836 }, + [ATHOS_LUT_CHAN_630750_IDX] = { 25230, 0x1, 0x69, 0x40000, 0x837 }, + [ATHOS_LUT_CHAN_630875_IDX] = { 25235, 0x1, 0x69, 0x4AAAB, 0x837 }, + [ATHOS_LUT_CHAN_631000_IDX] = { 25240, 0x1, 0x69, 0x55555, 0x837 }, + [ATHOS_LUT_CHAN_631125_IDX] = { 25245, 0x1, 0x69, 0x60000, 0x838 }, + [ATHOS_LUT_CHAN_631250_IDX] = { 25250, 0x1, 0x69, 0x6AAAB, 0x838 }, + [ATHOS_LUT_CHAN_631375_IDX] = { 25255, 0x1, 0x69, 0x75555, 0x839 }, + [ATHOS_LUT_CHAN_631500_IDX] = { 25260, 0x1, 0x69, 0x80000, 0x839 }, + [ATHOS_LUT_CHAN_631625_IDX] = { 25265, 0x1, 0x69, 0x8AAAB, 0x839 }, + [ATHOS_LUT_CHAN_631750_IDX] = { 25270, 0x1, 0x69, 0x95555, 0x83A }, + [ATHOS_LUT_CHAN_631875_IDX] = { 25275, 0x1, 0x69, 0xA0000, 0x83A }, + [ATHOS_LUT_CHAN_632000_IDX] = { 25280, 0x1, 0x69, 0xAAAAB, 0x83B }, + [ATHOS_LUT_CHAN_632125_IDX] = { 25285, 0x1, 0x69, 0xB5555, 0x83B }, + [ATHOS_LUT_CHAN_632250_IDX] = { 25290, 0x1, 0x69, 0xC0000, 0x83C }, + [ATHOS_LUT_CHAN_632375_IDX] = { 25295, 0x1, 0x69, 0xCAAAB, 0x83C }, + [ATHOS_LUT_CHAN_632500_IDX] = { 25300, 0x1, 0x69, 0xD5555, 0x83C }, + [ATHOS_LUT_CHAN_632625_IDX] = { 25305, 0x1, 0x69, 0xE0000, 0x83D }, + [ATHOS_LUT_CHAN_632750_IDX] = { 25310, 0x1, 0x69, 0xEAAAB, 0x83D }, + [ATHOS_LUT_CHAN_632875_IDX] = { 25315, 0x1, 0x69, 0xF5555, 0x83E }, + [ATHOS_LUT_CHAN_633000_IDX] = { 25320, 0x1, 0x69, 0x100000, 0x83E }, + [ATHOS_LUT_CHAN_633125_IDX] = { 25325, 0x1, 0x69, 0x10AAAB, 0x83E }, + [ATHOS_LUT_CHAN_633250_IDX] = { 25330, 0x1, 0x69, 0x115555, 0x83F }, + [ATHOS_LUT_CHAN_633375_IDX] = { 25335, 0x1, 0x69, 0x120000, 0x83F }, + [ATHOS_LUT_CHAN_633500_IDX] = { 25340, 0x1, 0x69, 0x12AAAB, 0x840 }, + [ATHOS_LUT_CHAN_633625_IDX] = { 25345, 0x1, 0x69, 0x135555, 0x840 }, + [ATHOS_LUT_CHAN_633750_IDX] = { 25350, 0x1, 0x69, 0x140000, 0x841 }, + [ATHOS_LUT_CHAN_633875_IDX] = { 25355, 0x1, 0x69, 0x14AAAB, 0x841 }, + [ATHOS_LUT_CHAN_634000_IDX] = { 25360, 0x1, 0x69, 0x155555, 0x841 }, + [ATHOS_LUT_CHAN_634125_IDX] = { 25365, 0x1, 0x69, 0x160000, 0x842 }, + [ATHOS_LUT_CHAN_634250_IDX] = { 25370, 0x1, 0x69, 0x16AAAB, 0x842 }, + [ATHOS_LUT_CHAN_634375_IDX] = { 25375, 0x1, 0x69, 0x175555, 0x843 }, + [ATHOS_LUT_CHAN_634500_IDX] = { 25380, 0x1, 0x69, 0x180000, 0x843 }, + [ATHOS_LUT_CHAN_634625_IDX] = { 25385, 0x1, 0x69, 0x18AAAB, 0x843 }, + [ATHOS_LUT_CHAN_634750_IDX] = { 25390, 0x1, 0x69, 0x195555, 0x844 }, + [ATHOS_LUT_CHAN_634875_IDX] = { 25395, 0x1, 0x69, 0x1A0000, 0x844 }, + [ATHOS_LUT_CHAN_635000_IDX] = { 25400, 0x1, 0x69, 0x1AAAAB, 0x845 }, + [ATHOS_LUT_CHAN_635125_IDX] = { 25405, 0x1, 0x69, 0x1B5555, 0x845 }, + [ATHOS_LUT_CHAN_635250_IDX] = { 25410, 0x1, 0x69, 0x1C0000, 0x846 }, + [ATHOS_LUT_CHAN_635375_IDX] = { 25415, 0x1, 0x69, 0x1CAAAB, 0x846 }, + [ATHOS_LUT_CHAN_635500_IDX] = { 25420, 0x1, 0x69, 0x1D5555, 0x846 }, + [ATHOS_LUT_CHAN_635625_IDX] = { 25425, 0x1, 0x69, 0x1E0000, 0x847 }, + [ATHOS_LUT_CHAN_635750_IDX] = { 25430, 0x1, 0x69, 0x1EAAAB, 0x847 }, + [ATHOS_LUT_CHAN_635875_IDX] = { 25435, 0x1, 0x69, 0x1F5555, 0x848 }, + [ATHOS_LUT_CHAN_636000_IDX] = { 25440, 0x1, 0x6A, 0x0, 0x848 }, + [ATHOS_LUT_CHAN_636125_IDX] = { 25445, 0x1, 0x6A, 0xAAAB, 0x848 }, + [ATHOS_LUT_CHAN_636250_IDX] = { 25450, 0x1, 0x6A, 0x15555, 0x849 }, + [ATHOS_LUT_CHAN_636375_IDX] = { 25455, 0x1, 0x6A, 0x20000, 0x849 }, + [ATHOS_LUT_CHAN_636500_IDX] = { 25460, 0x1, 0x6A, 0x2AAAB, 0x84A }, + [ATHOS_LUT_CHAN_636625_IDX] = { 25465, 0x1, 0x6A, 0x35555, 0x84A }, + [ATHOS_LUT_CHAN_636750_IDX] = { 25470, 0x1, 0x6A, 0x40000, 0x84B }, + [ATHOS_LUT_CHAN_636875_IDX] = { 25475, 0x1, 0x6A, 0x4AAAB, 0x84B }, + [ATHOS_LUT_CHAN_637000_IDX] = { 25480, 0x1, 0x6A, 0x55555, 0x84B }, + [ATHOS_LUT_CHAN_637125_IDX] = { 25485, 0x1, 0x6A, 0x60000, 0x84C }, + [ATHOS_LUT_CHAN_637250_IDX] = { 25490, 0x1, 0x6A, 0x6AAAB, 0x84C }, + [ATHOS_LUT_CHAN_637375_IDX] = { 25495, 0x1, 0x6A, 0x75555, 0x84D }, + [ATHOS_LUT_CHAN_637500_IDX] = { 25500, 0x1, 0x6A, 0x80000, 0x84D }, + [ATHOS_LUT_CHAN_637625_IDX] = { 25505, 0x1, 0x6A, 0x8AAAB, 0x84D }, + [ATHOS_LUT_CHAN_637750_IDX] = { 25510, 0x1, 0x6A, 0x95555, 0x84E }, + [ATHOS_LUT_CHAN_637875_IDX] = { 25515, 0x1, 0x6A, 0xA0000, 0x84E }, + [ATHOS_LUT_CHAN_638000_IDX] = { 25520, 0x1, 0x6A, 0xAAAAB, 0x84F }, + [ATHOS_LUT_CHAN_638125_IDX] = { 25525, 0x1, 0x6A, 0xB5555, 0x84F }, + [ATHOS_LUT_CHAN_638250_IDX] = { 25530, 0x1, 0x6A, 0xC0000, 0x850 }, + [ATHOS_LUT_CHAN_638375_IDX] = { 25535, 0x1, 0x6A, 0xCAAAB, 0x850 }, + [ATHOS_LUT_CHAN_638500_IDX] = { 25540, 0x1, 0x6A, 0xD5555, 0x850 }, + [ATHOS_LUT_CHAN_638625_IDX] = { 25545, 0x1, 0x6A, 0xE0000, 0x851 }, + [ATHOS_LUT_CHAN_638750_IDX] = { 25550, 0x1, 0x6A, 0xEAAAB, 0x851 }, + [ATHOS_LUT_CHAN_638875_IDX] = { 25555, 0x1, 0x6A, 0xF5555, 0x852 }, + [ATHOS_LUT_CHAN_639000_IDX] = { 25560, 0x1, 0x6A, 0x100000, 0x852 }, + [ATHOS_LUT_CHAN_639125_IDX] = { 25565, 0x1, 0x6A, 0x10AAAB, 0x852 }, + [ATHOS_LUT_CHAN_639250_IDX] = { 25570, 0x1, 0x6A, 0x115555, 0x853 }, + [ATHOS_LUT_CHAN_639375_IDX] = { 25575, 0x1, 0x6A, 0x120000, 0x853 }, + [ATHOS_LUT_CHAN_639500_IDX] = { 25580, 0x1, 0x6A, 0x12AAAB, 0x854 }, + [ATHOS_LUT_CHAN_639625_IDX] = { 25585, 0x1, 0x6A, 0x135555, 0x854 }, + [ATHOS_LUT_CHAN_639750_IDX] = { 25590, 0x1, 0x6A, 0x140000, 0x855 }, + [ATHOS_LUT_CHAN_639875_IDX] = { 25595, 0x1, 0x6A, 0x14AAAB, 0x855 }, + [ATHOS_LUT_CHAN_640000_IDX] = { 25600, 0x1, 0x6A, 0x155555, 0x855 }, + [ATHOS_LUT_CHAN_640125_IDX] = { 25605, 0x1, 0x6A, 0x160000, 0x856 }, + [ATHOS_LUT_CHAN_640250_IDX] = { 25610, 0x1, 0x6A, 0x16AAAB, 0x856 }, + [ATHOS_LUT_CHAN_640375_IDX] = { 25615, 0x1, 0x6A, 0x175555, 0x857 }, + [ATHOS_LUT_CHAN_640500_IDX] = { 25620, 0x1, 0x6A, 0x180000, 0x857 }, + [ATHOS_LUT_CHAN_640625_IDX] = { 25625, 0x1, 0x6A, 0x18AAAB, 0x857 }, + [ATHOS_LUT_CHAN_640750_IDX] = { 25630, 0x1, 0x6A, 0x195555, 0x858 }, + [ATHOS_LUT_CHAN_640875_IDX] = { 25635, 0x1, 0x6A, 0x1A0000, 0x858 }, + [ATHOS_LUT_CHAN_641000_IDX] = { 25640, 0x1, 0x6A, 0x1AAAAB, 0x859 }, + [ATHOS_LUT_CHAN_641125_IDX] = { 25645, 0x1, 0x6A, 0x1B5555, 0x859 }, + [ATHOS_LUT_CHAN_641250_IDX] = { 25650, 0x1, 0x6A, 0x1C0000, 0x85A }, + [ATHOS_LUT_CHAN_641375_IDX] = { 25655, 0x1, 0x6A, 0x1CAAAB, 0x85A }, + [ATHOS_LUT_CHAN_641500_IDX] = { 25660, 0x1, 0x6A, 0x1D5555, 0x85A }, + [ATHOS_LUT_CHAN_641625_IDX] = { 25665, 0x1, 0x6A, 0x1E0000, 0x85B }, + [ATHOS_LUT_CHAN_641750_IDX] = { 25670, 0x1, 0x6A, 0x1EAAAB, 0x85B }, + [ATHOS_LUT_CHAN_641875_IDX] = { 25675, 0x1, 0x6A, 0x1F5555, 0x85C }, + [ATHOS_LUT_CHAN_642000_IDX] = { 25680, 0x1, 0x6B, 0x0, 0x85C }, + [ATHOS_LUT_CHAN_642125_IDX] = { 25685, 0x1, 0x6B, 0xAAAB, 0x85C }, + [ATHOS_LUT_CHAN_642250_IDX] = { 25690, 0x1, 0x6B, 0x15555, 0x85D }, + [ATHOS_LUT_CHAN_642375_IDX] = { 25695, 0x1, 0x6B, 0x20000, 0x85D }, + [ATHOS_LUT_CHAN_642500_IDX] = { 25700, 0x1, 0x6B, 0x2AAAB, 0x85E }, + [ATHOS_LUT_CHAN_642625_IDX] = { 25705, 0x1, 0x6B, 0x35555, 0x85E }, + [ATHOS_LUT_CHAN_642750_IDX] = { 25710, 0x1, 0x6B, 0x40000, 0x85F }, + [ATHOS_LUT_CHAN_642875_IDX] = { 25715, 0x1, 0x6B, 0x4AAAB, 0x85F }, + [ATHOS_LUT_CHAN_643000_IDX] = { 25720, 0x1, 0x6B, 0x55555, 0x85F }, + [ATHOS_LUT_CHAN_643125_IDX] = { 25725, 0x1, 0x6B, 0x60000, 0x860 }, + [ATHOS_LUT_CHAN_643250_IDX] = { 25730, 0x1, 0x6B, 0x6AAAB, 0x860 }, + [ATHOS_LUT_CHAN_643375_IDX] = { 25735, 0x1, 0x6B, 0x75555, 0x861 }, + [ATHOS_LUT_CHAN_643500_IDX] = { 25740, 0x1, 0x6B, 0x80000, 0x861 }, + [ATHOS_LUT_CHAN_643625_IDX] = { 25745, 0x1, 0x6B, 0x8AAAB, 0x861 }, + [ATHOS_LUT_CHAN_643750_IDX] = { 25750, 0x1, 0x6B, 0x95555, 0x862 }, + [ATHOS_LUT_CHAN_643875_IDX] = { 25755, 0x1, 0x6B, 0xA0000, 0x862 }, + [ATHOS_LUT_CHAN_644000_IDX] = { 25760, 0x1, 0x6B, 0xAAAAB, 0x863 }, + [ATHOS_LUT_CHAN_644125_IDX] = { 25765, 0x1, 0x6B, 0xB5555, 0x863 }, + [ATHOS_LUT_CHAN_644250_IDX] = { 25770, 0x1, 0x6B, 0xC0000, 0x864 }, + [ATHOS_LUT_CHAN_644375_IDX] = { 25775, 0x1, 0x6B, 0xCAAAB, 0x864 }, + [ATHOS_LUT_CHAN_644500_IDX] = { 25780, 0x1, 0x6B, 0xD5555, 0x864 }, + [ATHOS_LUT_CHAN_644625_IDX] = { 25785, 0x1, 0x6B, 0xE0000, 0x865 }, + [ATHOS_LUT_CHAN_644750_IDX] = { 25790, 0x1, 0x6B, 0xEAAAB, 0x865 }, + [ATHOS_LUT_CHAN_644875_IDX] = { 25795, 0x1, 0x6B, 0xF5555, 0x866 }, + [ATHOS_LUT_CHAN_645000_IDX] = { 25800, 0x1, 0x6B, 0x100000, 0x866 }, + [ATHOS_LUT_CHAN_645125_IDX] = { 25805, 0x1, 0x6B, 0x10AAAB, 0x866 }, + [ATHOS_LUT_CHAN_645250_IDX] = { 25810, 0x1, 0x6B, 0x115555, 0x867 }, + [ATHOS_LUT_CHAN_645375_IDX] = { 25815, 0x1, 0x6B, 0x120000, 0x867 }, + [ATHOS_LUT_CHAN_645500_IDX] = { 25820, 0x1, 0x6B, 0x12AAAB, 0x868 }, + [ATHOS_LUT_CHAN_645625_IDX] = { 25825, 0x1, 0x6B, 0x135555, 0x868 }, + [ATHOS_LUT_CHAN_645750_IDX] = { 25830, 0x1, 0x6B, 0x140000, 0x869 }, + [ATHOS_LUT_CHAN_645875_IDX] = { 25835, 0x1, 0x6B, 0x14AAAB, 0x869 }, + [ATHOS_LUT_CHAN_646000_IDX] = { 25840, 0x1, 0x6B, 0x155555, 0x869 }, + [ATHOS_LUT_CHAN_646125_IDX] = { 25845, 0x1, 0x6B, 0x160000, 0x86A }, + [ATHOS_LUT_CHAN_646250_IDX] = { 25850, 0x1, 0x6B, 0x16AAAB, 0x86A }, + [ATHOS_LUT_CHAN_646375_IDX] = { 25855, 0x1, 0x6B, 0x175555, 0x86B }, + [ATHOS_LUT_CHAN_646500_IDX] = { 25860, 0x1, 0x6B, 0x180000, 0x86B }, + [ATHOS_LUT_CHAN_646625_IDX] = { 25865, 0x1, 0x6B, 0x18AAAB, 0x86B }, + [ATHOS_LUT_CHAN_646750_IDX] = { 25870, 0x1, 0x6B, 0x195555, 0x86C }, + [ATHOS_LUT_CHAN_646875_IDX] = { 25875, 0x1, 0x6B, 0x1A0000, 0x86C }, + [ATHOS_LUT_CHAN_647000_IDX] = { 25880, 0x1, 0x6B, 0x1AAAAB, 0x86D }, + [ATHOS_LUT_CHAN_647125_IDX] = { 25885, 0x1, 0x6B, 0x1B5555, 0x86D }, + [ATHOS_LUT_CHAN_647250_IDX] = { 25890, 0x1, 0x6B, 0x1C0000, 0x86E }, + [ATHOS_LUT_CHAN_647375_IDX] = { 25895, 0x1, 0x6B, 0x1CAAAB, 0x86E }, + [ATHOS_LUT_CHAN_647500_IDX] = { 25900, 0x1, 0x6B, 0x1D5555, 0x86E }, + [ATHOS_LUT_CHAN_647625_IDX] = { 25905, 0x1, 0x6B, 0x1E0000, 0x86F }, + [ATHOS_LUT_CHAN_647750_IDX] = { 25910, 0x1, 0x6B, 0x1EAAAB, 0x86F }, + [ATHOS_LUT_CHAN_647875_IDX] = { 25915, 0x1, 0x6B, 0x1F5555, 0x870 }, + [ATHOS_LUT_CHAN_648000_IDX] = { 25920, 0x1, 0x6C, 0x0, 0x870 }, + [ATHOS_LUT_CHAN_648125_IDX] = { 25925, 0x1, 0x6C, 0xAAAB, 0x870 }, + [ATHOS_LUT_CHAN_648250_IDX] = { 25930, 0x1, 0x6C, 0x15555, 0x871 }, + [ATHOS_LUT_CHAN_648375_IDX] = { 25935, 0x1, 0x6C, 0x20000, 0x871 }, + [ATHOS_LUT_CHAN_648500_IDX] = { 25940, 0x1, 0x6C, 0x2AAAB, 0x872 }, + [ATHOS_LUT_CHAN_648625_IDX] = { 25945, 0x1, 0x6C, 0x35555, 0x872 }, + [ATHOS_LUT_CHAN_648750_IDX] = { 25950, 0x1, 0x6C, 0x40000, 0x873 }, + [ATHOS_LUT_CHAN_648875_IDX] = { 25955, 0x1, 0x6C, 0x4AAAB, 0x873 }, + [ATHOS_LUT_CHAN_649000_IDX] = { 25960, 0x1, 0x6C, 0x55555, 0x873 }, + [ATHOS_LUT_CHAN_649125_IDX] = { 25965, 0x1, 0x6C, 0x60000, 0x874 }, + [ATHOS_LUT_CHAN_649250_IDX] = { 25970, 0x1, 0x6C, 0x6AAAB, 0x874 }, + [ATHOS_LUT_CHAN_649375_IDX] = { 25975, 0x1, 0x6C, 0x75555, 0x875 }, + [ATHOS_LUT_CHAN_649500_IDX] = { 25980, 0x1, 0x6C, 0x80000, 0x875 }, + [ATHOS_LUT_CHAN_649625_IDX] = { 25985, 0x1, 0x6C, 0x8AAAB, 0x875 }, + [ATHOS_LUT_CHAN_649750_IDX] = { 25990, 0x1, 0x6C, 0x95555, 0x876 }, + [ATHOS_LUT_CHAN_649875_IDX] = { 25995, 0x1, 0x6C, 0xA0000, 0x876 }, + [ATHOS_LUT_CHAN_650000_IDX] = { 26000, 0x1, 0x6C, 0xAAAAB, 0x877 }, + [ATHOS_LUT_CHAN_650125_IDX] = { 26005, 0x1, 0x6C, 0xB5555, 0x877 }, + [ATHOS_LUT_CHAN_650250_IDX] = { 26010, 0x1, 0x6C, 0xC0000, 0x878 }, + [ATHOS_LUT_CHAN_650375_IDX] = { 26015, 0x1, 0x6C, 0xCAAAB, 0x878 }, + [ATHOS_LUT_CHAN_650500_IDX] = { 26020, 0x1, 0x6C, 0xD5555, 0x878 }, + [ATHOS_LUT_CHAN_650625_IDX] = { 26025, 0x1, 0x6C, 0xE0000, 0x879 }, + [ATHOS_LUT_CHAN_650750_IDX] = { 26030, 0x1, 0x6C, 0xEAAAB, 0x879 }, + [ATHOS_LUT_CHAN_650875_IDX] = { 26035, 0x1, 0x6C, 0xF5555, 0x87A }, + [ATHOS_LUT_CHAN_651000_IDX] = { 26040, 0x1, 0x6C, 0x100000, 0x87A }, + [ATHOS_LUT_CHAN_651125_IDX] = { 26045, 0x1, 0x6C, 0x10AAAB, 0x87A }, + [ATHOS_LUT_CHAN_651250_IDX] = { 26050, 0x1, 0x6C, 0x115555, 0x87B }, + [ATHOS_LUT_CHAN_651375_IDX] = { 26055, 0x1, 0x6C, 0x120000, 0x87B }, + [ATHOS_LUT_CHAN_651500_IDX] = { 26060, 0x1, 0x6C, 0x12AAAB, 0x87C }, + [ATHOS_LUT_CHAN_651625_IDX] = { 26065, 0x1, 0x6C, 0x135555, 0x87C }, + [ATHOS_LUT_CHAN_651750_IDX] = { 26070, 0x1, 0x6C, 0x140000, 0x87D }, + [ATHOS_LUT_CHAN_651875_IDX] = { 26075, 0x1, 0x6C, 0x14AAAB, 0x87D }, + [ATHOS_LUT_CHAN_652000_IDX] = { 26080, 0x1, 0x6C, 0x155555, 0x87D }, + [ATHOS_LUT_CHAN_652125_IDX] = { 26085, 0x1, 0x6C, 0x160000, 0x87E }, + [ATHOS_LUT_CHAN_652250_IDX] = { 26090, 0x1, 0x6C, 0x16AAAB, 0x87E }, + [ATHOS_LUT_CHAN_652375_IDX] = { 26095, 0x1, 0x6C, 0x175555, 0x87F }, + [ATHOS_LUT_CHAN_652500_IDX] = { 26100, 0x1, 0x6C, 0x180000, 0x87F }, + [ATHOS_LUT_CHAN_652625_IDX] = { 26105, 0x1, 0x6C, 0x18AAAB, 0x87F }, + [ATHOS_LUT_CHAN_652750_IDX] = { 26110, 0x1, 0x6C, 0x195555, 0x880 }, + [ATHOS_LUT_CHAN_652875_IDX] = { 26115, 0x1, 0x6C, 0x1A0000, 0x880 }, + [ATHOS_LUT_CHAN_653000_IDX] = { 26120, 0x1, 0x6C, 0x1AAAAB, 0x881 }, + [ATHOS_LUT_CHAN_653125_IDX] = { 26125, 0x1, 0x6C, 0x1B5555, 0x881 }, + [ATHOS_LUT_CHAN_653250_IDX] = { 26130, 0x1, 0x6C, 0x1C0000, 0x882 }, + [ATHOS_LUT_CHAN_653375_IDX] = { 26135, 0x1, 0x6C, 0x1CAAAB, 0x882 }, + [ATHOS_LUT_CHAN_653500_IDX] = { 26140, 0x1, 0x6C, 0x1D5555, 0x882 }, + [ATHOS_LUT_CHAN_653625_IDX] = { 26145, 0x1, 0x6C, 0x1E0000, 0x883 }, + [ATHOS_LUT_CHAN_653750_IDX] = { 26150, 0x1, 0x6C, 0x1EAAAB, 0x883 }, + [ATHOS_LUT_CHAN_653875_IDX] = { 26155, 0x1, 0x6C, 0x1F5555, 0x884 }, + [ATHOS_LUT_CHAN_654000_IDX] = { 26160, 0x1, 0x6D, 0x0, 0x884 }, + [ATHOS_LUT_CHAN_654125_IDX] = { 26165, 0x1, 0x6D, 0xAAAB, 0x884 }, + [ATHOS_LUT_CHAN_654250_IDX] = { 26170, 0x1, 0x6D, 0x15555, 0x885 }, + [ATHOS_LUT_CHAN_654375_IDX] = { 26175, 0x1, 0x6D, 0x20000, 0x885 }, + [ATHOS_LUT_CHAN_654500_IDX] = { 26180, 0x1, 0x6D, 0x2AAAB, 0x886 }, + [ATHOS_LUT_CHAN_654625_IDX] = { 26185, 0x1, 0x6D, 0x35555, 0x886 }, + [ATHOS_LUT_CHAN_654750_IDX] = { 26190, 0x1, 0x6D, 0x40000, 0x887 }, + [ATHOS_LUT_CHAN_654875_IDX] = { 26195, 0x1, 0x6D, 0x4AAAB, 0x887 }, + [ATHOS_LUT_CHAN_655000_IDX] = { 26200, 0x1, 0x6D, 0x55555, 0x887 }, + [ATHOS_LUT_CHAN_655125_IDX] = { 26205, 0x1, 0x6D, 0x60000, 0x888 }, + [ATHOS_LUT_CHAN_655250_IDX] = { 26210, 0x1, 0x6D, 0x6AAAB, 0x888 }, + [ATHOS_LUT_CHAN_655375_IDX] = { 26215, 0x1, 0x6D, 0x75555, 0x889 }, + [ATHOS_LUT_CHAN_655500_IDX] = { 26220, 0x1, 0x6D, 0x80000, 0x889 }, + [ATHOS_LUT_CHAN_655625_IDX] = { 26225, 0x1, 0x6D, 0x8AAAB, 0x889 }, + [ATHOS_LUT_CHAN_655750_IDX] = { 26230, 0x1, 0x6D, 0x95555, 0x88A }, + [ATHOS_LUT_CHAN_655875_IDX] = { 26235, 0x1, 0x6D, 0xA0000, 0x88A }, + [ATHOS_LUT_CHAN_656000_IDX] = { 26240, 0x1, 0x6D, 0xAAAAB, 0x88B }, + [ATHOS_LUT_CHAN_656125_IDX] = { 26245, 0x1, 0x6D, 0xB5555, 0x88B }, + [ATHOS_LUT_CHAN_656250_IDX] = { 26250, 0x1, 0x6D, 0xC0000, 0x88C }, + [ATHOS_LUT_CHAN_656375_IDX] = { 26255, 0x1, 0x6D, 0xCAAAB, 0x88C }, + [ATHOS_LUT_CHAN_656500_IDX] = { 26260, 0x1, 0x6D, 0xD5555, 0x88C }, + [ATHOS_LUT_CHAN_656625_IDX] = { 26265, 0x1, 0x6D, 0xE0000, 0x88D }, + [ATHOS_LUT_CHAN_656750_IDX] = { 26270, 0x1, 0x6D, 0xEAAAB, 0x88D }, + [ATHOS_LUT_CHAN_656875_IDX] = { 26275, 0x1, 0x6D, 0xF5555, 0x88E }, + [ATHOS_LUT_CHAN_657000_IDX] = { 26280, 0x1, 0x6D, 0x100000, 0x88E }, + [ATHOS_LUT_CHAN_657125_IDX] = { 26285, 0x1, 0x6D, 0x10AAAB, 0x88E }, + [ATHOS_LUT_CHAN_657250_IDX] = { 26290, 0x1, 0x6D, 0x115555, 0x88F }, + [ATHOS_LUT_CHAN_657375_IDX] = { 26295, 0x1, 0x6D, 0x120000, 0x88F }, + [ATHOS_LUT_CHAN_657500_IDX] = { 26300, 0x1, 0x6D, 0x12AAAB, 0x890 }, + [ATHOS_LUT_CHAN_657625_IDX] = { 26305, 0x1, 0x6D, 0x135555, 0x890 }, + [ATHOS_LUT_CHAN_657750_IDX] = { 26310, 0x1, 0x6D, 0x140000, 0x891 }, + [ATHOS_LUT_CHAN_657875_IDX] = { 26315, 0x1, 0x6D, 0x14AAAB, 0x891 }, + [ATHOS_LUT_CHAN_658000_IDX] = { 26320, 0x1, 0x6D, 0x155555, 0x891 }, + [ATHOS_LUT_CHAN_658125_IDX] = { 26325, 0x1, 0x6D, 0x160000, 0x892 }, + [ATHOS_LUT_CHAN_658250_IDX] = { 26330, 0x1, 0x6D, 0x16AAAB, 0x892 }, + [ATHOS_LUT_CHAN_658375_IDX] = { 26335, 0x1, 0x6D, 0x175555, 0x893 }, + [ATHOS_LUT_CHAN_658500_IDX] = { 26340, 0x1, 0x6D, 0x180000, 0x893 }, + [ATHOS_LUT_CHAN_658625_IDX] = { 26345, 0x1, 0x6D, 0x18AAAB, 0x893 }, + [ATHOS_LUT_CHAN_658750_IDX] = { 26350, 0x1, 0x6D, 0x195555, 0x894 }, + [ATHOS_LUT_CHAN_658875_IDX] = { 26355, 0x1, 0x6D, 0x1A0000, 0x894 }, + [ATHOS_LUT_CHAN_659000_IDX] = { 26360, 0x1, 0x6D, 0x1AAAAB, 0x895 }, + [ATHOS_LUT_CHAN_659125_IDX] = { 26365, 0x1, 0x6D, 0x1B5555, 0x895 }, + [ATHOS_LUT_CHAN_659250_IDX] = { 26370, 0x1, 0x6D, 0x1C0000, 0x896 }, + [ATHOS_LUT_CHAN_659375_IDX] = { 26375, 0x1, 0x6D, 0x1CAAAB, 0x896 }, + [ATHOS_LUT_CHAN_659500_IDX] = { 26380, 0x1, 0x6D, 0x1D5555, 0x896 }, + [ATHOS_LUT_CHAN_659625_IDX] = { 26385, 0x1, 0x6D, 0x1E0000, 0x897 }, + [ATHOS_LUT_CHAN_659750_IDX] = { 26390, 0x1, 0x6D, 0x1EAAAB, 0x897 }, + [ATHOS_LUT_CHAN_659875_IDX] = { 26395, 0x1, 0x6D, 0x1F5555, 0x898 }, + [ATHOS_LUT_CHAN_660000_IDX] = { 26400, 0x1, 0x6E, 0x0, 0x898 }, + [ATHOS_LUT_CHAN_660125_IDX] = { 26405, 0x1, 0x6E, 0xAAAB, 0x898 }, + [ATHOS_LUT_CHAN_660250_IDX] = { 26410, 0x1, 0x6E, 0x15555, 0x899 }, + [ATHOS_LUT_CHAN_660375_IDX] = { 26415, 0x1, 0x6E, 0x20000, 0x899 }, + [ATHOS_LUT_CHAN_660500_IDX] = { 26420, 0x1, 0x6E, 0x2AAAB, 0x89A }, + [ATHOS_LUT_CHAN_660625_IDX] = { 26425, 0x1, 0x6E, 0x35555, 0x89A }, + [ATHOS_LUT_CHAN_660750_IDX] = { 26430, 0x1, 0x6E, 0x40000, 0x89B }, + [ATHOS_LUT_CHAN_660875_IDX] = { 26435, 0x1, 0x6E, 0x4AAAB, 0x89B }, + [ATHOS_LUT_CHAN_661000_IDX] = { 26440, 0x1, 0x6E, 0x55555, 0x89B }, + [ATHOS_LUT_CHAN_661125_IDX] = { 26445, 0x1, 0x6E, 0x60000, 0x89C }, + [ATHOS_LUT_CHAN_661250_IDX] = { 26450, 0x1, 0x6E, 0x6AAAB, 0x89C }, + [ATHOS_LUT_CHAN_661375_IDX] = { 26455, 0x1, 0x6E, 0x75555, 0x89D }, + [ATHOS_LUT_CHAN_661500_IDX] = { 26460, 0x1, 0x6E, 0x80000, 0x89D }, + [ATHOS_LUT_CHAN_661625_IDX] = { 26465, 0x1, 0x6E, 0x8AAAB, 0x89D }, + [ATHOS_LUT_CHAN_661750_IDX] = { 26470, 0x1, 0x6E, 0x95555, 0x89E }, + [ATHOS_LUT_CHAN_661875_IDX] = { 26475, 0x1, 0x6E, 0xA0000, 0x89E }, + [ATHOS_LUT_CHAN_662000_IDX] = { 26480, 0x1, 0x6E, 0xAAAAB, 0x89F }, + [ATHOS_LUT_CHAN_662125_IDX] = { 26485, 0x1, 0x6E, 0xB5555, 0x89F }, + [ATHOS_LUT_CHAN_662250_IDX] = { 26490, 0x1, 0x6E, 0xC0000, 0x8A0 }, + [ATHOS_LUT_CHAN_662375_IDX] = { 26495, 0x1, 0x6E, 0xCAAAB, 0x8A0 }, + [ATHOS_LUT_CHAN_662500_IDX] = { 26500, 0x1, 0x6E, 0xD5555, 0x8A0 }, + [ATHOS_LUT_CHAN_662625_IDX] = { 26505, 0x1, 0x6E, 0xE0000, 0x8A1 }, + [ATHOS_LUT_CHAN_662750_IDX] = { 26510, 0x1, 0x6E, 0xEAAAB, 0x8A1 }, + [ATHOS_LUT_CHAN_662875_IDX] = { 26515, 0x1, 0x6E, 0xF5555, 0x8A2 }, + [ATHOS_LUT_CHAN_663000_IDX] = { 26520, 0x1, 0x6E, 0x100000, 0x8A2 }, + [ATHOS_LUT_CHAN_663125_IDX] = { 26525, 0x1, 0x6E, 0x10AAAB, 0x8A2 }, + [ATHOS_LUT_CHAN_663250_IDX] = { 26530, 0x1, 0x6E, 0x115555, 0x8A3 }, + [ATHOS_LUT_CHAN_663375_IDX] = { 26535, 0x1, 0x6E, 0x120000, 0x8A3 }, + [ATHOS_LUT_CHAN_663500_IDX] = { 26540, 0x1, 0x6E, 0x12AAAB, 0x8A4 }, + [ATHOS_LUT_CHAN_663625_IDX] = { 26545, 0x1, 0x6E, 0x135555, 0x8A4 }, + [ATHOS_LUT_CHAN_663750_IDX] = { 26550, 0x1, 0x6E, 0x140000, 0x8A5 }, + [ATHOS_LUT_CHAN_663875_IDX] = { 26555, 0x1, 0x6E, 0x14AAAB, 0x8A5 }, + [ATHOS_LUT_CHAN_664000_IDX] = { 26560, 0x1, 0x6E, 0x155555, 0x8A5 }, + [ATHOS_LUT_CHAN_664125_IDX] = { 26565, 0x1, 0x6E, 0x160000, 0x8A6 }, + [ATHOS_LUT_CHAN_664250_IDX] = { 26570, 0x1, 0x6E, 0x16AAAB, 0x8A6 }, + [ATHOS_LUT_CHAN_664375_IDX] = { 26575, 0x1, 0x6E, 0x175555, 0x8A7 }, + [ATHOS_LUT_CHAN_664500_IDX] = { 26580, 0x1, 0x6E, 0x180000, 0x8A7 }, + [ATHOS_LUT_CHAN_664625_IDX] = { 26585, 0x1, 0x6E, 0x18AAAB, 0x8A7 }, + [ATHOS_LUT_CHAN_664750_IDX] = { 26590, 0x1, 0x6E, 0x195555, 0x8A8 }, + [ATHOS_LUT_CHAN_664875_IDX] = { 26595, 0x1, 0x6E, 0x1A0000, 0x8A8 }, + [ATHOS_LUT_CHAN_665000_IDX] = { 26600, 0x1, 0x6E, 0x1AAAAB, 0x8A9 }, + [ATHOS_LUT_CHAN_665125_IDX] = { 26605, 0x1, 0x6E, 0x1B5555, 0x8A9 }, + [ATHOS_LUT_CHAN_665250_IDX] = { 26610, 0x1, 0x6E, 0x1C0000, 0x8AA }, + [ATHOS_LUT_CHAN_665375_IDX] = { 26615, 0x1, 0x6E, 0x1CAAAB, 0x8AA }, + [ATHOS_LUT_CHAN_665500_IDX] = { 26620, 0x1, 0x6E, 0x1D5555, 0x8AA }, + [ATHOS_LUT_CHAN_665625_IDX] = { 26625, 0x1, 0x6E, 0x1E0000, 0x8AB }, + [ATHOS_LUT_CHAN_665750_IDX] = { 26630, 0x1, 0x6E, 0x1EAAAB, 0x8AB }, + [ATHOS_LUT_CHAN_665875_IDX] = { 26635, 0x1, 0x6E, 0x1F5555, 0x8AC }, + [ATHOS_LUT_CHAN_666000_IDX] = { 26640, 0x1, 0x6F, 0x0, 0x8AC }, + [ATHOS_LUT_CHAN_666125_IDX] = { 26645, 0x1, 0x6F, 0xAAAB, 0x8AC }, + [ATHOS_LUT_CHAN_666250_IDX] = { 26650, 0x1, 0x6F, 0x15555, 0x8AD }, + [ATHOS_LUT_CHAN_666375_IDX] = { 26655, 0x1, 0x6F, 0x20000, 0x8AD }, + [ATHOS_LUT_CHAN_666500_IDX] = { 26660, 0x1, 0x6F, 0x2AAAB, 0x8AE }, + [ATHOS_LUT_CHAN_666625_IDX] = { 26665, 0x1, 0x6F, 0x35555, 0x8AE }, + [ATHOS_LUT_CHAN_666750_IDX] = { 26670, 0x1, 0x6F, 0x40000, 0x8AF }, + [ATHOS_LUT_CHAN_666875_IDX] = { 26675, 0x1, 0x6F, 0x4AAAB, 0x8AF }, + [ATHOS_LUT_CHAN_667000_IDX] = { 26680, 0x1, 0x6F, 0x55555, 0x8AF }, + [ATHOS_LUT_CHAN_667125_IDX] = { 26685, 0x1, 0x6F, 0x60000, 0x8B0 }, + [ATHOS_LUT_CHAN_667250_IDX] = { 26690, 0x1, 0x6F, 0x6AAAB, 0x8B0 }, + [ATHOS_LUT_CHAN_667375_IDX] = { 26695, 0x1, 0x6F, 0x75555, 0x8B1 }, + [ATHOS_LUT_CHAN_667500_IDX] = { 26700, 0x1, 0x6F, 0x80000, 0x8B1 }, + [ATHOS_LUT_CHAN_667625_IDX] = { 26705, 0x1, 0x6F, 0x8AAAB, 0x8B1 }, + [ATHOS_LUT_CHAN_667750_IDX] = { 26710, 0x1, 0x6F, 0x95555, 0x8B2 }, + [ATHOS_LUT_CHAN_667875_IDX] = { 26715, 0x1, 0x6F, 0xA0000, 0x8B2 }, + [ATHOS_LUT_CHAN_668000_IDX] = { 26720, 0x1, 0x6F, 0xAAAAB, 0x8B3 }, + [ATHOS_LUT_CHAN_668125_IDX] = { 26725, 0x1, 0x6F, 0xB5555, 0x8B3 }, + [ATHOS_LUT_CHAN_668250_IDX] = { 26730, 0x1, 0x6F, 0xC0000, 0x8B4 }, + [ATHOS_LUT_CHAN_668375_IDX] = { 26735, 0x1, 0x6F, 0xCAAAB, 0x8B4 }, + [ATHOS_LUT_CHAN_668500_IDX] = { 26740, 0x1, 0x6F, 0xD5555, 0x8B4 }, + [ATHOS_LUT_CHAN_668625_IDX] = { 26745, 0x1, 0x6F, 0xE0000, 0x8B5 }, + [ATHOS_LUT_CHAN_668750_IDX] = { 26750, 0x1, 0x6F, 0xEAAAB, 0x8B5 }, + [ATHOS_LUT_CHAN_668875_IDX] = { 26755, 0x1, 0x6F, 0xF5555, 0x8B6 }, + [ATHOS_LUT_CHAN_669000_IDX] = { 26760, 0x1, 0x6F, 0x100000, 0x8B6 }, + [ATHOS_LUT_CHAN_669125_IDX] = { 26765, 0x1, 0x6F, 0x10AAAB, 0x8B6 }, + [ATHOS_LUT_CHAN_669250_IDX] = { 26770, 0x1, 0x6F, 0x115555, 0x8B7 }, + [ATHOS_LUT_CHAN_669375_IDX] = { 26775, 0x1, 0x6F, 0x120000, 0x8B7 }, + [ATHOS_LUT_CHAN_669500_IDX] = { 26780, 0x1, 0x6F, 0x12AAAB, 0x8B8 }, + [ATHOS_LUT_CHAN_669625_IDX] = { 26785, 0x1, 0x6F, 0x135555, 0x8B8 }, + [ATHOS_LUT_CHAN_669750_IDX] = { 26790, 0x1, 0x6F, 0x140000, 0x8B9 }, + [ATHOS_LUT_CHAN_669875_IDX] = { 26795, 0x1, 0x6F, 0x14AAAB, 0x8B9 }, + [ATHOS_LUT_CHAN_670000_IDX] = { 26800, 0x1, 0x6F, 0x155555, 0x8B9 }, + [ATHOS_LUT_CHAN_670125_IDX] = { 26805, 0x1, 0x6F, 0x160000, 0x8BA }, + [ATHOS_LUT_CHAN_670250_IDX] = { 26810, 0x1, 0x6F, 0x16AAAB, 0x8BA }, + [ATHOS_LUT_CHAN_670375_IDX] = { 26815, 0x1, 0x6F, 0x175555, 0x8BB }, + [ATHOS_LUT_CHAN_670500_IDX] = { 26820, 0x1, 0x6F, 0x180000, 0x8BB }, + [ATHOS_LUT_CHAN_670625_IDX] = { 26825, 0x1, 0x6F, 0x18AAAB, 0x8BB }, + [ATHOS_LUT_CHAN_670750_IDX] = { 26830, 0x1, 0x6F, 0x195555, 0x8BC }, + [ATHOS_LUT_CHAN_670875_IDX] = { 26835, 0x1, 0x6F, 0x1A0000, 0x8BC }, + [ATHOS_LUT_CHAN_671000_IDX] = { 26840, 0x1, 0x6F, 0x1AAAAB, 0x8BD }, + [ATHOS_LUT_CHAN_671125_IDX] = { 26845, 0x1, 0x6F, 0x1B5555, 0x8BD }, + [ATHOS_LUT_CHAN_671250_IDX] = { 26850, 0x1, 0x6F, 0x1C0000, 0x8BE }, + [ATHOS_LUT_CHAN_671375_IDX] = { 26855, 0x1, 0x6F, 0x1CAAAB, 0x8BE }, + [ATHOS_LUT_CHAN_671500_IDX] = { 26860, 0x1, 0x6F, 0x1D5555, 0x8BE }, + [ATHOS_LUT_CHAN_671625_IDX] = { 26865, 0x1, 0x6F, 0x1E0000, 0x8BF }, + [ATHOS_LUT_CHAN_671750_IDX] = { 26870, 0x1, 0x6F, 0x1EAAAB, 0x8BF }, + [ATHOS_LUT_CHAN_671875_IDX] = { 26875, 0x1, 0x6F, 0x1F5555, 0x8C0 }, + [ATHOS_LUT_CHAN_672000_IDX] = { 26880, 0x1, 0x70, 0x0, 0x8C0 }, + [ATHOS_LUT_CHAN_672125_IDX] = { 26885, 0x1, 0x70, 0xAAAB, 0x8C0 }, + [ATHOS_LUT_CHAN_672250_IDX] = { 26890, 0x1, 0x70, 0x15555, 0x8C1 }, + [ATHOS_LUT_CHAN_672375_IDX] = { 26895, 0x1, 0x70, 0x20000, 0x8C1 }, + [ATHOS_LUT_CHAN_672500_IDX] = { 26900, 0x1, 0x70, 0x2AAAB, 0x8C2 }, + [ATHOS_LUT_CHAN_672625_IDX] = { 26905, 0x1, 0x70, 0x35555, 0x8C2 }, + [ATHOS_LUT_CHAN_672750_IDX] = { 26910, 0x1, 0x70, 0x40000, 0x8C3 }, + [ATHOS_LUT_CHAN_672875_IDX] = { 26915, 0x1, 0x70, 0x4AAAB, 0x8C3 }, + [ATHOS_LUT_CHAN_673000_IDX] = { 26920, 0x1, 0x70, 0x55555, 0x8C3 }, + [ATHOS_LUT_CHAN_673125_IDX] = { 26925, 0x1, 0x70, 0x60000, 0x8C4 }, + [ATHOS_LUT_CHAN_673250_IDX] = { 26930, 0x1, 0x70, 0x6AAAB, 0x8C4 }, + [ATHOS_LUT_CHAN_673375_IDX] = { 26935, 0x1, 0x70, 0x75555, 0x8C5 }, + [ATHOS_LUT_CHAN_673500_IDX] = { 26940, 0x1, 0x70, 0x80000, 0x8C5 }, + [ATHOS_LUT_CHAN_673625_IDX] = { 26945, 0x1, 0x70, 0x8AAAB, 0x8C5 }, + [ATHOS_LUT_CHAN_673750_IDX] = { 26950, 0x1, 0x70, 0x95555, 0x8C6 }, + [ATHOS_LUT_CHAN_673875_IDX] = { 26955, 0x1, 0x70, 0xA0000, 0x8C6 }, + [ATHOS_LUT_CHAN_674000_IDX] = { 26960, 0x1, 0x70, 0xAAAAB, 0x8C7 }, + [ATHOS_LUT_CHAN_674125_IDX] = { 26965, 0x1, 0x70, 0xB5555, 0x8C7 }, + [ATHOS_LUT_CHAN_674250_IDX] = { 26970, 0x1, 0x70, 0xC0000, 0x8C8 }, + [ATHOS_LUT_CHAN_674375_IDX] = { 26975, 0x1, 0x70, 0xCAAAB, 0x8C8 }, + [ATHOS_LUT_CHAN_674500_IDX] = { 26980, 0x1, 0x70, 0xD5555, 0x8C8 }, + [ATHOS_LUT_CHAN_674625_IDX] = { 26985, 0x1, 0x70, 0xE0000, 0x8C9 }, + [ATHOS_LUT_CHAN_674750_IDX] = { 26990, 0x1, 0x70, 0xEAAAB, 0x8C9 }, + [ATHOS_LUT_CHAN_674875_IDX] = { 26995, 0x1, 0x70, 0xF5555, 0x8CA }, + [ATHOS_LUT_CHAN_675000_IDX] = { 27000, 0x1, 0x70, 0x100000, 0x8CA }, + [ATHOS_LUT_CHAN_675125_IDX] = { 27005, 0x1, 0x70, 0x10AAAB, 0x8CA }, + [ATHOS_LUT_CHAN_675250_IDX] = { 27010, 0x1, 0x70, 0x115555, 0x8CB }, + [ATHOS_LUT_CHAN_675375_IDX] = { 27015, 0x1, 0x70, 0x120000, 0x8CB }, + [ATHOS_LUT_CHAN_675500_IDX] = { 27020, 0x1, 0x70, 0x12AAAB, 0x8CC }, + [ATHOS_LUT_CHAN_675625_IDX] = { 27025, 0x1, 0x70, 0x135555, 0x8CC }, + [ATHOS_LUT_CHAN_675750_IDX] = { 27030, 0x1, 0x70, 0x140000, 0x8CD }, + [ATHOS_LUT_CHAN_675875_IDX] = { 27035, 0x1, 0x70, 0x14AAAB, 0x8CD }, + [ATHOS_LUT_CHAN_676000_IDX] = { 27040, 0x1, 0x70, 0x155555, 0x8CD }, + [ATHOS_LUT_CHAN_676125_IDX] = { 27045, 0x1, 0x70, 0x160000, 0x8CE }, + [ATHOS_LUT_CHAN_676250_IDX] = { 27050, 0x1, 0x70, 0x16AAAB, 0x8CE }, + [ATHOS_LUT_CHAN_676375_IDX] = { 27055, 0x1, 0x70, 0x175555, 0x8CF }, + [ATHOS_LUT_CHAN_676500_IDX] = { 27060, 0x1, 0x70, 0x180000, 0x8CF }, + [ATHOS_LUT_CHAN_676625_IDX] = { 27065, 0x1, 0x70, 0x18AAAB, 0x8CF }, + [ATHOS_LUT_CHAN_676750_IDX] = { 27070, 0x1, 0x70, 0x195555, 0x8D0 }, + [ATHOS_LUT_CHAN_676875_IDX] = { 27075, 0x1, 0x70, 0x1A0000, 0x8D0 }, + [ATHOS_LUT_CHAN_677000_IDX] = { 27080, 0x1, 0x70, 0x1AAAAB, 0x8D1 }, + [ATHOS_LUT_CHAN_677125_IDX] = { 27085, 0x1, 0x70, 0x1B5555, 0x8D1 }, + [ATHOS_LUT_CHAN_677250_IDX] = { 27090, 0x1, 0x70, 0x1C0000, 0x8D2 }, + [ATHOS_LUT_CHAN_677375_IDX] = { 27095, 0x1, 0x70, 0x1CAAAB, 0x8D2 }, + [ATHOS_LUT_CHAN_677500_IDX] = { 27100, 0x1, 0x70, 0x1D5555, 0x8D2 }, + [ATHOS_LUT_CHAN_677625_IDX] = { 27105, 0x1, 0x70, 0x1E0000, 0x8D3 }, + [ATHOS_LUT_CHAN_677750_IDX] = { 27110, 0x1, 0x70, 0x1EAAAB, 0x8D3 }, + [ATHOS_LUT_CHAN_677875_IDX] = { 27115, 0x1, 0x70, 0x1F5555, 0x8D4 }, + [ATHOS_LUT_CHAN_678000_IDX] = { 27120, 0x1, 0x71, 0x0, 0x8D4 }, + [ATHOS_LUT_CHAN_678125_IDX] = { 27125, 0x1, 0x71, 0xAAAB, 0x8D4 }, + [ATHOS_LUT_CHAN_678250_IDX] = { 27130, 0x1, 0x71, 0x15555, 0x8D5 }, + [ATHOS_LUT_CHAN_678375_IDX] = { 27135, 0x1, 0x71, 0x20000, 0x8D5 }, + [ATHOS_LUT_CHAN_678500_IDX] = { 27140, 0x1, 0x71, 0x2AAAB, 0x8D6 }, + [ATHOS_LUT_CHAN_678625_IDX] = { 27145, 0x1, 0x71, 0x35555, 0x8D6 }, + [ATHOS_LUT_CHAN_678750_IDX] = { 27150, 0x1, 0x71, 0x40000, 0x8D7 }, + [ATHOS_LUT_CHAN_678875_IDX] = { 27155, 0x1, 0x71, 0x4AAAB, 0x8D7 }, + [ATHOS_LUT_CHAN_679000_IDX] = { 27160, 0x1, 0x71, 0x55555, 0x8D7 }, + [ATHOS_LUT_CHAN_679125_IDX] = { 27165, 0x1, 0x71, 0x60000, 0x8D8 }, + [ATHOS_LUT_CHAN_679250_IDX] = { 27170, 0x1, 0x71, 0x6AAAB, 0x8D8 }, + [ATHOS_LUT_CHAN_679375_IDX] = { 27175, 0x1, 0x71, 0x75555, 0x8D9 }, + [ATHOS_LUT_CHAN_679500_IDX] = { 27180, 0x1, 0x71, 0x80000, 0x8D9 }, + [ATHOS_LUT_CHAN_679625_IDX] = { 27185, 0x1, 0x71, 0x8AAAB, 0x8D9 }, + [ATHOS_LUT_CHAN_679750_IDX] = { 27190, 0x1, 0x71, 0x95555, 0x8DA }, + [ATHOS_LUT_CHAN_679875_IDX] = { 27195, 0x1, 0x71, 0xA0000, 0x8DA }, + [ATHOS_LUT_CHAN_680000_IDX] = { 27200, 0x1, 0x71, 0xAAAAB, 0x8DB }, + [ATHOS_LUT_CHAN_680125_IDX] = { 27205, 0x1, 0x71, 0xB5555, 0x8DB }, + [ATHOS_LUT_CHAN_680250_IDX] = { 27210, 0x1, 0x71, 0xC0000, 0x8DC }, + [ATHOS_LUT_CHAN_680375_IDX] = { 27215, 0x1, 0x71, 0xCAAAB, 0x8DC }, + [ATHOS_LUT_CHAN_680500_IDX] = { 27220, 0x1, 0x71, 0xD5555, 0x8DC }, + [ATHOS_LUT_CHAN_680625_IDX] = { 27225, 0x1, 0x71, 0xE0000, 0x8DD }, + [ATHOS_LUT_CHAN_680750_IDX] = { 27230, 0x1, 0x71, 0xEAAAB, 0x8DD }, + [ATHOS_LUT_CHAN_680875_IDX] = { 27235, 0x1, 0x71, 0xF5555, 0x8DE }, + [ATHOS_LUT_CHAN_681000_IDX] = { 27240, 0x1, 0x71, 0x100000, 0x8DE }, + [ATHOS_LUT_CHAN_681125_IDX] = { 27245, 0x1, 0x71, 0x10AAAB, 0x8DE }, + [ATHOS_LUT_CHAN_681250_IDX] = { 27250, 0x1, 0x71, 0x115555, 0x8DF }, + [ATHOS_LUT_CHAN_681375_IDX] = { 27255, 0x1, 0x71, 0x120000, 0x8DF }, + [ATHOS_LUT_CHAN_681500_IDX] = { 27260, 0x1, 0x71, 0x12AAAB, 0x8E0 }, + [ATHOS_LUT_CHAN_681625_IDX] = { 27265, 0x1, 0x71, 0x135555, 0x8E0 }, + [ATHOS_LUT_CHAN_681750_IDX] = { 27270, 0x1, 0x71, 0x140000, 0x8E1 }, + [ATHOS_LUT_CHAN_681875_IDX] = { 27275, 0x1, 0x71, 0x14AAAB, 0x8E1 }, + [ATHOS_LUT_CHAN_682000_IDX] = { 27280, 0x1, 0x71, 0x155555, 0x8E1 }, + [ATHOS_LUT_CHAN_682125_IDX] = { 27285, 0x1, 0x71, 0x160000, 0x8E2 }, + [ATHOS_LUT_CHAN_682250_IDX] = { 27290, 0x1, 0x71, 0x16AAAB, 0x8E2 }, + [ATHOS_LUT_CHAN_682375_IDX] = { 27295, 0x1, 0x71, 0x175555, 0x8E3 }, + [ATHOS_LUT_CHAN_682500_IDX] = { 27300, 0x1, 0x71, 0x180000, 0x8E3 }, + [ATHOS_LUT_CHAN_682625_IDX] = { 27305, 0x1, 0x71, 0x18AAAB, 0x8E3 }, + [ATHOS_LUT_CHAN_682750_IDX] = { 27310, 0x1, 0x71, 0x195555, 0x8E4 }, + [ATHOS_LUT_CHAN_682875_IDX] = { 27315, 0x1, 0x71, 0x1A0000, 0x8E4 }, + [ATHOS_LUT_CHAN_683000_IDX] = { 27320, 0x1, 0x71, 0x1AAAAB, 0x8E5 }, + [ATHOS_LUT_CHAN_683125_IDX] = { 27325, 0x1, 0x71, 0x1B5555, 0x8E5 }, + [ATHOS_LUT_CHAN_683250_IDX] = { 27330, 0x1, 0x71, 0x1C0000, 0x8E6 }, + [ATHOS_LUT_CHAN_683375_IDX] = { 27335, 0x1, 0x71, 0x1CAAAB, 0x8E6 }, + [ATHOS_LUT_CHAN_683500_IDX] = { 27340, 0x1, 0x71, 0x1D5555, 0x8E6 }, + [ATHOS_LUT_CHAN_683625_IDX] = { 27345, 0x1, 0x71, 0x1E0000, 0x8E7 }, + [ATHOS_LUT_CHAN_683750_IDX] = { 27350, 0x1, 0x71, 0x1EAAAB, 0x8E7 }, + [ATHOS_LUT_CHAN_683875_IDX] = { 27355, 0x1, 0x71, 0x1F5555, 0x8E8 }, + [ATHOS_LUT_CHAN_684000_IDX] = { 27360, 0x1, 0x72, 0x0, 0x8E8 }, + [ATHOS_LUT_CHAN_684125_IDX] = { 27365, 0x1, 0x72, 0xAAAB, 0x8E8 }, + [ATHOS_LUT_CHAN_684250_IDX] = { 27370, 0x1, 0x72, 0x15555, 0x8E9 }, + [ATHOS_LUT_CHAN_684375_IDX] = { 27375, 0x1, 0x72, 0x20000, 0x8E9 }, + [ATHOS_LUT_CHAN_684500_IDX] = { 27380, 0x1, 0x72, 0x2AAAB, 0x8EA }, + [ATHOS_LUT_CHAN_684625_IDX] = { 27385, 0x1, 0x72, 0x35555, 0x8EA }, + [ATHOS_LUT_CHAN_684750_IDX] = { 27390, 0x1, 0x72, 0x40000, 0x8EB }, + [ATHOS_LUT_CHAN_684875_IDX] = { 27395, 0x1, 0x72, 0x4AAAB, 0x8EB }, + [ATHOS_LUT_CHAN_685000_IDX] = { 27400, 0x1, 0x72, 0x55555, 0x8EB }, + [ATHOS_LUT_CHAN_685125_IDX] = { 27405, 0x1, 0x72, 0x60000, 0x8EC }, + [ATHOS_LUT_CHAN_685250_IDX] = { 27410, 0x1, 0x72, 0x6AAAB, 0x8EC }, + [ATHOS_LUT_CHAN_685375_IDX] = { 27415, 0x1, 0x72, 0x75555, 0x8ED }, + [ATHOS_LUT_CHAN_685500_IDX] = { 27420, 0x1, 0x72, 0x80000, 0x8ED }, + [ATHOS_LUT_CHAN_685625_IDX] = { 27425, 0x1, 0x72, 0x8AAAB, 0x8ED }, + [ATHOS_LUT_CHAN_685750_IDX] = { 27430, 0x1, 0x72, 0x95555, 0x8EE }, + [ATHOS_LUT_CHAN_685875_IDX] = { 27435, 0x1, 0x72, 0xA0000, 0x8EE }, + [ATHOS_LUT_CHAN_686000_IDX] = { 27440, 0x1, 0x72, 0xAAAAB, 0x8EF }, + [ATHOS_LUT_CHAN_686125_IDX] = { 27445, 0x1, 0x72, 0xB5555, 0x8EF }, + [ATHOS_LUT_CHAN_686250_IDX] = { 27450, 0x1, 0x72, 0xC0000, 0x8F0 }, + [ATHOS_LUT_CHAN_686375_IDX] = { 27455, 0x1, 0x72, 0xCAAAB, 0x8F0 }, + [ATHOS_LUT_CHAN_686500_IDX] = { 27460, 0x1, 0x72, 0xD5555, 0x8F0 }, + [ATHOS_LUT_CHAN_686625_IDX] = { 27465, 0x1, 0x72, 0xE0000, 0x8F1 }, + [ATHOS_LUT_CHAN_686750_IDX] = { 27470, 0x1, 0x72, 0xEAAAB, 0x8F1 }, + [ATHOS_LUT_CHAN_686875_IDX] = { 27475, 0x1, 0x72, 0xF5555, 0x8F2 }, + [ATHOS_LUT_CHAN_687000_IDX] = { 27480, 0x1, 0x72, 0x100000, 0x8F2 }, + [ATHOS_LUT_CHAN_687125_IDX] = { 27485, 0x1, 0x72, 0x10AAAB, 0x8F2 }, + [ATHOS_LUT_CHAN_687250_IDX] = { 27490, 0x1, 0x72, 0x115555, 0x8F3 }, + [ATHOS_LUT_CHAN_687375_IDX] = { 27495, 0x1, 0x72, 0x120000, 0x8F3 }, + [ATHOS_LUT_CHAN_687500_IDX] = { 27500, 0x1, 0x72, 0x12AAAB, 0x8F4 }, + [ATHOS_LUT_CHAN_687625_IDX] = { 27505, 0x1, 0x72, 0x135555, 0x8F4 }, + [ATHOS_LUT_CHAN_687750_IDX] = { 27510, 0x1, 0x72, 0x140000, 0x8F5 }, + [ATHOS_LUT_CHAN_687875_IDX] = { 27515, 0x1, 0x72, 0x14AAAB, 0x8F5 }, + [ATHOS_LUT_CHAN_688000_IDX] = { 27520, 0x1, 0x72, 0x155555, 0x8F5 }, + [ATHOS_LUT_CHAN_688125_IDX] = { 27525, 0x1, 0x72, 0x160000, 0x8F6 }, + [ATHOS_LUT_CHAN_688250_IDX] = { 27530, 0x1, 0x72, 0x16AAAB, 0x8F6 }, + [ATHOS_LUT_CHAN_688375_IDX] = { 27535, 0x1, 0x72, 0x175555, 0x8F7 }, + [ATHOS_LUT_CHAN_688500_IDX] = { 27540, 0x1, 0x72, 0x180000, 0x8F7 }, + [ATHOS_LUT_CHAN_688625_IDX] = { 27545, 0x1, 0x72, 0x18AAAB, 0x8F7 }, + [ATHOS_LUT_CHAN_688750_IDX] = { 27550, 0x1, 0x72, 0x195555, 0x8F8 }, + [ATHOS_LUT_CHAN_688875_IDX] = { 27555, 0x1, 0x72, 0x1A0000, 0x8F8 }, + [ATHOS_LUT_CHAN_689000_IDX] = { 27560, 0x1, 0x72, 0x1AAAAB, 0x8F9 }, + [ATHOS_LUT_CHAN_689125_IDX] = { 27565, 0x1, 0x72, 0x1B5555, 0x8F9 }, + [ATHOS_LUT_CHAN_689250_IDX] = { 27570, 0x1, 0x72, 0x1C0000, 0x8FA }, + [ATHOS_LUT_CHAN_689375_IDX] = { 27575, 0x1, 0x72, 0x1CAAAB, 0x8FA }, + [ATHOS_LUT_CHAN_689500_IDX] = { 27580, 0x1, 0x72, 0x1D5555, 0x8FA }, + [ATHOS_LUT_CHAN_689625_IDX] = { 27585, 0x1, 0x72, 0x1E0000, 0x8FB }, + [ATHOS_LUT_CHAN_689750_IDX] = { 27590, 0x1, 0x72, 0x1EAAAB, 0x8FB }, + [ATHOS_LUT_CHAN_689875_IDX] = { 27595, 0x1, 0x72, 0x1F5555, 0x8FC }, + [ATHOS_LUT_CHAN_690000_IDX] = { 27600, 0x1, 0x73, 0x0, 0x8FC }, + [ATHOS_LUT_CHAN_690125_IDX] = { 27605, 0x1, 0x73, 0xAAAB, 0x8FC }, + [ATHOS_LUT_CHAN_690250_IDX] = { 27610, 0x1, 0x73, 0x15555, 0x8FD }, + [ATHOS_LUT_CHAN_690375_IDX] = { 27615, 0x1, 0x73, 0x20000, 0x8FD }, + [ATHOS_LUT_CHAN_690500_IDX] = { 27620, 0x1, 0x73, 0x2AAAB, 0x8FE }, + [ATHOS_LUT_CHAN_690625_IDX] = { 27625, 0x1, 0x73, 0x35555, 0x8FE }, + [ATHOS_LUT_CHAN_690750_IDX] = { 27630, 0x1, 0x73, 0x40000, 0x8FF }, + [ATHOS_LUT_CHAN_690875_IDX] = { 27635, 0x1, 0x73, 0x4AAAB, 0x8FF }, + [ATHOS_LUT_CHAN_691000_IDX] = { 27640, 0x1, 0x73, 0x55555, 0x8FF }, + [ATHOS_LUT_CHAN_691125_IDX] = { 27645, 0x1, 0x73, 0x60000, 0x900 }, + [ATHOS_LUT_CHAN_691250_IDX] = { 27650, 0x1, 0x73, 0x6AAAB, 0x900 }, + [ATHOS_LUT_CHAN_691375_IDX] = { 27655, 0x1, 0x73, 0x75555, 0x901 }, + [ATHOS_LUT_CHAN_691500_IDX] = { 27660, 0x1, 0x73, 0x80000, 0x901 }, + [ATHOS_LUT_CHAN_691625_IDX] = { 27665, 0x1, 0x73, 0x8AAAB, 0x901 }, + [ATHOS_LUT_CHAN_691750_IDX] = { 27670, 0x1, 0x73, 0x95555, 0x902 }, + [ATHOS_LUT_CHAN_691875_IDX] = { 27675, 0x1, 0x73, 0xA0000, 0x902 }, + [ATHOS_LUT_CHAN_692000_IDX] = { 27680, 0x1, 0x73, 0xAAAAB, 0x903 }, + [ATHOS_LUT_CHAN_692125_IDX] = { 27685, 0x1, 0x73, 0xB5555, 0x903 }, + [ATHOS_LUT_CHAN_692250_IDX] = { 27690, 0x1, 0x73, 0xC0000, 0x904 }, + [ATHOS_LUT_CHAN_692375_IDX] = { 27695, 0x1, 0x73, 0xCAAAB, 0x904 }, + [ATHOS_LUT_CHAN_692500_IDX] = { 27700, 0x1, 0x73, 0xD5555, 0x904 }, + [ATHOS_LUT_CHAN_692625_IDX] = { 27705, 0x1, 0x73, 0xE0000, 0x905 }, + [ATHOS_LUT_CHAN_692750_IDX] = { 27710, 0x1, 0x73, 0xEAAAB, 0x905 }, + [ATHOS_LUT_CHAN_692875_IDX] = { 27715, 0x1, 0x73, 0xF5555, 0x906 }, + [ATHOS_LUT_CHAN_693000_IDX] = { 27720, 0x1, 0x73, 0x100000, 0x906 }, + [ATHOS_LUT_CHAN_693125_IDX] = { 27725, 0x1, 0x73, 0x10AAAB, 0x906 }, + [ATHOS_LUT_CHAN_693250_IDX] = { 27730, 0x1, 0x73, 0x115555, 0x907 }, + [ATHOS_LUT_CHAN_693375_IDX] = { 27735, 0x1, 0x73, 0x120000, 0x907 }, + [ATHOS_LUT_CHAN_693500_IDX] = { 27740, 0x1, 0x73, 0x12AAAB, 0x908 }, + [ATHOS_LUT_CHAN_693625_IDX] = { 27745, 0x1, 0x73, 0x135555, 0x908 }, + [ATHOS_LUT_CHAN_693750_IDX] = { 27750, 0x1, 0x73, 0x140000, 0x909 }, + [ATHOS_LUT_CHAN_693875_IDX] = { 27755, 0x1, 0x73, 0x14AAAB, 0x909 }, + [ATHOS_LUT_CHAN_694000_IDX] = { 27760, 0x1, 0x73, 0x155555, 0x909 }, + [ATHOS_LUT_CHAN_694125_IDX] = { 27765, 0x1, 0x73, 0x160000, 0x90A }, + [ATHOS_LUT_CHAN_694250_IDX] = { 27770, 0x1, 0x73, 0x16AAAB, 0x90A }, + [ATHOS_LUT_CHAN_694375_IDX] = { 27775, 0x1, 0x73, 0x175555, 0x90B }, + [ATHOS_LUT_CHAN_694500_IDX] = { 27780, 0x1, 0x73, 0x180000, 0x90B }, + [ATHOS_LUT_CHAN_694625_IDX] = { 27785, 0x1, 0x73, 0x18AAAB, 0x90B }, + [ATHOS_LUT_CHAN_694750_IDX] = { 27790, 0x1, 0x73, 0x195555, 0x90C }, + [ATHOS_LUT_CHAN_694875_IDX] = { 27795, 0x1, 0x73, 0x1A0000, 0x90C }, + [ATHOS_LUT_CHAN_695000_IDX] = { 27800, 0x1, 0x73, 0x1AAAAB, 0x90D }, + [ATHOS_LUT_CHAN_695125_IDX] = { 27805, 0x1, 0x73, 0x1B5555, 0x90D }, + [ATHOS_LUT_CHAN_695250_IDX] = { 27810, 0x1, 0x73, 0x1C0000, 0x90E }, + [ATHOS_LUT_CHAN_695375_IDX] = { 27815, 0x1, 0x73, 0x1CAAAB, 0x90E }, + [ATHOS_LUT_CHAN_695500_IDX] = { 27820, 0x1, 0x73, 0x1D5555, 0x90E }, + [ATHOS_LUT_CHAN_695625_IDX] = { 27825, 0x1, 0x73, 0x1E0000, 0x90F }, + [ATHOS_LUT_CHAN_695750_IDX] = { 27830, 0x1, 0x73, 0x1EAAAB, 0x90F }, + [ATHOS_LUT_CHAN_695875_IDX] = { 27835, 0x1, 0x73, 0x1F5555, 0x910 }, + [ATHOS_LUT_CHAN_696000_IDX] = { 27840, 0x1, 0x74, 0x0, 0x910 }, + [ATHOS_LUT_CHAN_696125_IDX] = { 27845, 0x1, 0x74, 0xAAAB, 0x910 }, + [ATHOS_LUT_CHAN_696250_IDX] = { 27850, 0x1, 0x74, 0x15555, 0x911 }, + [ATHOS_LUT_CHAN_696375_IDX] = { 27855, 0x1, 0x74, 0x20000, 0x911 }, + [ATHOS_LUT_CHAN_696500_IDX] = { 27860, 0x1, 0x74, 0x2AAAB, 0x912 }, + [ATHOS_LUT_CHAN_696625_IDX] = { 27865, 0x1, 0x74, 0x35555, 0x912 }, + [ATHOS_LUT_CHAN_696750_IDX] = { 27870, 0x1, 0x74, 0x40000, 0x913 }, + [ATHOS_LUT_CHAN_696875_IDX] = { 27875, 0x1, 0x74, 0x4AAAB, 0x913 }, + [ATHOS_LUT_CHAN_697000_IDX] = { 27880, 0x1, 0x74, 0x55555, 0x913 }, + [ATHOS_LUT_CHAN_697125_IDX] = { 27885, 0x1, 0x74, 0x60000, 0x914 }, + [ATHOS_LUT_CHAN_697250_IDX] = { 27890, 0x1, 0x74, 0x6AAAB, 0x914 }, + [ATHOS_LUT_CHAN_697375_IDX] = { 27895, 0x1, 0x74, 0x75555, 0x915 }, + [ATHOS_LUT_CHAN_697500_IDX] = { 27900, 0x1, 0x74, 0x80000, 0x915 }, + [ATHOS_LUT_CHAN_697625_IDX] = { 27905, 0x1, 0x74, 0x8AAAB, 0x915 }, + [ATHOS_LUT_CHAN_697750_IDX] = { 27910, 0x1, 0x74, 0x95555, 0x916 }, + [ATHOS_LUT_CHAN_697875_IDX] = { 27915, 0x1, 0x74, 0xA0000, 0x916 }, + [ATHOS_LUT_CHAN_698000_IDX] = { 27920, 0x1, 0x74, 0xAAAAB, 0x917 }, + [ATHOS_LUT_CHAN_698125_IDX] = { 27925, 0x1, 0x74, 0xB5555, 0x917 }, + [ATHOS_LUT_CHAN_698250_IDX] = { 27930, 0x1, 0x74, 0xC0000, 0x918 }, + [ATHOS_LUT_CHAN_698375_IDX] = { 27935, 0x1, 0x74, 0xCAAAB, 0x918 }, + [ATHOS_LUT_CHAN_698500_IDX] = { 27940, 0x1, 0x74, 0xD5555, 0x918 }, + [ATHOS_LUT_CHAN_698625_IDX] = { 27945, 0x1, 0x74, 0xE0000, 0x919 }, + [ATHOS_LUT_CHAN_698750_IDX] = { 27950, 0x1, 0x74, 0xEAAAB, 0x919 }, + [ATHOS_LUT_CHAN_698875_IDX] = { 27955, 0x1, 0x74, 0xF5555, 0x91A }, + [ATHOS_LUT_CHAN_699000_IDX] = { 27960, 0x1, 0x74, 0x100000, 0x91A }, + [ATHOS_LUT_CHAN_699125_IDX] = { 27965, 0x1, 0x74, 0x10AAAB, 0x91A }, + [ATHOS_LUT_CHAN_699250_IDX] = { 27970, 0x1, 0x74, 0x115555, 0x91B }, + [ATHOS_LUT_CHAN_699375_IDX] = { 27975, 0x1, 0x74, 0x120000, 0x91B }, + [ATHOS_LUT_CHAN_699500_IDX] = { 27980, 0x1, 0x74, 0x12AAAB, 0x91C }, + [ATHOS_LUT_CHAN_699625_IDX] = { 27985, 0x1, 0x74, 0x135555, 0x91C }, + [ATHOS_LUT_CHAN_699750_IDX] = { 27990, 0x1, 0x74, 0x140000, 0x91D }, + [ATHOS_LUT_CHAN_699875_IDX] = { 27995, 0x1, 0x74, 0x14AAAB, 0x91D }, + [ATHOS_LUT_CHAN_700000_IDX] = { 28000, 0x1, 0x74, 0x155555, 0x91D }, + [ATHOS_LUT_CHAN_700125_IDX] = { 28005, 0x1, 0x74, 0x160000, 0x91E }, + [ATHOS_LUT_CHAN_700250_IDX] = { 28010, 0x1, 0x74, 0x16AAAB, 0x91E }, + [ATHOS_LUT_CHAN_700375_IDX] = { 28015, 0x1, 0x74, 0x175555, 0x91F }, + [ATHOS_LUT_CHAN_700500_IDX] = { 28020, 0x1, 0x74, 0x180000, 0x91F }, + [ATHOS_LUT_CHAN_700625_IDX] = { 28025, 0x1, 0x74, 0x18AAAB, 0x91F }, + [ATHOS_LUT_CHAN_700750_IDX] = { 28030, 0x1, 0x74, 0x195555, 0x920 }, + [ATHOS_LUT_CHAN_700875_IDX] = { 28035, 0x1, 0x74, 0x1A0000, 0x920 }, + [ATHOS_LUT_CHAN_701000_IDX] = { 28040, 0x1, 0x74, 0x1AAAAB, 0x921 }, + [ATHOS_LUT_CHAN_701125_IDX] = { 28045, 0x1, 0x74, 0x1B5555, 0x921 }, + [ATHOS_LUT_CHAN_701250_IDX] = { 28050, 0x1, 0x74, 0x1C0000, 0x922 }, + [ATHOS_LUT_CHAN_701375_IDX] = { 28055, 0x1, 0x74, 0x1CAAAB, 0x922 }, + [ATHOS_LUT_CHAN_701500_IDX] = { 28060, 0x1, 0x74, 0x1D5555, 0x922 }, + [ATHOS_LUT_CHAN_701625_IDX] = { 28065, 0x1, 0x74, 0x1E0000, 0x923 }, + [ATHOS_LUT_CHAN_701750_IDX] = { 28070, 0x1, 0x74, 0x1EAAAB, 0x923 }, + [ATHOS_LUT_CHAN_701875_IDX] = { 28075, 0x1, 0x74, 0x1F5555, 0x924 }, + [ATHOS_LUT_CHAN_702000_IDX] = { 28080, 0x1, 0x75, 0x0, 0x924 }, + [ATHOS_LUT_CHAN_702125_IDX] = { 28085, 0x1, 0x75, 0xAAAB, 0x924 }, + [ATHOS_LUT_CHAN_702250_IDX] = { 28090, 0x1, 0x75, 0x15555, 0x925 }, + [ATHOS_LUT_CHAN_702375_IDX] = { 28095, 0x1, 0x75, 0x20000, 0x925 }, + [ATHOS_LUT_CHAN_702500_IDX] = { 28100, 0x1, 0x75, 0x2AAAB, 0x926 }, + [ATHOS_LUT_CHAN_702625_IDX] = { 28105, 0x1, 0x75, 0x35555, 0x926 }, + [ATHOS_LUT_CHAN_702750_IDX] = { 28110, 0x1, 0x75, 0x40000, 0x927 }, + [ATHOS_LUT_CHAN_702875_IDX] = { 28115, 0x1, 0x75, 0x4AAAB, 0x927 }, + [ATHOS_LUT_CHAN_703000_IDX] = { 28120, 0x1, 0x75, 0x55555, 0x927 }, + [ATHOS_LUT_CHAN_703125_IDX] = { 28125, 0x1, 0x75, 0x60000, 0x928 }, + [ATHOS_LUT_CHAN_703250_IDX] = { 28130, 0x1, 0x75, 0x6AAAB, 0x928 }, + [ATHOS_LUT_CHAN_703375_IDX] = { 28135, 0x1, 0x75, 0x75555, 0x929 }, + [ATHOS_LUT_CHAN_703500_IDX] = { 28140, 0x1, 0x75, 0x80000, 0x929 }, + [ATHOS_LUT_CHAN_703625_IDX] = { 28145, 0x1, 0x75, 0x8AAAB, 0x929 }, + [ATHOS_LUT_CHAN_703750_IDX] = { 28150, 0x1, 0x75, 0x95555, 0x92A }, + [ATHOS_LUT_CHAN_703875_IDX] = { 28155, 0x1, 0x75, 0xA0000, 0x92A }, + [ATHOS_LUT_CHAN_704000_IDX] = { 28160, 0x1, 0x75, 0xAAAAB, 0x92B }, + [ATHOS_LUT_CHAN_704125_IDX] = { 28165, 0x1, 0x75, 0xB5555, 0x92B }, + [ATHOS_LUT_CHAN_704250_IDX] = { 28170, 0x1, 0x75, 0xC0000, 0x92C }, + [ATHOS_LUT_CHAN_704375_IDX] = { 28175, 0x1, 0x75, 0xCAAAB, 0x92C }, + [ATHOS_LUT_CHAN_704500_IDX] = { 28180, 0x1, 0x75, 0xD5555, 0x92C }, + [ATHOS_LUT_CHAN_704625_IDX] = { 28185, 0x1, 0x75, 0xE0000, 0x92D }, + [ATHOS_LUT_CHAN_704750_IDX] = { 28190, 0x1, 0x75, 0xEAAAB, 0x92D }, + [ATHOS_LUT_CHAN_704875_IDX] = { 28195, 0x1, 0x75, 0xF5555, 0x92E }, + [ATHOS_LUT_CHAN_705000_IDX] = { 28200, 0x1, 0x75, 0x100000, 0x92E }, + [ATHOS_LUT_CHAN_705125_IDX] = { 28205, 0x1, 0x75, 0x10AAAB, 0x92E }, + [ATHOS_LUT_CHAN_705250_IDX] = { 28210, 0x1, 0x75, 0x115555, 0x92F }, + [ATHOS_LUT_CHAN_705375_IDX] = { 28215, 0x1, 0x75, 0x120000, 0x92F }, + [ATHOS_LUT_CHAN_705500_IDX] = { 28220, 0x1, 0x75, 0x12AAAB, 0x930 }, + [ATHOS_LUT_CHAN_705625_IDX] = { 28225, 0x1, 0x75, 0x135555, 0x930 }, + [ATHOS_LUT_CHAN_705750_IDX] = { 28230, 0x1, 0x75, 0x140000, 0x931 }, + [ATHOS_LUT_CHAN_705875_IDX] = { 28235, 0x1, 0x75, 0x14AAAB, 0x931 }, + [ATHOS_LUT_CHAN_706000_IDX] = { 28240, 0x1, 0x75, 0x155555, 0x931 }, + [ATHOS_LUT_CHAN_706125_IDX] = { 28245, 0x1, 0x75, 0x160000, 0x932 }, + [ATHOS_LUT_CHAN_706250_IDX] = { 28250, 0x1, 0x75, 0x16AAAB, 0x932 }, + [ATHOS_LUT_CHAN_706375_IDX] = { 28255, 0x1, 0x75, 0x175555, 0x933 }, + [ATHOS_LUT_CHAN_706500_IDX] = { 28260, 0x1, 0x75, 0x180000, 0x933 }, + [ATHOS_LUT_CHAN_706625_IDX] = { 28265, 0x1, 0x75, 0x18AAAB, 0x933 }, + [ATHOS_LUT_CHAN_706750_IDX] = { 28270, 0x1, 0x75, 0x195555, 0x934 }, + [ATHOS_LUT_CHAN_706875_IDX] = { 28275, 0x1, 0x75, 0x1A0000, 0x934 }, + [ATHOS_LUT_CHAN_707000_IDX] = { 28280, 0x1, 0x75, 0x1AAAAB, 0x935 }, + [ATHOS_LUT_CHAN_707125_IDX] = { 28285, 0x1, 0x75, 0x1B5555, 0x935 }, + [ATHOS_LUT_CHAN_707250_IDX] = { 28290, 0x1, 0x75, 0x1C0000, 0x936 }, + [ATHOS_LUT_CHAN_707375_IDX] = { 28295, 0x1, 0x75, 0x1CAAAB, 0x936 }, + [ATHOS_LUT_CHAN_707500_IDX] = { 28300, 0x1, 0x75, 0x1D5555, 0x936 }, + [ATHOS_LUT_CHAN_707625_IDX] = { 28305, 0x1, 0x75, 0x1E0000, 0x937 }, + [ATHOS_LUT_CHAN_707750_IDX] = { 28310, 0x1, 0x75, 0x1EAAAB, 0x937 }, + [ATHOS_LUT_CHAN_707875_IDX] = { 28315, 0x1, 0x75, 0x1F5555, 0x938 }, + [ATHOS_LUT_CHAN_708000_IDX] = { 28320, 0x1, 0x76, 0x0, 0x938 }, + [ATHOS_LUT_CHAN_708125_IDX] = { 28325, 0x1, 0x76, 0xAAAB, 0x938 }, + [ATHOS_LUT_CHAN_708250_IDX] = { 28330, 0x1, 0x76, 0x15555, 0x939 }, + [ATHOS_LUT_CHAN_708375_IDX] = { 28335, 0x1, 0x76, 0x20000, 0x939 }, + [ATHOS_LUT_CHAN_708500_IDX] = { 28340, 0x1, 0x76, 0x2AAAB, 0x93A }, + [ATHOS_LUT_CHAN_708625_IDX] = { 28345, 0x1, 0x76, 0x35555, 0x93A }, + [ATHOS_LUT_CHAN_708750_IDX] = { 28350, 0x1, 0x76, 0x40000, 0x93B }, + [ATHOS_LUT_CHAN_708875_IDX] = { 28355, 0x1, 0x76, 0x4AAAB, 0x93B }, + [ATHOS_LUT_CHAN_709000_IDX] = { 28360, 0x1, 0x76, 0x55555, 0x93B }, + [ATHOS_LUT_CHAN_709125_IDX] = { 28365, 0x1, 0x76, 0x60000, 0x93C }, + [ATHOS_LUT_CHAN_709250_IDX] = { 28370, 0x1, 0x76, 0x6AAAB, 0x93C }, + [ATHOS_LUT_CHAN_709375_IDX] = { 28375, 0x1, 0x76, 0x75555, 0x93D }, + [ATHOS_LUT_CHAN_709500_IDX] = { 28380, 0x1, 0x76, 0x80000, 0x93D }, + [ATHOS_LUT_CHAN_709625_IDX] = { 28385, 0x1, 0x76, 0x8AAAB, 0x93D }, + [ATHOS_LUT_CHAN_709750_IDX] = { 28390, 0x1, 0x76, 0x95555, 0x93E }, + [ATHOS_LUT_CHAN_709875_IDX] = { 28395, 0x1, 0x76, 0xA0000, 0x93E }, + [ATHOS_LUT_CHAN_710000_IDX] = { 28400, 0x1, 0x76, 0xAAAAB, 0x93F }, + [ATHOS_LUT_CHAN_710125_IDX] = { 28405, 0x1, 0x76, 0xB5555, 0x93F }, + [ATHOS_LUT_CHAN_710250_IDX] = { 28410, 0x1, 0x76, 0xC0000, 0x940 }, + [ATHOS_LUT_CHAN_710375_IDX] = { 28415, 0x1, 0x76, 0xCAAAB, 0x940 }, + [ATHOS_LUT_CHAN_710500_IDX] = { 28420, 0x1, 0x76, 0xD5555, 0x940 }, + [ATHOS_LUT_CHAN_710625_IDX] = { 28425, 0x1, 0x76, 0xE0000, 0x941 }, + [ATHOS_LUT_CHAN_710750_IDX] = { 28430, 0x1, 0x76, 0xEAAAB, 0x941 }, + [ATHOS_LUT_CHAN_710875_IDX] = { 28435, 0x1, 0x76, 0xF5555, 0x942 }, + [ATHOS_LUT_CHAN_711000_IDX] = { 28440, 0x1, 0x76, 0x100000, 0x942 }, + [ATHOS_LUT_CHAN_711125_IDX] = { 28445, 0x1, 0x76, 0x10AAAB, 0x942 }, + [ATHOS_LUT_CHAN_711250_IDX] = { 28450, 0x1, 0x76, 0x115555, 0x943 }, + [ATHOS_LUT_CHAN_711375_IDX] = { 28455, 0x1, 0x76, 0x120000, 0x943 }, + [ATHOS_LUT_CHAN_711500_IDX] = { 28460, 0x1, 0x76, 0x12AAAB, 0x944 }, + [ATHOS_LUT_CHAN_711625_IDX] = { 28465, 0x1, 0x76, 0x135555, 0x944 }, + [ATHOS_LUT_CHAN_711750_IDX] = { 28470, 0x1, 0x76, 0x140000, 0x945 }, + [ATHOS_LUT_CHAN_711875_IDX] = { 28475, 0x1, 0x76, 0x14AAAB, 0x945 }, + [ATHOS_LUT_CHAN_712000_IDX] = { 28480, 0x1, 0x76, 0x155555, 0x945 }, + [ATHOS_LUT_CHAN_712125_IDX] = { 28485, 0x1, 0x76, 0x160000, 0x946 }, + [ATHOS_LUT_CHAN_712250_IDX] = { 28490, 0x1, 0x76, 0x16AAAB, 0x946 }, + [ATHOS_LUT_CHAN_712375_IDX] = { 28495, 0x1, 0x76, 0x175555, 0x947 }, + [ATHOS_LUT_CHAN_712500_IDX] = { 28500, 0x1, 0x76, 0x180000, 0x947 }, + [ATHOS_LUT_CHAN_712625_IDX] = { 28505, 0x1, 0x76, 0x18AAAB, 0x947 }, + [ATHOS_LUT_CHAN_712750_IDX] = { 28510, 0x1, 0x76, 0x195555, 0x948 }, + [ATHOS_LUT_CHAN_712875_IDX] = { 28515, 0x1, 0x76, 0x1A0000, 0x948 }, + [ATHOS_LUT_CHAN_713000_IDX] = { 28520, 0x1, 0x76, 0x1AAAAB, 0x949 }, + [ATHOS_LUT_CHAN_713125_IDX] = { 28525, 0x1, 0x76, 0x1B5555, 0x949 }, + [ATHOS_LUT_CHAN_713250_IDX] = { 28530, 0x1, 0x76, 0x1C0000, 0x94A }, + [ATHOS_LUT_CHAN_713375_IDX] = { 28535, 0x1, 0x76, 0x1CAAAB, 0x94A }, + [ATHOS_LUT_CHAN_713500_IDX] = { 28540, 0x1, 0x76, 0x1D5555, 0x94A }, + [ATHOS_LUT_CHAN_713625_IDX] = { 28545, 0x1, 0x76, 0x1E0000, 0x94B }, + [ATHOS_LUT_CHAN_713750_IDX] = { 28550, 0x1, 0x76, 0x1EAAAB, 0x94B }, + [ATHOS_LUT_CHAN_713875_IDX] = { 28555, 0x1, 0x76, 0x1F5555, 0x94C }, + [ATHOS_LUT_CHAN_714000_IDX] = { 28560, 0x1, 0x77, 0x0, 0x94C }, + [ATHOS_LUT_CHAN_714125_IDX] = { 28565, 0x1, 0x77, 0xAAAB, 0x94C }, + [ATHOS_LUT_CHAN_714250_IDX] = { 28570, 0x1, 0x77, 0x15555, 0x94D }, + [ATHOS_LUT_CHAN_714375_IDX] = { 28575, 0x1, 0x77, 0x20000, 0x94D }, + [ATHOS_LUT_CHAN_714500_IDX] = { 28580, 0x1, 0x77, 0x2AAAB, 0x94E }, + [ATHOS_LUT_CHAN_714625_IDX] = { 28585, 0x1, 0x77, 0x35555, 0x94E }, + [ATHOS_LUT_CHAN_714750_IDX] = { 28590, 0x1, 0x77, 0x40000, 0x94F }, + [ATHOS_LUT_CHAN_714875_IDX] = { 28595, 0x1, 0x77, 0x4AAAB, 0x94F }, + [ATHOS_LUT_CHAN_715000_IDX] = { 28600, 0x1, 0x77, 0x55555, 0x94F }, + [ATHOS_LUT_CHAN_715125_IDX] = { 28605, 0x1, 0x77, 0x60000, 0x950 }, + [ATHOS_LUT_CHAN_715250_IDX] = { 28610, 0x1, 0x77, 0x6AAAB, 0x950 }, + [ATHOS_LUT_CHAN_715375_IDX] = { 28615, 0x1, 0x77, 0x75555, 0x951 }, + [ATHOS_LUT_CHAN_715500_IDX] = { 28620, 0x1, 0x77, 0x80000, 0x951 }, + [ATHOS_LUT_CHAN_715625_IDX] = { 28625, 0x1, 0x77, 0x8AAAB, 0x951 }, + [ATHOS_LUT_CHAN_715750_IDX] = { 28630, 0x1, 0x77, 0x95555, 0x952 }, + [ATHOS_LUT_CHAN_715875_IDX] = { 28635, 0x1, 0x77, 0xA0000, 0x952 }, + [ATHOS_LUT_CHAN_716000_IDX] = { 28640, 0x1, 0x77, 0xAAAAB, 0x953 }, + [ATHOS_LUT_CHAN_716125_IDX] = { 28645, 0x1, 0x77, 0xB5555, 0x953 }, + [ATHOS_LUT_CHAN_716250_IDX] = { 28650, 0x1, 0x77, 0xC0000, 0x954 }, + [ATHOS_LUT_CHAN_716375_IDX] = { 28655, 0x1, 0x77, 0xCAAAB, 0x954 }, + [ATHOS_LUT_CHAN_716500_IDX] = { 28660, 0x1, 0x77, 0xD5555, 0x954 }, + [ATHOS_LUT_CHAN_716625_IDX] = { 28665, 0x1, 0x77, 0xE0000, 0x955 }, + [ATHOS_LUT_CHAN_716750_IDX] = { 28670, 0x1, 0x77, 0xEAAAB, 0x955 }, + [ATHOS_LUT_CHAN_716875_IDX] = { 28675, 0x1, 0x77, 0xF5555, 0x956 }, + [ATHOS_LUT_CHAN_717000_IDX] = { 28680, 0x1, 0x77, 0x100000, 0x956 }, + [ATHOS_LUT_CHAN_717125_IDX] = { 28685, 0x1, 0x77, 0x10AAAB, 0x956 }, + [ATHOS_LUT_CHAN_717250_IDX] = { 28690, 0x1, 0x77, 0x115555, 0x957 }, + [ATHOS_LUT_CHAN_717375_IDX] = { 28695, 0x1, 0x77, 0x120000, 0x957 }, + [ATHOS_LUT_CHAN_717500_IDX] = { 28700, 0x1, 0x77, 0x12AAAB, 0x958 }, + [ATHOS_LUT_CHAN_717625_IDX] = { 28705, 0x1, 0x77, 0x135555, 0x958 }, + [ATHOS_LUT_CHAN_717750_IDX] = { 28710, 0x1, 0x77, 0x140000, 0x959 }, + [ATHOS_LUT_CHAN_717875_IDX] = { 28715, 0x1, 0x77, 0x14AAAB, 0x959 }, + [ATHOS_LUT_CHAN_718000_IDX] = { 28720, 0x1, 0x77, 0x155555, 0x959 }, + [ATHOS_LUT_CHAN_718125_IDX] = { 28725, 0x1, 0x77, 0x160000, 0x95A }, + [ATHOS_LUT_CHAN_718250_IDX] = { 28730, 0x1, 0x77, 0x16AAAB, 0x95A }, + [ATHOS_LUT_CHAN_718375_IDX] = { 28735, 0x1, 0x77, 0x175555, 0x95B }, + [ATHOS_LUT_CHAN_718500_IDX] = { 28740, 0x1, 0x77, 0x180000, 0x95B }, + [ATHOS_LUT_CHAN_718625_IDX] = { 28745, 0x1, 0x77, 0x18AAAB, 0x95B }, + [ATHOS_LUT_CHAN_718750_IDX] = { 28750, 0x1, 0x77, 0x195555, 0x95C }, + [ATHOS_LUT_CHAN_718875_IDX] = { 28755, 0x1, 0x77, 0x1A0000, 0x95C }, + [ATHOS_LUT_CHAN_719000_IDX] = { 28760, 0x1, 0x77, 0x1AAAAB, 0x95D }, + [ATHOS_LUT_CHAN_719125_IDX] = { 28765, 0x1, 0x77, 0x1B5555, 0x95D }, + [ATHOS_LUT_CHAN_719250_IDX] = { 28770, 0x1, 0x77, 0x1C0000, 0x95E }, + [ATHOS_LUT_CHAN_719375_IDX] = { 28775, 0x1, 0x77, 0x1CAAAB, 0x95E }, + [ATHOS_LUT_CHAN_719500_IDX] = { 28780, 0x1, 0x77, 0x1D5555, 0x95E }, + [ATHOS_LUT_CHAN_719625_IDX] = { 28785, 0x1, 0x77, 0x1E0000, 0x95F }, + [ATHOS_LUT_CHAN_719750_IDX] = { 28790, 0x1, 0x77, 0x1EAAAB, 0x95F }, + [ATHOS_LUT_CHAN_719875_IDX] = { 28795, 0x1, 0x77, 0x1F5555, 0x960 }, + [ATHOS_LUT_CHAN_720000_IDX] = { 28800, 0x1, 0x78, 0x0, 0x960 }, + [ATHOS_LUT_CHAN_720125_IDX] = { 28805, 0x1, 0x78, 0xAAAB, 0x960 }, + [ATHOS_LUT_CHAN_720250_IDX] = { 28810, 0x1, 0x78, 0x15555, 0x961 }, + [ATHOS_LUT_CHAN_720375_IDX] = { 28815, 0x1, 0x78, 0x20000, 0x961 }, + [ATHOS_LUT_CHAN_720500_IDX] = { 28820, 0x1, 0x78, 0x2AAAB, 0x962 }, + [ATHOS_LUT_CHAN_720625_IDX] = { 28825, 0x1, 0x78, 0x35555, 0x962 }, + [ATHOS_LUT_CHAN_720750_IDX] = { 28830, 0x1, 0x78, 0x40000, 0x963 }, + [ATHOS_LUT_CHAN_720875_IDX] = { 28835, 0x1, 0x78, 0x4AAAB, 0x963 }, + [ATHOS_LUT_CHAN_721000_IDX] = { 28840, 0x1, 0x78, 0x55555, 0x963 }, + [ATHOS_LUT_CHAN_721125_IDX] = { 28845, 0x1, 0x78, 0x60000, 0x964 }, + [ATHOS_LUT_CHAN_721250_IDX] = { 28850, 0x1, 0x78, 0x6AAAB, 0x964 }, + [ATHOS_LUT_CHAN_721375_IDX] = { 28855, 0x1, 0x78, 0x75555, 0x965 }, + [ATHOS_LUT_CHAN_721500_IDX] = { 28860, 0x1, 0x78, 0x80000, 0x965 } +}; + +const struct common_lut_line athos_lut_6g_60_mhz[ATHOS_LUT_CHAN_6G_MAX] = { + [ATHOS_LUT_CHAN_593000_IDX] = { 23720, 0x0, 0x41, 0x1C71C7, 0x7B9 }, + [ATHOS_LUT_CHAN_593125_IDX] = { 23725, 0x0, 0x41, 0x1CE38E, 0x7B9 }, + [ATHOS_LUT_CHAN_593250_IDX] = { 23730, 0x0, 0x41, 0x1D5555, 0x7BA }, + [ATHOS_LUT_CHAN_593375_IDX] = { 23735, 0x0, 0x41, 0x1DC71C, 0x7BA }, + [ATHOS_LUT_CHAN_593500_IDX] = { 23740, 0x0, 0x41, 0x1E38E4, 0x7BA }, + [ATHOS_LUT_CHAN_593625_IDX] = { 23745, 0x0, 0x41, 0x1EAAAB, 0x7BB }, + [ATHOS_LUT_CHAN_593750_IDX] = { 23750, 0x0, 0x41, 0x1F1C72, 0x7BB }, + [ATHOS_LUT_CHAN_593875_IDX] = { 23755, 0x0, 0x41, 0x1F8E39, 0x7BC }, + [ATHOS_LUT_CHAN_594000_IDX] = { 23760, 0x0, 0x42, 0x0, 0x7BC }, + [ATHOS_LUT_CHAN_594125_IDX] = { 23765, 0x0, 0x42, 0x71C7, 0x7BC }, + [ATHOS_LUT_CHAN_594250_IDX] = { 23770, 0x0, 0x42, 0xE38E, 0x7BD }, + [ATHOS_LUT_CHAN_594375_IDX] = { 23775, 0x0, 0x42, 0x15555, 0x7BD }, + [ATHOS_LUT_CHAN_594500_IDX] = { 23780, 0x0, 0x42, 0x1C71C, 0x7BE }, + [ATHOS_LUT_CHAN_594625_IDX] = { 23785, 0x0, 0x42, 0x238E4, 0x7BE }, + [ATHOS_LUT_CHAN_594750_IDX] = { 23790, 0x0, 0x42, 0x2AAAB, 0x7BF }, + [ATHOS_LUT_CHAN_594875_IDX] = { 23795, 0x0, 0x42, 0x31C72, 0x7BF }, + [ATHOS_LUT_CHAN_595000_IDX] = { 23800, 0x0, 0x42, 0x38E39, 0x7BF }, + [ATHOS_LUT_CHAN_595125_IDX] = { 23805, 0x0, 0x42, 0x40000, 0x7C0 }, + [ATHOS_LUT_CHAN_595250_IDX] = { 23810, 0x0, 0x42, 0x471C7, 0x7C0 }, + [ATHOS_LUT_CHAN_595375_IDX] = { 23815, 0x0, 0x42, 0x4E38E, 0x7C1 }, + [ATHOS_LUT_CHAN_595500_IDX] = { 23820, 0x0, 0x42, 0x55555, 0x7C1 }, + [ATHOS_LUT_CHAN_595625_IDX] = { 23825, 0x0, 0x42, 0x5C71C, 0x7C1 }, + [ATHOS_LUT_CHAN_595750_IDX] = { 23830, 0x0, 0x42, 0x638E4, 0x7C2 }, + [ATHOS_LUT_CHAN_595875_IDX] = { 23835, 0x0, 0x42, 0x6AAAB, 0x7C2 }, + [ATHOS_LUT_CHAN_596000_IDX] = { 23840, 0x0, 0x42, 0x71C72, 0x7C3 }, + [ATHOS_LUT_CHAN_596125_IDX] = { 23845, 0x0, 0x42, 0x78E39, 0x7C3 }, + [ATHOS_LUT_CHAN_596250_IDX] = { 23850, 0x0, 0x42, 0x80000, 0x7C4 }, + [ATHOS_LUT_CHAN_596375_IDX] = { 23855, 0x0, 0x42, 0x871C7, 0x7C4 }, + [ATHOS_LUT_CHAN_596500_IDX] = { 23860, 0x0, 0x42, 0x8E38E, 0x7C4 }, + [ATHOS_LUT_CHAN_596625_IDX] = { 23865, 0x0, 0x42, 0x95555, 0x7C5 }, + [ATHOS_LUT_CHAN_596750_IDX] = { 23870, 0x0, 0x42, 0x9C71C, 0x7C5 }, + [ATHOS_LUT_CHAN_596875_IDX] = { 23875, 0x0, 0x42, 0xA38E4, 0x7C6 }, + [ATHOS_LUT_CHAN_597000_IDX] = { 23880, 0x0, 0x42, 0xAAAAB, 0x7C6 }, + [ATHOS_LUT_CHAN_597125_IDX] = { 23885, 0x0, 0x42, 0xB1C72, 0x7C6 }, + [ATHOS_LUT_CHAN_597250_IDX] = { 23890, 0x0, 0x42, 0xB8E39, 0x7C7 }, + [ATHOS_LUT_CHAN_597375_IDX] = { 23895, 0x0, 0x42, 0xC0000, 0x7C7 }, + [ATHOS_LUT_CHAN_597500_IDX] = { 23900, 0x0, 0x42, 0xC71C7, 0x7C8 }, + [ATHOS_LUT_CHAN_597625_IDX] = { 23905, 0x0, 0x42, 0xCE38E, 0x7C8 }, + [ATHOS_LUT_CHAN_597750_IDX] = { 23910, 0x0, 0x42, 0xD5555, 0x7C9 }, + [ATHOS_LUT_CHAN_597875_IDX] = { 23915, 0x0, 0x42, 0xDC71C, 0x7C9 }, + [ATHOS_LUT_CHAN_598000_IDX] = { 23920, 0x0, 0x42, 0xE38E4, 0x7C9 }, + [ATHOS_LUT_CHAN_598125_IDX] = { 23925, 0x0, 0x42, 0xEAAAB, 0x7CA }, + [ATHOS_LUT_CHAN_598250_IDX] = { 23930, 0x0, 0x42, 0xF1C72, 0x7CA }, + [ATHOS_LUT_CHAN_598375_IDX] = { 23935, 0x0, 0x42, 0xF8E39, 0x7CB }, + [ATHOS_LUT_CHAN_598500_IDX] = { 23940, 0x0, 0x42, 0x100000, 0x7CB }, + [ATHOS_LUT_CHAN_598625_IDX] = { 23945, 0x0, 0x42, 0x1071C7, 0x7CB }, + [ATHOS_LUT_CHAN_598750_IDX] = { 23950, 0x0, 0x42, 0x10E38E, 0x7CC }, + [ATHOS_LUT_CHAN_598875_IDX] = { 23955, 0x0, 0x42, 0x115555, 0x7CC }, + [ATHOS_LUT_CHAN_599000_IDX] = { 23960, 0x0, 0x42, 0x11C71C, 0x7CD }, + [ATHOS_LUT_CHAN_599125_IDX] = { 23965, 0x0, 0x42, 0x1238E4, 0x7CD }, + [ATHOS_LUT_CHAN_599250_IDX] = { 23970, 0x0, 0x42, 0x12AAAB, 0x7CE }, + [ATHOS_LUT_CHAN_599375_IDX] = { 23975, 0x0, 0x42, 0x131C72, 0x7CE }, + [ATHOS_LUT_CHAN_599500_IDX] = { 23980, 0x0, 0x42, 0x138E39, 0x7CE }, + [ATHOS_LUT_CHAN_599625_IDX] = { 23985, 0x0, 0x42, 0x140000, 0x7CF }, + [ATHOS_LUT_CHAN_599750_IDX] = { 23990, 0x0, 0x42, 0x1471C7, 0x7CF }, + [ATHOS_LUT_CHAN_599875_IDX] = { 23995, 0x0, 0x42, 0x14E38E, 0x7D0 }, + [ATHOS_LUT_CHAN_600000_IDX] = { 24000, 0x0, 0x42, 0x155555, 0x7D0 }, + [ATHOS_LUT_CHAN_600125_IDX] = { 24005, 0x0, 0x42, 0x15C71C, 0x7D0 }, + [ATHOS_LUT_CHAN_600250_IDX] = { 24010, 0x0, 0x42, 0x1638E4, 0x7D1 }, + [ATHOS_LUT_CHAN_600375_IDX] = { 24015, 0x0, 0x42, 0x16AAAB, 0x7D1 }, + [ATHOS_LUT_CHAN_600500_IDX] = { 24020, 0x0, 0x42, 0x171C72, 0x7D2 }, + [ATHOS_LUT_CHAN_600625_IDX] = { 24025, 0x0, 0x42, 0x178E39, 0x7D2 }, + [ATHOS_LUT_CHAN_600750_IDX] = { 24030, 0x0, 0x42, 0x180000, 0x7D3 }, + [ATHOS_LUT_CHAN_600875_IDX] = { 24035, 0x0, 0x42, 0x1871C7, 0x7D3 }, + [ATHOS_LUT_CHAN_601000_IDX] = { 24040, 0x0, 0x42, 0x18E38E, 0x7D3 }, + [ATHOS_LUT_CHAN_601125_IDX] = { 24045, 0x0, 0x42, 0x195555, 0x7D4 }, + [ATHOS_LUT_CHAN_601250_IDX] = { 24050, 0x0, 0x42, 0x19C71C, 0x7D4 }, + [ATHOS_LUT_CHAN_601375_IDX] = { 24055, 0x0, 0x42, 0x1A38E4, 0x7D5 }, + [ATHOS_LUT_CHAN_601500_IDX] = { 24060, 0x0, 0x42, 0x1AAAAB, 0x7D5 }, + [ATHOS_LUT_CHAN_601625_IDX] = { 24065, 0x0, 0x42, 0x1B1C72, 0x7D5 }, + [ATHOS_LUT_CHAN_601750_IDX] = { 24070, 0x0, 0x42, 0x1B8E39, 0x7D6 }, + [ATHOS_LUT_CHAN_601875_IDX] = { 24075, 0x0, 0x42, 0x1C0000, 0x7D6 }, + [ATHOS_LUT_CHAN_602000_IDX] = { 24080, 0x0, 0x42, 0x1C71C7, 0x7D7 }, + [ATHOS_LUT_CHAN_602125_IDX] = { 24085, 0x0, 0x42, 0x1CE38E, 0x7D7 }, + [ATHOS_LUT_CHAN_602250_IDX] = { 24090, 0x0, 0x42, 0x1D5555, 0x7D8 }, + [ATHOS_LUT_CHAN_602375_IDX] = { 24095, 0x0, 0x42, 0x1DC71C, 0x7D8 }, + [ATHOS_LUT_CHAN_602500_IDX] = { 24100, 0x0, 0x42, 0x1E38E4, 0x7D8 }, + [ATHOS_LUT_CHAN_602625_IDX] = { 24105, 0x0, 0x42, 0x1EAAAB, 0x7D9 }, + [ATHOS_LUT_CHAN_602750_IDX] = { 24110, 0x0, 0x42, 0x1F1C72, 0x7D9 }, + [ATHOS_LUT_CHAN_602875_IDX] = { 24115, 0x0, 0x42, 0x1F8E39, 0x7DA }, + [ATHOS_LUT_CHAN_603000_IDX] = { 24120, 0x0, 0x43, 0x0, 0x7DA }, + [ATHOS_LUT_CHAN_603125_IDX] = { 24125, 0x0, 0x43, 0x71C7, 0x7DA }, + [ATHOS_LUT_CHAN_603250_IDX] = { 24130, 0x0, 0x43, 0xE38E, 0x7DB }, + [ATHOS_LUT_CHAN_603375_IDX] = { 24135, 0x0, 0x43, 0x15555, 0x7DB }, + [ATHOS_LUT_CHAN_603500_IDX] = { 24140, 0x0, 0x43, 0x1C71C, 0x7DC }, + [ATHOS_LUT_CHAN_603625_IDX] = { 24145, 0x0, 0x43, 0x238E4, 0x7DC }, + [ATHOS_LUT_CHAN_603750_IDX] = { 24150, 0x0, 0x43, 0x2AAAB, 0x7DD }, + [ATHOS_LUT_CHAN_603875_IDX] = { 24155, 0x0, 0x43, 0x31C72, 0x7DD }, + [ATHOS_LUT_CHAN_604000_IDX] = { 24160, 0x0, 0x43, 0x38E39, 0x7DD }, + [ATHOS_LUT_CHAN_604125_IDX] = { 24165, 0x0, 0x43, 0x40000, 0x7DE }, + [ATHOS_LUT_CHAN_604250_IDX] = { 24170, 0x0, 0x43, 0x471C7, 0x7DE }, + [ATHOS_LUT_CHAN_604375_IDX] = { 24175, 0x0, 0x43, 0x4E38E, 0x7DF }, + [ATHOS_LUT_CHAN_604500_IDX] = { 24180, 0x0, 0x43, 0x55555, 0x7DF }, + [ATHOS_LUT_CHAN_604625_IDX] = { 24185, 0x0, 0x43, 0x5C71C, 0x7DF }, + [ATHOS_LUT_CHAN_604750_IDX] = { 24190, 0x0, 0x43, 0x638E4, 0x7E0 }, + [ATHOS_LUT_CHAN_604875_IDX] = { 24195, 0x0, 0x43, 0x6AAAB, 0x7E0 }, + [ATHOS_LUT_CHAN_605000_IDX] = { 24200, 0x0, 0x43, 0x71C72, 0x7E1 }, + [ATHOS_LUT_CHAN_605125_IDX] = { 24205, 0x0, 0x43, 0x78E39, 0x7E1 }, + [ATHOS_LUT_CHAN_605250_IDX] = { 24210, 0x0, 0x43, 0x80000, 0x7E2 }, + [ATHOS_LUT_CHAN_605375_IDX] = { 24215, 0x0, 0x43, 0x871C7, 0x7E2 }, + [ATHOS_LUT_CHAN_605500_IDX] = { 24220, 0x0, 0x43, 0x8E38E, 0x7E2 }, + [ATHOS_LUT_CHAN_605625_IDX] = { 24225, 0x0, 0x43, 0x95555, 0x7E3 }, + [ATHOS_LUT_CHAN_605750_IDX] = { 24230, 0x0, 0x43, 0x9C71C, 0x7E3 }, + [ATHOS_LUT_CHAN_605875_IDX] = { 24235, 0x0, 0x43, 0xA38E4, 0x7E4 }, + [ATHOS_LUT_CHAN_606000_IDX] = { 24240, 0x0, 0x43, 0xAAAAB, 0x7E4 }, + [ATHOS_LUT_CHAN_606125_IDX] = { 24245, 0x0, 0x43, 0xB1C72, 0x7E4 }, + [ATHOS_LUT_CHAN_606250_IDX] = { 24250, 0x0, 0x43, 0xB8E39, 0x7E5 }, + [ATHOS_LUT_CHAN_606375_IDX] = { 24255, 0x0, 0x43, 0xC0000, 0x7E5 }, + [ATHOS_LUT_CHAN_606500_IDX] = { 24260, 0x0, 0x43, 0xC71C7, 0x7E6 }, + [ATHOS_LUT_CHAN_606625_IDX] = { 24265, 0x0, 0x43, 0xCE38E, 0x7E6 }, + [ATHOS_LUT_CHAN_606750_IDX] = { 24270, 0x0, 0x43, 0xD5555, 0x7E7 }, + [ATHOS_LUT_CHAN_606875_IDX] = { 24275, 0x0, 0x43, 0xDC71C, 0x7E7 }, + [ATHOS_LUT_CHAN_607000_IDX] = { 24280, 0x0, 0x43, 0xE38E4, 0x7E7 }, + [ATHOS_LUT_CHAN_607125_IDX] = { 24285, 0x0, 0x43, 0xEAAAB, 0x7E8 }, + [ATHOS_LUT_CHAN_607250_IDX] = { 24290, 0x0, 0x43, 0xF1C72, 0x7E8 }, + [ATHOS_LUT_CHAN_607375_IDX] = { 24295, 0x0, 0x43, 0xF8E39, 0x7E9 }, + [ATHOS_LUT_CHAN_607500_IDX] = { 24300, 0x0, 0x43, 0x100000, 0x7E9 }, + [ATHOS_LUT_CHAN_607625_IDX] = { 24305, 0x0, 0x43, 0x1071C7, 0x7E9 }, + [ATHOS_LUT_CHAN_607750_IDX] = { 24310, 0x0, 0x43, 0x10E38E, 0x7EA }, + [ATHOS_LUT_CHAN_607875_IDX] = { 24315, 0x0, 0x43, 0x115555, 0x7EA }, + [ATHOS_LUT_CHAN_608000_IDX] = { 24320, 0x0, 0x43, 0x11C71C, 0x7EB }, + [ATHOS_LUT_CHAN_608125_IDX] = { 24325, 0x0, 0x43, 0x1238E4, 0x7EB }, + [ATHOS_LUT_CHAN_608250_IDX] = { 24330, 0x0, 0x43, 0x12AAAB, 0x7EC }, + [ATHOS_LUT_CHAN_608375_IDX] = { 24335, 0x0, 0x43, 0x131C72, 0x7EC }, + [ATHOS_LUT_CHAN_608500_IDX] = { 24340, 0x0, 0x43, 0x138E39, 0x7EC }, + [ATHOS_LUT_CHAN_608625_IDX] = { 24345, 0x0, 0x43, 0x140000, 0x7ED }, + [ATHOS_LUT_CHAN_608750_IDX] = { 24350, 0x0, 0x43, 0x1471C7, 0x7ED }, + [ATHOS_LUT_CHAN_608875_IDX] = { 24355, 0x0, 0x43, 0x14E38E, 0x7EE }, + [ATHOS_LUT_CHAN_609000_IDX] = { 24360, 0x0, 0x43, 0x155555, 0x7EE }, + [ATHOS_LUT_CHAN_609125_IDX] = { 24365, 0x0, 0x43, 0x15C71C, 0x7EE }, + [ATHOS_LUT_CHAN_609250_IDX] = { 24370, 0x0, 0x43, 0x1638E4, 0x7EF }, + [ATHOS_LUT_CHAN_609375_IDX] = { 24375, 0x0, 0x43, 0x16AAAB, 0x7EF }, + [ATHOS_LUT_CHAN_609500_IDX] = { 24380, 0x0, 0x43, 0x171C72, 0x7F0 }, + [ATHOS_LUT_CHAN_609625_IDX] = { 24385, 0x0, 0x43, 0x178E39, 0x7F0 }, + [ATHOS_LUT_CHAN_609750_IDX] = { 24390, 0x0, 0x43, 0x180000, 0x7F1 }, + [ATHOS_LUT_CHAN_609875_IDX] = { 24395, 0x0, 0x43, 0x1871C7, 0x7F1 }, + [ATHOS_LUT_CHAN_610000_IDX] = { 24400, 0x1, 0x43, 0x18E38E, 0x7F1 }, + [ATHOS_LUT_CHAN_610125_IDX] = { 24405, 0x1, 0x43, 0x195555, 0x7F2 }, + [ATHOS_LUT_CHAN_610250_IDX] = { 24410, 0x1, 0x43, 0x19C71C, 0x7F2 }, + [ATHOS_LUT_CHAN_610375_IDX] = { 24415, 0x1, 0x43, 0x1A38E4, 0x7F3 }, + [ATHOS_LUT_CHAN_610500_IDX] = { 24420, 0x1, 0x43, 0x1AAAAB, 0x7F3 }, + [ATHOS_LUT_CHAN_610625_IDX] = { 24425, 0x1, 0x43, 0x1B1C72, 0x7F3 }, + [ATHOS_LUT_CHAN_610750_IDX] = { 24430, 0x1, 0x43, 0x1B8E39, 0x7F4 }, + [ATHOS_LUT_CHAN_610875_IDX] = { 24435, 0x1, 0x43, 0x1C0000, 0x7F4 }, + [ATHOS_LUT_CHAN_611000_IDX] = { 24440, 0x1, 0x43, 0x1C71C7, 0x7F5 }, + [ATHOS_LUT_CHAN_611125_IDX] = { 24445, 0x1, 0x43, 0x1CE38E, 0x7F5 }, + [ATHOS_LUT_CHAN_611250_IDX] = { 24450, 0x1, 0x43, 0x1D5555, 0x7F6 }, + [ATHOS_LUT_CHAN_611375_IDX] = { 24455, 0x1, 0x43, 0x1DC71C, 0x7F6 }, + [ATHOS_LUT_CHAN_611500_IDX] = { 24460, 0x1, 0x43, 0x1E38E4, 0x7F6 }, + [ATHOS_LUT_CHAN_611625_IDX] = { 24465, 0x1, 0x43, 0x1EAAAB, 0x7F7 }, + [ATHOS_LUT_CHAN_611750_IDX] = { 24470, 0x1, 0x43, 0x1F1C72, 0x7F7 }, + [ATHOS_LUT_CHAN_611875_IDX] = { 24475, 0x1, 0x43, 0x1F8E39, 0x7F8 }, + [ATHOS_LUT_CHAN_612000_IDX] = { 24480, 0x1, 0x44, 0x0, 0x7F8 }, + [ATHOS_LUT_CHAN_612125_IDX] = { 24485, 0x1, 0x44, 0x71C7, 0x7F8 }, + [ATHOS_LUT_CHAN_612250_IDX] = { 24490, 0x1, 0x44, 0xE38E, 0x7F9 }, + [ATHOS_LUT_CHAN_612375_IDX] = { 24495, 0x1, 0x44, 0x15555, 0x7F9 }, + [ATHOS_LUT_CHAN_612500_IDX] = { 24500, 0x1, 0x44, 0x1C71C, 0x7FA }, + [ATHOS_LUT_CHAN_612625_IDX] = { 24505, 0x1, 0x44, 0x238E4, 0x7FA }, + [ATHOS_LUT_CHAN_612750_IDX] = { 24510, 0x1, 0x44, 0x2AAAB, 0x7FB }, + [ATHOS_LUT_CHAN_612875_IDX] = { 24515, 0x1, 0x44, 0x31C72, 0x7FB }, + [ATHOS_LUT_CHAN_613000_IDX] = { 24520, 0x1, 0x44, 0x38E39, 0x7FB }, + [ATHOS_LUT_CHAN_613125_IDX] = { 24525, 0x1, 0x44, 0x40000, 0x7FC }, + [ATHOS_LUT_CHAN_613250_IDX] = { 24530, 0x1, 0x44, 0x471C7, 0x7FC }, + [ATHOS_LUT_CHAN_613375_IDX] = { 24535, 0x1, 0x44, 0x4E38E, 0x7FD }, + [ATHOS_LUT_CHAN_613500_IDX] = { 24540, 0x1, 0x44, 0x55555, 0x7FD }, + [ATHOS_LUT_CHAN_613625_IDX] = { 24545, 0x1, 0x44, 0x5C71C, 0x7FD }, + [ATHOS_LUT_CHAN_613750_IDX] = { 24550, 0x1, 0x44, 0x638E4, 0x7FE }, + [ATHOS_LUT_CHAN_613875_IDX] = { 24555, 0x1, 0x44, 0x6AAAB, 0x7FE }, + [ATHOS_LUT_CHAN_614000_IDX] = { 24560, 0x1, 0x44, 0x71C72, 0x7FF }, + [ATHOS_LUT_CHAN_614125_IDX] = { 24565, 0x1, 0x44, 0x78E39, 0x7FF }, + [ATHOS_LUT_CHAN_614250_IDX] = { 24570, 0x1, 0x44, 0x80000, 0x800 }, + [ATHOS_LUT_CHAN_614375_IDX] = { 24575, 0x1, 0x44, 0x871C7, 0x800 }, + [ATHOS_LUT_CHAN_614500_IDX] = { 24580, 0x1, 0x44, 0x8E38E, 0x800 }, + [ATHOS_LUT_CHAN_614625_IDX] = { 24585, 0x1, 0x44, 0x95555, 0x801 }, + [ATHOS_LUT_CHAN_614750_IDX] = { 24590, 0x1, 0x44, 0x9C71C, 0x801 }, + [ATHOS_LUT_CHAN_614875_IDX] = { 24595, 0x1, 0x44, 0xA38E4, 0x802 }, + [ATHOS_LUT_CHAN_615000_IDX] = { 24600, 0x1, 0x44, 0xAAAAB, 0x802 }, + [ATHOS_LUT_CHAN_615125_IDX] = { 24605, 0x1, 0x44, 0xB1C72, 0x802 }, + [ATHOS_LUT_CHAN_615250_IDX] = { 24610, 0x1, 0x44, 0xB8E39, 0x803 }, + [ATHOS_LUT_CHAN_615375_IDX] = { 24615, 0x1, 0x44, 0xC0000, 0x803 }, + [ATHOS_LUT_CHAN_615500_IDX] = { 24620, 0x1, 0x44, 0xC71C7, 0x804 }, + [ATHOS_LUT_CHAN_615625_IDX] = { 24625, 0x1, 0x44, 0xCE38E, 0x804 }, + [ATHOS_LUT_CHAN_615750_IDX] = { 24630, 0x1, 0x44, 0xD5555, 0x805 }, + [ATHOS_LUT_CHAN_615875_IDX] = { 24635, 0x1, 0x44, 0xDC71C, 0x805 }, + [ATHOS_LUT_CHAN_616000_IDX] = { 24640, 0x1, 0x44, 0xE38E4, 0x805 }, + [ATHOS_LUT_CHAN_616125_IDX] = { 24645, 0x1, 0x44, 0xEAAAB, 0x806 }, + [ATHOS_LUT_CHAN_616250_IDX] = { 24650, 0x1, 0x44, 0xF1C72, 0x806 }, + [ATHOS_LUT_CHAN_616375_IDX] = { 24655, 0x1, 0x44, 0xF8E39, 0x807 }, + [ATHOS_LUT_CHAN_616500_IDX] = { 24660, 0x1, 0x44, 0x100000, 0x807 }, + [ATHOS_LUT_CHAN_616625_IDX] = { 24665, 0x1, 0x44, 0x1071C7, 0x807 }, + [ATHOS_LUT_CHAN_616750_IDX] = { 24670, 0x1, 0x44, 0x10E38E, 0x808 }, + [ATHOS_LUT_CHAN_616875_IDX] = { 24675, 0x1, 0x44, 0x115555, 0x808 }, + [ATHOS_LUT_CHAN_617000_IDX] = { 24680, 0x1, 0x44, 0x11C71C, 0x809 }, + [ATHOS_LUT_CHAN_617125_IDX] = { 24685, 0x1, 0x44, 0x1238E4, 0x809 }, + [ATHOS_LUT_CHAN_617250_IDX] = { 24690, 0x1, 0x44, 0x12AAAB, 0x80A }, + [ATHOS_LUT_CHAN_617375_IDX] = { 24695, 0x1, 0x44, 0x131C72, 0x80A }, + [ATHOS_LUT_CHAN_617500_IDX] = { 24700, 0x1, 0x44, 0x138E39, 0x80A }, + [ATHOS_LUT_CHAN_617625_IDX] = { 24705, 0x1, 0x44, 0x140000, 0x80B }, + [ATHOS_LUT_CHAN_617750_IDX] = { 24710, 0x1, 0x44, 0x1471C7, 0x80B }, + [ATHOS_LUT_CHAN_617875_IDX] = { 24715, 0x1, 0x44, 0x14E38E, 0x80C }, + [ATHOS_LUT_CHAN_618000_IDX] = { 24720, 0x1, 0x44, 0x155555, 0x80C }, + [ATHOS_LUT_CHAN_618125_IDX] = { 24725, 0x1, 0x44, 0x15C71C, 0x80C }, + [ATHOS_LUT_CHAN_618250_IDX] = { 24730, 0x1, 0x44, 0x1638E4, 0x80D }, + [ATHOS_LUT_CHAN_618375_IDX] = { 24735, 0x1, 0x44, 0x16AAAB, 0x80D }, + [ATHOS_LUT_CHAN_618500_IDX] = { 24740, 0x1, 0x44, 0x171C72, 0x80E }, + [ATHOS_LUT_CHAN_618625_IDX] = { 24745, 0x1, 0x44, 0x178E39, 0x80E }, + [ATHOS_LUT_CHAN_618750_IDX] = { 24750, 0x1, 0x44, 0x180000, 0x80F }, + [ATHOS_LUT_CHAN_618875_IDX] = { 24755, 0x1, 0x44, 0x1871C7, 0x80F }, + [ATHOS_LUT_CHAN_619000_IDX] = { 24760, 0x1, 0x44, 0x18E38E, 0x80F }, + [ATHOS_LUT_CHAN_619125_IDX] = { 24765, 0x1, 0x44, 0x195555, 0x810 }, + [ATHOS_LUT_CHAN_619250_IDX] = { 24770, 0x1, 0x44, 0x19C71C, 0x810 }, + [ATHOS_LUT_CHAN_619375_IDX] = { 24775, 0x1, 0x44, 0x1A38E4, 0x811 }, + [ATHOS_LUT_CHAN_619500_IDX] = { 24780, 0x1, 0x44, 0x1AAAAB, 0x811 }, + [ATHOS_LUT_CHAN_619625_IDX] = { 24785, 0x1, 0x44, 0x1B1C72, 0x811 }, + [ATHOS_LUT_CHAN_619750_IDX] = { 24790, 0x1, 0x44, 0x1B8E39, 0x812 }, + [ATHOS_LUT_CHAN_619875_IDX] = { 24795, 0x1, 0x44, 0x1C0000, 0x812 }, + [ATHOS_LUT_CHAN_620000_IDX] = { 24800, 0x1, 0x44, 0x1C71C7, 0x813 }, + [ATHOS_LUT_CHAN_620125_IDX] = { 24805, 0x1, 0x44, 0x1CE38E, 0x813 }, + [ATHOS_LUT_CHAN_620250_IDX] = { 24810, 0x1, 0x44, 0x1D5555, 0x814 }, + [ATHOS_LUT_CHAN_620375_IDX] = { 24815, 0x1, 0x44, 0x1DC71C, 0x814 }, + [ATHOS_LUT_CHAN_620500_IDX] = { 24820, 0x1, 0x44, 0x1E38E4, 0x814 }, + [ATHOS_LUT_CHAN_620625_IDX] = { 24825, 0x1, 0x44, 0x1EAAAB, 0x815 }, + [ATHOS_LUT_CHAN_620750_IDX] = { 24830, 0x1, 0x44, 0x1F1C72, 0x815 }, + [ATHOS_LUT_CHAN_620875_IDX] = { 24835, 0x1, 0x44, 0x1F8E39, 0x816 }, + [ATHOS_LUT_CHAN_621000_IDX] = { 24840, 0x1, 0x45, 0x0, 0x816 }, + [ATHOS_LUT_CHAN_621125_IDX] = { 24845, 0x1, 0x45, 0x71C7, 0x816 }, + [ATHOS_LUT_CHAN_621250_IDX] = { 24850, 0x1, 0x45, 0xE38E, 0x817 }, + [ATHOS_LUT_CHAN_621375_IDX] = { 24855, 0x1, 0x45, 0x15555, 0x817 }, + [ATHOS_LUT_CHAN_621500_IDX] = { 24860, 0x1, 0x45, 0x1C71C, 0x818 }, + [ATHOS_LUT_CHAN_621625_IDX] = { 24865, 0x1, 0x45, 0x238E4, 0x818 }, + [ATHOS_LUT_CHAN_621750_IDX] = { 24870, 0x1, 0x45, 0x2AAAB, 0x819 }, + [ATHOS_LUT_CHAN_621875_IDX] = { 24875, 0x1, 0x45, 0x31C72, 0x819 }, + [ATHOS_LUT_CHAN_622000_IDX] = { 24880, 0x1, 0x45, 0x38E39, 0x819 }, + [ATHOS_LUT_CHAN_622125_IDX] = { 24885, 0x1, 0x45, 0x40000, 0x81A }, + [ATHOS_LUT_CHAN_622250_IDX] = { 24890, 0x1, 0x45, 0x471C7, 0x81A }, + [ATHOS_LUT_CHAN_622375_IDX] = { 24895, 0x1, 0x45, 0x4E38E, 0x81B }, + [ATHOS_LUT_CHAN_622500_IDX] = { 24900, 0x1, 0x45, 0x55555, 0x81B }, + [ATHOS_LUT_CHAN_622625_IDX] = { 24905, 0x1, 0x45, 0x5C71C, 0x81B }, + [ATHOS_LUT_CHAN_622750_IDX] = { 24910, 0x1, 0x45, 0x638E4, 0x81C }, + [ATHOS_LUT_CHAN_622875_IDX] = { 24915, 0x1, 0x45, 0x6AAAB, 0x81C }, + [ATHOS_LUT_CHAN_623000_IDX] = { 24920, 0x1, 0x45, 0x71C72, 0x81D }, + [ATHOS_LUT_CHAN_623125_IDX] = { 24925, 0x1, 0x45, 0x78E39, 0x81D }, + [ATHOS_LUT_CHAN_623250_IDX] = { 24930, 0x1, 0x45, 0x80000, 0x81E }, + [ATHOS_LUT_CHAN_623375_IDX] = { 24935, 0x1, 0x45, 0x871C7, 0x81E }, + [ATHOS_LUT_CHAN_623500_IDX] = { 24940, 0x1, 0x45, 0x8E38E, 0x81E }, + [ATHOS_LUT_CHAN_623625_IDX] = { 24945, 0x1, 0x45, 0x95555, 0x81F }, + [ATHOS_LUT_CHAN_623750_IDX] = { 24950, 0x1, 0x45, 0x9C71C, 0x81F }, + [ATHOS_LUT_CHAN_623875_IDX] = { 24955, 0x1, 0x45, 0xA38E4, 0x820 }, + [ATHOS_LUT_CHAN_624000_IDX] = { 24960, 0x1, 0x45, 0xAAAAB, 0x820 }, + [ATHOS_LUT_CHAN_624125_IDX] = { 24965, 0x1, 0x45, 0xB1C72, 0x820 }, + [ATHOS_LUT_CHAN_624250_IDX] = { 24970, 0x1, 0x45, 0xB8E39, 0x821 }, + [ATHOS_LUT_CHAN_624375_IDX] = { 24975, 0x1, 0x45, 0xC0000, 0x821 }, + [ATHOS_LUT_CHAN_624500_IDX] = { 24980, 0x1, 0x45, 0xC71C7, 0x822 }, + [ATHOS_LUT_CHAN_624625_IDX] = { 24985, 0x1, 0x45, 0xCE38E, 0x822 }, + [ATHOS_LUT_CHAN_624750_IDX] = { 24990, 0x1, 0x45, 0xD5555, 0x823 }, + [ATHOS_LUT_CHAN_624875_IDX] = { 24995, 0x1, 0x45, 0xDC71C, 0x823 }, + [ATHOS_LUT_CHAN_625000_IDX] = { 25000, 0x1, 0x45, 0xE38E4, 0x823 }, + [ATHOS_LUT_CHAN_625125_IDX] = { 25005, 0x1, 0x45, 0xEAAAB, 0x824 }, + [ATHOS_LUT_CHAN_625250_IDX] = { 25010, 0x1, 0x45, 0xF1C72, 0x824 }, + [ATHOS_LUT_CHAN_625375_IDX] = { 25015, 0x1, 0x45, 0xF8E39, 0x825 }, + [ATHOS_LUT_CHAN_625500_IDX] = { 25020, 0x1, 0x45, 0x100000, 0x825 }, + [ATHOS_LUT_CHAN_625625_IDX] = { 25025, 0x1, 0x45, 0x1071C7, 0x825 }, + [ATHOS_LUT_CHAN_625750_IDX] = { 25030, 0x1, 0x45, 0x10E38E, 0x826 }, + [ATHOS_LUT_CHAN_625875_IDX] = { 25035, 0x1, 0x45, 0x115555, 0x826 }, + [ATHOS_LUT_CHAN_626000_IDX] = { 25040, 0x1, 0x45, 0x11C71C, 0x827 }, + [ATHOS_LUT_CHAN_626125_IDX] = { 25045, 0x1, 0x45, 0x1238E4, 0x827 }, + [ATHOS_LUT_CHAN_626250_IDX] = { 25050, 0x1, 0x45, 0x12AAAB, 0x828 }, + [ATHOS_LUT_CHAN_626375_IDX] = { 25055, 0x1, 0x45, 0x131C72, 0x828 }, + [ATHOS_LUT_CHAN_626500_IDX] = { 25060, 0x1, 0x45, 0x138E39, 0x828 }, + [ATHOS_LUT_CHAN_626625_IDX] = { 25065, 0x1, 0x45, 0x140000, 0x829 }, + [ATHOS_LUT_CHAN_626750_IDX] = { 25070, 0x1, 0x45, 0x1471C7, 0x829 }, + [ATHOS_LUT_CHAN_626875_IDX] = { 25075, 0x1, 0x45, 0x14E38E, 0x82A }, + [ATHOS_LUT_CHAN_627000_IDX] = { 25080, 0x1, 0x45, 0x155555, 0x82A }, + [ATHOS_LUT_CHAN_627125_IDX] = { 25085, 0x1, 0x45, 0x15C71C, 0x82A }, + [ATHOS_LUT_CHAN_627250_IDX] = { 25090, 0x1, 0x45, 0x1638E4, 0x82B }, + [ATHOS_LUT_CHAN_627375_IDX] = { 25095, 0x1, 0x45, 0x16AAAB, 0x82B }, + [ATHOS_LUT_CHAN_627500_IDX] = { 25100, 0x1, 0x45, 0x171C72, 0x82C }, + [ATHOS_LUT_CHAN_627625_IDX] = { 25105, 0x1, 0x45, 0x178E39, 0x82C }, + [ATHOS_LUT_CHAN_627750_IDX] = { 25110, 0x1, 0x45, 0x180000, 0x82D }, + [ATHOS_LUT_CHAN_627875_IDX] = { 25115, 0x1, 0x45, 0x1871C7, 0x82D }, + [ATHOS_LUT_CHAN_628000_IDX] = { 25120, 0x1, 0x45, 0x18E38E, 0x82D }, + [ATHOS_LUT_CHAN_628125_IDX] = { 25125, 0x1, 0x45, 0x195555, 0x82E }, + [ATHOS_LUT_CHAN_628250_IDX] = { 25130, 0x1, 0x45, 0x19C71C, 0x82E }, + [ATHOS_LUT_CHAN_628375_IDX] = { 25135, 0x1, 0x45, 0x1A38E4, 0x82F }, + [ATHOS_LUT_CHAN_628500_IDX] = { 25140, 0x1, 0x45, 0x1AAAAB, 0x82F }, + [ATHOS_LUT_CHAN_628625_IDX] = { 25145, 0x1, 0x45, 0x1B1C72, 0x82F }, + [ATHOS_LUT_CHAN_628750_IDX] = { 25150, 0x1, 0x45, 0x1B8E39, 0x830 }, + [ATHOS_LUT_CHAN_628875_IDX] = { 25155, 0x1, 0x45, 0x1C0000, 0x830 }, + [ATHOS_LUT_CHAN_629000_IDX] = { 25160, 0x1, 0x45, 0x1C71C7, 0x831 }, + [ATHOS_LUT_CHAN_629125_IDX] = { 25165, 0x1, 0x45, 0x1CE38E, 0x831 }, + [ATHOS_LUT_CHAN_629250_IDX] = { 25170, 0x1, 0x45, 0x1D5555, 0x832 }, + [ATHOS_LUT_CHAN_629375_IDX] = { 25175, 0x1, 0x45, 0x1DC71C, 0x832 }, + [ATHOS_LUT_CHAN_629500_IDX] = { 25180, 0x1, 0x45, 0x1E38E4, 0x832 }, + [ATHOS_LUT_CHAN_629625_IDX] = { 25185, 0x1, 0x45, 0x1EAAAB, 0x833 }, + [ATHOS_LUT_CHAN_629750_IDX] = { 25190, 0x1, 0x45, 0x1F1C72, 0x833 }, + [ATHOS_LUT_CHAN_629875_IDX] = { 25195, 0x1, 0x45, 0x1F8E39, 0x834 }, + [ATHOS_LUT_CHAN_630000_IDX] = { 25200, 0x1, 0x46, 0x0, 0x834 }, + [ATHOS_LUT_CHAN_630125_IDX] = { 25205, 0x1, 0x46, 0x71C7, 0x834 }, + [ATHOS_LUT_CHAN_630250_IDX] = { 25210, 0x1, 0x46, 0xE38E, 0x835 }, + [ATHOS_LUT_CHAN_630375_IDX] = { 25215, 0x1, 0x46, 0x15555, 0x835 }, + [ATHOS_LUT_CHAN_630500_IDX] = { 25220, 0x1, 0x46, 0x1C71C, 0x836 }, + [ATHOS_LUT_CHAN_630625_IDX] = { 25225, 0x1, 0x46, 0x238E4, 0x836 }, + [ATHOS_LUT_CHAN_630750_IDX] = { 25230, 0x1, 0x46, 0x2AAAB, 0x837 }, + [ATHOS_LUT_CHAN_630875_IDX] = { 25235, 0x1, 0x46, 0x31C72, 0x837 }, + [ATHOS_LUT_CHAN_631000_IDX] = { 25240, 0x1, 0x46, 0x38E39, 0x837 }, + [ATHOS_LUT_CHAN_631125_IDX] = { 25245, 0x1, 0x46, 0x40000, 0x838 }, + [ATHOS_LUT_CHAN_631250_IDX] = { 25250, 0x1, 0x46, 0x471C7, 0x838 }, + [ATHOS_LUT_CHAN_631375_IDX] = { 25255, 0x1, 0x46, 0x4E38E, 0x839 }, + [ATHOS_LUT_CHAN_631500_IDX] = { 25260, 0x1, 0x46, 0x55555, 0x839 }, + [ATHOS_LUT_CHAN_631625_IDX] = { 25265, 0x1, 0x46, 0x5C71C, 0x839 }, + [ATHOS_LUT_CHAN_631750_IDX] = { 25270, 0x1, 0x46, 0x638E4, 0x83A }, + [ATHOS_LUT_CHAN_631875_IDX] = { 25275, 0x1, 0x46, 0x6AAAB, 0x83A }, + [ATHOS_LUT_CHAN_632000_IDX] = { 25280, 0x1, 0x46, 0x71C72, 0x83B }, + [ATHOS_LUT_CHAN_632125_IDX] = { 25285, 0x1, 0x46, 0x78E39, 0x83B }, + [ATHOS_LUT_CHAN_632250_IDX] = { 25290, 0x1, 0x46, 0x80000, 0x83C }, + [ATHOS_LUT_CHAN_632375_IDX] = { 25295, 0x1, 0x46, 0x871C7, 0x83C }, + [ATHOS_LUT_CHAN_632500_IDX] = { 25300, 0x1, 0x46, 0x8E38E, 0x83C }, + [ATHOS_LUT_CHAN_632625_IDX] = { 25305, 0x1, 0x46, 0x95555, 0x83D }, + [ATHOS_LUT_CHAN_632750_IDX] = { 25310, 0x1, 0x46, 0x9C71C, 0x83D }, + [ATHOS_LUT_CHAN_632875_IDX] = { 25315, 0x1, 0x46, 0xA38E4, 0x83E }, + [ATHOS_LUT_CHAN_633000_IDX] = { 25320, 0x1, 0x46, 0xAAAAB, 0x83E }, + [ATHOS_LUT_CHAN_633125_IDX] = { 25325, 0x1, 0x46, 0xB1C72, 0x83E }, + [ATHOS_LUT_CHAN_633250_IDX] = { 25330, 0x1, 0x46, 0xB8E39, 0x83F }, + [ATHOS_LUT_CHAN_633375_IDX] = { 25335, 0x1, 0x46, 0xC0000, 0x83F }, + [ATHOS_LUT_CHAN_633500_IDX] = { 25340, 0x1, 0x46, 0xC71C7, 0x840 }, + [ATHOS_LUT_CHAN_633625_IDX] = { 25345, 0x1, 0x46, 0xCE38E, 0x840 }, + [ATHOS_LUT_CHAN_633750_IDX] = { 25350, 0x1, 0x46, 0xD5555, 0x841 }, + [ATHOS_LUT_CHAN_633875_IDX] = { 25355, 0x1, 0x46, 0xDC71C, 0x841 }, + [ATHOS_LUT_CHAN_634000_IDX] = { 25360, 0x1, 0x46, 0xE38E4, 0x841 }, + [ATHOS_LUT_CHAN_634125_IDX] = { 25365, 0x1, 0x46, 0xEAAAB, 0x842 }, + [ATHOS_LUT_CHAN_634250_IDX] = { 25370, 0x1, 0x46, 0xF1C72, 0x842 }, + [ATHOS_LUT_CHAN_634375_IDX] = { 25375, 0x1, 0x46, 0xF8E39, 0x843 }, + [ATHOS_LUT_CHAN_634500_IDX] = { 25380, 0x1, 0x46, 0x100000, 0x843 }, + [ATHOS_LUT_CHAN_634625_IDX] = { 25385, 0x1, 0x46, 0x1071C7, 0x843 }, + [ATHOS_LUT_CHAN_634750_IDX] = { 25390, 0x1, 0x46, 0x10E38E, 0x844 }, + [ATHOS_LUT_CHAN_634875_IDX] = { 25395, 0x1, 0x46, 0x115555, 0x844 }, + [ATHOS_LUT_CHAN_635000_IDX] = { 25400, 0x1, 0x46, 0x11C71C, 0x845 }, + [ATHOS_LUT_CHAN_635125_IDX] = { 25405, 0x1, 0x46, 0x1238E4, 0x845 }, + [ATHOS_LUT_CHAN_635250_IDX] = { 25410, 0x1, 0x46, 0x12AAAB, 0x846 }, + [ATHOS_LUT_CHAN_635375_IDX] = { 25415, 0x1, 0x46, 0x131C72, 0x846 }, + [ATHOS_LUT_CHAN_635500_IDX] = { 25420, 0x1, 0x46, 0x138E39, 0x846 }, + [ATHOS_LUT_CHAN_635625_IDX] = { 25425, 0x1, 0x46, 0x140000, 0x847 }, + [ATHOS_LUT_CHAN_635750_IDX] = { 25430, 0x1, 0x46, 0x1471C7, 0x847 }, + [ATHOS_LUT_CHAN_635875_IDX] = { 25435, 0x1, 0x46, 0x14E38E, 0x848 }, + [ATHOS_LUT_CHAN_636000_IDX] = { 25440, 0x1, 0x46, 0x155555, 0x848 }, + [ATHOS_LUT_CHAN_636125_IDX] = { 25445, 0x1, 0x46, 0x15C71C, 0x848 }, + [ATHOS_LUT_CHAN_636250_IDX] = { 25450, 0x1, 0x46, 0x1638E4, 0x849 }, + [ATHOS_LUT_CHAN_636375_IDX] = { 25455, 0x1, 0x46, 0x16AAAB, 0x849 }, + [ATHOS_LUT_CHAN_636500_IDX] = { 25460, 0x1, 0x46, 0x171C72, 0x84A }, + [ATHOS_LUT_CHAN_636625_IDX] = { 25465, 0x1, 0x46, 0x178E39, 0x84A }, + [ATHOS_LUT_CHAN_636750_IDX] = { 25470, 0x1, 0x46, 0x180000, 0x84B }, + [ATHOS_LUT_CHAN_636875_IDX] = { 25475, 0x1, 0x46, 0x1871C7, 0x84B }, + [ATHOS_LUT_CHAN_637000_IDX] = { 25480, 0x1, 0x46, 0x18E38E, 0x84B }, + [ATHOS_LUT_CHAN_637125_IDX] = { 25485, 0x1, 0x46, 0x195555, 0x84C }, + [ATHOS_LUT_CHAN_637250_IDX] = { 25490, 0x1, 0x46, 0x19C71C, 0x84C }, + [ATHOS_LUT_CHAN_637375_IDX] = { 25495, 0x1, 0x46, 0x1A38E4, 0x84D }, + [ATHOS_LUT_CHAN_637500_IDX] = { 25500, 0x1, 0x46, 0x1AAAAB, 0x84D }, + [ATHOS_LUT_CHAN_637625_IDX] = { 25505, 0x1, 0x46, 0x1B1C72, 0x84D }, + [ATHOS_LUT_CHAN_637750_IDX] = { 25510, 0x1, 0x46, 0x1B8E39, 0x84E }, + [ATHOS_LUT_CHAN_637875_IDX] = { 25515, 0x1, 0x46, 0x1C0000, 0x84E }, + [ATHOS_LUT_CHAN_638000_IDX] = { 25520, 0x1, 0x46, 0x1C71C7, 0x84F }, + [ATHOS_LUT_CHAN_638125_IDX] = { 25525, 0x1, 0x46, 0x1CE38E, 0x84F }, + [ATHOS_LUT_CHAN_638250_IDX] = { 25530, 0x1, 0x46, 0x1D5555, 0x850 }, + [ATHOS_LUT_CHAN_638375_IDX] = { 25535, 0x1, 0x46, 0x1DC71C, 0x850 }, + [ATHOS_LUT_CHAN_638500_IDX] = { 25540, 0x1, 0x46, 0x1E38E4, 0x850 }, + [ATHOS_LUT_CHAN_638625_IDX] = { 25545, 0x1, 0x46, 0x1EAAAB, 0x851 }, + [ATHOS_LUT_CHAN_638750_IDX] = { 25550, 0x1, 0x46, 0x1F1C72, 0x851 }, + [ATHOS_LUT_CHAN_638875_IDX] = { 25555, 0x1, 0x46, 0x1F8E39, 0x852 }, + [ATHOS_LUT_CHAN_639000_IDX] = { 25560, 0x1, 0x47, 0x0, 0x852 }, + [ATHOS_LUT_CHAN_639125_IDX] = { 25565, 0x1, 0x47, 0x71C7, 0x852 }, + [ATHOS_LUT_CHAN_639250_IDX] = { 25570, 0x1, 0x47, 0xE38E, 0x853 }, + [ATHOS_LUT_CHAN_639375_IDX] = { 25575, 0x1, 0x47, 0x15555, 0x853 }, + [ATHOS_LUT_CHAN_639500_IDX] = { 25580, 0x1, 0x47, 0x1C71C, 0x854 }, + [ATHOS_LUT_CHAN_639625_IDX] = { 25585, 0x1, 0x47, 0x238E4, 0x854 }, + [ATHOS_LUT_CHAN_639750_IDX] = { 25590, 0x1, 0x47, 0x2AAAB, 0x855 }, + [ATHOS_LUT_CHAN_639875_IDX] = { 25595, 0x1, 0x47, 0x31C72, 0x855 }, + [ATHOS_LUT_CHAN_640000_IDX] = { 25600, 0x1, 0x47, 0x38E39, 0x855 }, + [ATHOS_LUT_CHAN_640125_IDX] = { 25605, 0x1, 0x47, 0x40000, 0x856 }, + [ATHOS_LUT_CHAN_640250_IDX] = { 25610, 0x1, 0x47, 0x471C7, 0x856 }, + [ATHOS_LUT_CHAN_640375_IDX] = { 25615, 0x1, 0x47, 0x4E38E, 0x857 }, + [ATHOS_LUT_CHAN_640500_IDX] = { 25620, 0x1, 0x47, 0x55555, 0x857 }, + [ATHOS_LUT_CHAN_640625_IDX] = { 25625, 0x1, 0x47, 0x5C71C, 0x857 }, + [ATHOS_LUT_CHAN_640750_IDX] = { 25630, 0x1, 0x47, 0x638E4, 0x858 }, + [ATHOS_LUT_CHAN_640875_IDX] = { 25635, 0x1, 0x47, 0x6AAAB, 0x858 }, + [ATHOS_LUT_CHAN_641000_IDX] = { 25640, 0x1, 0x47, 0x71C72, 0x859 }, + [ATHOS_LUT_CHAN_641125_IDX] = { 25645, 0x1, 0x47, 0x78E39, 0x859 }, + [ATHOS_LUT_CHAN_641250_IDX] = { 25650, 0x1, 0x47, 0x80000, 0x85A }, + [ATHOS_LUT_CHAN_641375_IDX] = { 25655, 0x1, 0x47, 0x871C7, 0x85A }, + [ATHOS_LUT_CHAN_641500_IDX] = { 25660, 0x1, 0x47, 0x8E38E, 0x85A }, + [ATHOS_LUT_CHAN_641625_IDX] = { 25665, 0x1, 0x47, 0x95555, 0x85B }, + [ATHOS_LUT_CHAN_641750_IDX] = { 25670, 0x1, 0x47, 0x9C71C, 0x85B }, + [ATHOS_LUT_CHAN_641875_IDX] = { 25675, 0x1, 0x47, 0xA38E4, 0x85C }, + [ATHOS_LUT_CHAN_642000_IDX] = { 25680, 0x1, 0x47, 0xAAAAB, 0x85C }, + [ATHOS_LUT_CHAN_642125_IDX] = { 25685, 0x1, 0x47, 0xB1C72, 0x85C }, + [ATHOS_LUT_CHAN_642250_IDX] = { 25690, 0x1, 0x47, 0xB8E39, 0x85D }, + [ATHOS_LUT_CHAN_642375_IDX] = { 25695, 0x1, 0x47, 0xC0000, 0x85D }, + [ATHOS_LUT_CHAN_642500_IDX] = { 25700, 0x1, 0x47, 0xC71C7, 0x85E }, + [ATHOS_LUT_CHAN_642625_IDX] = { 25705, 0x1, 0x47, 0xCE38E, 0x85E }, + [ATHOS_LUT_CHAN_642750_IDX] = { 25710, 0x1, 0x47, 0xD5555, 0x85F }, + [ATHOS_LUT_CHAN_642875_IDX] = { 25715, 0x1, 0x47, 0xDC71C, 0x85F }, + [ATHOS_LUT_CHAN_643000_IDX] = { 25720, 0x1, 0x47, 0xE38E4, 0x85F }, + [ATHOS_LUT_CHAN_643125_IDX] = { 25725, 0x1, 0x47, 0xEAAAB, 0x860 }, + [ATHOS_LUT_CHAN_643250_IDX] = { 25730, 0x1, 0x47, 0xF1C72, 0x860 }, + [ATHOS_LUT_CHAN_643375_IDX] = { 25735, 0x1, 0x47, 0xF8E39, 0x861 }, + [ATHOS_LUT_CHAN_643500_IDX] = { 25740, 0x1, 0x47, 0x100000, 0x861 }, + [ATHOS_LUT_CHAN_643625_IDX] = { 25745, 0x1, 0x47, 0x1071C7, 0x861 }, + [ATHOS_LUT_CHAN_643750_IDX] = { 25750, 0x1, 0x47, 0x10E38E, 0x862 }, + [ATHOS_LUT_CHAN_643875_IDX] = { 25755, 0x1, 0x47, 0x115555, 0x862 }, + [ATHOS_LUT_CHAN_644000_IDX] = { 25760, 0x1, 0x47, 0x11C71C, 0x863 }, + [ATHOS_LUT_CHAN_644125_IDX] = { 25765, 0x1, 0x47, 0x1238E4, 0x863 }, + [ATHOS_LUT_CHAN_644250_IDX] = { 25770, 0x1, 0x47, 0x12AAAB, 0x864 }, + [ATHOS_LUT_CHAN_644375_IDX] = { 25775, 0x1, 0x47, 0x131C72, 0x864 }, + [ATHOS_LUT_CHAN_644500_IDX] = { 25780, 0x1, 0x47, 0x138E39, 0x864 }, + [ATHOS_LUT_CHAN_644625_IDX] = { 25785, 0x1, 0x47, 0x140000, 0x865 }, + [ATHOS_LUT_CHAN_644750_IDX] = { 25790, 0x1, 0x47, 0x1471C7, 0x865 }, + [ATHOS_LUT_CHAN_644875_IDX] = { 25795, 0x1, 0x47, 0x14E38E, 0x866 }, + [ATHOS_LUT_CHAN_645000_IDX] = { 25800, 0x1, 0x47, 0x155555, 0x866 }, + [ATHOS_LUT_CHAN_645125_IDX] = { 25805, 0x1, 0x47, 0x15C71C, 0x866 }, + [ATHOS_LUT_CHAN_645250_IDX] = { 25810, 0x1, 0x47, 0x1638E4, 0x867 }, + [ATHOS_LUT_CHAN_645375_IDX] = { 25815, 0x1, 0x47, 0x16AAAB, 0x867 }, + [ATHOS_LUT_CHAN_645500_IDX] = { 25820, 0x1, 0x47, 0x171C72, 0x868 }, + [ATHOS_LUT_CHAN_645625_IDX] = { 25825, 0x1, 0x47, 0x178E39, 0x868 }, + [ATHOS_LUT_CHAN_645750_IDX] = { 25830, 0x1, 0x47, 0x180000, 0x869 }, + [ATHOS_LUT_CHAN_645875_IDX] = { 25835, 0x1, 0x47, 0x1871C7, 0x869 }, + [ATHOS_LUT_CHAN_646000_IDX] = { 25840, 0x1, 0x47, 0x18E38E, 0x869 }, + [ATHOS_LUT_CHAN_646125_IDX] = { 25845, 0x1, 0x47, 0x195555, 0x86A }, + [ATHOS_LUT_CHAN_646250_IDX] = { 25850, 0x1, 0x47, 0x19C71C, 0x86A }, + [ATHOS_LUT_CHAN_646375_IDX] = { 25855, 0x1, 0x47, 0x1A38E4, 0x86B }, + [ATHOS_LUT_CHAN_646500_IDX] = { 25860, 0x1, 0x47, 0x1AAAAB, 0x86B }, + [ATHOS_LUT_CHAN_646625_IDX] = { 25865, 0x1, 0x47, 0x1B1C72, 0x86B }, + [ATHOS_LUT_CHAN_646750_IDX] = { 25870, 0x1, 0x47, 0x1B8E39, 0x86C }, + [ATHOS_LUT_CHAN_646875_IDX] = { 25875, 0x1, 0x47, 0x1C0000, 0x86C }, + [ATHOS_LUT_CHAN_647000_IDX] = { 25880, 0x1, 0x47, 0x1C71C7, 0x86D }, + [ATHOS_LUT_CHAN_647125_IDX] = { 25885, 0x1, 0x47, 0x1CE38E, 0x86D }, + [ATHOS_LUT_CHAN_647250_IDX] = { 25890, 0x1, 0x47, 0x1D5555, 0x86E }, + [ATHOS_LUT_CHAN_647375_IDX] = { 25895, 0x1, 0x47, 0x1DC71C, 0x86E }, + [ATHOS_LUT_CHAN_647500_IDX] = { 25900, 0x1, 0x47, 0x1E38E4, 0x86E }, + [ATHOS_LUT_CHAN_647625_IDX] = { 25905, 0x1, 0x47, 0x1EAAAB, 0x86F }, + [ATHOS_LUT_CHAN_647750_IDX] = { 25910, 0x1, 0x47, 0x1F1C72, 0x86F }, + [ATHOS_LUT_CHAN_647875_IDX] = { 25915, 0x1, 0x47, 0x1F8E39, 0x870 }, + [ATHOS_LUT_CHAN_648000_IDX] = { 25920, 0x1, 0x48, 0x0, 0x870 }, + [ATHOS_LUT_CHAN_648125_IDX] = { 25925, 0x1, 0x48, 0x71C7, 0x870 }, + [ATHOS_LUT_CHAN_648250_IDX] = { 25930, 0x1, 0x48, 0xE38E, 0x871 }, + [ATHOS_LUT_CHAN_648375_IDX] = { 25935, 0x1, 0x48, 0x15555, 0x871 }, + [ATHOS_LUT_CHAN_648500_IDX] = { 25940, 0x1, 0x48, 0x1C71C, 0x872 }, + [ATHOS_LUT_CHAN_648625_IDX] = { 25945, 0x1, 0x48, 0x238E4, 0x872 }, + [ATHOS_LUT_CHAN_648750_IDX] = { 25950, 0x1, 0x48, 0x2AAAB, 0x873 }, + [ATHOS_LUT_CHAN_648875_IDX] = { 25955, 0x1, 0x48, 0x31C72, 0x873 }, + [ATHOS_LUT_CHAN_649000_IDX] = { 25960, 0x1, 0x48, 0x38E39, 0x873 }, + [ATHOS_LUT_CHAN_649125_IDX] = { 25965, 0x1, 0x48, 0x40000, 0x874 }, + [ATHOS_LUT_CHAN_649250_IDX] = { 25970, 0x1, 0x48, 0x471C7, 0x874 }, + [ATHOS_LUT_CHAN_649375_IDX] = { 25975, 0x1, 0x48, 0x4E38E, 0x875 }, + [ATHOS_LUT_CHAN_649500_IDX] = { 25980, 0x1, 0x48, 0x55555, 0x875 }, + [ATHOS_LUT_CHAN_649625_IDX] = { 25985, 0x1, 0x48, 0x5C71C, 0x875 }, + [ATHOS_LUT_CHAN_649750_IDX] = { 25990, 0x1, 0x48, 0x638E4, 0x876 }, + [ATHOS_LUT_CHAN_649875_IDX] = { 25995, 0x1, 0x48, 0x6AAAB, 0x876 }, + [ATHOS_LUT_CHAN_650000_IDX] = { 26000, 0x1, 0x48, 0x71C72, 0x877 }, + [ATHOS_LUT_CHAN_650125_IDX] = { 26005, 0x1, 0x48, 0x78E39, 0x877 }, + [ATHOS_LUT_CHAN_650250_IDX] = { 26010, 0x1, 0x48, 0x80000, 0x878 }, + [ATHOS_LUT_CHAN_650375_IDX] = { 26015, 0x1, 0x48, 0x871C7, 0x878 }, + [ATHOS_LUT_CHAN_650500_IDX] = { 26020, 0x1, 0x48, 0x8E38E, 0x878 }, + [ATHOS_LUT_CHAN_650625_IDX] = { 26025, 0x1, 0x48, 0x95555, 0x879 }, + [ATHOS_LUT_CHAN_650750_IDX] = { 26030, 0x1, 0x48, 0x9C71C, 0x879 }, + [ATHOS_LUT_CHAN_650875_IDX] = { 26035, 0x1, 0x48, 0xA38E4, 0x87A }, + [ATHOS_LUT_CHAN_651000_IDX] = { 26040, 0x1, 0x48, 0xAAAAB, 0x87A }, + [ATHOS_LUT_CHAN_651125_IDX] = { 26045, 0x1, 0x48, 0xB1C72, 0x87A }, + [ATHOS_LUT_CHAN_651250_IDX] = { 26050, 0x1, 0x48, 0xB8E39, 0x87B }, + [ATHOS_LUT_CHAN_651375_IDX] = { 26055, 0x1, 0x48, 0xC0000, 0x87B }, + [ATHOS_LUT_CHAN_651500_IDX] = { 26060, 0x1, 0x48, 0xC71C7, 0x87C }, + [ATHOS_LUT_CHAN_651625_IDX] = { 26065, 0x1, 0x48, 0xCE38E, 0x87C }, + [ATHOS_LUT_CHAN_651750_IDX] = { 26070, 0x1, 0x48, 0xD5555, 0x87D }, + [ATHOS_LUT_CHAN_651875_IDX] = { 26075, 0x1, 0x48, 0xDC71C, 0x87D }, + [ATHOS_LUT_CHAN_652000_IDX] = { 26080, 0x1, 0x48, 0xE38E4, 0x87D }, + [ATHOS_LUT_CHAN_652125_IDX] = { 26085, 0x1, 0x48, 0xEAAAB, 0x87E }, + [ATHOS_LUT_CHAN_652250_IDX] = { 26090, 0x1, 0x48, 0xF1C72, 0x87E }, + [ATHOS_LUT_CHAN_652375_IDX] = { 26095, 0x1, 0x48, 0xF8E39, 0x87F }, + [ATHOS_LUT_CHAN_652500_IDX] = { 26100, 0x1, 0x48, 0x100000, 0x87F }, + [ATHOS_LUT_CHAN_652625_IDX] = { 26105, 0x1, 0x48, 0x1071C7, 0x87F }, + [ATHOS_LUT_CHAN_652750_IDX] = { 26110, 0x1, 0x48, 0x10E38E, 0x880 }, + [ATHOS_LUT_CHAN_652875_IDX] = { 26115, 0x1, 0x48, 0x115555, 0x880 }, + [ATHOS_LUT_CHAN_653000_IDX] = { 26120, 0x1, 0x48, 0x11C71C, 0x881 }, + [ATHOS_LUT_CHAN_653125_IDX] = { 26125, 0x1, 0x48, 0x1238E4, 0x881 }, + [ATHOS_LUT_CHAN_653250_IDX] = { 26130, 0x1, 0x48, 0x12AAAB, 0x882 }, + [ATHOS_LUT_CHAN_653375_IDX] = { 26135, 0x1, 0x48, 0x131C72, 0x882 }, + [ATHOS_LUT_CHAN_653500_IDX] = { 26140, 0x1, 0x48, 0x138E39, 0x882 }, + [ATHOS_LUT_CHAN_653625_IDX] = { 26145, 0x1, 0x48, 0x140000, 0x883 }, + [ATHOS_LUT_CHAN_653750_IDX] = { 26150, 0x1, 0x48, 0x1471C7, 0x883 }, + [ATHOS_LUT_CHAN_653875_IDX] = { 26155, 0x1, 0x48, 0x14E38E, 0x884 }, + [ATHOS_LUT_CHAN_654000_IDX] = { 26160, 0x1, 0x48, 0x155555, 0x884 }, + [ATHOS_LUT_CHAN_654125_IDX] = { 26165, 0x1, 0x48, 0x15C71C, 0x884 }, + [ATHOS_LUT_CHAN_654250_IDX] = { 26170, 0x1, 0x48, 0x1638E4, 0x885 }, + [ATHOS_LUT_CHAN_654375_IDX] = { 26175, 0x1, 0x48, 0x16AAAB, 0x885 }, + [ATHOS_LUT_CHAN_654500_IDX] = { 26180, 0x1, 0x48, 0x171C72, 0x886 }, + [ATHOS_LUT_CHAN_654625_IDX] = { 26185, 0x1, 0x48, 0x178E39, 0x886 }, + [ATHOS_LUT_CHAN_654750_IDX] = { 26190, 0x1, 0x48, 0x180000, 0x887 }, + [ATHOS_LUT_CHAN_654875_IDX] = { 26195, 0x1, 0x48, 0x1871C7, 0x887 }, + [ATHOS_LUT_CHAN_655000_IDX] = { 26200, 0x1, 0x48, 0x18E38E, 0x887 }, + [ATHOS_LUT_CHAN_655125_IDX] = { 26205, 0x1, 0x48, 0x195555, 0x888 }, + [ATHOS_LUT_CHAN_655250_IDX] = { 26210, 0x1, 0x48, 0x19C71C, 0x888 }, + [ATHOS_LUT_CHAN_655375_IDX] = { 26215, 0x1, 0x48, 0x1A38E4, 0x889 }, + [ATHOS_LUT_CHAN_655500_IDX] = { 26220, 0x1, 0x48, 0x1AAAAB, 0x889 }, + [ATHOS_LUT_CHAN_655625_IDX] = { 26225, 0x1, 0x48, 0x1B1C72, 0x889 }, + [ATHOS_LUT_CHAN_655750_IDX] = { 26230, 0x1, 0x48, 0x1B8E39, 0x88A }, + [ATHOS_LUT_CHAN_655875_IDX] = { 26235, 0x1, 0x48, 0x1C0000, 0x88A }, + [ATHOS_LUT_CHAN_656000_IDX] = { 26240, 0x1, 0x48, 0x1C71C7, 0x88B }, + [ATHOS_LUT_CHAN_656125_IDX] = { 26245, 0x1, 0x48, 0x1CE38E, 0x88B }, + [ATHOS_LUT_CHAN_656250_IDX] = { 26250, 0x1, 0x48, 0x1D5555, 0x88C }, + [ATHOS_LUT_CHAN_656375_IDX] = { 26255, 0x1, 0x48, 0x1DC71C, 0x88C }, + [ATHOS_LUT_CHAN_656500_IDX] = { 26260, 0x1, 0x48, 0x1E38E4, 0x88C }, + [ATHOS_LUT_CHAN_656625_IDX] = { 26265, 0x1, 0x48, 0x1EAAAB, 0x88D }, + [ATHOS_LUT_CHAN_656750_IDX] = { 26270, 0x1, 0x48, 0x1F1C72, 0x88D }, + [ATHOS_LUT_CHAN_656875_IDX] = { 26275, 0x1, 0x48, 0x1F8E39, 0x88E }, + [ATHOS_LUT_CHAN_657000_IDX] = { 26280, 0x1, 0x49, 0x0, 0x88E }, + [ATHOS_LUT_CHAN_657125_IDX] = { 26285, 0x1, 0x49, 0x71C7, 0x88E }, + [ATHOS_LUT_CHAN_657250_IDX] = { 26290, 0x1, 0x49, 0xE38E, 0x88F }, + [ATHOS_LUT_CHAN_657375_IDX] = { 26295, 0x1, 0x49, 0x15555, 0x88F }, + [ATHOS_LUT_CHAN_657500_IDX] = { 26300, 0x1, 0x49, 0x1C71C, 0x890 }, + [ATHOS_LUT_CHAN_657625_IDX] = { 26305, 0x1, 0x49, 0x238E4, 0x890 }, + [ATHOS_LUT_CHAN_657750_IDX] = { 26310, 0x1, 0x49, 0x2AAAB, 0x891 }, + [ATHOS_LUT_CHAN_657875_IDX] = { 26315, 0x1, 0x49, 0x31C72, 0x891 }, + [ATHOS_LUT_CHAN_658000_IDX] = { 26320, 0x1, 0x49, 0x38E39, 0x891 }, + [ATHOS_LUT_CHAN_658125_IDX] = { 26325, 0x1, 0x49, 0x40000, 0x892 }, + [ATHOS_LUT_CHAN_658250_IDX] = { 26330, 0x1, 0x49, 0x471C7, 0x892 }, + [ATHOS_LUT_CHAN_658375_IDX] = { 26335, 0x1, 0x49, 0x4E38E, 0x893 }, + [ATHOS_LUT_CHAN_658500_IDX] = { 26340, 0x1, 0x49, 0x55555, 0x893 }, + [ATHOS_LUT_CHAN_658625_IDX] = { 26345, 0x1, 0x49, 0x5C71C, 0x893 }, + [ATHOS_LUT_CHAN_658750_IDX] = { 26350, 0x1, 0x49, 0x638E4, 0x894 }, + [ATHOS_LUT_CHAN_658875_IDX] = { 26355, 0x1, 0x49, 0x6AAAB, 0x894 }, + [ATHOS_LUT_CHAN_659000_IDX] = { 26360, 0x1, 0x49, 0x71C72, 0x895 }, + [ATHOS_LUT_CHAN_659125_IDX] = { 26365, 0x1, 0x49, 0x78E39, 0x895 }, + [ATHOS_LUT_CHAN_659250_IDX] = { 26370, 0x1, 0x49, 0x80000, 0x896 }, + [ATHOS_LUT_CHAN_659375_IDX] = { 26375, 0x1, 0x49, 0x871C7, 0x896 }, + [ATHOS_LUT_CHAN_659500_IDX] = { 26380, 0x1, 0x49, 0x8E38E, 0x896 }, + [ATHOS_LUT_CHAN_659625_IDX] = { 26385, 0x1, 0x49, 0x95555, 0x897 }, + [ATHOS_LUT_CHAN_659750_IDX] = { 26390, 0x1, 0x49, 0x9C71C, 0x897 }, + [ATHOS_LUT_CHAN_659875_IDX] = { 26395, 0x1, 0x49, 0xA38E4, 0x898 }, + [ATHOS_LUT_CHAN_660000_IDX] = { 26400, 0x1, 0x49, 0xAAAAB, 0x898 }, + [ATHOS_LUT_CHAN_660125_IDX] = { 26405, 0x1, 0x49, 0xB1C72, 0x898 }, + [ATHOS_LUT_CHAN_660250_IDX] = { 26410, 0x1, 0x49, 0xB8E39, 0x899 }, + [ATHOS_LUT_CHAN_660375_IDX] = { 26415, 0x1, 0x49, 0xC0000, 0x899 }, + [ATHOS_LUT_CHAN_660500_IDX] = { 26420, 0x1, 0x49, 0xC71C7, 0x89A }, + [ATHOS_LUT_CHAN_660625_IDX] = { 26425, 0x1, 0x49, 0xCE38E, 0x89A }, + [ATHOS_LUT_CHAN_660750_IDX] = { 26430, 0x1, 0x49, 0xD5555, 0x89B }, + [ATHOS_LUT_CHAN_660875_IDX] = { 26435, 0x1, 0x49, 0xDC71C, 0x89B }, + [ATHOS_LUT_CHAN_661000_IDX] = { 26440, 0x1, 0x49, 0xE38E4, 0x89B }, + [ATHOS_LUT_CHAN_661125_IDX] = { 26445, 0x1, 0x49, 0xEAAAB, 0x89C }, + [ATHOS_LUT_CHAN_661250_IDX] = { 26450, 0x1, 0x49, 0xF1C72, 0x89C }, + [ATHOS_LUT_CHAN_661375_IDX] = { 26455, 0x1, 0x49, 0xF8E39, 0x89D }, + [ATHOS_LUT_CHAN_661500_IDX] = { 26460, 0x1, 0x49, 0x100000, 0x89D }, + [ATHOS_LUT_CHAN_661625_IDX] = { 26465, 0x1, 0x49, 0x1071C7, 0x89D }, + [ATHOS_LUT_CHAN_661750_IDX] = { 26470, 0x1, 0x49, 0x10E38E, 0x89E }, + [ATHOS_LUT_CHAN_661875_IDX] = { 26475, 0x1, 0x49, 0x115555, 0x89E }, + [ATHOS_LUT_CHAN_662000_IDX] = { 26480, 0x1, 0x49, 0x11C71C, 0x89F }, + [ATHOS_LUT_CHAN_662125_IDX] = { 26485, 0x1, 0x49, 0x1238E4, 0x89F }, + [ATHOS_LUT_CHAN_662250_IDX] = { 26490, 0x1, 0x49, 0x12AAAB, 0x8A0 }, + [ATHOS_LUT_CHAN_662375_IDX] = { 26495, 0x1, 0x49, 0x131C72, 0x8A0 }, + [ATHOS_LUT_CHAN_662500_IDX] = { 26500, 0x1, 0x49, 0x138E39, 0x8A0 }, + [ATHOS_LUT_CHAN_662625_IDX] = { 26505, 0x1, 0x49, 0x140000, 0x8A1 }, + [ATHOS_LUT_CHAN_662750_IDX] = { 26510, 0x1, 0x49, 0x1471C7, 0x8A1 }, + [ATHOS_LUT_CHAN_662875_IDX] = { 26515, 0x1, 0x49, 0x14E38E, 0x8A2 }, + [ATHOS_LUT_CHAN_663000_IDX] = { 26520, 0x1, 0x49, 0x155555, 0x8A2 }, + [ATHOS_LUT_CHAN_663125_IDX] = { 26525, 0x1, 0x49, 0x15C71C, 0x8A2 }, + [ATHOS_LUT_CHAN_663250_IDX] = { 26530, 0x1, 0x49, 0x1638E4, 0x8A3 }, + [ATHOS_LUT_CHAN_663375_IDX] = { 26535, 0x1, 0x49, 0x16AAAB, 0x8A3 }, + [ATHOS_LUT_CHAN_663500_IDX] = { 26540, 0x1, 0x49, 0x171C72, 0x8A4 }, + [ATHOS_LUT_CHAN_663625_IDX] = { 26545, 0x1, 0x49, 0x178E39, 0x8A4 }, + [ATHOS_LUT_CHAN_663750_IDX] = { 26550, 0x1, 0x49, 0x180000, 0x8A5 }, + [ATHOS_LUT_CHAN_663875_IDX] = { 26555, 0x1, 0x49, 0x1871C7, 0x8A5 }, + [ATHOS_LUT_CHAN_664000_IDX] = { 26560, 0x1, 0x49, 0x18E38E, 0x8A5 }, + [ATHOS_LUT_CHAN_664125_IDX] = { 26565, 0x1, 0x49, 0x195555, 0x8A6 }, + [ATHOS_LUT_CHAN_664250_IDX] = { 26570, 0x1, 0x49, 0x19C71C, 0x8A6 }, + [ATHOS_LUT_CHAN_664375_IDX] = { 26575, 0x1, 0x49, 0x1A38E4, 0x8A7 }, + [ATHOS_LUT_CHAN_664500_IDX] = { 26580, 0x1, 0x49, 0x1AAAAB, 0x8A7 }, + [ATHOS_LUT_CHAN_664625_IDX] = { 26585, 0x1, 0x49, 0x1B1C72, 0x8A7 }, + [ATHOS_LUT_CHAN_664750_IDX] = { 26590, 0x1, 0x49, 0x1B8E39, 0x8A8 }, + [ATHOS_LUT_CHAN_664875_IDX] = { 26595, 0x1, 0x49, 0x1C0000, 0x8A8 }, + [ATHOS_LUT_CHAN_665000_IDX] = { 26600, 0x1, 0x49, 0x1C71C7, 0x8A9 }, + [ATHOS_LUT_CHAN_665125_IDX] = { 26605, 0x1, 0x49, 0x1CE38E, 0x8A9 }, + [ATHOS_LUT_CHAN_665250_IDX] = { 26610, 0x1, 0x49, 0x1D5555, 0x8AA }, + [ATHOS_LUT_CHAN_665375_IDX] = { 26615, 0x1, 0x49, 0x1DC71C, 0x8AA }, + [ATHOS_LUT_CHAN_665500_IDX] = { 26620, 0x1, 0x49, 0x1E38E4, 0x8AA }, + [ATHOS_LUT_CHAN_665625_IDX] = { 26625, 0x1, 0x49, 0x1EAAAB, 0x8AB }, + [ATHOS_LUT_CHAN_665750_IDX] = { 26630, 0x1, 0x49, 0x1F1C72, 0x8AB }, + [ATHOS_LUT_CHAN_665875_IDX] = { 26635, 0x1, 0x49, 0x1F8E39, 0x8AC }, + [ATHOS_LUT_CHAN_666000_IDX] = { 26640, 0x1, 0x4A, 0x0, 0x8AC }, + [ATHOS_LUT_CHAN_666125_IDX] = { 26645, 0x1, 0x4A, 0x71C7, 0x8AC }, + [ATHOS_LUT_CHAN_666250_IDX] = { 26650, 0x1, 0x4A, 0xE38E, 0x8AD }, + [ATHOS_LUT_CHAN_666375_IDX] = { 26655, 0x1, 0x4A, 0x15555, 0x8AD }, + [ATHOS_LUT_CHAN_666500_IDX] = { 26660, 0x1, 0x4A, 0x1C71C, 0x8AE }, + [ATHOS_LUT_CHAN_666625_IDX] = { 26665, 0x1, 0x4A, 0x238E4, 0x8AE }, + [ATHOS_LUT_CHAN_666750_IDX] = { 26670, 0x1, 0x4A, 0x2AAAB, 0x8AF }, + [ATHOS_LUT_CHAN_666875_IDX] = { 26675, 0x1, 0x4A, 0x31C72, 0x8AF }, + [ATHOS_LUT_CHAN_667000_IDX] = { 26680, 0x1, 0x4A, 0x38E39, 0x8AF }, + [ATHOS_LUT_CHAN_667125_IDX] = { 26685, 0x1, 0x4A, 0x40000, 0x8B0 }, + [ATHOS_LUT_CHAN_667250_IDX] = { 26690, 0x1, 0x4A, 0x471C7, 0x8B0 }, + [ATHOS_LUT_CHAN_667375_IDX] = { 26695, 0x1, 0x4A, 0x4E38E, 0x8B1 }, + [ATHOS_LUT_CHAN_667500_IDX] = { 26700, 0x1, 0x4A, 0x55555, 0x8B1 }, + [ATHOS_LUT_CHAN_667625_IDX] = { 26705, 0x1, 0x4A, 0x5C71C, 0x8B1 }, + [ATHOS_LUT_CHAN_667750_IDX] = { 26710, 0x1, 0x4A, 0x638E4, 0x8B2 }, + [ATHOS_LUT_CHAN_667875_IDX] = { 26715, 0x1, 0x4A, 0x6AAAB, 0x8B2 }, + [ATHOS_LUT_CHAN_668000_IDX] = { 26720, 0x1, 0x4A, 0x71C72, 0x8B3 }, + [ATHOS_LUT_CHAN_668125_IDX] = { 26725, 0x1, 0x4A, 0x78E39, 0x8B3 }, + [ATHOS_LUT_CHAN_668250_IDX] = { 26730, 0x1, 0x4A, 0x80000, 0x8B4 }, + [ATHOS_LUT_CHAN_668375_IDX] = { 26735, 0x1, 0x4A, 0x871C7, 0x8B4 }, + [ATHOS_LUT_CHAN_668500_IDX] = { 26740, 0x1, 0x4A, 0x8E38E, 0x8B4 }, + [ATHOS_LUT_CHAN_668625_IDX] = { 26745, 0x1, 0x4A, 0x95555, 0x8B5 }, + [ATHOS_LUT_CHAN_668750_IDX] = { 26750, 0x1, 0x4A, 0x9C71C, 0x8B5 }, + [ATHOS_LUT_CHAN_668875_IDX] = { 26755, 0x1, 0x4A, 0xA38E4, 0x8B6 }, + [ATHOS_LUT_CHAN_669000_IDX] = { 26760, 0x1, 0x4A, 0xAAAAB, 0x8B6 }, + [ATHOS_LUT_CHAN_669125_IDX] = { 26765, 0x1, 0x4A, 0xB1C72, 0x8B6 }, + [ATHOS_LUT_CHAN_669250_IDX] = { 26770, 0x1, 0x4A, 0xB8E39, 0x8B7 }, + [ATHOS_LUT_CHAN_669375_IDX] = { 26775, 0x1, 0x4A, 0xC0000, 0x8B7 }, + [ATHOS_LUT_CHAN_669500_IDX] = { 26780, 0x1, 0x4A, 0xC71C7, 0x8B8 }, + [ATHOS_LUT_CHAN_669625_IDX] = { 26785, 0x1, 0x4A, 0xCE38E, 0x8B8 }, + [ATHOS_LUT_CHAN_669750_IDX] = { 26790, 0x1, 0x4A, 0xD5555, 0x8B9 }, + [ATHOS_LUT_CHAN_669875_IDX] = { 26795, 0x1, 0x4A, 0xDC71C, 0x8B9 }, + [ATHOS_LUT_CHAN_670000_IDX] = { 26800, 0x1, 0x4A, 0xE38E4, 0x8B9 }, + [ATHOS_LUT_CHAN_670125_IDX] = { 26805, 0x1, 0x4A, 0xEAAAB, 0x8BA }, + [ATHOS_LUT_CHAN_670250_IDX] = { 26810, 0x1, 0x4A, 0xF1C72, 0x8BA }, + [ATHOS_LUT_CHAN_670375_IDX] = { 26815, 0x1, 0x4A, 0xF8E39, 0x8BB }, + [ATHOS_LUT_CHAN_670500_IDX] = { 26820, 0x1, 0x4A, 0x100000, 0x8BB }, + [ATHOS_LUT_CHAN_670625_IDX] = { 26825, 0x1, 0x4A, 0x1071C7, 0x8BB }, + [ATHOS_LUT_CHAN_670750_IDX] = { 26830, 0x1, 0x4A, 0x10E38E, 0x8BC }, + [ATHOS_LUT_CHAN_670875_IDX] = { 26835, 0x1, 0x4A, 0x115555, 0x8BC }, + [ATHOS_LUT_CHAN_671000_IDX] = { 26840, 0x1, 0x4A, 0x11C71C, 0x8BD }, + [ATHOS_LUT_CHAN_671125_IDX] = { 26845, 0x1, 0x4A, 0x1238E4, 0x8BD }, + [ATHOS_LUT_CHAN_671250_IDX] = { 26850, 0x1, 0x4A, 0x12AAAB, 0x8BE }, + [ATHOS_LUT_CHAN_671375_IDX] = { 26855, 0x1, 0x4A, 0x131C72, 0x8BE }, + [ATHOS_LUT_CHAN_671500_IDX] = { 26860, 0x1, 0x4A, 0x138E39, 0x8BE }, + [ATHOS_LUT_CHAN_671625_IDX] = { 26865, 0x1, 0x4A, 0x140000, 0x8BF }, + [ATHOS_LUT_CHAN_671750_IDX] = { 26870, 0x1, 0x4A, 0x1471C7, 0x8BF }, + [ATHOS_LUT_CHAN_671875_IDX] = { 26875, 0x1, 0x4A, 0x14E38E, 0x8C0 }, + [ATHOS_LUT_CHAN_672000_IDX] = { 26880, 0x1, 0x4A, 0x155555, 0x8C0 }, + [ATHOS_LUT_CHAN_672125_IDX] = { 26885, 0x1, 0x4A, 0x15C71C, 0x8C0 }, + [ATHOS_LUT_CHAN_672250_IDX] = { 26890, 0x1, 0x4A, 0x1638E4, 0x8C1 }, + [ATHOS_LUT_CHAN_672375_IDX] = { 26895, 0x1, 0x4A, 0x16AAAB, 0x8C1 }, + [ATHOS_LUT_CHAN_672500_IDX] = { 26900, 0x1, 0x4A, 0x171C72, 0x8C2 }, + [ATHOS_LUT_CHAN_672625_IDX] = { 26905, 0x1, 0x4A, 0x178E39, 0x8C2 }, + [ATHOS_LUT_CHAN_672750_IDX] = { 26910, 0x1, 0x4A, 0x180000, 0x8C3 }, + [ATHOS_LUT_CHAN_672875_IDX] = { 26915, 0x1, 0x4A, 0x1871C7, 0x8C3 }, + [ATHOS_LUT_CHAN_673000_IDX] = { 26920, 0x1, 0x4A, 0x18E38E, 0x8C3 }, + [ATHOS_LUT_CHAN_673125_IDX] = { 26925, 0x1, 0x4A, 0x195555, 0x8C4 }, + [ATHOS_LUT_CHAN_673250_IDX] = { 26930, 0x1, 0x4A, 0x19C71C, 0x8C4 }, + [ATHOS_LUT_CHAN_673375_IDX] = { 26935, 0x1, 0x4A, 0x1A38E4, 0x8C5 }, + [ATHOS_LUT_CHAN_673500_IDX] = { 26940, 0x1, 0x4A, 0x1AAAAB, 0x8C5 }, + [ATHOS_LUT_CHAN_673625_IDX] = { 26945, 0x1, 0x4A, 0x1B1C72, 0x8C5 }, + [ATHOS_LUT_CHAN_673750_IDX] = { 26950, 0x1, 0x4A, 0x1B8E39, 0x8C6 }, + [ATHOS_LUT_CHAN_673875_IDX] = { 26955, 0x1, 0x4A, 0x1C0000, 0x8C6 }, + [ATHOS_LUT_CHAN_674000_IDX] = { 26960, 0x1, 0x4A, 0x1C71C7, 0x8C7 }, + [ATHOS_LUT_CHAN_674125_IDX] = { 26965, 0x1, 0x4A, 0x1CE38E, 0x8C7 }, + [ATHOS_LUT_CHAN_674250_IDX] = { 26970, 0x1, 0x4A, 0x1D5555, 0x8C8 }, + [ATHOS_LUT_CHAN_674375_IDX] = { 26975, 0x1, 0x4A, 0x1DC71C, 0x8C8 }, + [ATHOS_LUT_CHAN_674500_IDX] = { 26980, 0x1, 0x4A, 0x1E38E4, 0x8C8 }, + [ATHOS_LUT_CHAN_674625_IDX] = { 26985, 0x1, 0x4A, 0x1EAAAB, 0x8C9 }, + [ATHOS_LUT_CHAN_674750_IDX] = { 26990, 0x1, 0x4A, 0x1F1C72, 0x8C9 }, + [ATHOS_LUT_CHAN_674875_IDX] = { 26995, 0x1, 0x4A, 0x1F8E39, 0x8CA }, + [ATHOS_LUT_CHAN_675000_IDX] = { 27000, 0x1, 0x4B, 0x0, 0x8CA }, + [ATHOS_LUT_CHAN_675125_IDX] = { 27005, 0x1, 0x4B, 0x71C7, 0x8CA }, + [ATHOS_LUT_CHAN_675250_IDX] = { 27010, 0x1, 0x4B, 0xE38E, 0x8CB }, + [ATHOS_LUT_CHAN_675375_IDX] = { 27015, 0x1, 0x4B, 0x15555, 0x8CB }, + [ATHOS_LUT_CHAN_675500_IDX] = { 27020, 0x1, 0x4B, 0x1C71C, 0x8CC }, + [ATHOS_LUT_CHAN_675625_IDX] = { 27025, 0x1, 0x4B, 0x238E4, 0x8CC }, + [ATHOS_LUT_CHAN_675750_IDX] = { 27030, 0x1, 0x4B, 0x2AAAB, 0x8CD }, + [ATHOS_LUT_CHAN_675875_IDX] = { 27035, 0x1, 0x4B, 0x31C72, 0x8CD }, + [ATHOS_LUT_CHAN_676000_IDX] = { 27040, 0x1, 0x4B, 0x38E39, 0x8CD }, + [ATHOS_LUT_CHAN_676125_IDX] = { 27045, 0x1, 0x4B, 0x40000, 0x8CE }, + [ATHOS_LUT_CHAN_676250_IDX] = { 27050, 0x1, 0x4B, 0x471C7, 0x8CE }, + [ATHOS_LUT_CHAN_676375_IDX] = { 27055, 0x1, 0x4B, 0x4E38E, 0x8CF }, + [ATHOS_LUT_CHAN_676500_IDX] = { 27060, 0x1, 0x4B, 0x55555, 0x8CF }, + [ATHOS_LUT_CHAN_676625_IDX] = { 27065, 0x1, 0x4B, 0x5C71C, 0x8CF }, + [ATHOS_LUT_CHAN_676750_IDX] = { 27070, 0x1, 0x4B, 0x638E4, 0x8D0 }, + [ATHOS_LUT_CHAN_676875_IDX] = { 27075, 0x1, 0x4B, 0x6AAAB, 0x8D0 }, + [ATHOS_LUT_CHAN_677000_IDX] = { 27080, 0x1, 0x4B, 0x71C72, 0x8D1 }, + [ATHOS_LUT_CHAN_677125_IDX] = { 27085, 0x1, 0x4B, 0x78E39, 0x8D1 }, + [ATHOS_LUT_CHAN_677250_IDX] = { 27090, 0x1, 0x4B, 0x80000, 0x8D2 }, + [ATHOS_LUT_CHAN_677375_IDX] = { 27095, 0x1, 0x4B, 0x871C7, 0x8D2 }, + [ATHOS_LUT_CHAN_677500_IDX] = { 27100, 0x1, 0x4B, 0x8E38E, 0x8D2 }, + [ATHOS_LUT_CHAN_677625_IDX] = { 27105, 0x1, 0x4B, 0x95555, 0x8D3 }, + [ATHOS_LUT_CHAN_677750_IDX] = { 27110, 0x1, 0x4B, 0x9C71C, 0x8D3 }, + [ATHOS_LUT_CHAN_677875_IDX] = { 27115, 0x1, 0x4B, 0xA38E4, 0x8D4 }, + [ATHOS_LUT_CHAN_678000_IDX] = { 27120, 0x1, 0x4B, 0xAAAAB, 0x8D4 }, + [ATHOS_LUT_CHAN_678125_IDX] = { 27125, 0x1, 0x4B, 0xB1C72, 0x8D4 }, + [ATHOS_LUT_CHAN_678250_IDX] = { 27130, 0x1, 0x4B, 0xB8E39, 0x8D5 }, + [ATHOS_LUT_CHAN_678375_IDX] = { 27135, 0x1, 0x4B, 0xC0000, 0x8D5 }, + [ATHOS_LUT_CHAN_678500_IDX] = { 27140, 0x1, 0x4B, 0xC71C7, 0x8D6 }, + [ATHOS_LUT_CHAN_678625_IDX] = { 27145, 0x1, 0x4B, 0xCE38E, 0x8D6 }, + [ATHOS_LUT_CHAN_678750_IDX] = { 27150, 0x1, 0x4B, 0xD5555, 0x8D7 }, + [ATHOS_LUT_CHAN_678875_IDX] = { 27155, 0x1, 0x4B, 0xDC71C, 0x8D7 }, + [ATHOS_LUT_CHAN_679000_IDX] = { 27160, 0x1, 0x4B, 0xE38E4, 0x8D7 }, + [ATHOS_LUT_CHAN_679125_IDX] = { 27165, 0x1, 0x4B, 0xEAAAB, 0x8D8 }, + [ATHOS_LUT_CHAN_679250_IDX] = { 27170, 0x1, 0x4B, 0xF1C72, 0x8D8 }, + [ATHOS_LUT_CHAN_679375_IDX] = { 27175, 0x1, 0x4B, 0xF8E39, 0x8D9 }, + [ATHOS_LUT_CHAN_679500_IDX] = { 27180, 0x1, 0x4B, 0x100000, 0x8D9 }, + [ATHOS_LUT_CHAN_679625_IDX] = { 27185, 0x1, 0x4B, 0x1071C7, 0x8D9 }, + [ATHOS_LUT_CHAN_679750_IDX] = { 27190, 0x1, 0x4B, 0x10E38E, 0x8DA }, + [ATHOS_LUT_CHAN_679875_IDX] = { 27195, 0x1, 0x4B, 0x115555, 0x8DA }, + [ATHOS_LUT_CHAN_680000_IDX] = { 27200, 0x1, 0x4B, 0x11C71C, 0x8DB }, + [ATHOS_LUT_CHAN_680125_IDX] = { 27205, 0x1, 0x4B, 0x1238E4, 0x8DB }, + [ATHOS_LUT_CHAN_680250_IDX] = { 27210, 0x1, 0x4B, 0x12AAAB, 0x8DC }, + [ATHOS_LUT_CHAN_680375_IDX] = { 27215, 0x1, 0x4B, 0x131C72, 0x8DC }, + [ATHOS_LUT_CHAN_680500_IDX] = { 27220, 0x1, 0x4B, 0x138E39, 0x8DC }, + [ATHOS_LUT_CHAN_680625_IDX] = { 27225, 0x1, 0x4B, 0x140000, 0x8DD }, + [ATHOS_LUT_CHAN_680750_IDX] = { 27230, 0x1, 0x4B, 0x1471C7, 0x8DD }, + [ATHOS_LUT_CHAN_680875_IDX] = { 27235, 0x1, 0x4B, 0x14E38E, 0x8DE }, + [ATHOS_LUT_CHAN_681000_IDX] = { 27240, 0x1, 0x4B, 0x155555, 0x8DE }, + [ATHOS_LUT_CHAN_681125_IDX] = { 27245, 0x1, 0x4B, 0x15C71C, 0x8DE }, + [ATHOS_LUT_CHAN_681250_IDX] = { 27250, 0x1, 0x4B, 0x1638E4, 0x8DF }, + [ATHOS_LUT_CHAN_681375_IDX] = { 27255, 0x1, 0x4B, 0x16AAAB, 0x8DF }, + [ATHOS_LUT_CHAN_681500_IDX] = { 27260, 0x1, 0x4B, 0x171C72, 0x8E0 }, + [ATHOS_LUT_CHAN_681625_IDX] = { 27265, 0x1, 0x4B, 0x178E39, 0x8E0 }, + [ATHOS_LUT_CHAN_681750_IDX] = { 27270, 0x1, 0x4B, 0x180000, 0x8E1 }, + [ATHOS_LUT_CHAN_681875_IDX] = { 27275, 0x1, 0x4B, 0x1871C7, 0x8E1 }, + [ATHOS_LUT_CHAN_682000_IDX] = { 27280, 0x1, 0x4B, 0x18E38E, 0x8E1 }, + [ATHOS_LUT_CHAN_682125_IDX] = { 27285, 0x1, 0x4B, 0x195555, 0x8E2 }, + [ATHOS_LUT_CHAN_682250_IDX] = { 27290, 0x1, 0x4B, 0x19C71C, 0x8E2 }, + [ATHOS_LUT_CHAN_682375_IDX] = { 27295, 0x1, 0x4B, 0x1A38E4, 0x8E3 }, + [ATHOS_LUT_CHAN_682500_IDX] = { 27300, 0x1, 0x4B, 0x1AAAAB, 0x8E3 }, + [ATHOS_LUT_CHAN_682625_IDX] = { 27305, 0x1, 0x4B, 0x1B1C72, 0x8E3 }, + [ATHOS_LUT_CHAN_682750_IDX] = { 27310, 0x1, 0x4B, 0x1B8E39, 0x8E4 }, + [ATHOS_LUT_CHAN_682875_IDX] = { 27315, 0x1, 0x4B, 0x1C0000, 0x8E4 }, + [ATHOS_LUT_CHAN_683000_IDX] = { 27320, 0x1, 0x4B, 0x1C71C7, 0x8E5 }, + [ATHOS_LUT_CHAN_683125_IDX] = { 27325, 0x1, 0x4B, 0x1CE38E, 0x8E5 }, + [ATHOS_LUT_CHAN_683250_IDX] = { 27330, 0x1, 0x4B, 0x1D5555, 0x8E6 }, + [ATHOS_LUT_CHAN_683375_IDX] = { 27335, 0x1, 0x4B, 0x1DC71C, 0x8E6 }, + [ATHOS_LUT_CHAN_683500_IDX] = { 27340, 0x1, 0x4B, 0x1E38E4, 0x8E6 }, + [ATHOS_LUT_CHAN_683625_IDX] = { 27345, 0x1, 0x4B, 0x1EAAAB, 0x8E7 }, + [ATHOS_LUT_CHAN_683750_IDX] = { 27350, 0x1, 0x4B, 0x1F1C72, 0x8E7 }, + [ATHOS_LUT_CHAN_683875_IDX] = { 27355, 0x1, 0x4B, 0x1F8E39, 0x8E8 }, + [ATHOS_LUT_CHAN_684000_IDX] = { 27360, 0x1, 0x4C, 0x0, 0x8E8 }, + [ATHOS_LUT_CHAN_684125_IDX] = { 27365, 0x1, 0x4C, 0x71C7, 0x8E8 }, + [ATHOS_LUT_CHAN_684250_IDX] = { 27370, 0x1, 0x4C, 0xE38E, 0x8E9 }, + [ATHOS_LUT_CHAN_684375_IDX] = { 27375, 0x1, 0x4C, 0x15555, 0x8E9 }, + [ATHOS_LUT_CHAN_684500_IDX] = { 27380, 0x1, 0x4C, 0x1C71C, 0x8EA }, + [ATHOS_LUT_CHAN_684625_IDX] = { 27385, 0x1, 0x4C, 0x238E4, 0x8EA }, + [ATHOS_LUT_CHAN_684750_IDX] = { 27390, 0x1, 0x4C, 0x2AAAB, 0x8EB }, + [ATHOS_LUT_CHAN_684875_IDX] = { 27395, 0x1, 0x4C, 0x31C72, 0x8EB }, + [ATHOS_LUT_CHAN_685000_IDX] = { 27400, 0x1, 0x4C, 0x38E39, 0x8EB }, + [ATHOS_LUT_CHAN_685125_IDX] = { 27405, 0x1, 0x4C, 0x40000, 0x8EC }, + [ATHOS_LUT_CHAN_685250_IDX] = { 27410, 0x1, 0x4C, 0x471C7, 0x8EC }, + [ATHOS_LUT_CHAN_685375_IDX] = { 27415, 0x1, 0x4C, 0x4E38E, 0x8ED }, + [ATHOS_LUT_CHAN_685500_IDX] = { 27420, 0x1, 0x4C, 0x55555, 0x8ED }, + [ATHOS_LUT_CHAN_685625_IDX] = { 27425, 0x1, 0x4C, 0x5C71C, 0x8ED }, + [ATHOS_LUT_CHAN_685750_IDX] = { 27430, 0x1, 0x4C, 0x638E4, 0x8EE }, + [ATHOS_LUT_CHAN_685875_IDX] = { 27435, 0x1, 0x4C, 0x6AAAB, 0x8EE }, + [ATHOS_LUT_CHAN_686000_IDX] = { 27440, 0x1, 0x4C, 0x71C72, 0x8EF }, + [ATHOS_LUT_CHAN_686125_IDX] = { 27445, 0x1, 0x4C, 0x78E39, 0x8EF }, + [ATHOS_LUT_CHAN_686250_IDX] = { 27450, 0x1, 0x4C, 0x80000, 0x8F0 }, + [ATHOS_LUT_CHAN_686375_IDX] = { 27455, 0x1, 0x4C, 0x871C7, 0x8F0 }, + [ATHOS_LUT_CHAN_686500_IDX] = { 27460, 0x1, 0x4C, 0x8E38E, 0x8F0 }, + [ATHOS_LUT_CHAN_686625_IDX] = { 27465, 0x1, 0x4C, 0x95555, 0x8F1 }, + [ATHOS_LUT_CHAN_686750_IDX] = { 27470, 0x1, 0x4C, 0x9C71C, 0x8F1 }, + [ATHOS_LUT_CHAN_686875_IDX] = { 27475, 0x1, 0x4C, 0xA38E4, 0x8F2 }, + [ATHOS_LUT_CHAN_687000_IDX] = { 27480, 0x1, 0x4C, 0xAAAAB, 0x8F2 }, + [ATHOS_LUT_CHAN_687125_IDX] = { 27485, 0x1, 0x4C, 0xB1C72, 0x8F2 }, + [ATHOS_LUT_CHAN_687250_IDX] = { 27490, 0x1, 0x4C, 0xB8E39, 0x8F3 }, + [ATHOS_LUT_CHAN_687375_IDX] = { 27495, 0x1, 0x4C, 0xC0000, 0x8F3 }, + [ATHOS_LUT_CHAN_687500_IDX] = { 27500, 0x1, 0x4C, 0xC71C7, 0x8F4 }, + [ATHOS_LUT_CHAN_687625_IDX] = { 27505, 0x1, 0x4C, 0xCE38E, 0x8F4 }, + [ATHOS_LUT_CHAN_687750_IDX] = { 27510, 0x1, 0x4C, 0xD5555, 0x8F5 }, + [ATHOS_LUT_CHAN_687875_IDX] = { 27515, 0x1, 0x4C, 0xDC71C, 0x8F5 }, + [ATHOS_LUT_CHAN_688000_IDX] = { 27520, 0x1, 0x4C, 0xE38E4, 0x8F5 }, + [ATHOS_LUT_CHAN_688125_IDX] = { 27525, 0x1, 0x4C, 0xEAAAB, 0x8F6 }, + [ATHOS_LUT_CHAN_688250_IDX] = { 27530, 0x1, 0x4C, 0xF1C72, 0x8F6 }, + [ATHOS_LUT_CHAN_688375_IDX] = { 27535, 0x1, 0x4C, 0xF8E39, 0x8F7 }, + [ATHOS_LUT_CHAN_688500_IDX] = { 27540, 0x1, 0x4C, 0x100000, 0x8F7 }, + [ATHOS_LUT_CHAN_688625_IDX] = { 27545, 0x1, 0x4C, 0x1071C7, 0x8F7 }, + [ATHOS_LUT_CHAN_688750_IDX] = { 27550, 0x1, 0x4C, 0x10E38E, 0x8F8 }, + [ATHOS_LUT_CHAN_688875_IDX] = { 27555, 0x1, 0x4C, 0x115555, 0x8F8 }, + [ATHOS_LUT_CHAN_689000_IDX] = { 27560, 0x1, 0x4C, 0x11C71C, 0x8F9 }, + [ATHOS_LUT_CHAN_689125_IDX] = { 27565, 0x1, 0x4C, 0x1238E4, 0x8F9 }, + [ATHOS_LUT_CHAN_689250_IDX] = { 27570, 0x1, 0x4C, 0x12AAAB, 0x8FA }, + [ATHOS_LUT_CHAN_689375_IDX] = { 27575, 0x1, 0x4C, 0x131C72, 0x8FA }, + [ATHOS_LUT_CHAN_689500_IDX] = { 27580, 0x1, 0x4C, 0x138E39, 0x8FA }, + [ATHOS_LUT_CHAN_689625_IDX] = { 27585, 0x1, 0x4C, 0x140000, 0x8FB }, + [ATHOS_LUT_CHAN_689750_IDX] = { 27590, 0x1, 0x4C, 0x1471C7, 0x8FB }, + [ATHOS_LUT_CHAN_689875_IDX] = { 27595, 0x1, 0x4C, 0x14E38E, 0x8FC }, + [ATHOS_LUT_CHAN_690000_IDX] = { 27600, 0x1, 0x4C, 0x155555, 0x8FC }, + [ATHOS_LUT_CHAN_690125_IDX] = { 27605, 0x1, 0x4C, 0x15C71C, 0x8FC }, + [ATHOS_LUT_CHAN_690250_IDX] = { 27610, 0x1, 0x4C, 0x1638E4, 0x8FD }, + [ATHOS_LUT_CHAN_690375_IDX] = { 27615, 0x1, 0x4C, 0x16AAAB, 0x8FD }, + [ATHOS_LUT_CHAN_690500_IDX] = { 27620, 0x1, 0x4C, 0x171C72, 0x8FE }, + [ATHOS_LUT_CHAN_690625_IDX] = { 27625, 0x1, 0x4C, 0x178E39, 0x8FE }, + [ATHOS_LUT_CHAN_690750_IDX] = { 27630, 0x1, 0x4C, 0x180000, 0x8FF }, + [ATHOS_LUT_CHAN_690875_IDX] = { 27635, 0x1, 0x4C, 0x1871C7, 0x8FF }, + [ATHOS_LUT_CHAN_691000_IDX] = { 27640, 0x1, 0x4C, 0x18E38E, 0x8FF }, + [ATHOS_LUT_CHAN_691125_IDX] = { 27645, 0x1, 0x4C, 0x195555, 0x900 }, + [ATHOS_LUT_CHAN_691250_IDX] = { 27650, 0x1, 0x4C, 0x19C71C, 0x900 }, + [ATHOS_LUT_CHAN_691375_IDX] = { 27655, 0x1, 0x4C, 0x1A38E4, 0x901 }, + [ATHOS_LUT_CHAN_691500_IDX] = { 27660, 0x1, 0x4C, 0x1AAAAB, 0x901 }, + [ATHOS_LUT_CHAN_691625_IDX] = { 27665, 0x1, 0x4C, 0x1B1C72, 0x901 }, + [ATHOS_LUT_CHAN_691750_IDX] = { 27670, 0x1, 0x4C, 0x1B8E39, 0x902 }, + [ATHOS_LUT_CHAN_691875_IDX] = { 27675, 0x1, 0x4C, 0x1C0000, 0x902 }, + [ATHOS_LUT_CHAN_692000_IDX] = { 27680, 0x1, 0x4C, 0x1C71C7, 0x903 }, + [ATHOS_LUT_CHAN_692125_IDX] = { 27685, 0x1, 0x4C, 0x1CE38E, 0x903 }, + [ATHOS_LUT_CHAN_692250_IDX] = { 27690, 0x1, 0x4C, 0x1D5555, 0x904 }, + [ATHOS_LUT_CHAN_692375_IDX] = { 27695, 0x1, 0x4C, 0x1DC71C, 0x904 }, + [ATHOS_LUT_CHAN_692500_IDX] = { 27700, 0x1, 0x4C, 0x1E38E4, 0x904 }, + [ATHOS_LUT_CHAN_692625_IDX] = { 27705, 0x1, 0x4C, 0x1EAAAB, 0x905 }, + [ATHOS_LUT_CHAN_692750_IDX] = { 27710, 0x1, 0x4C, 0x1F1C72, 0x905 }, + [ATHOS_LUT_CHAN_692875_IDX] = { 27715, 0x1, 0x4C, 0x1F8E39, 0x906 }, + [ATHOS_LUT_CHAN_693000_IDX] = { 27720, 0x1, 0x4D, 0x0, 0x906 }, + [ATHOS_LUT_CHAN_693125_IDX] = { 27725, 0x1, 0x4D, 0x71C7, 0x906 }, + [ATHOS_LUT_CHAN_693250_IDX] = { 27730, 0x1, 0x4D, 0xE38E, 0x907 }, + [ATHOS_LUT_CHAN_693375_IDX] = { 27735, 0x1, 0x4D, 0x15555, 0x907 }, + [ATHOS_LUT_CHAN_693500_IDX] = { 27740, 0x1, 0x4D, 0x1C71C, 0x908 }, + [ATHOS_LUT_CHAN_693625_IDX] = { 27745, 0x1, 0x4D, 0x238E4, 0x908 }, + [ATHOS_LUT_CHAN_693750_IDX] = { 27750, 0x1, 0x4D, 0x2AAAB, 0x909 }, + [ATHOS_LUT_CHAN_693875_IDX] = { 27755, 0x1, 0x4D, 0x31C72, 0x909 }, + [ATHOS_LUT_CHAN_694000_IDX] = { 27760, 0x1, 0x4D, 0x38E39, 0x909 }, + [ATHOS_LUT_CHAN_694125_IDX] = { 27765, 0x1, 0x4D, 0x40000, 0x90A }, + [ATHOS_LUT_CHAN_694250_IDX] = { 27770, 0x1, 0x4D, 0x471C7, 0x90A }, + [ATHOS_LUT_CHAN_694375_IDX] = { 27775, 0x1, 0x4D, 0x4E38E, 0x90B }, + [ATHOS_LUT_CHAN_694500_IDX] = { 27780, 0x1, 0x4D, 0x55555, 0x90B }, + [ATHOS_LUT_CHAN_694625_IDX] = { 27785, 0x1, 0x4D, 0x5C71C, 0x90B }, + [ATHOS_LUT_CHAN_694750_IDX] = { 27790, 0x1, 0x4D, 0x638E4, 0x90C }, + [ATHOS_LUT_CHAN_694875_IDX] = { 27795, 0x1, 0x4D, 0x6AAAB, 0x90C }, + [ATHOS_LUT_CHAN_695000_IDX] = { 27800, 0x1, 0x4D, 0x71C72, 0x90D }, + [ATHOS_LUT_CHAN_695125_IDX] = { 27805, 0x1, 0x4D, 0x78E39, 0x90D }, + [ATHOS_LUT_CHAN_695250_IDX] = { 27810, 0x1, 0x4D, 0x80000, 0x90E }, + [ATHOS_LUT_CHAN_695375_IDX] = { 27815, 0x1, 0x4D, 0x871C7, 0x90E }, + [ATHOS_LUT_CHAN_695500_IDX] = { 27820, 0x1, 0x4D, 0x8E38E, 0x90E }, + [ATHOS_LUT_CHAN_695625_IDX] = { 27825, 0x1, 0x4D, 0x95555, 0x90F }, + [ATHOS_LUT_CHAN_695750_IDX] = { 27830, 0x1, 0x4D, 0x9C71C, 0x90F }, + [ATHOS_LUT_CHAN_695875_IDX] = { 27835, 0x1, 0x4D, 0xA38E4, 0x910 }, + [ATHOS_LUT_CHAN_696000_IDX] = { 27840, 0x1, 0x4D, 0xAAAAB, 0x910 }, + [ATHOS_LUT_CHAN_696125_IDX] = { 27845, 0x1, 0x4D, 0xB1C72, 0x910 }, + [ATHOS_LUT_CHAN_696250_IDX] = { 27850, 0x1, 0x4D, 0xB8E39, 0x911 }, + [ATHOS_LUT_CHAN_696375_IDX] = { 27855, 0x1, 0x4D, 0xC0000, 0x911 }, + [ATHOS_LUT_CHAN_696500_IDX] = { 27860, 0x1, 0x4D, 0xC71C7, 0x912 }, + [ATHOS_LUT_CHAN_696625_IDX] = { 27865, 0x1, 0x4D, 0xCE38E, 0x912 }, + [ATHOS_LUT_CHAN_696750_IDX] = { 27870, 0x1, 0x4D, 0xD5555, 0x913 }, + [ATHOS_LUT_CHAN_696875_IDX] = { 27875, 0x1, 0x4D, 0xDC71C, 0x913 }, + [ATHOS_LUT_CHAN_697000_IDX] = { 27880, 0x1, 0x4D, 0xE38E4, 0x913 }, + [ATHOS_LUT_CHAN_697125_IDX] = { 27885, 0x1, 0x4D, 0xEAAAB, 0x914 }, + [ATHOS_LUT_CHAN_697250_IDX] = { 27890, 0x1, 0x4D, 0xF1C72, 0x914 }, + [ATHOS_LUT_CHAN_697375_IDX] = { 27895, 0x1, 0x4D, 0xF8E39, 0x915 }, + [ATHOS_LUT_CHAN_697500_IDX] = { 27900, 0x1, 0x4D, 0x100000, 0x915 }, + [ATHOS_LUT_CHAN_697625_IDX] = { 27905, 0x1, 0x4D, 0x1071C7, 0x915 }, + [ATHOS_LUT_CHAN_697750_IDX] = { 27910, 0x1, 0x4D, 0x10E38E, 0x916 }, + [ATHOS_LUT_CHAN_697875_IDX] = { 27915, 0x1, 0x4D, 0x115555, 0x916 }, + [ATHOS_LUT_CHAN_698000_IDX] = { 27920, 0x1, 0x4D, 0x11C71C, 0x917 }, + [ATHOS_LUT_CHAN_698125_IDX] = { 27925, 0x1, 0x4D, 0x1238E4, 0x917 }, + [ATHOS_LUT_CHAN_698250_IDX] = { 27930, 0x1, 0x4D, 0x12AAAB, 0x918 }, + [ATHOS_LUT_CHAN_698375_IDX] = { 27935, 0x1, 0x4D, 0x131C72, 0x918 }, + [ATHOS_LUT_CHAN_698500_IDX] = { 27940, 0x1, 0x4D, 0x138E39, 0x918 }, + [ATHOS_LUT_CHAN_698625_IDX] = { 27945, 0x1, 0x4D, 0x140000, 0x919 }, + [ATHOS_LUT_CHAN_698750_IDX] = { 27950, 0x1, 0x4D, 0x1471C7, 0x919 }, + [ATHOS_LUT_CHAN_698875_IDX] = { 27955, 0x1, 0x4D, 0x14E38E, 0x91A }, + [ATHOS_LUT_CHAN_699000_IDX] = { 27960, 0x1, 0x4D, 0x155555, 0x91A }, + [ATHOS_LUT_CHAN_699125_IDX] = { 27965, 0x1, 0x4D, 0x15C71C, 0x91A }, + [ATHOS_LUT_CHAN_699250_IDX] = { 27970, 0x1, 0x4D, 0x1638E4, 0x91B }, + [ATHOS_LUT_CHAN_699375_IDX] = { 27975, 0x1, 0x4D, 0x16AAAB, 0x91B }, + [ATHOS_LUT_CHAN_699500_IDX] = { 27980, 0x1, 0x4D, 0x171C72, 0x91C }, + [ATHOS_LUT_CHAN_699625_IDX] = { 27985, 0x1, 0x4D, 0x178E39, 0x91C }, + [ATHOS_LUT_CHAN_699750_IDX] = { 27990, 0x1, 0x4D, 0x180000, 0x91D }, + [ATHOS_LUT_CHAN_699875_IDX] = { 27995, 0x1, 0x4D, 0x1871C7, 0x91D }, + [ATHOS_LUT_CHAN_700000_IDX] = { 28000, 0x1, 0x4D, 0x18E38E, 0x91D }, + [ATHOS_LUT_CHAN_700125_IDX] = { 28005, 0x1, 0x4D, 0x195555, 0x91E }, + [ATHOS_LUT_CHAN_700250_IDX] = { 28010, 0x1, 0x4D, 0x19C71C, 0x91E }, + [ATHOS_LUT_CHAN_700375_IDX] = { 28015, 0x1, 0x4D, 0x1A38E4, 0x91F }, + [ATHOS_LUT_CHAN_700500_IDX] = { 28020, 0x1, 0x4D, 0x1AAAAB, 0x91F }, + [ATHOS_LUT_CHAN_700625_IDX] = { 28025, 0x1, 0x4D, 0x1B1C72, 0x91F }, + [ATHOS_LUT_CHAN_700750_IDX] = { 28030, 0x1, 0x4D, 0x1B8E39, 0x920 }, + [ATHOS_LUT_CHAN_700875_IDX] = { 28035, 0x1, 0x4D, 0x1C0000, 0x920 }, + [ATHOS_LUT_CHAN_701000_IDX] = { 28040, 0x1, 0x4D, 0x1C71C7, 0x921 }, + [ATHOS_LUT_CHAN_701125_IDX] = { 28045, 0x1, 0x4D, 0x1CE38E, 0x921 }, + [ATHOS_LUT_CHAN_701250_IDX] = { 28050, 0x1, 0x4D, 0x1D5555, 0x922 }, + [ATHOS_LUT_CHAN_701375_IDX] = { 28055, 0x1, 0x4D, 0x1DC71C, 0x922 }, + [ATHOS_LUT_CHAN_701500_IDX] = { 28060, 0x1, 0x4D, 0x1E38E4, 0x922 }, + [ATHOS_LUT_CHAN_701625_IDX] = { 28065, 0x1, 0x4D, 0x1EAAAB, 0x923 }, + [ATHOS_LUT_CHAN_701750_IDX] = { 28070, 0x1, 0x4D, 0x1F1C72, 0x923 }, + [ATHOS_LUT_CHAN_701875_IDX] = { 28075, 0x1, 0x4D, 0x1F8E39, 0x924 }, + [ATHOS_LUT_CHAN_702000_IDX] = { 28080, 0x1, 0x4E, 0x0, 0x924 }, + [ATHOS_LUT_CHAN_702125_IDX] = { 28085, 0x1, 0x4E, 0x71C7, 0x924 }, + [ATHOS_LUT_CHAN_702250_IDX] = { 28090, 0x1, 0x4E, 0xE38E, 0x925 }, + [ATHOS_LUT_CHAN_702375_IDX] = { 28095, 0x1, 0x4E, 0x15555, 0x925 }, + [ATHOS_LUT_CHAN_702500_IDX] = { 28100, 0x1, 0x4E, 0x1C71C, 0x926 }, + [ATHOS_LUT_CHAN_702625_IDX] = { 28105, 0x1, 0x4E, 0x238E4, 0x926 }, + [ATHOS_LUT_CHAN_702750_IDX] = { 28110, 0x1, 0x4E, 0x2AAAB, 0x927 }, + [ATHOS_LUT_CHAN_702875_IDX] = { 28115, 0x1, 0x4E, 0x31C72, 0x927 }, + [ATHOS_LUT_CHAN_703000_IDX] = { 28120, 0x1, 0x4E, 0x38E39, 0x927 }, + [ATHOS_LUT_CHAN_703125_IDX] = { 28125, 0x1, 0x4E, 0x40000, 0x928 }, + [ATHOS_LUT_CHAN_703250_IDX] = { 28130, 0x1, 0x4E, 0x471C7, 0x928 }, + [ATHOS_LUT_CHAN_703375_IDX] = { 28135, 0x1, 0x4E, 0x4E38E, 0x929 }, + [ATHOS_LUT_CHAN_703500_IDX] = { 28140, 0x1, 0x4E, 0x55555, 0x929 }, + [ATHOS_LUT_CHAN_703625_IDX] = { 28145, 0x1, 0x4E, 0x5C71C, 0x929 }, + [ATHOS_LUT_CHAN_703750_IDX] = { 28150, 0x1, 0x4E, 0x638E4, 0x92A }, + [ATHOS_LUT_CHAN_703875_IDX] = { 28155, 0x1, 0x4E, 0x6AAAB, 0x92A }, + [ATHOS_LUT_CHAN_704000_IDX] = { 28160, 0x1, 0x4E, 0x71C72, 0x92B }, + [ATHOS_LUT_CHAN_704125_IDX] = { 28165, 0x1, 0x4E, 0x78E39, 0x92B }, + [ATHOS_LUT_CHAN_704250_IDX] = { 28170, 0x1, 0x4E, 0x80000, 0x92C }, + [ATHOS_LUT_CHAN_704375_IDX] = { 28175, 0x1, 0x4E, 0x871C7, 0x92C }, + [ATHOS_LUT_CHAN_704500_IDX] = { 28180, 0x1, 0x4E, 0x8E38E, 0x92C }, + [ATHOS_LUT_CHAN_704625_IDX] = { 28185, 0x1, 0x4E, 0x95555, 0x92D }, + [ATHOS_LUT_CHAN_704750_IDX] = { 28190, 0x1, 0x4E, 0x9C71C, 0x92D }, + [ATHOS_LUT_CHAN_704875_IDX] = { 28195, 0x1, 0x4E, 0xA38E4, 0x92E }, + [ATHOS_LUT_CHAN_705000_IDX] = { 28200, 0x1, 0x4E, 0xAAAAB, 0x92E }, + [ATHOS_LUT_CHAN_705125_IDX] = { 28205, 0x1, 0x4E, 0xB1C72, 0x92E }, + [ATHOS_LUT_CHAN_705250_IDX] = { 28210, 0x1, 0x4E, 0xB8E39, 0x92F }, + [ATHOS_LUT_CHAN_705375_IDX] = { 28215, 0x1, 0x4E, 0xC0000, 0x92F }, + [ATHOS_LUT_CHAN_705500_IDX] = { 28220, 0x1, 0x4E, 0xC71C7, 0x930 }, + [ATHOS_LUT_CHAN_705625_IDX] = { 28225, 0x1, 0x4E, 0xCE38E, 0x930 }, + [ATHOS_LUT_CHAN_705750_IDX] = { 28230, 0x1, 0x4E, 0xD5555, 0x931 }, + [ATHOS_LUT_CHAN_705875_IDX] = { 28235, 0x1, 0x4E, 0xDC71C, 0x931 }, + [ATHOS_LUT_CHAN_706000_IDX] = { 28240, 0x1, 0x4E, 0xE38E4, 0x931 }, + [ATHOS_LUT_CHAN_706125_IDX] = { 28245, 0x1, 0x4E, 0xEAAAB, 0x932 }, + [ATHOS_LUT_CHAN_706250_IDX] = { 28250, 0x1, 0x4E, 0xF1C72, 0x932 }, + [ATHOS_LUT_CHAN_706375_IDX] = { 28255, 0x1, 0x4E, 0xF8E39, 0x933 }, + [ATHOS_LUT_CHAN_706500_IDX] = { 28260, 0x1, 0x4E, 0x100000, 0x933 }, + [ATHOS_LUT_CHAN_706625_IDX] = { 28265, 0x1, 0x4E, 0x1071C7, 0x933 }, + [ATHOS_LUT_CHAN_706750_IDX] = { 28270, 0x1, 0x4E, 0x10E38E, 0x934 }, + [ATHOS_LUT_CHAN_706875_IDX] = { 28275, 0x1, 0x4E, 0x115555, 0x934 }, + [ATHOS_LUT_CHAN_707000_IDX] = { 28280, 0x1, 0x4E, 0x11C71C, 0x935 }, + [ATHOS_LUT_CHAN_707125_IDX] = { 28285, 0x1, 0x4E, 0x1238E4, 0x935 }, + [ATHOS_LUT_CHAN_707250_IDX] = { 28290, 0x1, 0x4E, 0x12AAAB, 0x936 }, + [ATHOS_LUT_CHAN_707375_IDX] = { 28295, 0x1, 0x4E, 0x131C72, 0x936 }, + [ATHOS_LUT_CHAN_707500_IDX] = { 28300, 0x1, 0x4E, 0x138E39, 0x936 }, + [ATHOS_LUT_CHAN_707625_IDX] = { 28305, 0x1, 0x4E, 0x140000, 0x937 }, + [ATHOS_LUT_CHAN_707750_IDX] = { 28310, 0x1, 0x4E, 0x1471C7, 0x937 }, + [ATHOS_LUT_CHAN_707875_IDX] = { 28315, 0x1, 0x4E, 0x14E38E, 0x938 }, + [ATHOS_LUT_CHAN_708000_IDX] = { 28320, 0x1, 0x4E, 0x155555, 0x938 }, + [ATHOS_LUT_CHAN_708125_IDX] = { 28325, 0x1, 0x4E, 0x15C71C, 0x938 }, + [ATHOS_LUT_CHAN_708250_IDX] = { 28330, 0x1, 0x4E, 0x1638E4, 0x939 }, + [ATHOS_LUT_CHAN_708375_IDX] = { 28335, 0x1, 0x4E, 0x16AAAB, 0x939 }, + [ATHOS_LUT_CHAN_708500_IDX] = { 28340, 0x1, 0x4E, 0x171C72, 0x93A }, + [ATHOS_LUT_CHAN_708625_IDX] = { 28345, 0x1, 0x4E, 0x178E39, 0x93A }, + [ATHOS_LUT_CHAN_708750_IDX] = { 28350, 0x1, 0x4E, 0x180000, 0x93B }, + [ATHOS_LUT_CHAN_708875_IDX] = { 28355, 0x1, 0x4E, 0x1871C7, 0x93B }, + [ATHOS_LUT_CHAN_709000_IDX] = { 28360, 0x1, 0x4E, 0x18E38E, 0x93B }, + [ATHOS_LUT_CHAN_709125_IDX] = { 28365, 0x1, 0x4E, 0x195555, 0x93C }, + [ATHOS_LUT_CHAN_709250_IDX] = { 28370, 0x1, 0x4E, 0x19C71C, 0x93C }, + [ATHOS_LUT_CHAN_709375_IDX] = { 28375, 0x1, 0x4E, 0x1A38E4, 0x93D }, + [ATHOS_LUT_CHAN_709500_IDX] = { 28380, 0x1, 0x4E, 0x1AAAAB, 0x93D }, + [ATHOS_LUT_CHAN_709625_IDX] = { 28385, 0x1, 0x4E, 0x1B1C72, 0x93D }, + [ATHOS_LUT_CHAN_709750_IDX] = { 28390, 0x1, 0x4E, 0x1B8E39, 0x93E }, + [ATHOS_LUT_CHAN_709875_IDX] = { 28395, 0x1, 0x4E, 0x1C0000, 0x93E }, + [ATHOS_LUT_CHAN_710000_IDX] = { 28400, 0x1, 0x4E, 0x1C71C7, 0x93F }, + [ATHOS_LUT_CHAN_710125_IDX] = { 28405, 0x1, 0x4E, 0x1CE38E, 0x93F }, + [ATHOS_LUT_CHAN_710250_IDX] = { 28410, 0x1, 0x4E, 0x1D5555, 0x940 }, + [ATHOS_LUT_CHAN_710375_IDX] = { 28415, 0x1, 0x4E, 0x1DC71C, 0x940 }, + [ATHOS_LUT_CHAN_710500_IDX] = { 28420, 0x1, 0x4E, 0x1E38E4, 0x940 }, + [ATHOS_LUT_CHAN_710625_IDX] = { 28425, 0x1, 0x4E, 0x1EAAAB, 0x941 }, + [ATHOS_LUT_CHAN_710750_IDX] = { 28430, 0x1, 0x4E, 0x1F1C72, 0x941 }, + [ATHOS_LUT_CHAN_710875_IDX] = { 28435, 0x1, 0x4E, 0x1F8E39, 0x942 }, + [ATHOS_LUT_CHAN_711000_IDX] = { 28440, 0x1, 0x4F, 0x0, 0x942 }, + [ATHOS_LUT_CHAN_711125_IDX] = { 28445, 0x1, 0x4F, 0x71C7, 0x942 }, + [ATHOS_LUT_CHAN_711250_IDX] = { 28450, 0x1, 0x4F, 0xE38E, 0x943 }, + [ATHOS_LUT_CHAN_711375_IDX] = { 28455, 0x1, 0x4F, 0x15555, 0x943 }, + [ATHOS_LUT_CHAN_711500_IDX] = { 28460, 0x1, 0x4F, 0x1C71C, 0x944 }, + [ATHOS_LUT_CHAN_711625_IDX] = { 28465, 0x1, 0x4F, 0x238E4, 0x944 }, + [ATHOS_LUT_CHAN_711750_IDX] = { 28470, 0x1, 0x4F, 0x2AAAB, 0x945 }, + [ATHOS_LUT_CHAN_711875_IDX] = { 28475, 0x1, 0x4F, 0x31C72, 0x945 }, + [ATHOS_LUT_CHAN_712000_IDX] = { 28480, 0x1, 0x4F, 0x38E39, 0x945 }, + [ATHOS_LUT_CHAN_712125_IDX] = { 28485, 0x1, 0x4F, 0x40000, 0x946 }, + [ATHOS_LUT_CHAN_712250_IDX] = { 28490, 0x1, 0x4F, 0x471C7, 0x946 }, + [ATHOS_LUT_CHAN_712375_IDX] = { 28495, 0x1, 0x4F, 0x4E38E, 0x947 }, + [ATHOS_LUT_CHAN_712500_IDX] = { 28500, 0x1, 0x4F, 0x55555, 0x947 }, + [ATHOS_LUT_CHAN_712625_IDX] = { 28505, 0x1, 0x4F, 0x5C71C, 0x947 }, + [ATHOS_LUT_CHAN_712750_IDX] = { 28510, 0x1, 0x4F, 0x638E4, 0x948 }, + [ATHOS_LUT_CHAN_712875_IDX] = { 28515, 0x1, 0x4F, 0x6AAAB, 0x948 }, + [ATHOS_LUT_CHAN_713000_IDX] = { 28520, 0x1, 0x4F, 0x71C72, 0x949 }, + [ATHOS_LUT_CHAN_713125_IDX] = { 28525, 0x1, 0x4F, 0x78E39, 0x949 }, + [ATHOS_LUT_CHAN_713250_IDX] = { 28530, 0x1, 0x4F, 0x80000, 0x94A }, + [ATHOS_LUT_CHAN_713375_IDX] = { 28535, 0x1, 0x4F, 0x871C7, 0x94A }, + [ATHOS_LUT_CHAN_713500_IDX] = { 28540, 0x1, 0x4F, 0x8E38E, 0x94A }, + [ATHOS_LUT_CHAN_713625_IDX] = { 28545, 0x1, 0x4F, 0x95555, 0x94B }, + [ATHOS_LUT_CHAN_713750_IDX] = { 28550, 0x1, 0x4F, 0x9C71C, 0x94B }, + [ATHOS_LUT_CHAN_713875_IDX] = { 28555, 0x1, 0x4F, 0xA38E4, 0x94C }, + [ATHOS_LUT_CHAN_714000_IDX] = { 28560, 0x1, 0x4F, 0xAAAAB, 0x94C }, + [ATHOS_LUT_CHAN_714125_IDX] = { 28565, 0x1, 0x4F, 0xB1C72, 0x94C }, + [ATHOS_LUT_CHAN_714250_IDX] = { 28570, 0x1, 0x4F, 0xB8E39, 0x94D }, + [ATHOS_LUT_CHAN_714375_IDX] = { 28575, 0x1, 0x4F, 0xC0000, 0x94D }, + [ATHOS_LUT_CHAN_714500_IDX] = { 28580, 0x1, 0x4F, 0xC71C7, 0x94E }, + [ATHOS_LUT_CHAN_714625_IDX] = { 28585, 0x1, 0x4F, 0xCE38E, 0x94E }, + [ATHOS_LUT_CHAN_714750_IDX] = { 28590, 0x1, 0x4F, 0xD5555, 0x94F }, + [ATHOS_LUT_CHAN_714875_IDX] = { 28595, 0x1, 0x4F, 0xDC71C, 0x94F }, + [ATHOS_LUT_CHAN_715000_IDX] = { 28600, 0x1, 0x4F, 0xE38E4, 0x94F }, + [ATHOS_LUT_CHAN_715125_IDX] = { 28605, 0x1, 0x4F, 0xEAAAB, 0x950 }, + [ATHOS_LUT_CHAN_715250_IDX] = { 28610, 0x1, 0x4F, 0xF1C72, 0x950 }, + [ATHOS_LUT_CHAN_715375_IDX] = { 28615, 0x1, 0x4F, 0xF8E39, 0x951 }, + [ATHOS_LUT_CHAN_715500_IDX] = { 28620, 0x1, 0x4F, 0x100000, 0x951 }, + [ATHOS_LUT_CHAN_715625_IDX] = { 28625, 0x1, 0x4F, 0x1071C7, 0x951 }, + [ATHOS_LUT_CHAN_715750_IDX] = { 28630, 0x1, 0x4F, 0x10E38E, 0x952 }, + [ATHOS_LUT_CHAN_715875_IDX] = { 28635, 0x1, 0x4F, 0x115555, 0x952 }, + [ATHOS_LUT_CHAN_716000_IDX] = { 28640, 0x1, 0x4F, 0x11C71C, 0x953 }, + [ATHOS_LUT_CHAN_716125_IDX] = { 28645, 0x1, 0x4F, 0x1238E4, 0x953 }, + [ATHOS_LUT_CHAN_716250_IDX] = { 28650, 0x1, 0x4F, 0x12AAAB, 0x954 }, + [ATHOS_LUT_CHAN_716375_IDX] = { 28655, 0x1, 0x4F, 0x131C72, 0x954 }, + [ATHOS_LUT_CHAN_716500_IDX] = { 28660, 0x1, 0x4F, 0x138E39, 0x954 }, + [ATHOS_LUT_CHAN_716625_IDX] = { 28665, 0x1, 0x4F, 0x140000, 0x955 }, + [ATHOS_LUT_CHAN_716750_IDX] = { 28670, 0x1, 0x4F, 0x1471C7, 0x955 }, + [ATHOS_LUT_CHAN_716875_IDX] = { 28675, 0x1, 0x4F, 0x14E38E, 0x956 }, + [ATHOS_LUT_CHAN_717000_IDX] = { 28680, 0x1, 0x4F, 0x155555, 0x956 }, + [ATHOS_LUT_CHAN_717125_IDX] = { 28685, 0x1, 0x4F, 0x15C71C, 0x956 }, + [ATHOS_LUT_CHAN_717250_IDX] = { 28690, 0x1, 0x4F, 0x1638E4, 0x957 }, + [ATHOS_LUT_CHAN_717375_IDX] = { 28695, 0x1, 0x4F, 0x16AAAB, 0x957 }, + [ATHOS_LUT_CHAN_717500_IDX] = { 28700, 0x1, 0x4F, 0x171C72, 0x958 }, + [ATHOS_LUT_CHAN_717625_IDX] = { 28705, 0x1, 0x4F, 0x178E39, 0x958 }, + [ATHOS_LUT_CHAN_717750_IDX] = { 28710, 0x1, 0x4F, 0x180000, 0x959 }, + [ATHOS_LUT_CHAN_717875_IDX] = { 28715, 0x1, 0x4F, 0x1871C7, 0x959 }, + [ATHOS_LUT_CHAN_718000_IDX] = { 28720, 0x1, 0x4F, 0x18E38E, 0x959 }, + [ATHOS_LUT_CHAN_718125_IDX] = { 28725, 0x1, 0x4F, 0x195555, 0x95A }, + [ATHOS_LUT_CHAN_718250_IDX] = { 28730, 0x1, 0x4F, 0x19C71C, 0x95A }, + [ATHOS_LUT_CHAN_718375_IDX] = { 28735, 0x1, 0x4F, 0x1A38E4, 0x95B }, + [ATHOS_LUT_CHAN_718500_IDX] = { 28740, 0x1, 0x4F, 0x1AAAAB, 0x95B }, + [ATHOS_LUT_CHAN_718625_IDX] = { 28745, 0x1, 0x4F, 0x1B1C72, 0x95B }, + [ATHOS_LUT_CHAN_718750_IDX] = { 28750, 0x1, 0x4F, 0x1B8E39, 0x95C }, + [ATHOS_LUT_CHAN_718875_IDX] = { 28755, 0x1, 0x4F, 0x1C0000, 0x95C }, + [ATHOS_LUT_CHAN_719000_IDX] = { 28760, 0x1, 0x4F, 0x1C71C7, 0x95D }, + [ATHOS_LUT_CHAN_719125_IDX] = { 28765, 0x1, 0x4F, 0x1CE38E, 0x95D }, + [ATHOS_LUT_CHAN_719250_IDX] = { 28770, 0x1, 0x4F, 0x1D5555, 0x95E }, + [ATHOS_LUT_CHAN_719375_IDX] = { 28775, 0x1, 0x4F, 0x1DC71C, 0x95E }, + [ATHOS_LUT_CHAN_719500_IDX] = { 28780, 0x1, 0x4F, 0x1E38E4, 0x95E }, + [ATHOS_LUT_CHAN_719625_IDX] = { 28785, 0x1, 0x4F, 0x1EAAAB, 0x95F }, + [ATHOS_LUT_CHAN_719750_IDX] = { 28790, 0x1, 0x4F, 0x1F1C72, 0x95F }, + [ATHOS_LUT_CHAN_719875_IDX] = { 28795, 0x1, 0x4F, 0x1F8E39, 0x960 }, + [ATHOS_LUT_CHAN_720000_IDX] = { 28800, 0x1, 0x50, 0x0, 0x960 }, + [ATHOS_LUT_CHAN_720125_IDX] = { 28805, 0x1, 0x50, 0x71C7, 0x960 }, + [ATHOS_LUT_CHAN_720250_IDX] = { 28810, 0x1, 0x50, 0xE38E, 0x961 }, + [ATHOS_LUT_CHAN_720375_IDX] = { 28815, 0x1, 0x50, 0x15555, 0x961 }, + [ATHOS_LUT_CHAN_720500_IDX] = { 28820, 0x1, 0x50, 0x1C71C, 0x962 }, + [ATHOS_LUT_CHAN_720625_IDX] = { 28825, 0x1, 0x50, 0x238E4, 0x962 }, + [ATHOS_LUT_CHAN_720750_IDX] = { 28830, 0x1, 0x50, 0x2AAAB, 0x963 }, + [ATHOS_LUT_CHAN_720875_IDX] = { 28835, 0x1, 0x50, 0x31C72, 0x963 }, + [ATHOS_LUT_CHAN_721000_IDX] = { 28840, 0x1, 0x50, 0x38E39, 0x963 }, + [ATHOS_LUT_CHAN_721125_IDX] = { 28845, 0x1, 0x50, 0x40000, 0x964 }, + [ATHOS_LUT_CHAN_721250_IDX] = { 28850, 0x1, 0x50, 0x471C7, 0x964 }, + [ATHOS_LUT_CHAN_721375_IDX] = { 28855, 0x1, 0x50, 0x4E38E, 0x965 }, + [ATHOS_LUT_CHAN_721500_IDX] = { 28860, 0x1, 0x50, 0x55555, 0x965 } +}; + +const struct common_lut_line athos_b_lut_6g_40_mhz[ATHOS_B_6G_LUT_CHAN_6G_MAX] = { + [ATHOS_B_6G_LUT_CHAN_593000_IDX] = { 23720, 0x0, 0x62, 0x1AAAAB, 0x7B9 }, + [ATHOS_B_6G_LUT_CHAN_593125_IDX] = { 23725, 0x0, 0x62, 0x1B5555, 0x7B9 }, + [ATHOS_B_6G_LUT_CHAN_593250_IDX] = { 23730, 0x0, 0x62, 0x1C0000, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593375_IDX] = { 23735, 0x0, 0x62, 0x1CAAAB, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593500_IDX] = { 23740, 0x0, 0x62, 0x1D5555, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593625_IDX] = { 23745, 0x0, 0x62, 0x1E0000, 0x7BB }, + [ATHOS_B_6G_LUT_CHAN_593750_IDX] = { 23750, 0x0, 0x62, 0x1EAAAB, 0x7BB }, + [ATHOS_B_6G_LUT_CHAN_593875_IDX] = { 23755, 0x0, 0x62, 0x1F5555, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594000_IDX] = { 23760, 0x0, 0x63, 0x0, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594125_IDX] = { 23765, 0x0, 0x63, 0xAAAB, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594250_IDX] = { 23770, 0x0, 0x63, 0x15555, 0x7BD }, + [ATHOS_B_6G_LUT_CHAN_594375_IDX] = { 23775, 0x0, 0x63, 0x20000, 0x7BD }, + [ATHOS_B_6G_LUT_CHAN_594500_IDX] = { 23780, 0x0, 0x63, 0x2AAAB, 0x7BE }, + [ATHOS_B_6G_LUT_CHAN_594625_IDX] = { 23785, 0x0, 0x63, 0x35555, 0x7BE }, + [ATHOS_B_6G_LUT_CHAN_594750_IDX] = { 23790, 0x0, 0x63, 0x40000, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_594875_IDX] = { 23795, 0x0, 0x63, 0x4AAAB, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_595000_IDX] = { 23800, 0x0, 0x63, 0x55555, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_595125_IDX] = { 23805, 0x0, 0x63, 0x60000, 0x7C0 }, + [ATHOS_B_6G_LUT_CHAN_595250_IDX] = { 23810, 0x0, 0x63, 0x6AAAB, 0x7C0 }, + [ATHOS_B_6G_LUT_CHAN_595375_IDX] = { 23815, 0x0, 0x63, 0x75555, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595500_IDX] = { 23820, 0x0, 0x63, 0x80000, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595625_IDX] = { 23825, 0x0, 0x63, 0x8AAAB, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595750_IDX] = { 23830, 0x0, 0x63, 0x95555, 0x7C2 }, + [ATHOS_B_6G_LUT_CHAN_595875_IDX] = { 23835, 0x0, 0x63, 0xA0000, 0x7C2 }, + [ATHOS_B_6G_LUT_CHAN_596000_IDX] = { 23840, 0x0, 0x63, 0xAAAAB, 0x7C3 }, + [ATHOS_B_6G_LUT_CHAN_596125_IDX] = { 23845, 0x0, 0x63, 0xB5555, 0x7C3 }, + [ATHOS_B_6G_LUT_CHAN_596250_IDX] = { 23850, 0x0, 0x63, 0xC0000, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596375_IDX] = { 23855, 0x0, 0x63, 0xCAAAB, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596500_IDX] = { 23860, 0x0, 0x63, 0xD5555, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596625_IDX] = { 23865, 0x0, 0x63, 0xE0000, 0x7C5 }, + [ATHOS_B_6G_LUT_CHAN_596750_IDX] = { 23870, 0x0, 0x63, 0xEAAAB, 0x7C5 }, + [ATHOS_B_6G_LUT_CHAN_596875_IDX] = { 23875, 0x0, 0x63, 0xF5555, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597000_IDX] = { 23880, 0x0, 0x63, 0x100000, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597125_IDX] = { 23885, 0x0, 0x63, 0x10AAAB, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597250_IDX] = { 23890, 0x0, 0x63, 0x115555, 0x7C7 }, + [ATHOS_B_6G_LUT_CHAN_597375_IDX] = { 23895, 0x0, 0x63, 0x120000, 0x7C7 }, + [ATHOS_B_6G_LUT_CHAN_597500_IDX] = { 23900, 0x0, 0x63, 0x12AAAB, 0x7C8 }, + [ATHOS_B_6G_LUT_CHAN_597625_IDX] = { 23905, 0x0, 0x63, 0x135555, 0x7C8 }, + [ATHOS_B_6G_LUT_CHAN_597750_IDX] = { 23910, 0x0, 0x63, 0x140000, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_597875_IDX] = { 23915, 0x0, 0x63, 0x14AAAB, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_598000_IDX] = { 23920, 0x0, 0x63, 0x155555, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_598125_IDX] = { 23925, 0x0, 0x63, 0x160000, 0x7CA }, + [ATHOS_B_6G_LUT_CHAN_598250_IDX] = { 23930, 0x0, 0x63, 0x16AAAB, 0x7CA }, + [ATHOS_B_6G_LUT_CHAN_598375_IDX] = { 23935, 0x0, 0x63, 0x175555, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598500_IDX] = { 23940, 0x0, 0x63, 0x180000, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598625_IDX] = { 23945, 0x0, 0x63, 0x18AAAB, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598750_IDX] = { 23950, 0x0, 0x63, 0x195555, 0x7CC }, + [ATHOS_B_6G_LUT_CHAN_598875_IDX] = { 23955, 0x0, 0x63, 0x1A0000, 0x7CC }, + [ATHOS_B_6G_LUT_CHAN_599000_IDX] = { 23960, 0x0, 0x63, 0x1AAAAB, 0x7CD }, + [ATHOS_B_6G_LUT_CHAN_599125_IDX] = { 23965, 0x0, 0x63, 0x1B5555, 0x7CD }, + [ATHOS_B_6G_LUT_CHAN_599250_IDX] = { 23970, 0x0, 0x63, 0x1C0000, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599375_IDX] = { 23975, 0x0, 0x63, 0x1CAAAB, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599500_IDX] = { 23980, 0x0, 0x63, 0x1D5555, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599625_IDX] = { 23985, 0x0, 0x63, 0x1E0000, 0x7CF }, + [ATHOS_B_6G_LUT_CHAN_599750_IDX] = { 23990, 0x0, 0x63, 0x1EAAAB, 0x7CF }, + [ATHOS_B_6G_LUT_CHAN_599875_IDX] = { 23995, 0x0, 0x63, 0x1F5555, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600000_IDX] = { 24000, 0x0, 0x64, 0x0, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600125_IDX] = { 24005, 0x0, 0x64, 0xAAAB, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600250_IDX] = { 24010, 0x0, 0x64, 0x15555, 0x7D1 }, + [ATHOS_B_6G_LUT_CHAN_600375_IDX] = { 24015, 0x0, 0x64, 0x20000, 0x7D1 }, + [ATHOS_B_6G_LUT_CHAN_600500_IDX] = { 24020, 0x0, 0x64, 0x2AAAB, 0x7D2 }, + [ATHOS_B_6G_LUT_CHAN_600625_IDX] = { 24025, 0x0, 0x64, 0x35555, 0x7D2 }, + [ATHOS_B_6G_LUT_CHAN_600750_IDX] = { 24030, 0x0, 0x64, 0x40000, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_600875_IDX] = { 24035, 0x0, 0x64, 0x4AAAB, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_601000_IDX] = { 24040, 0x0, 0x64, 0x55555, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_601125_IDX] = { 24045, 0x0, 0x64, 0x60000, 0x7D4 }, + [ATHOS_B_6G_LUT_CHAN_601250_IDX] = { 24050, 0x0, 0x64, 0x6AAAB, 0x7D4 }, + [ATHOS_B_6G_LUT_CHAN_601375_IDX] = { 24055, 0x0, 0x64, 0x75555, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601500_IDX] = { 24060, 0x0, 0x64, 0x80000, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601625_IDX] = { 24065, 0x0, 0x64, 0x8AAAB, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601750_IDX] = { 24070, 0x0, 0x64, 0x95555, 0x7D6 }, + [ATHOS_B_6G_LUT_CHAN_601875_IDX] = { 24075, 0x0, 0x64, 0xA0000, 0x7D6 }, + [ATHOS_B_6G_LUT_CHAN_602000_IDX] = { 24080, 0x0, 0x64, 0xAAAAB, 0x7D7 }, + [ATHOS_B_6G_LUT_CHAN_602125_IDX] = { 24085, 0x0, 0x64, 0xB5555, 0x7D7 }, + [ATHOS_B_6G_LUT_CHAN_602250_IDX] = { 24090, 0x0, 0x64, 0xC0000, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602375_IDX] = { 24095, 0x0, 0x64, 0xCAAAB, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602500_IDX] = { 24100, 0x0, 0x64, 0xD5555, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602625_IDX] = { 24105, 0x0, 0x64, 0xE0000, 0x7D9 }, + [ATHOS_B_6G_LUT_CHAN_602750_IDX] = { 24110, 0x0, 0x64, 0xEAAAB, 0x7D9 }, + [ATHOS_B_6G_LUT_CHAN_602875_IDX] = { 24115, 0x0, 0x64, 0xF5555, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603000_IDX] = { 24120, 0x0, 0x64, 0x100000, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603125_IDX] = { 24125, 0x0, 0x64, 0x10AAAB, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603250_IDX] = { 24130, 0x0, 0x64, 0x115555, 0x7DB }, + [ATHOS_B_6G_LUT_CHAN_603375_IDX] = { 24135, 0x0, 0x64, 0x120000, 0x7DB }, + [ATHOS_B_6G_LUT_CHAN_603500_IDX] = { 24140, 0x0, 0x64, 0x12AAAB, 0x7DC }, + [ATHOS_B_6G_LUT_CHAN_603625_IDX] = { 24145, 0x0, 0x64, 0x135555, 0x7DC }, + [ATHOS_B_6G_LUT_CHAN_603750_IDX] = { 24150, 0x0, 0x64, 0x140000, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_603875_IDX] = { 24155, 0x0, 0x64, 0x14AAAB, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_604000_IDX] = { 24160, 0x0, 0x64, 0x155555, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_604125_IDX] = { 24165, 0x0, 0x64, 0x160000, 0x7DE }, + [ATHOS_B_6G_LUT_CHAN_604250_IDX] = { 24170, 0x0, 0x64, 0x16AAAB, 0x7DE }, + [ATHOS_B_6G_LUT_CHAN_604375_IDX] = { 24175, 0x0, 0x64, 0x175555, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604500_IDX] = { 24180, 0x0, 0x64, 0x180000, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604625_IDX] = { 24185, 0x0, 0x64, 0x18AAAB, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604750_IDX] = { 24190, 0x0, 0x64, 0x195555, 0x7E0 }, + [ATHOS_B_6G_LUT_CHAN_604875_IDX] = { 24195, 0x0, 0x64, 0x1A0000, 0x7E0 }, + [ATHOS_B_6G_LUT_CHAN_605000_IDX] = { 24200, 0x0, 0x64, 0x1AAAAB, 0x7E1 }, + [ATHOS_B_6G_LUT_CHAN_605125_IDX] = { 24205, 0x0, 0x64, 0x1B5555, 0x7E1 }, + [ATHOS_B_6G_LUT_CHAN_605250_IDX] = { 24210, 0x0, 0x64, 0x1C0000, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605375_IDX] = { 24215, 0x0, 0x64, 0x1CAAAB, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605500_IDX] = { 24220, 0x0, 0x64, 0x1D5555, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605625_IDX] = { 24225, 0x0, 0x64, 0x1E0000, 0x7E3 }, + [ATHOS_B_6G_LUT_CHAN_605750_IDX] = { 24230, 0x0, 0x64, 0x1EAAAB, 0x7E3 }, + [ATHOS_B_6G_LUT_CHAN_605875_IDX] = { 24235, 0x0, 0x64, 0x1F5555, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606000_IDX] = { 24240, 0x0, 0x65, 0x0, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606125_IDX] = { 24245, 0x0, 0x65, 0xAAAB, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606250_IDX] = { 24250, 0x0, 0x65, 0x15555, 0x7E5 }, + [ATHOS_B_6G_LUT_CHAN_606375_IDX] = { 24255, 0x0, 0x65, 0x20000, 0x7E5 }, + [ATHOS_B_6G_LUT_CHAN_606500_IDX] = { 24260, 0x0, 0x65, 0x2AAAB, 0x7E6 }, + [ATHOS_B_6G_LUT_CHAN_606625_IDX] = { 24265, 0x0, 0x65, 0x35555, 0x7E6 }, + [ATHOS_B_6G_LUT_CHAN_606750_IDX] = { 24270, 0x0, 0x65, 0x40000, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_606875_IDX] = { 24275, 0x0, 0x65, 0x4AAAB, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_607000_IDX] = { 24280, 0x0, 0x65, 0x55555, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_607125_IDX] = { 24285, 0x0, 0x65, 0x60000, 0x7E8 }, + [ATHOS_B_6G_LUT_CHAN_607250_IDX] = { 24290, 0x0, 0x65, 0x6AAAB, 0x7E8 }, + [ATHOS_B_6G_LUT_CHAN_607375_IDX] = { 24295, 0x0, 0x65, 0x75555, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607500_IDX] = { 24300, 0x0, 0x65, 0x80000, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607625_IDX] = { 24305, 0x0, 0x65, 0x8AAAB, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607750_IDX] = { 24310, 0x0, 0x65, 0x95555, 0x7EA }, + [ATHOS_B_6G_LUT_CHAN_607875_IDX] = { 24315, 0x0, 0x65, 0xA0000, 0x7EA }, + [ATHOS_B_6G_LUT_CHAN_608000_IDX] = { 24320, 0x0, 0x65, 0xAAAAB, 0x7EB }, + [ATHOS_B_6G_LUT_CHAN_608125_IDX] = { 24325, 0x0, 0x65, 0xB5555, 0x7EB }, + [ATHOS_B_6G_LUT_CHAN_608250_IDX] = { 24330, 0x0, 0x65, 0xC0000, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608375_IDX] = { 24335, 0x0, 0x65, 0xCAAAB, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608500_IDX] = { 24340, 0x0, 0x65, 0xD5555, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608625_IDX] = { 24345, 0x0, 0x65, 0xE0000, 0x7ED }, + [ATHOS_B_6G_LUT_CHAN_608750_IDX] = { 24350, 0x0, 0x65, 0xEAAAB, 0x7ED }, + [ATHOS_B_6G_LUT_CHAN_608875_IDX] = { 24355, 0x0, 0x65, 0xF5555, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609000_IDX] = { 24360, 0x0, 0x65, 0x100000, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609125_IDX] = { 24365, 0x0, 0x65, 0x10AAAB, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609250_IDX] = { 24370, 0x0, 0x65, 0x115555, 0x7EF }, + [ATHOS_B_6G_LUT_CHAN_609375_IDX] = { 24375, 0x0, 0x65, 0x120000, 0x7EF }, + [ATHOS_B_6G_LUT_CHAN_609500_IDX] = { 24380, 0x0, 0x65, 0x12AAAB, 0x7F0 }, + [ATHOS_B_6G_LUT_CHAN_609625_IDX] = { 24385, 0x0, 0x65, 0x135555, 0x7F0 }, + [ATHOS_B_6G_LUT_CHAN_609750_IDX] = { 24390, 0x0, 0x65, 0x140000, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_609875_IDX] = { 24395, 0x0, 0x65, 0x14AAAB, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_610000_IDX] = { 24400, 0x1, 0x65, 0x155555, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_610125_IDX] = { 24405, 0x1, 0x65, 0x160000, 0x7F2 }, + [ATHOS_B_6G_LUT_CHAN_610250_IDX] = { 24410, 0x1, 0x65, 0x16AAAB, 0x7F2 }, + [ATHOS_B_6G_LUT_CHAN_610375_IDX] = { 24415, 0x1, 0x65, 0x175555, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610500_IDX] = { 24420, 0x1, 0x65, 0x180000, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610625_IDX] = { 24425, 0x1, 0x65, 0x18AAAB, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610750_IDX] = { 24430, 0x1, 0x65, 0x195555, 0x7F4 }, + [ATHOS_B_6G_LUT_CHAN_610875_IDX] = { 24435, 0x1, 0x65, 0x1A0000, 0x7F4 }, + [ATHOS_B_6G_LUT_CHAN_611000_IDX] = { 24440, 0x1, 0x65, 0x1AAAAB, 0x7F5 }, + [ATHOS_B_6G_LUT_CHAN_611125_IDX] = { 24445, 0x1, 0x65, 0x1B5555, 0x7F5 }, + [ATHOS_B_6G_LUT_CHAN_611250_IDX] = { 24450, 0x1, 0x65, 0x1C0000, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611375_IDX] = { 24455, 0x1, 0x65, 0x1CAAAB, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611500_IDX] = { 24460, 0x1, 0x65, 0x1D5555, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611625_IDX] = { 24465, 0x1, 0x65, 0x1E0000, 0x7F7 }, + [ATHOS_B_6G_LUT_CHAN_611750_IDX] = { 24470, 0x1, 0x65, 0x1EAAAB, 0x7F7 }, + [ATHOS_B_6G_LUT_CHAN_611875_IDX] = { 24475, 0x1, 0x65, 0x1F5555, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612000_IDX] = { 24480, 0x1, 0x66, 0x0, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612125_IDX] = { 24485, 0x1, 0x66, 0xAAAB, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612250_IDX] = { 24490, 0x1, 0x66, 0x15555, 0x7F9 }, + [ATHOS_B_6G_LUT_CHAN_612375_IDX] = { 24495, 0x1, 0x66, 0x20000, 0x7F9 }, + [ATHOS_B_6G_LUT_CHAN_612500_IDX] = { 24500, 0x1, 0x66, 0x2AAAB, 0x7FA }, + [ATHOS_B_6G_LUT_CHAN_612625_IDX] = { 24505, 0x1, 0x66, 0x35555, 0x7FA }, + [ATHOS_B_6G_LUT_CHAN_612750_IDX] = { 24510, 0x1, 0x66, 0x40000, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_612875_IDX] = { 24515, 0x1, 0x66, 0x4AAAB, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_613000_IDX] = { 24520, 0x1, 0x66, 0x55555, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_613125_IDX] = { 24525, 0x1, 0x66, 0x60000, 0x7FC }, + [ATHOS_B_6G_LUT_CHAN_613250_IDX] = { 24530, 0x1, 0x66, 0x6AAAB, 0x7FC }, + [ATHOS_B_6G_LUT_CHAN_613375_IDX] = { 24535, 0x1, 0x66, 0x75555, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613500_IDX] = { 24540, 0x1, 0x66, 0x80000, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613625_IDX] = { 24545, 0x1, 0x66, 0x8AAAB, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613750_IDX] = { 24550, 0x1, 0x66, 0x95555, 0x7FE }, + [ATHOS_B_6G_LUT_CHAN_613875_IDX] = { 24555, 0x1, 0x66, 0xA0000, 0x7FE }, + [ATHOS_B_6G_LUT_CHAN_614000_IDX] = { 24560, 0x1, 0x66, 0xAAAAB, 0x7FF }, + [ATHOS_B_6G_LUT_CHAN_614125_IDX] = { 24565, 0x1, 0x66, 0xB5555, 0x7FF }, + [ATHOS_B_6G_LUT_CHAN_614250_IDX] = { 24570, 0x1, 0x66, 0xC0000, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614375_IDX] = { 24575, 0x1, 0x66, 0xCAAAB, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614500_IDX] = { 24580, 0x1, 0x66, 0xD5555, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614625_IDX] = { 24585, 0x1, 0x66, 0xE0000, 0x801 }, + [ATHOS_B_6G_LUT_CHAN_614750_IDX] = { 24590, 0x1, 0x66, 0xEAAAB, 0x801 }, + [ATHOS_B_6G_LUT_CHAN_614875_IDX] = { 24595, 0x1, 0x66, 0xF5555, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615000_IDX] = { 24600, 0x1, 0x66, 0x100000, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615125_IDX] = { 24605, 0x1, 0x66, 0x10AAAB, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615250_IDX] = { 24610, 0x1, 0x66, 0x115555, 0x803 }, + [ATHOS_B_6G_LUT_CHAN_615375_IDX] = { 24615, 0x1, 0x66, 0x120000, 0x803 }, + [ATHOS_B_6G_LUT_CHAN_615500_IDX] = { 24620, 0x1, 0x66, 0x12AAAB, 0x804 }, + [ATHOS_B_6G_LUT_CHAN_615625_IDX] = { 24625, 0x1, 0x66, 0x135555, 0x804 }, + [ATHOS_B_6G_LUT_CHAN_615750_IDX] = { 24630, 0x1, 0x66, 0x140000, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_615875_IDX] = { 24635, 0x1, 0x66, 0x14AAAB, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_616000_IDX] = { 24640, 0x1, 0x66, 0x155555, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_616125_IDX] = { 24645, 0x1, 0x66, 0x160000, 0x806 }, + [ATHOS_B_6G_LUT_CHAN_616250_IDX] = { 24650, 0x1, 0x66, 0x16AAAB, 0x806 }, + [ATHOS_B_6G_LUT_CHAN_616375_IDX] = { 24655, 0x1, 0x66, 0x175555, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616500_IDX] = { 24660, 0x1, 0x66, 0x180000, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616625_IDX] = { 24665, 0x1, 0x66, 0x18AAAB, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616750_IDX] = { 24670, 0x1, 0x66, 0x195555, 0x808 }, + [ATHOS_B_6G_LUT_CHAN_616875_IDX] = { 24675, 0x1, 0x66, 0x1A0000, 0x808 }, + [ATHOS_B_6G_LUT_CHAN_617000_IDX] = { 24680, 0x1, 0x66, 0x1AAAAB, 0x809 }, + [ATHOS_B_6G_LUT_CHAN_617125_IDX] = { 24685, 0x1, 0x66, 0x1B5555, 0x809 }, + [ATHOS_B_6G_LUT_CHAN_617250_IDX] = { 24690, 0x1, 0x66, 0x1C0000, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617375_IDX] = { 24695, 0x1, 0x66, 0x1CAAAB, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617500_IDX] = { 24700, 0x1, 0x66, 0x1D5555, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617625_IDX] = { 24705, 0x1, 0x66, 0x1E0000, 0x80B }, + [ATHOS_B_6G_LUT_CHAN_617750_IDX] = { 24710, 0x1, 0x66, 0x1EAAAB, 0x80B }, + [ATHOS_B_6G_LUT_CHAN_617875_IDX] = { 24715, 0x1, 0x66, 0x1F5555, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618000_IDX] = { 24720, 0x1, 0x67, 0x0, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618125_IDX] = { 24725, 0x1, 0x67, 0xAAAB, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618250_IDX] = { 24730, 0x1, 0x67, 0x15555, 0x80D }, + [ATHOS_B_6G_LUT_CHAN_618375_IDX] = { 24735, 0x1, 0x67, 0x20000, 0x80D }, + [ATHOS_B_6G_LUT_CHAN_618500_IDX] = { 24740, 0x1, 0x67, 0x2AAAB, 0x80E }, + [ATHOS_B_6G_LUT_CHAN_618625_IDX] = { 24745, 0x1, 0x67, 0x35555, 0x80E }, + [ATHOS_B_6G_LUT_CHAN_618750_IDX] = { 24750, 0x1, 0x67, 0x40000, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_618875_IDX] = { 24755, 0x1, 0x67, 0x4AAAB, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_619000_IDX] = { 24760, 0x1, 0x67, 0x55555, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_619125_IDX] = { 24765, 0x1, 0x67, 0x60000, 0x810 }, + [ATHOS_B_6G_LUT_CHAN_619250_IDX] = { 24770, 0x1, 0x67, 0x6AAAB, 0x810 }, + [ATHOS_B_6G_LUT_CHAN_619375_IDX] = { 24775, 0x1, 0x67, 0x75555, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619500_IDX] = { 24780, 0x1, 0x67, 0x80000, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619625_IDX] = { 24785, 0x1, 0x67, 0x8AAAB, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619750_IDX] = { 24790, 0x1, 0x67, 0x95555, 0x812 }, + [ATHOS_B_6G_LUT_CHAN_619875_IDX] = { 24795, 0x1, 0x67, 0xA0000, 0x812 }, + [ATHOS_B_6G_LUT_CHAN_620000_IDX] = { 24800, 0x1, 0x67, 0xAAAAB, 0x813 }, + [ATHOS_B_6G_LUT_CHAN_620125_IDX] = { 24805, 0x1, 0x67, 0xB5555, 0x813 }, + [ATHOS_B_6G_LUT_CHAN_620250_IDX] = { 24810, 0x1, 0x67, 0xC0000, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620375_IDX] = { 24815, 0x1, 0x67, 0xCAAAB, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620500_IDX] = { 24820, 0x1, 0x67, 0xD5555, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620625_IDX] = { 24825, 0x1, 0x67, 0xE0000, 0x815 }, + [ATHOS_B_6G_LUT_CHAN_620750_IDX] = { 24830, 0x1, 0x67, 0xEAAAB, 0x815 }, + [ATHOS_B_6G_LUT_CHAN_620875_IDX] = { 24835, 0x1, 0x67, 0xF5555, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621000_IDX] = { 24840, 0x1, 0x67, 0x100000, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621125_IDX] = { 24845, 0x1, 0x67, 0x10AAAB, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621250_IDX] = { 24850, 0x1, 0x67, 0x115555, 0x817 }, + [ATHOS_B_6G_LUT_CHAN_621375_IDX] = { 24855, 0x1, 0x67, 0x120000, 0x817 }, + [ATHOS_B_6G_LUT_CHAN_621500_IDX] = { 24860, 0x1, 0x67, 0x12AAAB, 0x818 }, + [ATHOS_B_6G_LUT_CHAN_621625_IDX] = { 24865, 0x1, 0x67, 0x135555, 0x818 }, + [ATHOS_B_6G_LUT_CHAN_621750_IDX] = { 24870, 0x1, 0x67, 0x140000, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_621875_IDX] = { 24875, 0x1, 0x67, 0x14AAAB, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_622000_IDX] = { 24880, 0x1, 0x67, 0x155555, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_622125_IDX] = { 24885, 0x1, 0x67, 0x160000, 0x81A }, + [ATHOS_B_6G_LUT_CHAN_622250_IDX] = { 24890, 0x1, 0x67, 0x16AAAB, 0x81A }, + [ATHOS_B_6G_LUT_CHAN_622375_IDX] = { 24895, 0x1, 0x67, 0x175555, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622500_IDX] = { 24900, 0x1, 0x67, 0x180000, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622625_IDX] = { 24905, 0x1, 0x67, 0x18AAAB, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622750_IDX] = { 24910, 0x1, 0x67, 0x195555, 0x81C }, + [ATHOS_B_6G_LUT_CHAN_622875_IDX] = { 24915, 0x1, 0x67, 0x1A0000, 0x81C }, + [ATHOS_B_6G_LUT_CHAN_623000_IDX] = { 24920, 0x1, 0x67, 0x1AAAAB, 0x81D }, + [ATHOS_B_6G_LUT_CHAN_623125_IDX] = { 24925, 0x1, 0x67, 0x1B5555, 0x81D }, + [ATHOS_B_6G_LUT_CHAN_623250_IDX] = { 24930, 0x1, 0x67, 0x1C0000, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623375_IDX] = { 24935, 0x1, 0x67, 0x1CAAAB, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623500_IDX] = { 24940, 0x1, 0x67, 0x1D5555, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623625_IDX] = { 24945, 0x1, 0x67, 0x1E0000, 0x81F }, + [ATHOS_B_6G_LUT_CHAN_623750_IDX] = { 24950, 0x1, 0x67, 0x1EAAAB, 0x81F }, + [ATHOS_B_6G_LUT_CHAN_623875_IDX] = { 24955, 0x1, 0x67, 0x1F5555, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624000_IDX] = { 24960, 0x1, 0x68, 0x0, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624125_IDX] = { 24965, 0x1, 0x68, 0xAAAB, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624250_IDX] = { 24970, 0x1, 0x68, 0x15555, 0x821 }, + [ATHOS_B_6G_LUT_CHAN_624375_IDX] = { 24975, 0x1, 0x68, 0x20000, 0x821 }, + [ATHOS_B_6G_LUT_CHAN_624500_IDX] = { 24980, 0x1, 0x68, 0x2AAAB, 0x822 }, + [ATHOS_B_6G_LUT_CHAN_624625_IDX] = { 24985, 0x1, 0x68, 0x35555, 0x822 }, + [ATHOS_B_6G_LUT_CHAN_624750_IDX] = { 24990, 0x1, 0x68, 0x40000, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_624875_IDX] = { 24995, 0x1, 0x68, 0x4AAAB, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_625000_IDX] = { 25000, 0x1, 0x68, 0x55555, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_625125_IDX] = { 25005, 0x1, 0x68, 0x60000, 0x824 }, + [ATHOS_B_6G_LUT_CHAN_625250_IDX] = { 25010, 0x1, 0x68, 0x6AAAB, 0x824 }, + [ATHOS_B_6G_LUT_CHAN_625375_IDX] = { 25015, 0x1, 0x68, 0x75555, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625500_IDX] = { 25020, 0x1, 0x68, 0x80000, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625625_IDX] = { 25025, 0x1, 0x68, 0x8AAAB, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625750_IDX] = { 25030, 0x1, 0x68, 0x95555, 0x826 }, + [ATHOS_B_6G_LUT_CHAN_625875_IDX] = { 25035, 0x1, 0x68, 0xA0000, 0x826 }, + [ATHOS_B_6G_LUT_CHAN_626000_IDX] = { 25040, 0x1, 0x68, 0xAAAAB, 0x827 }, + [ATHOS_B_6G_LUT_CHAN_626125_IDX] = { 25045, 0x1, 0x68, 0xB5555, 0x827 }, + [ATHOS_B_6G_LUT_CHAN_626250_IDX] = { 25050, 0x1, 0x68, 0xC0000, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626375_IDX] = { 25055, 0x1, 0x68, 0xCAAAB, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626500_IDX] = { 25060, 0x1, 0x68, 0xD5555, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626625_IDX] = { 25065, 0x1, 0x68, 0xE0000, 0x829 }, + [ATHOS_B_6G_LUT_CHAN_626750_IDX] = { 25070, 0x1, 0x68, 0xEAAAB, 0x829 }, + [ATHOS_B_6G_LUT_CHAN_626875_IDX] = { 25075, 0x1, 0x68, 0xF5555, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627000_IDX] = { 25080, 0x1, 0x68, 0x100000, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627125_IDX] = { 25085, 0x1, 0x68, 0x10AAAB, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627250_IDX] = { 25090, 0x1, 0x68, 0x115555, 0x82B }, + [ATHOS_B_6G_LUT_CHAN_627375_IDX] = { 25095, 0x1, 0x68, 0x120000, 0x82B }, + [ATHOS_B_6G_LUT_CHAN_627500_IDX] = { 25100, 0x1, 0x68, 0x12AAAB, 0x82C }, + [ATHOS_B_6G_LUT_CHAN_627625_IDX] = { 25105, 0x1, 0x68, 0x135555, 0x82C }, + [ATHOS_B_6G_LUT_CHAN_627750_IDX] = { 25110, 0x1, 0x68, 0x140000, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_627875_IDX] = { 25115, 0x1, 0x68, 0x14AAAB, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_628000_IDX] = { 25120, 0x1, 0x68, 0x155555, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_628125_IDX] = { 25125, 0x1, 0x68, 0x160000, 0x82E }, + [ATHOS_B_6G_LUT_CHAN_628250_IDX] = { 25130, 0x1, 0x68, 0x16AAAB, 0x82E }, + [ATHOS_B_6G_LUT_CHAN_628375_IDX] = { 25135, 0x1, 0x68, 0x175555, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628500_IDX] = { 25140, 0x1, 0x68, 0x180000, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628625_IDX] = { 25145, 0x1, 0x68, 0x18AAAB, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628750_IDX] = { 25150, 0x1, 0x68, 0x195555, 0x830 }, + [ATHOS_B_6G_LUT_CHAN_628875_IDX] = { 25155, 0x1, 0x68, 0x1A0000, 0x830 }, + [ATHOS_B_6G_LUT_CHAN_629000_IDX] = { 25160, 0x1, 0x68, 0x1AAAAB, 0x831 }, + [ATHOS_B_6G_LUT_CHAN_629125_IDX] = { 25165, 0x1, 0x68, 0x1B5555, 0x831 }, + [ATHOS_B_6G_LUT_CHAN_629250_IDX] = { 25170, 0x1, 0x68, 0x1C0000, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629375_IDX] = { 25175, 0x1, 0x68, 0x1CAAAB, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629500_IDX] = { 25180, 0x1, 0x68, 0x1D5555, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629625_IDX] = { 25185, 0x1, 0x68, 0x1E0000, 0x833 }, + [ATHOS_B_6G_LUT_CHAN_629750_IDX] = { 25190, 0x1, 0x68, 0x1EAAAB, 0x833 }, + [ATHOS_B_6G_LUT_CHAN_629875_IDX] = { 25195, 0x1, 0x68, 0x1F5555, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630000_IDX] = { 25200, 0x1, 0x69, 0x0, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630125_IDX] = { 25205, 0x1, 0x69, 0xAAAB, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630250_IDX] = { 25210, 0x1, 0x69, 0x15555, 0x835 }, + [ATHOS_B_6G_LUT_CHAN_630375_IDX] = { 25215, 0x1, 0x69, 0x20000, 0x835 }, + [ATHOS_B_6G_LUT_CHAN_630500_IDX] = { 25220, 0x1, 0x69, 0x2AAAB, 0x836 }, + [ATHOS_B_6G_LUT_CHAN_630625_IDX] = { 25225, 0x1, 0x69, 0x35555, 0x836 }, + [ATHOS_B_6G_LUT_CHAN_630750_IDX] = { 25230, 0x1, 0x69, 0x40000, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_630875_IDX] = { 25235, 0x1, 0x69, 0x4AAAB, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_631000_IDX] = { 25240, 0x1, 0x69, 0x55555, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_631125_IDX] = { 25245, 0x1, 0x69, 0x60000, 0x838 }, + [ATHOS_B_6G_LUT_CHAN_631250_IDX] = { 25250, 0x1, 0x69, 0x6AAAB, 0x838 }, + [ATHOS_B_6G_LUT_CHAN_631375_IDX] = { 25255, 0x1, 0x69, 0x75555, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631500_IDX] = { 25260, 0x1, 0x69, 0x80000, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631625_IDX] = { 25265, 0x1, 0x69, 0x8AAAB, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631750_IDX] = { 25270, 0x1, 0x69, 0x95555, 0x83A }, + [ATHOS_B_6G_LUT_CHAN_631875_IDX] = { 25275, 0x1, 0x69, 0xA0000, 0x83A }, + [ATHOS_B_6G_LUT_CHAN_632000_IDX] = { 25280, 0x1, 0x69, 0xAAAAB, 0x83B }, + [ATHOS_B_6G_LUT_CHAN_632125_IDX] = { 25285, 0x1, 0x69, 0xB5555, 0x83B }, + [ATHOS_B_6G_LUT_CHAN_632250_IDX] = { 25290, 0x1, 0x69, 0xC0000, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632375_IDX] = { 25295, 0x1, 0x69, 0xCAAAB, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632500_IDX] = { 25300, 0x1, 0x69, 0xD5555, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632625_IDX] = { 25305, 0x1, 0x69, 0xE0000, 0x83D }, + [ATHOS_B_6G_LUT_CHAN_632750_IDX] = { 25310, 0x1, 0x69, 0xEAAAB, 0x83D }, + [ATHOS_B_6G_LUT_CHAN_632875_IDX] = { 25315, 0x1, 0x69, 0xF5555, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633000_IDX] = { 25320, 0x1, 0x69, 0x100000, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633125_IDX] = { 25325, 0x1, 0x69, 0x10AAAB, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633250_IDX] = { 25330, 0x1, 0x69, 0x115555, 0x83F }, + [ATHOS_B_6G_LUT_CHAN_633375_IDX] = { 25335, 0x1, 0x69, 0x120000, 0x83F }, + [ATHOS_B_6G_LUT_CHAN_633500_IDX] = { 25340, 0x1, 0x69, 0x12AAAB, 0x840 }, + [ATHOS_B_6G_LUT_CHAN_633625_IDX] = { 25345, 0x1, 0x69, 0x135555, 0x840 }, + [ATHOS_B_6G_LUT_CHAN_633750_IDX] = { 25350, 0x1, 0x69, 0x140000, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_633875_IDX] = { 25355, 0x1, 0x69, 0x14AAAB, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_634000_IDX] = { 25360, 0x1, 0x69, 0x155555, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_634125_IDX] = { 25365, 0x1, 0x69, 0x160000, 0x842 }, + [ATHOS_B_6G_LUT_CHAN_634250_IDX] = { 25370, 0x1, 0x69, 0x16AAAB, 0x842 }, + [ATHOS_B_6G_LUT_CHAN_634375_IDX] = { 25375, 0x1, 0x69, 0x175555, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634500_IDX] = { 25380, 0x1, 0x69, 0x180000, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634625_IDX] = { 25385, 0x1, 0x69, 0x18AAAB, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634750_IDX] = { 25390, 0x1, 0x69, 0x195555, 0x844 }, + [ATHOS_B_6G_LUT_CHAN_634875_IDX] = { 25395, 0x1, 0x69, 0x1A0000, 0x844 }, + [ATHOS_B_6G_LUT_CHAN_635000_IDX] = { 25400, 0x1, 0x69, 0x1AAAAB, 0x845 }, + [ATHOS_B_6G_LUT_CHAN_635125_IDX] = { 25405, 0x1, 0x69, 0x1B5555, 0x845 }, + [ATHOS_B_6G_LUT_CHAN_635250_IDX] = { 25410, 0x1, 0x69, 0x1C0000, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635375_IDX] = { 25415, 0x1, 0x69, 0x1CAAAB, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635500_IDX] = { 25420, 0x1, 0x69, 0x1D5555, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635625_IDX] = { 25425, 0x1, 0x69, 0x1E0000, 0x847 }, + [ATHOS_B_6G_LUT_CHAN_635750_IDX] = { 25430, 0x1, 0x69, 0x1EAAAB, 0x847 }, + [ATHOS_B_6G_LUT_CHAN_635875_IDX] = { 25435, 0x1, 0x69, 0x1F5555, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636000_IDX] = { 25440, 0x1, 0x6A, 0x0, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636125_IDX] = { 25445, 0x1, 0x6A, 0xAAAB, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636250_IDX] = { 25450, 0x1, 0x6A, 0x15555, 0x849 }, + [ATHOS_B_6G_LUT_CHAN_636375_IDX] = { 25455, 0x1, 0x6A, 0x20000, 0x849 }, + [ATHOS_B_6G_LUT_CHAN_636500_IDX] = { 25460, 0x1, 0x6A, 0x2AAAB, 0x84A }, + [ATHOS_B_6G_LUT_CHAN_636625_IDX] = { 25465, 0x1, 0x6A, 0x35555, 0x84A }, + [ATHOS_B_6G_LUT_CHAN_636750_IDX] = { 25470, 0x1, 0x6A, 0x40000, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_636875_IDX] = { 25475, 0x1, 0x6A, 0x4AAAB, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_637000_IDX] = { 25480, 0x1, 0x6A, 0x55555, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_637125_IDX] = { 25485, 0x1, 0x6A, 0x60000, 0x84C }, + [ATHOS_B_6G_LUT_CHAN_637250_IDX] = { 25490, 0x1, 0x6A, 0x6AAAB, 0x84C }, + [ATHOS_B_6G_LUT_CHAN_637375_IDX] = { 25495, 0x1, 0x6A, 0x75555, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637500_IDX] = { 25500, 0x1, 0x6A, 0x80000, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637625_IDX] = { 25505, 0x1, 0x6A, 0x8AAAB, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637750_IDX] = { 25510, 0x1, 0x6A, 0x95555, 0x84E }, + [ATHOS_B_6G_LUT_CHAN_637875_IDX] = { 25515, 0x1, 0x6A, 0xA0000, 0x84E }, + [ATHOS_B_6G_LUT_CHAN_638000_IDX] = { 25520, 0x1, 0x6A, 0xAAAAB, 0x84F }, + [ATHOS_B_6G_LUT_CHAN_638125_IDX] = { 25525, 0x1, 0x6A, 0xB5555, 0x84F }, + [ATHOS_B_6G_LUT_CHAN_638250_IDX] = { 25530, 0x1, 0x6A, 0xC0000, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638375_IDX] = { 25535, 0x1, 0x6A, 0xCAAAB, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638500_IDX] = { 25540, 0x1, 0x6A, 0xD5555, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638625_IDX] = { 25545, 0x1, 0x6A, 0xE0000, 0x851 }, + [ATHOS_B_6G_LUT_CHAN_638750_IDX] = { 25550, 0x1, 0x6A, 0xEAAAB, 0x851 }, + [ATHOS_B_6G_LUT_CHAN_638875_IDX] = { 25555, 0x1, 0x6A, 0xF5555, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639000_IDX] = { 25560, 0x1, 0x6A, 0x100000, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639125_IDX] = { 25565, 0x1, 0x6A, 0x10AAAB, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639250_IDX] = { 25570, 0x1, 0x6A, 0x115555, 0x853 }, + [ATHOS_B_6G_LUT_CHAN_639375_IDX] = { 25575, 0x1, 0x6A, 0x120000, 0x853 }, + [ATHOS_B_6G_LUT_CHAN_639500_IDX] = { 25580, 0x1, 0x6A, 0x12AAAB, 0x854 }, + [ATHOS_B_6G_LUT_CHAN_639625_IDX] = { 25585, 0x1, 0x6A, 0x135555, 0x854 }, + [ATHOS_B_6G_LUT_CHAN_639750_IDX] = { 25590, 0x1, 0x6A, 0x140000, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_639875_IDX] = { 25595, 0x1, 0x6A, 0x14AAAB, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_640000_IDX] = { 25600, 0x1, 0x6A, 0x155555, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_640125_IDX] = { 25605, 0x1, 0x6A, 0x160000, 0x856 }, + [ATHOS_B_6G_LUT_CHAN_640250_IDX] = { 25610, 0x1, 0x6A, 0x16AAAB, 0x856 }, + [ATHOS_B_6G_LUT_CHAN_640375_IDX] = { 25615, 0x1, 0x6A, 0x175555, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640500_IDX] = { 25620, 0x1, 0x6A, 0x180000, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640625_IDX] = { 25625, 0x1, 0x6A, 0x18AAAB, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640750_IDX] = { 25630, 0x1, 0x6A, 0x195555, 0x858 }, + [ATHOS_B_6G_LUT_CHAN_640875_IDX] = { 25635, 0x1, 0x6A, 0x1A0000, 0x858 }, + [ATHOS_B_6G_LUT_CHAN_641000_IDX] = { 25640, 0x1, 0x6A, 0x1AAAAB, 0x859 }, + [ATHOS_B_6G_LUT_CHAN_641125_IDX] = { 25645, 0x1, 0x6A, 0x1B5555, 0x859 }, + [ATHOS_B_6G_LUT_CHAN_641250_IDX] = { 25650, 0x1, 0x6A, 0x1C0000, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641375_IDX] = { 25655, 0x1, 0x6A, 0x1CAAAB, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641500_IDX] = { 25660, 0x1, 0x6A, 0x1D5555, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641625_IDX] = { 25665, 0x1, 0x6A, 0x1E0000, 0x85B }, + [ATHOS_B_6G_LUT_CHAN_641750_IDX] = { 25670, 0x1, 0x6A, 0x1EAAAB, 0x85B }, + [ATHOS_B_6G_LUT_CHAN_641875_IDX] = { 25675, 0x1, 0x6A, 0x1F5555, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642000_IDX] = { 25680, 0x1, 0x6B, 0x0, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642125_IDX] = { 25685, 0x1, 0x6B, 0xAAAB, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642250_IDX] = { 25690, 0x1, 0x6B, 0x15555, 0x85D }, + [ATHOS_B_6G_LUT_CHAN_642375_IDX] = { 25695, 0x1, 0x6B, 0x20000, 0x85D }, + [ATHOS_B_6G_LUT_CHAN_642500_IDX] = { 25700, 0x1, 0x6B, 0x2AAAB, 0x85E }, + [ATHOS_B_6G_LUT_CHAN_642625_IDX] = { 25705, 0x1, 0x6B, 0x35555, 0x85E }, + [ATHOS_B_6G_LUT_CHAN_642750_IDX] = { 25710, 0x1, 0x6B, 0x40000, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_642875_IDX] = { 25715, 0x1, 0x6B, 0x4AAAB, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_643000_IDX] = { 25720, 0x1, 0x6B, 0x55555, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_643125_IDX] = { 25725, 0x1, 0x6B, 0x60000, 0x860 }, + [ATHOS_B_6G_LUT_CHAN_643250_IDX] = { 25730, 0x1, 0x6B, 0x6AAAB, 0x860 }, + [ATHOS_B_6G_LUT_CHAN_643375_IDX] = { 25735, 0x1, 0x6B, 0x75555, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643500_IDX] = { 25740, 0x1, 0x6B, 0x80000, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643625_IDX] = { 25745, 0x1, 0x6B, 0x8AAAB, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643750_IDX] = { 25750, 0x1, 0x6B, 0x95555, 0x862 }, + [ATHOS_B_6G_LUT_CHAN_643875_IDX] = { 25755, 0x1, 0x6B, 0xA0000, 0x862 }, + [ATHOS_B_6G_LUT_CHAN_644000_IDX] = { 25760, 0x1, 0x6B, 0xAAAAB, 0x863 }, + [ATHOS_B_6G_LUT_CHAN_644125_IDX] = { 25765, 0x1, 0x6B, 0xB5555, 0x863 }, + [ATHOS_B_6G_LUT_CHAN_644250_IDX] = { 25770, 0x1, 0x6B, 0xC0000, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644375_IDX] = { 25775, 0x1, 0x6B, 0xCAAAB, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644500_IDX] = { 25780, 0x1, 0x6B, 0xD5555, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644625_IDX] = { 25785, 0x1, 0x6B, 0xE0000, 0x865 }, + [ATHOS_B_6G_LUT_CHAN_644750_IDX] = { 25790, 0x1, 0x6B, 0xEAAAB, 0x865 }, + [ATHOS_B_6G_LUT_CHAN_644875_IDX] = { 25795, 0x1, 0x6B, 0xF5555, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645000_IDX] = { 25800, 0x1, 0x6B, 0x100000, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645125_IDX] = { 25805, 0x1, 0x6B, 0x10AAAB, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645250_IDX] = { 25810, 0x1, 0x6B, 0x115555, 0x867 }, + [ATHOS_B_6G_LUT_CHAN_645375_IDX] = { 25815, 0x1, 0x6B, 0x120000, 0x867 }, + [ATHOS_B_6G_LUT_CHAN_645500_IDX] = { 25820, 0x1, 0x6B, 0x12AAAB, 0x868 }, + [ATHOS_B_6G_LUT_CHAN_645625_IDX] = { 25825, 0x1, 0x6B, 0x135555, 0x868 }, + [ATHOS_B_6G_LUT_CHAN_645750_IDX] = { 25830, 0x1, 0x6B, 0x140000, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_645875_IDX] = { 25835, 0x1, 0x6B, 0x14AAAB, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_646000_IDX] = { 25840, 0x1, 0x6B, 0x155555, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_646125_IDX] = { 25845, 0x1, 0x6B, 0x160000, 0x86A }, + [ATHOS_B_6G_LUT_CHAN_646250_IDX] = { 25850, 0x1, 0x6B, 0x16AAAB, 0x86A }, + [ATHOS_B_6G_LUT_CHAN_646375_IDX] = { 25855, 0x1, 0x6B, 0x175555, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646500_IDX] = { 25860, 0x1, 0x6B, 0x180000, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646625_IDX] = { 25865, 0x1, 0x6B, 0x18AAAB, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646750_IDX] = { 25870, 0x1, 0x6B, 0x195555, 0x86C }, + [ATHOS_B_6G_LUT_CHAN_646875_IDX] = { 25875, 0x1, 0x6B, 0x1A0000, 0x86C }, + [ATHOS_B_6G_LUT_CHAN_647000_IDX] = { 25880, 0x1, 0x6B, 0x1AAAAB, 0x86D }, + [ATHOS_B_6G_LUT_CHAN_647125_IDX] = { 25885, 0x1, 0x6B, 0x1B5555, 0x86D }, + [ATHOS_B_6G_LUT_CHAN_647250_IDX] = { 25890, 0x1, 0x6B, 0x1C0000, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647375_IDX] = { 25895, 0x1, 0x6B, 0x1CAAAB, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647500_IDX] = { 25900, 0x1, 0x6B, 0x1D5555, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647625_IDX] = { 25905, 0x1, 0x6B, 0x1E0000, 0x86F }, + [ATHOS_B_6G_LUT_CHAN_647750_IDX] = { 25910, 0x1, 0x6B, 0x1EAAAB, 0x86F }, + [ATHOS_B_6G_LUT_CHAN_647875_IDX] = { 25915, 0x1, 0x6B, 0x1F5555, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648000_IDX] = { 25920, 0x1, 0x6C, 0x0, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648125_IDX] = { 25925, 0x1, 0x6C, 0xAAAB, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648250_IDX] = { 25930, 0x1, 0x6C, 0x15555, 0x871 }, + [ATHOS_B_6G_LUT_CHAN_648375_IDX] = { 25935, 0x1, 0x6C, 0x20000, 0x871 }, + [ATHOS_B_6G_LUT_CHAN_648500_IDX] = { 25940, 0x1, 0x6C, 0x2AAAB, 0x872 }, + [ATHOS_B_6G_LUT_CHAN_648625_IDX] = { 25945, 0x1, 0x6C, 0x35555, 0x872 }, + [ATHOS_B_6G_LUT_CHAN_648750_IDX] = { 25950, 0x1, 0x6C, 0x40000, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_648875_IDX] = { 25955, 0x1, 0x6C, 0x4AAAB, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_649000_IDX] = { 25960, 0x1, 0x6C, 0x55555, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_649125_IDX] = { 25965, 0x1, 0x6C, 0x60000, 0x874 }, + [ATHOS_B_6G_LUT_CHAN_649250_IDX] = { 25970, 0x1, 0x6C, 0x6AAAB, 0x874 }, + [ATHOS_B_6G_LUT_CHAN_649375_IDX] = { 25975, 0x1, 0x6C, 0x75555, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649500_IDX] = { 25980, 0x1, 0x6C, 0x80000, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649625_IDX] = { 25985, 0x1, 0x6C, 0x8AAAB, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649750_IDX] = { 25990, 0x1, 0x6C, 0x95555, 0x876 }, + [ATHOS_B_6G_LUT_CHAN_649875_IDX] = { 25995, 0x1, 0x6C, 0xA0000, 0x876 }, + [ATHOS_B_6G_LUT_CHAN_650000_IDX] = { 26000, 0x1, 0x6C, 0xAAAAB, 0x877 }, + [ATHOS_B_6G_LUT_CHAN_650125_IDX] = { 26005, 0x1, 0x6C, 0xB5555, 0x877 }, + [ATHOS_B_6G_LUT_CHAN_650250_IDX] = { 26010, 0x1, 0x6C, 0xC0000, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650375_IDX] = { 26015, 0x1, 0x6C, 0xCAAAB, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650500_IDX] = { 26020, 0x1, 0x6C, 0xD5555, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650625_IDX] = { 26025, 0x1, 0x6C, 0xE0000, 0x879 }, + [ATHOS_B_6G_LUT_CHAN_650750_IDX] = { 26030, 0x1, 0x6C, 0xEAAAB, 0x879 }, + [ATHOS_B_6G_LUT_CHAN_650875_IDX] = { 26035, 0x1, 0x6C, 0xF5555, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651000_IDX] = { 26040, 0x1, 0x6C, 0x100000, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651125_IDX] = { 26045, 0x1, 0x6C, 0x10AAAB, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651250_IDX] = { 26050, 0x1, 0x6C, 0x115555, 0x87B }, + [ATHOS_B_6G_LUT_CHAN_651375_IDX] = { 26055, 0x1, 0x6C, 0x120000, 0x87B }, + [ATHOS_B_6G_LUT_CHAN_651500_IDX] = { 26060, 0x1, 0x6C, 0x12AAAB, 0x87C }, + [ATHOS_B_6G_LUT_CHAN_651625_IDX] = { 26065, 0x1, 0x6C, 0x135555, 0x87C }, + [ATHOS_B_6G_LUT_CHAN_651750_IDX] = { 26070, 0x1, 0x6C, 0x140000, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_651875_IDX] = { 26075, 0x1, 0x6C, 0x14AAAB, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_652000_IDX] = { 26080, 0x1, 0x6C, 0x155555, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_652125_IDX] = { 26085, 0x1, 0x6C, 0x160000, 0x87E }, + [ATHOS_B_6G_LUT_CHAN_652250_IDX] = { 26090, 0x1, 0x6C, 0x16AAAB, 0x87E }, + [ATHOS_B_6G_LUT_CHAN_652375_IDX] = { 26095, 0x1, 0x6C, 0x175555, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652500_IDX] = { 26100, 0x1, 0x6C, 0x180000, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652625_IDX] = { 26105, 0x1, 0x6C, 0x18AAAB, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652750_IDX] = { 26110, 0x1, 0x6C, 0x195555, 0x880 }, + [ATHOS_B_6G_LUT_CHAN_652875_IDX] = { 26115, 0x1, 0x6C, 0x1A0000, 0x880 }, + [ATHOS_B_6G_LUT_CHAN_653000_IDX] = { 26120, 0x1, 0x6C, 0x1AAAAB, 0x881 }, + [ATHOS_B_6G_LUT_CHAN_653125_IDX] = { 26125, 0x1, 0x6C, 0x1B5555, 0x881 }, + [ATHOS_B_6G_LUT_CHAN_653250_IDX] = { 26130, 0x1, 0x6C, 0x1C0000, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653375_IDX] = { 26135, 0x1, 0x6C, 0x1CAAAB, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653500_IDX] = { 26140, 0x1, 0x6C, 0x1D5555, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653625_IDX] = { 26145, 0x1, 0x6C, 0x1E0000, 0x883 }, + [ATHOS_B_6G_LUT_CHAN_653750_IDX] = { 26150, 0x1, 0x6C, 0x1EAAAB, 0x883 }, + [ATHOS_B_6G_LUT_CHAN_653875_IDX] = { 26155, 0x1, 0x6C, 0x1F5555, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654000_IDX] = { 26160, 0x1, 0x6D, 0x0, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654125_IDX] = { 26165, 0x1, 0x6D, 0xAAAB, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654250_IDX] = { 26170, 0x1, 0x6D, 0x15555, 0x885 }, + [ATHOS_B_6G_LUT_CHAN_654375_IDX] = { 26175, 0x1, 0x6D, 0x20000, 0x885 }, + [ATHOS_B_6G_LUT_CHAN_654500_IDX] = { 26180, 0x1, 0x6D, 0x2AAAB, 0x886 }, + [ATHOS_B_6G_LUT_CHAN_654625_IDX] = { 26185, 0x1, 0x6D, 0x35555, 0x886 }, + [ATHOS_B_6G_LUT_CHAN_654750_IDX] = { 26190, 0x1, 0x6D, 0x40000, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_654875_IDX] = { 26195, 0x1, 0x6D, 0x4AAAB, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_655000_IDX] = { 26200, 0x1, 0x6D, 0x55555, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_655125_IDX] = { 26205, 0x1, 0x6D, 0x60000, 0x888 }, + [ATHOS_B_6G_LUT_CHAN_655250_IDX] = { 26210, 0x1, 0x6D, 0x6AAAB, 0x888 }, + [ATHOS_B_6G_LUT_CHAN_655375_IDX] = { 26215, 0x1, 0x6D, 0x75555, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655500_IDX] = { 26220, 0x1, 0x6D, 0x80000, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655625_IDX] = { 26225, 0x1, 0x6D, 0x8AAAB, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655750_IDX] = { 26230, 0x1, 0x6D, 0x95555, 0x88A }, + [ATHOS_B_6G_LUT_CHAN_655875_IDX] = { 26235, 0x1, 0x6D, 0xA0000, 0x88A }, + [ATHOS_B_6G_LUT_CHAN_656000_IDX] = { 26240, 0x1, 0x6D, 0xAAAAB, 0x88B }, + [ATHOS_B_6G_LUT_CHAN_656125_IDX] = { 26245, 0x1, 0x6D, 0xB5555, 0x88B }, + [ATHOS_B_6G_LUT_CHAN_656250_IDX] = { 26250, 0x1, 0x6D, 0xC0000, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656375_IDX] = { 26255, 0x1, 0x6D, 0xCAAAB, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656500_IDX] = { 26260, 0x1, 0x6D, 0xD5555, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656625_IDX] = { 26265, 0x1, 0x6D, 0xE0000, 0x88D }, + [ATHOS_B_6G_LUT_CHAN_656750_IDX] = { 26270, 0x1, 0x6D, 0xEAAAB, 0x88D }, + [ATHOS_B_6G_LUT_CHAN_656875_IDX] = { 26275, 0x1, 0x6D, 0xF5555, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657000_IDX] = { 26280, 0x1, 0x6D, 0x100000, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657125_IDX] = { 26285, 0x1, 0x6D, 0x10AAAB, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657250_IDX] = { 26290, 0x1, 0x6D, 0x115555, 0x88F }, + [ATHOS_B_6G_LUT_CHAN_657375_IDX] = { 26295, 0x1, 0x6D, 0x120000, 0x88F }, + [ATHOS_B_6G_LUT_CHAN_657500_IDX] = { 26300, 0x1, 0x6D, 0x12AAAB, 0x890 }, + [ATHOS_B_6G_LUT_CHAN_657625_IDX] = { 26305, 0x1, 0x6D, 0x135555, 0x890 }, + [ATHOS_B_6G_LUT_CHAN_657750_IDX] = { 26310, 0x1, 0x6D, 0x140000, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_657875_IDX] = { 26315, 0x1, 0x6D, 0x14AAAB, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_658000_IDX] = { 26320, 0x1, 0x6D, 0x155555, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_658125_IDX] = { 26325, 0x1, 0x6D, 0x160000, 0x892 }, + [ATHOS_B_6G_LUT_CHAN_658250_IDX] = { 26330, 0x1, 0x6D, 0x16AAAB, 0x892 }, + [ATHOS_B_6G_LUT_CHAN_658375_IDX] = { 26335, 0x1, 0x6D, 0x175555, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658500_IDX] = { 26340, 0x1, 0x6D, 0x180000, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658625_IDX] = { 26345, 0x1, 0x6D, 0x18AAAB, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658750_IDX] = { 26350, 0x1, 0x6D, 0x195555, 0x894 }, + [ATHOS_B_6G_LUT_CHAN_658875_IDX] = { 26355, 0x1, 0x6D, 0x1A0000, 0x894 }, + [ATHOS_B_6G_LUT_CHAN_659000_IDX] = { 26360, 0x1, 0x6D, 0x1AAAAB, 0x895 }, + [ATHOS_B_6G_LUT_CHAN_659125_IDX] = { 26365, 0x1, 0x6D, 0x1B5555, 0x895 }, + [ATHOS_B_6G_LUT_CHAN_659250_IDX] = { 26370, 0x1, 0x6D, 0x1C0000, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659375_IDX] = { 26375, 0x1, 0x6D, 0x1CAAAB, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659500_IDX] = { 26380, 0x1, 0x6D, 0x1D5555, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659625_IDX] = { 26385, 0x1, 0x6D, 0x1E0000, 0x897 }, + [ATHOS_B_6G_LUT_CHAN_659750_IDX] = { 26390, 0x1, 0x6D, 0x1EAAAB, 0x897 }, + [ATHOS_B_6G_LUT_CHAN_659875_IDX] = { 26395, 0x1, 0x6D, 0x1F5555, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660000_IDX] = { 26400, 0x1, 0x6E, 0x0, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660125_IDX] = { 26405, 0x1, 0x6E, 0xAAAB, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660250_IDX] = { 26410, 0x1, 0x6E, 0x15555, 0x899 }, + [ATHOS_B_6G_LUT_CHAN_660375_IDX] = { 26415, 0x1, 0x6E, 0x20000, 0x899 }, + [ATHOS_B_6G_LUT_CHAN_660500_IDX] = { 26420, 0x1, 0x6E, 0x2AAAB, 0x89A }, + [ATHOS_B_6G_LUT_CHAN_660625_IDX] = { 26425, 0x1, 0x6E, 0x35555, 0x89A }, + [ATHOS_B_6G_LUT_CHAN_660750_IDX] = { 26430, 0x1, 0x6E, 0x40000, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_660875_IDX] = { 26435, 0x1, 0x6E, 0x4AAAB, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_661000_IDX] = { 26440, 0x1, 0x6E, 0x55555, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_661125_IDX] = { 26445, 0x1, 0x6E, 0x60000, 0x89C }, + [ATHOS_B_6G_LUT_CHAN_661250_IDX] = { 26450, 0x1, 0x6E, 0x6AAAB, 0x89C }, + [ATHOS_B_6G_LUT_CHAN_661375_IDX] = { 26455, 0x1, 0x6E, 0x75555, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661500_IDX] = { 26460, 0x1, 0x6E, 0x80000, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661625_IDX] = { 26465, 0x1, 0x6E, 0x8AAAB, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661750_IDX] = { 26470, 0x1, 0x6E, 0x95555, 0x89E }, + [ATHOS_B_6G_LUT_CHAN_661875_IDX] = { 26475, 0x1, 0x6E, 0xA0000, 0x89E }, + [ATHOS_B_6G_LUT_CHAN_662000_IDX] = { 26480, 0x1, 0x6E, 0xAAAAB, 0x89F }, + [ATHOS_B_6G_LUT_CHAN_662125_IDX] = { 26485, 0x1, 0x6E, 0xB5555, 0x89F }, + [ATHOS_B_6G_LUT_CHAN_662250_IDX] = { 26490, 0x1, 0x6E, 0xC0000, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662375_IDX] = { 26495, 0x1, 0x6E, 0xCAAAB, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662500_IDX] = { 26500, 0x1, 0x6E, 0xD5555, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662625_IDX] = { 26505, 0x1, 0x6E, 0xE0000, 0x8A1 }, + [ATHOS_B_6G_LUT_CHAN_662750_IDX] = { 26510, 0x1, 0x6E, 0xEAAAB, 0x8A1 }, + [ATHOS_B_6G_LUT_CHAN_662875_IDX] = { 26515, 0x1, 0x6E, 0xF5555, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663000_IDX] = { 26520, 0x1, 0x6E, 0x100000, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663125_IDX] = { 26525, 0x1, 0x6E, 0x10AAAB, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663250_IDX] = { 26530, 0x1, 0x6E, 0x115555, 0x8A3 }, + [ATHOS_B_6G_LUT_CHAN_663375_IDX] = { 26535, 0x1, 0x6E, 0x120000, 0x8A3 }, + [ATHOS_B_6G_LUT_CHAN_663500_IDX] = { 26540, 0x1, 0x6E, 0x12AAAB, 0x8A4 }, + [ATHOS_B_6G_LUT_CHAN_663625_IDX] = { 26545, 0x1, 0x6E, 0x135555, 0x8A4 }, + [ATHOS_B_6G_LUT_CHAN_663750_IDX] = { 26550, 0x1, 0x6E, 0x140000, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_663875_IDX] = { 26555, 0x1, 0x6E, 0x14AAAB, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_664000_IDX] = { 26560, 0x1, 0x6E, 0x155555, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_664125_IDX] = { 26565, 0x1, 0x6E, 0x160000, 0x8A6 }, + [ATHOS_B_6G_LUT_CHAN_664250_IDX] = { 26570, 0x1, 0x6E, 0x16AAAB, 0x8A6 }, + [ATHOS_B_6G_LUT_CHAN_664375_IDX] = { 26575, 0x1, 0x6E, 0x175555, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664500_IDX] = { 26580, 0x1, 0x6E, 0x180000, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664625_IDX] = { 26585, 0x1, 0x6E, 0x18AAAB, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664750_IDX] = { 26590, 0x1, 0x6E, 0x195555, 0x8A8 }, + [ATHOS_B_6G_LUT_CHAN_664875_IDX] = { 26595, 0x1, 0x6E, 0x1A0000, 0x8A8 }, + [ATHOS_B_6G_LUT_CHAN_665000_IDX] = { 26600, 0x1, 0x6E, 0x1AAAAB, 0x8A9 }, + [ATHOS_B_6G_LUT_CHAN_665125_IDX] = { 26605, 0x1, 0x6E, 0x1B5555, 0x8A9 }, + [ATHOS_B_6G_LUT_CHAN_665250_IDX] = { 26610, 0x1, 0x6E, 0x1C0000, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665375_IDX] = { 26615, 0x1, 0x6E, 0x1CAAAB, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665500_IDX] = { 26620, 0x1, 0x6E, 0x1D5555, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665625_IDX] = { 26625, 0x1, 0x6E, 0x1E0000, 0x8AB }, + [ATHOS_B_6G_LUT_CHAN_665750_IDX] = { 26630, 0x1, 0x6E, 0x1EAAAB, 0x8AB }, + [ATHOS_B_6G_LUT_CHAN_665875_IDX] = { 26635, 0x1, 0x6E, 0x1F5555, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666000_IDX] = { 26640, 0x1, 0x6F, 0x0, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666125_IDX] = { 26645, 0x1, 0x6F, 0xAAAB, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666250_IDX] = { 26650, 0x1, 0x6F, 0x15555, 0x8AD }, + [ATHOS_B_6G_LUT_CHAN_666375_IDX] = { 26655, 0x1, 0x6F, 0x20000, 0x8AD }, + [ATHOS_B_6G_LUT_CHAN_666500_IDX] = { 26660, 0x1, 0x6F, 0x2AAAB, 0x8AE }, + [ATHOS_B_6G_LUT_CHAN_666625_IDX] = { 26665, 0x1, 0x6F, 0x35555, 0x8AE }, + [ATHOS_B_6G_LUT_CHAN_666750_IDX] = { 26670, 0x1, 0x6F, 0x40000, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_666875_IDX] = { 26675, 0x1, 0x6F, 0x4AAAB, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_667000_IDX] = { 26680, 0x1, 0x6F, 0x55555, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_667125_IDX] = { 26685, 0x1, 0x6F, 0x60000, 0x8B0 }, + [ATHOS_B_6G_LUT_CHAN_667250_IDX] = { 26690, 0x1, 0x6F, 0x6AAAB, 0x8B0 }, + [ATHOS_B_6G_LUT_CHAN_667375_IDX] = { 26695, 0x1, 0x6F, 0x75555, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667500_IDX] = { 26700, 0x1, 0x6F, 0x80000, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667625_IDX] = { 26705, 0x1, 0x6F, 0x8AAAB, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667750_IDX] = { 26710, 0x1, 0x6F, 0x95555, 0x8B2 }, + [ATHOS_B_6G_LUT_CHAN_667875_IDX] = { 26715, 0x1, 0x6F, 0xA0000, 0x8B2 }, + [ATHOS_B_6G_LUT_CHAN_668000_IDX] = { 26720, 0x1, 0x6F, 0xAAAAB, 0x8B3 }, + [ATHOS_B_6G_LUT_CHAN_668125_IDX] = { 26725, 0x1, 0x6F, 0xB5555, 0x8B3 }, + [ATHOS_B_6G_LUT_CHAN_668250_IDX] = { 26730, 0x1, 0x6F, 0xC0000, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668375_IDX] = { 26735, 0x1, 0x6F, 0xCAAAB, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668500_IDX] = { 26740, 0x1, 0x6F, 0xD5555, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668625_IDX] = { 26745, 0x1, 0x6F, 0xE0000, 0x8B5 }, + [ATHOS_B_6G_LUT_CHAN_668750_IDX] = { 26750, 0x1, 0x6F, 0xEAAAB, 0x8B5 }, + [ATHOS_B_6G_LUT_CHAN_668875_IDX] = { 26755, 0x1, 0x6F, 0xF5555, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669000_IDX] = { 26760, 0x1, 0x6F, 0x100000, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669125_IDX] = { 26765, 0x1, 0x6F, 0x10AAAB, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669250_IDX] = { 26770, 0x1, 0x6F, 0x115555, 0x8B7 }, + [ATHOS_B_6G_LUT_CHAN_669375_IDX] = { 26775, 0x1, 0x6F, 0x120000, 0x8B7 }, + [ATHOS_B_6G_LUT_CHAN_669500_IDX] = { 26780, 0x1, 0x6F, 0x12AAAB, 0x8B8 }, + [ATHOS_B_6G_LUT_CHAN_669625_IDX] = { 26785, 0x1, 0x6F, 0x135555, 0x8B8 }, + [ATHOS_B_6G_LUT_CHAN_669750_IDX] = { 26790, 0x1, 0x6F, 0x140000, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_669875_IDX] = { 26795, 0x1, 0x6F, 0x14AAAB, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_670000_IDX] = { 26800, 0x1, 0x6F, 0x155555, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_670125_IDX] = { 26805, 0x1, 0x6F, 0x160000, 0x8BA }, + [ATHOS_B_6G_LUT_CHAN_670250_IDX] = { 26810, 0x1, 0x6F, 0x16AAAB, 0x8BA }, + [ATHOS_B_6G_LUT_CHAN_670375_IDX] = { 26815, 0x1, 0x6F, 0x175555, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670500_IDX] = { 26820, 0x1, 0x6F, 0x180000, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670625_IDX] = { 26825, 0x1, 0x6F, 0x18AAAB, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670750_IDX] = { 26830, 0x1, 0x6F, 0x195555, 0x8BC }, + [ATHOS_B_6G_LUT_CHAN_670875_IDX] = { 26835, 0x1, 0x6F, 0x1A0000, 0x8BC }, + [ATHOS_B_6G_LUT_CHAN_671000_IDX] = { 26840, 0x1, 0x6F, 0x1AAAAB, 0x8BD }, + [ATHOS_B_6G_LUT_CHAN_671125_IDX] = { 26845, 0x1, 0x6F, 0x1B5555, 0x8BD }, + [ATHOS_B_6G_LUT_CHAN_671250_IDX] = { 26850, 0x1, 0x6F, 0x1C0000, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671375_IDX] = { 26855, 0x1, 0x6F, 0x1CAAAB, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671500_IDX] = { 26860, 0x1, 0x6F, 0x1D5555, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671625_IDX] = { 26865, 0x1, 0x6F, 0x1E0000, 0x8BF }, + [ATHOS_B_6G_LUT_CHAN_671750_IDX] = { 26870, 0x1, 0x6F, 0x1EAAAB, 0x8BF }, + [ATHOS_B_6G_LUT_CHAN_671875_IDX] = { 26875, 0x1, 0x6F, 0x1F5555, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672000_IDX] = { 26880, 0x1, 0x70, 0x0, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672125_IDX] = { 26885, 0x1, 0x70, 0xAAAB, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672250_IDX] = { 26890, 0x1, 0x70, 0x15555, 0x8C1 }, + [ATHOS_B_6G_LUT_CHAN_672375_IDX] = { 26895, 0x1, 0x70, 0x20000, 0x8C1 }, + [ATHOS_B_6G_LUT_CHAN_672500_IDX] = { 26900, 0x1, 0x70, 0x2AAAB, 0x8C2 }, + [ATHOS_B_6G_LUT_CHAN_672625_IDX] = { 26905, 0x1, 0x70, 0x35555, 0x8C2 }, + [ATHOS_B_6G_LUT_CHAN_672750_IDX] = { 26910, 0x1, 0x70, 0x40000, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_672875_IDX] = { 26915, 0x1, 0x70, 0x4AAAB, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_673000_IDX] = { 26920, 0x1, 0x70, 0x55555, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_673125_IDX] = { 26925, 0x1, 0x70, 0x60000, 0x8C4 }, + [ATHOS_B_6G_LUT_CHAN_673250_IDX] = { 26930, 0x1, 0x70, 0x6AAAB, 0x8C4 }, + [ATHOS_B_6G_LUT_CHAN_673375_IDX] = { 26935, 0x1, 0x70, 0x75555, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673500_IDX] = { 26940, 0x1, 0x70, 0x80000, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673625_IDX] = { 26945, 0x1, 0x70, 0x8AAAB, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673750_IDX] = { 26950, 0x1, 0x70, 0x95555, 0x8C6 }, + [ATHOS_B_6G_LUT_CHAN_673875_IDX] = { 26955, 0x1, 0x70, 0xA0000, 0x8C6 }, + [ATHOS_B_6G_LUT_CHAN_674000_IDX] = { 26960, 0x1, 0x70, 0xAAAAB, 0x8C7 }, + [ATHOS_B_6G_LUT_CHAN_674125_IDX] = { 26965, 0x1, 0x70, 0xB5555, 0x8C7 }, + [ATHOS_B_6G_LUT_CHAN_674250_IDX] = { 26970, 0x1, 0x70, 0xC0000, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674375_IDX] = { 26975, 0x1, 0x70, 0xCAAAB, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674500_IDX] = { 26980, 0x1, 0x70, 0xD5555, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674625_IDX] = { 26985, 0x1, 0x70, 0xE0000, 0x8C9 }, + [ATHOS_B_6G_LUT_CHAN_674750_IDX] = { 26990, 0x1, 0x70, 0xEAAAB, 0x8C9 }, + [ATHOS_B_6G_LUT_CHAN_674875_IDX] = { 26995, 0x1, 0x70, 0xF5555, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675000_IDX] = { 27000, 0x1, 0x70, 0x100000, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675125_IDX] = { 27005, 0x1, 0x70, 0x10AAAB, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675250_IDX] = { 27010, 0x1, 0x70, 0x115555, 0x8CB }, + [ATHOS_B_6G_LUT_CHAN_675375_IDX] = { 27015, 0x1, 0x70, 0x120000, 0x8CB }, + [ATHOS_B_6G_LUT_CHAN_675500_IDX] = { 27020, 0x1, 0x70, 0x12AAAB, 0x8CC }, + [ATHOS_B_6G_LUT_CHAN_675625_IDX] = { 27025, 0x1, 0x70, 0x135555, 0x8CC }, + [ATHOS_B_6G_LUT_CHAN_675750_IDX] = { 27030, 0x1, 0x70, 0x140000, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_675875_IDX] = { 27035, 0x1, 0x70, 0x14AAAB, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_676000_IDX] = { 27040, 0x1, 0x70, 0x155555, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_676125_IDX] = { 27045, 0x1, 0x70, 0x160000, 0x8CE }, + [ATHOS_B_6G_LUT_CHAN_676250_IDX] = { 27050, 0x1, 0x70, 0x16AAAB, 0x8CE }, + [ATHOS_B_6G_LUT_CHAN_676375_IDX] = { 27055, 0x1, 0x70, 0x175555, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676500_IDX] = { 27060, 0x1, 0x70, 0x180000, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676625_IDX] = { 27065, 0x1, 0x70, 0x18AAAB, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676750_IDX] = { 27070, 0x1, 0x70, 0x195555, 0x8D0 }, + [ATHOS_B_6G_LUT_CHAN_676875_IDX] = { 27075, 0x1, 0x70, 0x1A0000, 0x8D0 }, + [ATHOS_B_6G_LUT_CHAN_677000_IDX] = { 27080, 0x1, 0x70, 0x1AAAAB, 0x8D1 }, + [ATHOS_B_6G_LUT_CHAN_677125_IDX] = { 27085, 0x1, 0x70, 0x1B5555, 0x8D1 }, + [ATHOS_B_6G_LUT_CHAN_677250_IDX] = { 27090, 0x1, 0x70, 0x1C0000, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677375_IDX] = { 27095, 0x1, 0x70, 0x1CAAAB, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677500_IDX] = { 27100, 0x1, 0x70, 0x1D5555, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677625_IDX] = { 27105, 0x1, 0x70, 0x1E0000, 0x8D3 }, + [ATHOS_B_6G_LUT_CHAN_677750_IDX] = { 27110, 0x1, 0x70, 0x1EAAAB, 0x8D3 }, + [ATHOS_B_6G_LUT_CHAN_677875_IDX] = { 27115, 0x1, 0x70, 0x1F5555, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678000_IDX] = { 27120, 0x1, 0x71, 0x0, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678125_IDX] = { 27125, 0x1, 0x71, 0xAAAB, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678250_IDX] = { 27130, 0x1, 0x71, 0x15555, 0x8D5 }, + [ATHOS_B_6G_LUT_CHAN_678375_IDX] = { 27135, 0x1, 0x71, 0x20000, 0x8D5 }, + [ATHOS_B_6G_LUT_CHAN_678500_IDX] = { 27140, 0x1, 0x71, 0x2AAAB, 0x8D6 }, + [ATHOS_B_6G_LUT_CHAN_678625_IDX] = { 27145, 0x1, 0x71, 0x35555, 0x8D6 }, + [ATHOS_B_6G_LUT_CHAN_678750_IDX] = { 27150, 0x1, 0x71, 0x40000, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_678875_IDX] = { 27155, 0x1, 0x71, 0x4AAAB, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_679000_IDX] = { 27160, 0x1, 0x71, 0x55555, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_679125_IDX] = { 27165, 0x1, 0x71, 0x60000, 0x8D8 }, + [ATHOS_B_6G_LUT_CHAN_679250_IDX] = { 27170, 0x1, 0x71, 0x6AAAB, 0x8D8 }, + [ATHOS_B_6G_LUT_CHAN_679375_IDX] = { 27175, 0x1, 0x71, 0x75555, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679500_IDX] = { 27180, 0x1, 0x71, 0x80000, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679625_IDX] = { 27185, 0x1, 0x71, 0x8AAAB, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679750_IDX] = { 27190, 0x1, 0x71, 0x95555, 0x8DA }, + [ATHOS_B_6G_LUT_CHAN_679875_IDX] = { 27195, 0x1, 0x71, 0xA0000, 0x8DA }, + [ATHOS_B_6G_LUT_CHAN_680000_IDX] = { 27200, 0x1, 0x71, 0xAAAAB, 0x8DB }, + [ATHOS_B_6G_LUT_CHAN_680125_IDX] = { 27205, 0x1, 0x71, 0xB5555, 0x8DB }, + [ATHOS_B_6G_LUT_CHAN_680250_IDX] = { 27210, 0x1, 0x71, 0xC0000, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680375_IDX] = { 27215, 0x1, 0x71, 0xCAAAB, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680500_IDX] = { 27220, 0x1, 0x71, 0xD5555, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680625_IDX] = { 27225, 0x1, 0x71, 0xE0000, 0x8DD }, + [ATHOS_B_6G_LUT_CHAN_680750_IDX] = { 27230, 0x1, 0x71, 0xEAAAB, 0x8DD }, + [ATHOS_B_6G_LUT_CHAN_680875_IDX] = { 27235, 0x1, 0x71, 0xF5555, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681000_IDX] = { 27240, 0x1, 0x71, 0x100000, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681125_IDX] = { 27245, 0x1, 0x71, 0x10AAAB, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681250_IDX] = { 27250, 0x1, 0x71, 0x115555, 0x8DF }, + [ATHOS_B_6G_LUT_CHAN_681375_IDX] = { 27255, 0x1, 0x71, 0x120000, 0x8DF }, + [ATHOS_B_6G_LUT_CHAN_681500_IDX] = { 27260, 0x1, 0x71, 0x12AAAB, 0x8E0 }, + [ATHOS_B_6G_LUT_CHAN_681625_IDX] = { 27265, 0x1, 0x71, 0x135555, 0x8E0 }, + [ATHOS_B_6G_LUT_CHAN_681750_IDX] = { 27270, 0x1, 0x71, 0x140000, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_681875_IDX] = { 27275, 0x1, 0x71, 0x14AAAB, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_682000_IDX] = { 27280, 0x1, 0x71, 0x155555, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_682125_IDX] = { 27285, 0x1, 0x71, 0x160000, 0x8E2 }, + [ATHOS_B_6G_LUT_CHAN_682250_IDX] = { 27290, 0x1, 0x71, 0x16AAAB, 0x8E2 }, + [ATHOS_B_6G_LUT_CHAN_682375_IDX] = { 27295, 0x1, 0x71, 0x175555, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682500_IDX] = { 27300, 0x1, 0x71, 0x180000, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682625_IDX] = { 27305, 0x1, 0x71, 0x18AAAB, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682750_IDX] = { 27310, 0x1, 0x71, 0x195555, 0x8E4 }, + [ATHOS_B_6G_LUT_CHAN_682875_IDX] = { 27315, 0x1, 0x71, 0x1A0000, 0x8E4 }, + [ATHOS_B_6G_LUT_CHAN_683000_IDX] = { 27320, 0x1, 0x71, 0x1AAAAB, 0x8E5 }, + [ATHOS_B_6G_LUT_CHAN_683125_IDX] = { 27325, 0x1, 0x71, 0x1B5555, 0x8E5 }, + [ATHOS_B_6G_LUT_CHAN_683250_IDX] = { 27330, 0x1, 0x71, 0x1C0000, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683375_IDX] = { 27335, 0x1, 0x71, 0x1CAAAB, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683500_IDX] = { 27340, 0x1, 0x71, 0x1D5555, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683625_IDX] = { 27345, 0x1, 0x71, 0x1E0000, 0x8E7 }, + [ATHOS_B_6G_LUT_CHAN_683750_IDX] = { 27350, 0x1, 0x71, 0x1EAAAB, 0x8E7 }, + [ATHOS_B_6G_LUT_CHAN_683875_IDX] = { 27355, 0x1, 0x71, 0x1F5555, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684000_IDX] = { 27360, 0x1, 0x72, 0x0, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684125_IDX] = { 27365, 0x1, 0x72, 0xAAAB, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684250_IDX] = { 27370, 0x1, 0x72, 0x15555, 0x8E9 }, + [ATHOS_B_6G_LUT_CHAN_684375_IDX] = { 27375, 0x1, 0x72, 0x20000, 0x8E9 }, + [ATHOS_B_6G_LUT_CHAN_684500_IDX] = { 27380, 0x1, 0x72, 0x2AAAB, 0x8EA }, + [ATHOS_B_6G_LUT_CHAN_684625_IDX] = { 27385, 0x1, 0x72, 0x35555, 0x8EA }, + [ATHOS_B_6G_LUT_CHAN_684750_IDX] = { 27390, 0x1, 0x72, 0x40000, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_684875_IDX] = { 27395, 0x1, 0x72, 0x4AAAB, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_685000_IDX] = { 27400, 0x1, 0x72, 0x55555, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_685125_IDX] = { 27405, 0x1, 0x72, 0x60000, 0x8EC }, + [ATHOS_B_6G_LUT_CHAN_685250_IDX] = { 27410, 0x1, 0x72, 0x6AAAB, 0x8EC }, + [ATHOS_B_6G_LUT_CHAN_685375_IDX] = { 27415, 0x1, 0x72, 0x75555, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685500_IDX] = { 27420, 0x1, 0x72, 0x80000, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685625_IDX] = { 27425, 0x1, 0x72, 0x8AAAB, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685750_IDX] = { 27430, 0x1, 0x72, 0x95555, 0x8EE }, + [ATHOS_B_6G_LUT_CHAN_685875_IDX] = { 27435, 0x1, 0x72, 0xA0000, 0x8EE }, + [ATHOS_B_6G_LUT_CHAN_686000_IDX] = { 27440, 0x1, 0x72, 0xAAAAB, 0x8EF }, + [ATHOS_B_6G_LUT_CHAN_686125_IDX] = { 27445, 0x1, 0x72, 0xB5555, 0x8EF }, + [ATHOS_B_6G_LUT_CHAN_686250_IDX] = { 27450, 0x1, 0x72, 0xC0000, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686375_IDX] = { 27455, 0x1, 0x72, 0xCAAAB, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686500_IDX] = { 27460, 0x1, 0x72, 0xD5555, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686625_IDX] = { 27465, 0x1, 0x72, 0xE0000, 0x8F1 }, + [ATHOS_B_6G_LUT_CHAN_686750_IDX] = { 27470, 0x1, 0x72, 0xEAAAB, 0x8F1 }, + [ATHOS_B_6G_LUT_CHAN_686875_IDX] = { 27475, 0x1, 0x72, 0xF5555, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687000_IDX] = { 27480, 0x1, 0x72, 0x100000, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687125_IDX] = { 27485, 0x1, 0x72, 0x10AAAB, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687250_IDX] = { 27490, 0x1, 0x72, 0x115555, 0x8F3 }, + [ATHOS_B_6G_LUT_CHAN_687375_IDX] = { 27495, 0x1, 0x72, 0x120000, 0x8F3 }, + [ATHOS_B_6G_LUT_CHAN_687500_IDX] = { 27500, 0x1, 0x72, 0x12AAAB, 0x8F4 }, + [ATHOS_B_6G_LUT_CHAN_687625_IDX] = { 27505, 0x1, 0x72, 0x135555, 0x8F4 }, + [ATHOS_B_6G_LUT_CHAN_687750_IDX] = { 27510, 0x1, 0x72, 0x140000, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_687875_IDX] = { 27515, 0x1, 0x72, 0x14AAAB, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_688000_IDX] = { 27520, 0x1, 0x72, 0x155555, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_688125_IDX] = { 27525, 0x1, 0x72, 0x160000, 0x8F6 }, + [ATHOS_B_6G_LUT_CHAN_688250_IDX] = { 27530, 0x1, 0x72, 0x16AAAB, 0x8F6 }, + [ATHOS_B_6G_LUT_CHAN_688375_IDX] = { 27535, 0x1, 0x72, 0x175555, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688500_IDX] = { 27540, 0x1, 0x72, 0x180000, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688625_IDX] = { 27545, 0x1, 0x72, 0x18AAAB, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688750_IDX] = { 27550, 0x1, 0x72, 0x195555, 0x8F8 }, + [ATHOS_B_6G_LUT_CHAN_688875_IDX] = { 27555, 0x1, 0x72, 0x1A0000, 0x8F8 }, + [ATHOS_B_6G_LUT_CHAN_689000_IDX] = { 27560, 0x1, 0x72, 0x1AAAAB, 0x8F9 }, + [ATHOS_B_6G_LUT_CHAN_689125_IDX] = { 27565, 0x1, 0x72, 0x1B5555, 0x8F9 }, + [ATHOS_B_6G_LUT_CHAN_689250_IDX] = { 27570, 0x1, 0x72, 0x1C0000, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689375_IDX] = { 27575, 0x1, 0x72, 0x1CAAAB, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689500_IDX] = { 27580, 0x1, 0x72, 0x1D5555, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689625_IDX] = { 27585, 0x1, 0x72, 0x1E0000, 0x8FB }, + [ATHOS_B_6G_LUT_CHAN_689750_IDX] = { 27590, 0x1, 0x72, 0x1EAAAB, 0x8FB }, + [ATHOS_B_6G_LUT_CHAN_689875_IDX] = { 27595, 0x1, 0x72, 0x1F5555, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690000_IDX] = { 27600, 0x1, 0x73, 0x0, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690125_IDX] = { 27605, 0x1, 0x73, 0xAAAB, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690250_IDX] = { 27610, 0x1, 0x73, 0x15555, 0x8FD }, + [ATHOS_B_6G_LUT_CHAN_690375_IDX] = { 27615, 0x1, 0x73, 0x20000, 0x8FD }, + [ATHOS_B_6G_LUT_CHAN_690500_IDX] = { 27620, 0x1, 0x73, 0x2AAAB, 0x8FE }, + [ATHOS_B_6G_LUT_CHAN_690625_IDX] = { 27625, 0x1, 0x73, 0x35555, 0x8FE }, + [ATHOS_B_6G_LUT_CHAN_690750_IDX] = { 27630, 0x1, 0x73, 0x40000, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_690875_IDX] = { 27635, 0x1, 0x73, 0x4AAAB, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_691000_IDX] = { 27640, 0x1, 0x73, 0x55555, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_691125_IDX] = { 27645, 0x1, 0x73, 0x60000, 0x900 }, + [ATHOS_B_6G_LUT_CHAN_691250_IDX] = { 27650, 0x1, 0x73, 0x6AAAB, 0x900 }, + [ATHOS_B_6G_LUT_CHAN_691375_IDX] = { 27655, 0x1, 0x73, 0x75555, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691500_IDX] = { 27660, 0x1, 0x73, 0x80000, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691625_IDX] = { 27665, 0x1, 0x73, 0x8AAAB, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691750_IDX] = { 27670, 0x1, 0x73, 0x95555, 0x902 }, + [ATHOS_B_6G_LUT_CHAN_691875_IDX] = { 27675, 0x1, 0x73, 0xA0000, 0x902 }, + [ATHOS_B_6G_LUT_CHAN_692000_IDX] = { 27680, 0x1, 0x73, 0xAAAAB, 0x903 }, + [ATHOS_B_6G_LUT_CHAN_692125_IDX] = { 27685, 0x1, 0x73, 0xB5555, 0x903 }, + [ATHOS_B_6G_LUT_CHAN_692250_IDX] = { 27690, 0x1, 0x73, 0xC0000, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692375_IDX] = { 27695, 0x1, 0x73, 0xCAAAB, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692500_IDX] = { 27700, 0x1, 0x73, 0xD5555, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692625_IDX] = { 27705, 0x1, 0x73, 0xE0000, 0x905 }, + [ATHOS_B_6G_LUT_CHAN_692750_IDX] = { 27710, 0x1, 0x73, 0xEAAAB, 0x905 }, + [ATHOS_B_6G_LUT_CHAN_692875_IDX] = { 27715, 0x1, 0x73, 0xF5555, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693000_IDX] = { 27720, 0x1, 0x73, 0x100000, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693125_IDX] = { 27725, 0x1, 0x73, 0x10AAAB, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693250_IDX] = { 27730, 0x1, 0x73, 0x115555, 0x907 }, + [ATHOS_B_6G_LUT_CHAN_693375_IDX] = { 27735, 0x1, 0x73, 0x120000, 0x907 }, + [ATHOS_B_6G_LUT_CHAN_693500_IDX] = { 27740, 0x1, 0x73, 0x12AAAB, 0x908 }, + [ATHOS_B_6G_LUT_CHAN_693625_IDX] = { 27745, 0x1, 0x73, 0x135555, 0x908 }, + [ATHOS_B_6G_LUT_CHAN_693750_IDX] = { 27750, 0x1, 0x73, 0x140000, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_693875_IDX] = { 27755, 0x1, 0x73, 0x14AAAB, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_694000_IDX] = { 27760, 0x1, 0x73, 0x155555, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_694125_IDX] = { 27765, 0x1, 0x73, 0x160000, 0x90A }, + [ATHOS_B_6G_LUT_CHAN_694250_IDX] = { 27770, 0x1, 0x73, 0x16AAAB, 0x90A }, + [ATHOS_B_6G_LUT_CHAN_694375_IDX] = { 27775, 0x1, 0x73, 0x175555, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694500_IDX] = { 27780, 0x1, 0x73, 0x180000, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694625_IDX] = { 27785, 0x1, 0x73, 0x18AAAB, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694750_IDX] = { 27790, 0x1, 0x73, 0x195555, 0x90C }, + [ATHOS_B_6G_LUT_CHAN_694875_IDX] = { 27795, 0x1, 0x73, 0x1A0000, 0x90C }, + [ATHOS_B_6G_LUT_CHAN_695000_IDX] = { 27800, 0x1, 0x73, 0x1AAAAB, 0x90D }, + [ATHOS_B_6G_LUT_CHAN_695125_IDX] = { 27805, 0x1, 0x73, 0x1B5555, 0x90D }, + [ATHOS_B_6G_LUT_CHAN_695250_IDX] = { 27810, 0x1, 0x73, 0x1C0000, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695375_IDX] = { 27815, 0x1, 0x73, 0x1CAAAB, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695500_IDX] = { 27820, 0x1, 0x73, 0x1D5555, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695625_IDX] = { 27825, 0x1, 0x73, 0x1E0000, 0x90F }, + [ATHOS_B_6G_LUT_CHAN_695750_IDX] = { 27830, 0x1, 0x73, 0x1EAAAB, 0x90F }, + [ATHOS_B_6G_LUT_CHAN_695875_IDX] = { 27835, 0x1, 0x73, 0x1F5555, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696000_IDX] = { 27840, 0x1, 0x74, 0x0, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696125_IDX] = { 27845, 0x1, 0x74, 0xAAAB, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696250_IDX] = { 27850, 0x1, 0x74, 0x15555, 0x911 }, + [ATHOS_B_6G_LUT_CHAN_696375_IDX] = { 27855, 0x1, 0x74, 0x20000, 0x911 }, + [ATHOS_B_6G_LUT_CHAN_696500_IDX] = { 27860, 0x1, 0x74, 0x2AAAB, 0x912 }, + [ATHOS_B_6G_LUT_CHAN_696625_IDX] = { 27865, 0x1, 0x74, 0x35555, 0x912 }, + [ATHOS_B_6G_LUT_CHAN_696750_IDX] = { 27870, 0x1, 0x74, 0x40000, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_696875_IDX] = { 27875, 0x1, 0x74, 0x4AAAB, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_697000_IDX] = { 27880, 0x1, 0x74, 0x55555, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_697125_IDX] = { 27885, 0x1, 0x74, 0x60000, 0x914 }, + [ATHOS_B_6G_LUT_CHAN_697250_IDX] = { 27890, 0x1, 0x74, 0x6AAAB, 0x914 }, + [ATHOS_B_6G_LUT_CHAN_697375_IDX] = { 27895, 0x1, 0x74, 0x75555, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697500_IDX] = { 27900, 0x1, 0x74, 0x80000, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697625_IDX] = { 27905, 0x1, 0x74, 0x8AAAB, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697750_IDX] = { 27910, 0x1, 0x74, 0x95555, 0x916 }, + [ATHOS_B_6G_LUT_CHAN_697875_IDX] = { 27915, 0x1, 0x74, 0xA0000, 0x916 }, + [ATHOS_B_6G_LUT_CHAN_698000_IDX] = { 27920, 0x1, 0x74, 0xAAAAB, 0x917 }, + [ATHOS_B_6G_LUT_CHAN_698125_IDX] = { 27925, 0x1, 0x74, 0xB5555, 0x917 }, + [ATHOS_B_6G_LUT_CHAN_698250_IDX] = { 27930, 0x1, 0x74, 0xC0000, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698375_IDX] = { 27935, 0x1, 0x74, 0xCAAAB, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698500_IDX] = { 27940, 0x1, 0x74, 0xD5555, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698625_IDX] = { 27945, 0x1, 0x74, 0xE0000, 0x919 }, + [ATHOS_B_6G_LUT_CHAN_698750_IDX] = { 27950, 0x1, 0x74, 0xEAAAB, 0x919 }, + [ATHOS_B_6G_LUT_CHAN_698875_IDX] = { 27955, 0x1, 0x74, 0xF5555, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699000_IDX] = { 27960, 0x1, 0x74, 0x100000, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699125_IDX] = { 27965, 0x1, 0x74, 0x10AAAB, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699250_IDX] = { 27970, 0x1, 0x74, 0x115555, 0x91B }, + [ATHOS_B_6G_LUT_CHAN_699375_IDX] = { 27975, 0x1, 0x74, 0x120000, 0x91B }, + [ATHOS_B_6G_LUT_CHAN_699500_IDX] = { 27980, 0x1, 0x74, 0x12AAAB, 0x91C }, + [ATHOS_B_6G_LUT_CHAN_699625_IDX] = { 27985, 0x1, 0x74, 0x135555, 0x91C }, + [ATHOS_B_6G_LUT_CHAN_699750_IDX] = { 27990, 0x1, 0x74, 0x140000, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_699875_IDX] = { 27995, 0x1, 0x74, 0x14AAAB, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_700000_IDX] = { 28000, 0x1, 0x74, 0x155555, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_700125_IDX] = { 28005, 0x1, 0x74, 0x160000, 0x91E }, + [ATHOS_B_6G_LUT_CHAN_700250_IDX] = { 28010, 0x1, 0x74, 0x16AAAB, 0x91E }, + [ATHOS_B_6G_LUT_CHAN_700375_IDX] = { 28015, 0x1, 0x74, 0x175555, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700500_IDX] = { 28020, 0x1, 0x74, 0x180000, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700625_IDX] = { 28025, 0x1, 0x74, 0x18AAAB, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700750_IDX] = { 28030, 0x1, 0x74, 0x195555, 0x920 }, + [ATHOS_B_6G_LUT_CHAN_700875_IDX] = { 28035, 0x1, 0x74, 0x1A0000, 0x920 }, + [ATHOS_B_6G_LUT_CHAN_701000_IDX] = { 28040, 0x1, 0x74, 0x1AAAAB, 0x921 }, + [ATHOS_B_6G_LUT_CHAN_701125_IDX] = { 28045, 0x1, 0x74, 0x1B5555, 0x921 }, + [ATHOS_B_6G_LUT_CHAN_701250_IDX] = { 28050, 0x1, 0x74, 0x1C0000, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701375_IDX] = { 28055, 0x1, 0x74, 0x1CAAAB, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701500_IDX] = { 28060, 0x1, 0x74, 0x1D5555, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701625_IDX] = { 28065, 0x1, 0x74, 0x1E0000, 0x923 }, + [ATHOS_B_6G_LUT_CHAN_701750_IDX] = { 28070, 0x1, 0x74, 0x1EAAAB, 0x923 }, + [ATHOS_B_6G_LUT_CHAN_701875_IDX] = { 28075, 0x1, 0x74, 0x1F5555, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702000_IDX] = { 28080, 0x1, 0x75, 0x0, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702125_IDX] = { 28085, 0x1, 0x75, 0xAAAB, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702250_IDX] = { 28090, 0x1, 0x75, 0x15555, 0x925 }, + [ATHOS_B_6G_LUT_CHAN_702375_IDX] = { 28095, 0x1, 0x75, 0x20000, 0x925 }, + [ATHOS_B_6G_LUT_CHAN_702500_IDX] = { 28100, 0x1, 0x75, 0x2AAAB, 0x926 }, + [ATHOS_B_6G_LUT_CHAN_702625_IDX] = { 28105, 0x1, 0x75, 0x35555, 0x926 }, + [ATHOS_B_6G_LUT_CHAN_702750_IDX] = { 28110, 0x1, 0x75, 0x40000, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_702875_IDX] = { 28115, 0x1, 0x75, 0x4AAAB, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_703000_IDX] = { 28120, 0x1, 0x75, 0x55555, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_703125_IDX] = { 28125, 0x1, 0x75, 0x60000, 0x928 }, + [ATHOS_B_6G_LUT_CHAN_703250_IDX] = { 28130, 0x1, 0x75, 0x6AAAB, 0x928 }, + [ATHOS_B_6G_LUT_CHAN_703375_IDX] = { 28135, 0x1, 0x75, 0x75555, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703500_IDX] = { 28140, 0x1, 0x75, 0x80000, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703625_IDX] = { 28145, 0x1, 0x75, 0x8AAAB, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703750_IDX] = { 28150, 0x1, 0x75, 0x95555, 0x92A }, + [ATHOS_B_6G_LUT_CHAN_703875_IDX] = { 28155, 0x1, 0x75, 0xA0000, 0x92A }, + [ATHOS_B_6G_LUT_CHAN_704000_IDX] = { 28160, 0x1, 0x75, 0xAAAAB, 0x92B }, + [ATHOS_B_6G_LUT_CHAN_704125_IDX] = { 28165, 0x1, 0x75, 0xB5555, 0x92B }, + [ATHOS_B_6G_LUT_CHAN_704250_IDX] = { 28170, 0x1, 0x75, 0xC0000, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704375_IDX] = { 28175, 0x1, 0x75, 0xCAAAB, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704500_IDX] = { 28180, 0x1, 0x75, 0xD5555, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704625_IDX] = { 28185, 0x1, 0x75, 0xE0000, 0x92D }, + [ATHOS_B_6G_LUT_CHAN_704750_IDX] = { 28190, 0x1, 0x75, 0xEAAAB, 0x92D }, + [ATHOS_B_6G_LUT_CHAN_704875_IDX] = { 28195, 0x1, 0x75, 0xF5555, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705000_IDX] = { 28200, 0x1, 0x75, 0x100000, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705125_IDX] = { 28205, 0x1, 0x75, 0x10AAAB, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705250_IDX] = { 28210, 0x1, 0x75, 0x115555, 0x92F }, + [ATHOS_B_6G_LUT_CHAN_705375_IDX] = { 28215, 0x1, 0x75, 0x120000, 0x92F }, + [ATHOS_B_6G_LUT_CHAN_705500_IDX] = { 28220, 0x1, 0x75, 0x12AAAB, 0x930 }, + [ATHOS_B_6G_LUT_CHAN_705625_IDX] = { 28225, 0x1, 0x75, 0x135555, 0x930 }, + [ATHOS_B_6G_LUT_CHAN_705750_IDX] = { 28230, 0x1, 0x75, 0x140000, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_705875_IDX] = { 28235, 0x1, 0x75, 0x14AAAB, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_706000_IDX] = { 28240, 0x1, 0x75, 0x155555, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_706125_IDX] = { 28245, 0x1, 0x75, 0x160000, 0x932 }, + [ATHOS_B_6G_LUT_CHAN_706250_IDX] = { 28250, 0x1, 0x75, 0x16AAAB, 0x932 }, + [ATHOS_B_6G_LUT_CHAN_706375_IDX] = { 28255, 0x1, 0x75, 0x175555, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706500_IDX] = { 28260, 0x1, 0x75, 0x180000, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706625_IDX] = { 28265, 0x1, 0x75, 0x18AAAB, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706750_IDX] = { 28270, 0x1, 0x75, 0x195555, 0x934 }, + [ATHOS_B_6G_LUT_CHAN_706875_IDX] = { 28275, 0x1, 0x75, 0x1A0000, 0x934 }, + [ATHOS_B_6G_LUT_CHAN_707000_IDX] = { 28280, 0x1, 0x75, 0x1AAAAB, 0x935 }, + [ATHOS_B_6G_LUT_CHAN_707125_IDX] = { 28285, 0x1, 0x75, 0x1B5555, 0x935 }, + [ATHOS_B_6G_LUT_CHAN_707250_IDX] = { 28290, 0x1, 0x75, 0x1C0000, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707375_IDX] = { 28295, 0x1, 0x75, 0x1CAAAB, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707500_IDX] = { 28300, 0x1, 0x75, 0x1D5555, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707625_IDX] = { 28305, 0x1, 0x75, 0x1E0000, 0x937 }, + [ATHOS_B_6G_LUT_CHAN_707750_IDX] = { 28310, 0x1, 0x75, 0x1EAAAB, 0x937 }, + [ATHOS_B_6G_LUT_CHAN_707875_IDX] = { 28315, 0x1, 0x75, 0x1F5555, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708000_IDX] = { 28320, 0x1, 0x76, 0x0, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708125_IDX] = { 28325, 0x1, 0x76, 0xAAAB, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708250_IDX] = { 28330, 0x1, 0x76, 0x15555, 0x939 }, + [ATHOS_B_6G_LUT_CHAN_708375_IDX] = { 28335, 0x1, 0x76, 0x20000, 0x939 }, + [ATHOS_B_6G_LUT_CHAN_708500_IDX] = { 28340, 0x1, 0x76, 0x2AAAB, 0x93A }, + [ATHOS_B_6G_LUT_CHAN_708625_IDX] = { 28345, 0x1, 0x76, 0x35555, 0x93A }, + [ATHOS_B_6G_LUT_CHAN_708750_IDX] = { 28350, 0x1, 0x76, 0x40000, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_708875_IDX] = { 28355, 0x1, 0x76, 0x4AAAB, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_709000_IDX] = { 28360, 0x1, 0x76, 0x55555, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_709125_IDX] = { 28365, 0x1, 0x76, 0x60000, 0x93C }, + [ATHOS_B_6G_LUT_CHAN_709250_IDX] = { 28370, 0x1, 0x76, 0x6AAAB, 0x93C }, + [ATHOS_B_6G_LUT_CHAN_709375_IDX] = { 28375, 0x1, 0x76, 0x75555, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709500_IDX] = { 28380, 0x1, 0x76, 0x80000, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709625_IDX] = { 28385, 0x1, 0x76, 0x8AAAB, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709750_IDX] = { 28390, 0x1, 0x76, 0x95555, 0x93E }, + [ATHOS_B_6G_LUT_CHAN_709875_IDX] = { 28395, 0x1, 0x76, 0xA0000, 0x93E }, + [ATHOS_B_6G_LUT_CHAN_710000_IDX] = { 28400, 0x1, 0x76, 0xAAAAB, 0x93F }, + [ATHOS_B_6G_LUT_CHAN_710125_IDX] = { 28405, 0x1, 0x76, 0xB5555, 0x93F }, + [ATHOS_B_6G_LUT_CHAN_710250_IDX] = { 28410, 0x1, 0x76, 0xC0000, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710375_IDX] = { 28415, 0x1, 0x76, 0xCAAAB, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710500_IDX] = { 28420, 0x1, 0x76, 0xD5555, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710625_IDX] = { 28425, 0x1, 0x76, 0xE0000, 0x941 }, + [ATHOS_B_6G_LUT_CHAN_710750_IDX] = { 28430, 0x1, 0x76, 0xEAAAB, 0x941 }, + [ATHOS_B_6G_LUT_CHAN_710875_IDX] = { 28435, 0x1, 0x76, 0xF5555, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711000_IDX] = { 28440, 0x1, 0x76, 0x100000, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711125_IDX] = { 28445, 0x1, 0x76, 0x10AAAB, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711250_IDX] = { 28450, 0x1, 0x76, 0x115555, 0x943 }, + [ATHOS_B_6G_LUT_CHAN_711375_IDX] = { 28455, 0x1, 0x76, 0x120000, 0x943 }, + [ATHOS_B_6G_LUT_CHAN_711500_IDX] = { 28460, 0x1, 0x76, 0x12AAAB, 0x944 }, + [ATHOS_B_6G_LUT_CHAN_711625_IDX] = { 28465, 0x1, 0x76, 0x135555, 0x944 }, + [ATHOS_B_6G_LUT_CHAN_711750_IDX] = { 28470, 0x1, 0x76, 0x140000, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_711875_IDX] = { 28475, 0x1, 0x76, 0x14AAAB, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_712000_IDX] = { 28480, 0x1, 0x76, 0x155555, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_712125_IDX] = { 28485, 0x1, 0x76, 0x160000, 0x946 }, + [ATHOS_B_6G_LUT_CHAN_712250_IDX] = { 28490, 0x1, 0x76, 0x16AAAB, 0x946 }, + [ATHOS_B_6G_LUT_CHAN_712375_IDX] = { 28495, 0x1, 0x76, 0x175555, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712500_IDX] = { 28500, 0x1, 0x76, 0x180000, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712625_IDX] = { 28505, 0x1, 0x76, 0x18AAAB, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712750_IDX] = { 28510, 0x1, 0x76, 0x195555, 0x948 }, + [ATHOS_B_6G_LUT_CHAN_712875_IDX] = { 28515, 0x1, 0x76, 0x1A0000, 0x948 }, + [ATHOS_B_6G_LUT_CHAN_713000_IDX] = { 28520, 0x1, 0x76, 0x1AAAAB, 0x949 }, + [ATHOS_B_6G_LUT_CHAN_713125_IDX] = { 28525, 0x1, 0x76, 0x1B5555, 0x949 }, + [ATHOS_B_6G_LUT_CHAN_713250_IDX] = { 28530, 0x1, 0x76, 0x1C0000, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713375_IDX] = { 28535, 0x1, 0x76, 0x1CAAAB, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713500_IDX] = { 28540, 0x1, 0x76, 0x1D5555, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713625_IDX] = { 28545, 0x1, 0x76, 0x1E0000, 0x94B }, + [ATHOS_B_6G_LUT_CHAN_713750_IDX] = { 28550, 0x1, 0x76, 0x1EAAAB, 0x94B }, + [ATHOS_B_6G_LUT_CHAN_713875_IDX] = { 28555, 0x1, 0x76, 0x1F5555, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714000_IDX] = { 28560, 0x1, 0x77, 0x0, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714125_IDX] = { 28565, 0x1, 0x77, 0xAAAB, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714250_IDX] = { 28570, 0x1, 0x77, 0x15555, 0x94D }, + [ATHOS_B_6G_LUT_CHAN_714375_IDX] = { 28575, 0x1, 0x77, 0x20000, 0x94D }, + [ATHOS_B_6G_LUT_CHAN_714500_IDX] = { 28580, 0x1, 0x77, 0x2AAAB, 0x94E }, + [ATHOS_B_6G_LUT_CHAN_714625_IDX] = { 28585, 0x1, 0x77, 0x35555, 0x94E }, + [ATHOS_B_6G_LUT_CHAN_714750_IDX] = { 28590, 0x1, 0x77, 0x40000, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_714875_IDX] = { 28595, 0x1, 0x77, 0x4AAAB, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_715000_IDX] = { 28600, 0x1, 0x77, 0x55555, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_715125_IDX] = { 28605, 0x1, 0x77, 0x60000, 0x950 }, + [ATHOS_B_6G_LUT_CHAN_715250_IDX] = { 28610, 0x1, 0x77, 0x6AAAB, 0x950 }, + [ATHOS_B_6G_LUT_CHAN_715375_IDX] = { 28615, 0x1, 0x77, 0x75555, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715500_IDX] = { 28620, 0x1, 0x77, 0x80000, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715625_IDX] = { 28625, 0x1, 0x77, 0x8AAAB, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715750_IDX] = { 28630, 0x1, 0x77, 0x95555, 0x952 }, + [ATHOS_B_6G_LUT_CHAN_715875_IDX] = { 28635, 0x1, 0x77, 0xA0000, 0x952 }, + [ATHOS_B_6G_LUT_CHAN_716000_IDX] = { 28640, 0x1, 0x77, 0xAAAAB, 0x953 }, + [ATHOS_B_6G_LUT_CHAN_716125_IDX] = { 28645, 0x1, 0x77, 0xB5555, 0x953 }, + [ATHOS_B_6G_LUT_CHAN_716250_IDX] = { 28650, 0x1, 0x77, 0xC0000, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716375_IDX] = { 28655, 0x1, 0x77, 0xCAAAB, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716500_IDX] = { 28660, 0x1, 0x77, 0xD5555, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716625_IDX] = { 28665, 0x1, 0x77, 0xE0000, 0x955 }, + [ATHOS_B_6G_LUT_CHAN_716750_IDX] = { 28670, 0x1, 0x77, 0xEAAAB, 0x955 }, + [ATHOS_B_6G_LUT_CHAN_716875_IDX] = { 28675, 0x1, 0x77, 0xF5555, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717000_IDX] = { 28680, 0x1, 0x77, 0x100000, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717125_IDX] = { 28685, 0x1, 0x77, 0x10AAAB, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717250_IDX] = { 28690, 0x1, 0x77, 0x115555, 0x957 }, + [ATHOS_B_6G_LUT_CHAN_717375_IDX] = { 28695, 0x1, 0x77, 0x120000, 0x957 }, + [ATHOS_B_6G_LUT_CHAN_717500_IDX] = { 28700, 0x1, 0x77, 0x12AAAB, 0x958 }, + [ATHOS_B_6G_LUT_CHAN_717625_IDX] = { 28705, 0x1, 0x77, 0x135555, 0x958 }, + [ATHOS_B_6G_LUT_CHAN_717750_IDX] = { 28710, 0x1, 0x77, 0x140000, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_717875_IDX] = { 28715, 0x1, 0x77, 0x14AAAB, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_718000_IDX] = { 28720, 0x1, 0x77, 0x155555, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_718125_IDX] = { 28725, 0x1, 0x77, 0x160000, 0x95A }, + [ATHOS_B_6G_LUT_CHAN_718250_IDX] = { 28730, 0x1, 0x77, 0x16AAAB, 0x95A }, + [ATHOS_B_6G_LUT_CHAN_718375_IDX] = { 28735, 0x1, 0x77, 0x175555, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718500_IDX] = { 28740, 0x1, 0x77, 0x180000, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718625_IDX] = { 28745, 0x1, 0x77, 0x18AAAB, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718750_IDX] = { 28750, 0x1, 0x77, 0x195555, 0x95C }, + [ATHOS_B_6G_LUT_CHAN_718875_IDX] = { 28755, 0x1, 0x77, 0x1A0000, 0x95C }, + [ATHOS_B_6G_LUT_CHAN_719000_IDX] = { 28760, 0x1, 0x77, 0x1AAAAB, 0x95D }, + [ATHOS_B_6G_LUT_CHAN_719125_IDX] = { 28765, 0x1, 0x77, 0x1B5555, 0x95D }, + [ATHOS_B_6G_LUT_CHAN_719250_IDX] = { 28770, 0x1, 0x77, 0x1C0000, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719375_IDX] = { 28775, 0x1, 0x77, 0x1CAAAB, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719500_IDX] = { 28780, 0x1, 0x77, 0x1D5555, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719625_IDX] = { 28785, 0x1, 0x77, 0x1E0000, 0x95F }, + [ATHOS_B_6G_LUT_CHAN_719750_IDX] = { 28790, 0x1, 0x77, 0x1EAAAB, 0x95F }, + [ATHOS_B_6G_LUT_CHAN_719875_IDX] = { 28795, 0x1, 0x77, 0x1F5555, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720000_IDX] = { 28800, 0x1, 0x78, 0x0, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720125_IDX] = { 28805, 0x1, 0x78, 0xAAAB, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720250_IDX] = { 28810, 0x1, 0x78, 0x15555, 0x961 }, + [ATHOS_B_6G_LUT_CHAN_720375_IDX] = { 28815, 0x1, 0x78, 0x20000, 0x961 }, + [ATHOS_B_6G_LUT_CHAN_720500_IDX] = { 28820, 0x1, 0x78, 0x2AAAB, 0x962 }, + [ATHOS_B_6G_LUT_CHAN_720625_IDX] = { 28825, 0x1, 0x78, 0x35555, 0x962 }, + [ATHOS_B_6G_LUT_CHAN_720750_IDX] = { 28830, 0x1, 0x78, 0x40000, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_720875_IDX] = { 28835, 0x1, 0x78, 0x4AAAB, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_721000_IDX] = { 28840, 0x1, 0x78, 0x55555, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_721125_IDX] = { 28845, 0x1, 0x78, 0x60000, 0x964 }, + [ATHOS_B_6G_LUT_CHAN_721250_IDX] = { 28850, 0x1, 0x78, 0x6AAAB, 0x964 }, + [ATHOS_B_6G_LUT_CHAN_721375_IDX] = { 28855, 0x1, 0x78, 0x75555, 0x965 }, + [ATHOS_B_6G_LUT_CHAN_721500_IDX] = { 28860, 0x1, 0x78, 0x80000, 0x965 } +}; + +const struct common_lut_line athos_b_lut_6g_60_mhz[ATHOS_B_6G_LUT_CHAN_6G_MAX] = { + [ATHOS_B_6G_LUT_CHAN_593000_IDX] = { 23720, 0x1, 0x41, 0x1C71C7, 0x7B9 }, + [ATHOS_B_6G_LUT_CHAN_593125_IDX] = { 23725, 0x1, 0x41, 0x1CE38E, 0x7B9 }, + [ATHOS_B_6G_LUT_CHAN_593250_IDX] = { 23730, 0x1, 0x41, 0x1D5555, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593375_IDX] = { 23735, 0x1, 0x41, 0x1DC71C, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593500_IDX] = { 23740, 0x1, 0x41, 0x1E38E4, 0x7BA }, + [ATHOS_B_6G_LUT_CHAN_593625_IDX] = { 23745, 0x1, 0x41, 0x1EAAAB, 0x7BB }, + [ATHOS_B_6G_LUT_CHAN_593750_IDX] = { 23750, 0x1, 0x41, 0x1F1C72, 0x7BB }, + [ATHOS_B_6G_LUT_CHAN_593875_IDX] = { 23755, 0x1, 0x41, 0x1F8E39, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594000_IDX] = { 23760, 0x1, 0x42, 0x0, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594125_IDX] = { 23765, 0x1, 0x42, 0x71C7, 0x7BC }, + [ATHOS_B_6G_LUT_CHAN_594250_IDX] = { 23770, 0x1, 0x42, 0xE38E, 0x7BD }, + [ATHOS_B_6G_LUT_CHAN_594375_IDX] = { 23775, 0x1, 0x42, 0x15555, 0x7BD }, + [ATHOS_B_6G_LUT_CHAN_594500_IDX] = { 23780, 0x1, 0x42, 0x1C71C, 0x7BE }, + [ATHOS_B_6G_LUT_CHAN_594625_IDX] = { 23785, 0x1, 0x42, 0x238E4, 0x7BE }, + [ATHOS_B_6G_LUT_CHAN_594750_IDX] = { 23790, 0x1, 0x42, 0x2AAAB, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_594875_IDX] = { 23795, 0x1, 0x42, 0x31C72, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_595000_IDX] = { 23800, 0x1, 0x42, 0x38E39, 0x7BF }, + [ATHOS_B_6G_LUT_CHAN_595125_IDX] = { 23805, 0x1, 0x42, 0x40000, 0x7C0 }, + [ATHOS_B_6G_LUT_CHAN_595250_IDX] = { 23810, 0x1, 0x42, 0x471C7, 0x7C0 }, + [ATHOS_B_6G_LUT_CHAN_595375_IDX] = { 23815, 0x1, 0x42, 0x4E38E, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595500_IDX] = { 23820, 0x1, 0x42, 0x55555, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595625_IDX] = { 23825, 0x1, 0x42, 0x5C71C, 0x7C1 }, + [ATHOS_B_6G_LUT_CHAN_595750_IDX] = { 23830, 0x1, 0x42, 0x638E4, 0x7C2 }, + [ATHOS_B_6G_LUT_CHAN_595875_IDX] = { 23835, 0x1, 0x42, 0x6AAAB, 0x7C2 }, + [ATHOS_B_6G_LUT_CHAN_596000_IDX] = { 23840, 0x1, 0x42, 0x71C72, 0x7C3 }, + [ATHOS_B_6G_LUT_CHAN_596125_IDX] = { 23845, 0x1, 0x42, 0x78E39, 0x7C3 }, + [ATHOS_B_6G_LUT_CHAN_596250_IDX] = { 23850, 0x1, 0x42, 0x80000, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596375_IDX] = { 23855, 0x1, 0x42, 0x871C7, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596500_IDX] = { 23860, 0x1, 0x42, 0x8E38E, 0x7C4 }, + [ATHOS_B_6G_LUT_CHAN_596625_IDX] = { 23865, 0x1, 0x42, 0x95555, 0x7C5 }, + [ATHOS_B_6G_LUT_CHAN_596750_IDX] = { 23870, 0x1, 0x42, 0x9C71C, 0x7C5 }, + [ATHOS_B_6G_LUT_CHAN_596875_IDX] = { 23875, 0x1, 0x42, 0xA38E4, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597000_IDX] = { 23880, 0x1, 0x42, 0xAAAAB, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597125_IDX] = { 23885, 0x1, 0x42, 0xB1C72, 0x7C6 }, + [ATHOS_B_6G_LUT_CHAN_597250_IDX] = { 23890, 0x1, 0x42, 0xB8E39, 0x7C7 }, + [ATHOS_B_6G_LUT_CHAN_597375_IDX] = { 23895, 0x1, 0x42, 0xC0000, 0x7C7 }, + [ATHOS_B_6G_LUT_CHAN_597500_IDX] = { 23900, 0x1, 0x42, 0xC71C7, 0x7C8 }, + [ATHOS_B_6G_LUT_CHAN_597625_IDX] = { 23905, 0x1, 0x42, 0xCE38E, 0x7C8 }, + [ATHOS_B_6G_LUT_CHAN_597750_IDX] = { 23910, 0x1, 0x42, 0xD5555, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_597875_IDX] = { 23915, 0x1, 0x42, 0xDC71C, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_598000_IDX] = { 23920, 0x1, 0x42, 0xE38E4, 0x7C9 }, + [ATHOS_B_6G_LUT_CHAN_598125_IDX] = { 23925, 0x1, 0x42, 0xEAAAB, 0x7CA }, + [ATHOS_B_6G_LUT_CHAN_598250_IDX] = { 23930, 0x1, 0x42, 0xF1C72, 0x7CA }, + [ATHOS_B_6G_LUT_CHAN_598375_IDX] = { 23935, 0x1, 0x42, 0xF8E39, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598500_IDX] = { 23940, 0x1, 0x42, 0x100000, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598625_IDX] = { 23945, 0x1, 0x42, 0x1071C7, 0x7CB }, + [ATHOS_B_6G_LUT_CHAN_598750_IDX] = { 23950, 0x1, 0x42, 0x10E38E, 0x7CC }, + [ATHOS_B_6G_LUT_CHAN_598875_IDX] = { 23955, 0x1, 0x42, 0x115555, 0x7CC }, + [ATHOS_B_6G_LUT_CHAN_599000_IDX] = { 23960, 0x1, 0x42, 0x11C71C, 0x7CD }, + [ATHOS_B_6G_LUT_CHAN_599125_IDX] = { 23965, 0x1, 0x42, 0x1238E4, 0x7CD }, + [ATHOS_B_6G_LUT_CHAN_599250_IDX] = { 23970, 0x1, 0x42, 0x12AAAB, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599375_IDX] = { 23975, 0x1, 0x42, 0x131C72, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599500_IDX] = { 23980, 0x1, 0x42, 0x138E39, 0x7CE }, + [ATHOS_B_6G_LUT_CHAN_599625_IDX] = { 23985, 0x1, 0x42, 0x140000, 0x7CF }, + [ATHOS_B_6G_LUT_CHAN_599750_IDX] = { 23990, 0x1, 0x42, 0x1471C7, 0x7CF }, + [ATHOS_B_6G_LUT_CHAN_599875_IDX] = { 23995, 0x1, 0x42, 0x14E38E, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600000_IDX] = { 24000, 0x1, 0x42, 0x155555, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600125_IDX] = { 24005, 0x1, 0x42, 0x15C71C, 0x7D0 }, + [ATHOS_B_6G_LUT_CHAN_600250_IDX] = { 24010, 0x1, 0x42, 0x1638E4, 0x7D1 }, + [ATHOS_B_6G_LUT_CHAN_600375_IDX] = { 24015, 0x1, 0x42, 0x16AAAB, 0x7D1 }, + [ATHOS_B_6G_LUT_CHAN_600500_IDX] = { 24020, 0x1, 0x42, 0x171C72, 0x7D2 }, + [ATHOS_B_6G_LUT_CHAN_600625_IDX] = { 24025, 0x1, 0x42, 0x178E39, 0x7D2 }, + [ATHOS_B_6G_LUT_CHAN_600750_IDX] = { 24030, 0x1, 0x42, 0x180000, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_600875_IDX] = { 24035, 0x1, 0x42, 0x1871C7, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_601000_IDX] = { 24040, 0x1, 0x42, 0x18E38E, 0x7D3 }, + [ATHOS_B_6G_LUT_CHAN_601125_IDX] = { 24045, 0x1, 0x42, 0x195555, 0x7D4 }, + [ATHOS_B_6G_LUT_CHAN_601250_IDX] = { 24050, 0x1, 0x42, 0x19C71C, 0x7D4 }, + [ATHOS_B_6G_LUT_CHAN_601375_IDX] = { 24055, 0x1, 0x42, 0x1A38E4, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601500_IDX] = { 24060, 0x1, 0x42, 0x1AAAAB, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601625_IDX] = { 24065, 0x1, 0x42, 0x1B1C72, 0x7D5 }, + [ATHOS_B_6G_LUT_CHAN_601750_IDX] = { 24070, 0x1, 0x42, 0x1B8E39, 0x7D6 }, + [ATHOS_B_6G_LUT_CHAN_601875_IDX] = { 24075, 0x1, 0x42, 0x1C0000, 0x7D6 }, + [ATHOS_B_6G_LUT_CHAN_602000_IDX] = { 24080, 0x1, 0x42, 0x1C71C7, 0x7D7 }, + [ATHOS_B_6G_LUT_CHAN_602125_IDX] = { 24085, 0x1, 0x42, 0x1CE38E, 0x7D7 }, + [ATHOS_B_6G_LUT_CHAN_602250_IDX] = { 24090, 0x1, 0x42, 0x1D5555, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602375_IDX] = { 24095, 0x1, 0x42, 0x1DC71C, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602500_IDX] = { 24100, 0x1, 0x42, 0x1E38E4, 0x7D8 }, + [ATHOS_B_6G_LUT_CHAN_602625_IDX] = { 24105, 0x1, 0x42, 0x1EAAAB, 0x7D9 }, + [ATHOS_B_6G_LUT_CHAN_602750_IDX] = { 24110, 0x1, 0x42, 0x1F1C72, 0x7D9 }, + [ATHOS_B_6G_LUT_CHAN_602875_IDX] = { 24115, 0x1, 0x42, 0x1F8E39, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603000_IDX] = { 24120, 0x1, 0x43, 0x0, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603125_IDX] = { 24125, 0x1, 0x43, 0x71C7, 0x7DA }, + [ATHOS_B_6G_LUT_CHAN_603250_IDX] = { 24130, 0x1, 0x43, 0xE38E, 0x7DB }, + [ATHOS_B_6G_LUT_CHAN_603375_IDX] = { 24135, 0x1, 0x43, 0x15555, 0x7DB }, + [ATHOS_B_6G_LUT_CHAN_603500_IDX] = { 24140, 0x1, 0x43, 0x1C71C, 0x7DC }, + [ATHOS_B_6G_LUT_CHAN_603625_IDX] = { 24145, 0x1, 0x43, 0x238E4, 0x7DC }, + [ATHOS_B_6G_LUT_CHAN_603750_IDX] = { 24150, 0x1, 0x43, 0x2AAAB, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_603875_IDX] = { 24155, 0x1, 0x43, 0x31C72, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_604000_IDX] = { 24160, 0x1, 0x43, 0x38E39, 0x7DD }, + [ATHOS_B_6G_LUT_CHAN_604125_IDX] = { 24165, 0x1, 0x43, 0x40000, 0x7DE }, + [ATHOS_B_6G_LUT_CHAN_604250_IDX] = { 24170, 0x1, 0x43, 0x471C7, 0x7DE }, + [ATHOS_B_6G_LUT_CHAN_604375_IDX] = { 24175, 0x1, 0x43, 0x4E38E, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604500_IDX] = { 24180, 0x1, 0x43, 0x55555, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604625_IDX] = { 24185, 0x1, 0x43, 0x5C71C, 0x7DF }, + [ATHOS_B_6G_LUT_CHAN_604750_IDX] = { 24190, 0x1, 0x43, 0x638E4, 0x7E0 }, + [ATHOS_B_6G_LUT_CHAN_604875_IDX] = { 24195, 0x1, 0x43, 0x6AAAB, 0x7E0 }, + [ATHOS_B_6G_LUT_CHAN_605000_IDX] = { 24200, 0x1, 0x43, 0x71C72, 0x7E1 }, + [ATHOS_B_6G_LUT_CHAN_605125_IDX] = { 24205, 0x1, 0x43, 0x78E39, 0x7E1 }, + [ATHOS_B_6G_LUT_CHAN_605250_IDX] = { 24210, 0x1, 0x43, 0x80000, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605375_IDX] = { 24215, 0x1, 0x43, 0x871C7, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605500_IDX] = { 24220, 0x1, 0x43, 0x8E38E, 0x7E2 }, + [ATHOS_B_6G_LUT_CHAN_605625_IDX] = { 24225, 0x1, 0x43, 0x95555, 0x7E3 }, + [ATHOS_B_6G_LUT_CHAN_605750_IDX] = { 24230, 0x1, 0x43, 0x9C71C, 0x7E3 }, + [ATHOS_B_6G_LUT_CHAN_605875_IDX] = { 24235, 0x1, 0x43, 0xA38E4, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606000_IDX] = { 24240, 0x1, 0x43, 0xAAAAB, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606125_IDX] = { 24245, 0x1, 0x43, 0xB1C72, 0x7E4 }, + [ATHOS_B_6G_LUT_CHAN_606250_IDX] = { 24250, 0x1, 0x43, 0xB8E39, 0x7E5 }, + [ATHOS_B_6G_LUT_CHAN_606375_IDX] = { 24255, 0x1, 0x43, 0xC0000, 0x7E5 }, + [ATHOS_B_6G_LUT_CHAN_606500_IDX] = { 24260, 0x1, 0x43, 0xC71C7, 0x7E6 }, + [ATHOS_B_6G_LUT_CHAN_606625_IDX] = { 24265, 0x1, 0x43, 0xCE38E, 0x7E6 }, + [ATHOS_B_6G_LUT_CHAN_606750_IDX] = { 24270, 0x1, 0x43, 0xD5555, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_606875_IDX] = { 24275, 0x1, 0x43, 0xDC71C, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_607000_IDX] = { 24280, 0x1, 0x43, 0xE38E4, 0x7E7 }, + [ATHOS_B_6G_LUT_CHAN_607125_IDX] = { 24285, 0x1, 0x43, 0xEAAAB, 0x7E8 }, + [ATHOS_B_6G_LUT_CHAN_607250_IDX] = { 24290, 0x1, 0x43, 0xF1C72, 0x7E8 }, + [ATHOS_B_6G_LUT_CHAN_607375_IDX] = { 24295, 0x1, 0x43, 0xF8E39, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607500_IDX] = { 24300, 0x1, 0x43, 0x100000, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607625_IDX] = { 24305, 0x1, 0x43, 0x1071C7, 0x7E9 }, + [ATHOS_B_6G_LUT_CHAN_607750_IDX] = { 24310, 0x1, 0x43, 0x10E38E, 0x7EA }, + [ATHOS_B_6G_LUT_CHAN_607875_IDX] = { 24315, 0x1, 0x43, 0x115555, 0x7EA }, + [ATHOS_B_6G_LUT_CHAN_608000_IDX] = { 24320, 0x1, 0x43, 0x11C71C, 0x7EB }, + [ATHOS_B_6G_LUT_CHAN_608125_IDX] = { 24325, 0x1, 0x43, 0x1238E4, 0x7EB }, + [ATHOS_B_6G_LUT_CHAN_608250_IDX] = { 24330, 0x1, 0x43, 0x12AAAB, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608375_IDX] = { 24335, 0x1, 0x43, 0x131C72, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608500_IDX] = { 24340, 0x1, 0x43, 0x138E39, 0x7EC }, + [ATHOS_B_6G_LUT_CHAN_608625_IDX] = { 24345, 0x1, 0x43, 0x140000, 0x7ED }, + [ATHOS_B_6G_LUT_CHAN_608750_IDX] = { 24350, 0x1, 0x43, 0x1471C7, 0x7ED }, + [ATHOS_B_6G_LUT_CHAN_608875_IDX] = { 24355, 0x1, 0x43, 0x14E38E, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609000_IDX] = { 24360, 0x1, 0x43, 0x155555, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609125_IDX] = { 24365, 0x1, 0x43, 0x15C71C, 0x7EE }, + [ATHOS_B_6G_LUT_CHAN_609250_IDX] = { 24370, 0x1, 0x43, 0x1638E4, 0x7EF }, + [ATHOS_B_6G_LUT_CHAN_609375_IDX] = { 24375, 0x1, 0x43, 0x16AAAB, 0x7EF }, + [ATHOS_B_6G_LUT_CHAN_609500_IDX] = { 24380, 0x1, 0x43, 0x171C72, 0x7F0 }, + [ATHOS_B_6G_LUT_CHAN_609625_IDX] = { 24385, 0x1, 0x43, 0x178E39, 0x7F0 }, + [ATHOS_B_6G_LUT_CHAN_609750_IDX] = { 24390, 0x1, 0x43, 0x180000, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_609875_IDX] = { 24395, 0x1, 0x43, 0x1871C7, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_610000_IDX] = { 24400, 0x1, 0x43, 0x18E38E, 0x7F1 }, + [ATHOS_B_6G_LUT_CHAN_610125_IDX] = { 24405, 0x1, 0x43, 0x195555, 0x7F2 }, + [ATHOS_B_6G_LUT_CHAN_610250_IDX] = { 24410, 0x1, 0x43, 0x19C71C, 0x7F2 }, + [ATHOS_B_6G_LUT_CHAN_610375_IDX] = { 24415, 0x1, 0x43, 0x1A38E4, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610500_IDX] = { 24420, 0x1, 0x43, 0x1AAAAB, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610625_IDX] = { 24425, 0x1, 0x43, 0x1B1C72, 0x7F3 }, + [ATHOS_B_6G_LUT_CHAN_610750_IDX] = { 24430, 0x1, 0x43, 0x1B8E39, 0x7F4 }, + [ATHOS_B_6G_LUT_CHAN_610875_IDX] = { 24435, 0x1, 0x43, 0x1C0000, 0x7F4 }, + [ATHOS_B_6G_LUT_CHAN_611000_IDX] = { 24440, 0x1, 0x43, 0x1C71C7, 0x7F5 }, + [ATHOS_B_6G_LUT_CHAN_611125_IDX] = { 24445, 0x1, 0x43, 0x1CE38E, 0x7F5 }, + [ATHOS_B_6G_LUT_CHAN_611250_IDX] = { 24450, 0x1, 0x43, 0x1D5555, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611375_IDX] = { 24455, 0x1, 0x43, 0x1DC71C, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611500_IDX] = { 24460, 0x1, 0x43, 0x1E38E4, 0x7F6 }, + [ATHOS_B_6G_LUT_CHAN_611625_IDX] = { 24465, 0x1, 0x43, 0x1EAAAB, 0x7F7 }, + [ATHOS_B_6G_LUT_CHAN_611750_IDX] = { 24470, 0x1, 0x43, 0x1F1C72, 0x7F7 }, + [ATHOS_B_6G_LUT_CHAN_611875_IDX] = { 24475, 0x1, 0x43, 0x1F8E39, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612000_IDX] = { 24480, 0x1, 0x44, 0x0, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612125_IDX] = { 24485, 0x1, 0x44, 0x71C7, 0x7F8 }, + [ATHOS_B_6G_LUT_CHAN_612250_IDX] = { 24490, 0x1, 0x44, 0xE38E, 0x7F9 }, + [ATHOS_B_6G_LUT_CHAN_612375_IDX] = { 24495, 0x1, 0x44, 0x15555, 0x7F9 }, + [ATHOS_B_6G_LUT_CHAN_612500_IDX] = { 24500, 0x1, 0x44, 0x1C71C, 0x7FA }, + [ATHOS_B_6G_LUT_CHAN_612625_IDX] = { 24505, 0x1, 0x44, 0x238E4, 0x7FA }, + [ATHOS_B_6G_LUT_CHAN_612750_IDX] = { 24510, 0x1, 0x44, 0x2AAAB, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_612875_IDX] = { 24515, 0x1, 0x44, 0x31C72, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_613000_IDX] = { 24520, 0x1, 0x44, 0x38E39, 0x7FB }, + [ATHOS_B_6G_LUT_CHAN_613125_IDX] = { 24525, 0x1, 0x44, 0x40000, 0x7FC }, + [ATHOS_B_6G_LUT_CHAN_613250_IDX] = { 24530, 0x1, 0x44, 0x471C7, 0x7FC }, + [ATHOS_B_6G_LUT_CHAN_613375_IDX] = { 24535, 0x1, 0x44, 0x4E38E, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613500_IDX] = { 24540, 0x1, 0x44, 0x55555, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613625_IDX] = { 24545, 0x1, 0x44, 0x5C71C, 0x7FD }, + [ATHOS_B_6G_LUT_CHAN_613750_IDX] = { 24550, 0x1, 0x44, 0x638E4, 0x7FE }, + [ATHOS_B_6G_LUT_CHAN_613875_IDX] = { 24555, 0x1, 0x44, 0x6AAAB, 0x7FE }, + [ATHOS_B_6G_LUT_CHAN_614000_IDX] = { 24560, 0x1, 0x44, 0x71C72, 0x7FF }, + [ATHOS_B_6G_LUT_CHAN_614125_IDX] = { 24565, 0x1, 0x44, 0x78E39, 0x7FF }, + [ATHOS_B_6G_LUT_CHAN_614250_IDX] = { 24570, 0x1, 0x44, 0x80000, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614375_IDX] = { 24575, 0x1, 0x44, 0x871C7, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614500_IDX] = { 24580, 0x1, 0x44, 0x8E38E, 0x800 }, + [ATHOS_B_6G_LUT_CHAN_614625_IDX] = { 24585, 0x1, 0x44, 0x95555, 0x801 }, + [ATHOS_B_6G_LUT_CHAN_614750_IDX] = { 24590, 0x1, 0x44, 0x9C71C, 0x801 }, + [ATHOS_B_6G_LUT_CHAN_614875_IDX] = { 24595, 0x1, 0x44, 0xA38E4, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615000_IDX] = { 24600, 0x1, 0x44, 0xAAAAB, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615125_IDX] = { 24605, 0x1, 0x44, 0xB1C72, 0x802 }, + [ATHOS_B_6G_LUT_CHAN_615250_IDX] = { 24610, 0x1, 0x44, 0xB8E39, 0x803 }, + [ATHOS_B_6G_LUT_CHAN_615375_IDX] = { 24615, 0x1, 0x44, 0xC0000, 0x803 }, + [ATHOS_B_6G_LUT_CHAN_615500_IDX] = { 24620, 0x1, 0x44, 0xC71C7, 0x804 }, + [ATHOS_B_6G_LUT_CHAN_615625_IDX] = { 24625, 0x1, 0x44, 0xCE38E, 0x804 }, + [ATHOS_B_6G_LUT_CHAN_615750_IDX] = { 24630, 0x1, 0x44, 0xD5555, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_615875_IDX] = { 24635, 0x1, 0x44, 0xDC71C, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_616000_IDX] = { 24640, 0x1, 0x44, 0xE38E4, 0x805 }, + [ATHOS_B_6G_LUT_CHAN_616125_IDX] = { 24645, 0x1, 0x44, 0xEAAAB, 0x806 }, + [ATHOS_B_6G_LUT_CHAN_616250_IDX] = { 24650, 0x1, 0x44, 0xF1C72, 0x806 }, + [ATHOS_B_6G_LUT_CHAN_616375_IDX] = { 24655, 0x1, 0x44, 0xF8E39, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616500_IDX] = { 24660, 0x1, 0x44, 0x100000, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616625_IDX] = { 24665, 0x1, 0x44, 0x1071C7, 0x807 }, + [ATHOS_B_6G_LUT_CHAN_616750_IDX] = { 24670, 0x1, 0x44, 0x10E38E, 0x808 }, + [ATHOS_B_6G_LUT_CHAN_616875_IDX] = { 24675, 0x1, 0x44, 0x115555, 0x808 }, + [ATHOS_B_6G_LUT_CHAN_617000_IDX] = { 24680, 0x1, 0x44, 0x11C71C, 0x809 }, + [ATHOS_B_6G_LUT_CHAN_617125_IDX] = { 24685, 0x1, 0x44, 0x1238E4, 0x809 }, + [ATHOS_B_6G_LUT_CHAN_617250_IDX] = { 24690, 0x1, 0x44, 0x12AAAB, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617375_IDX] = { 24695, 0x1, 0x44, 0x131C72, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617500_IDX] = { 24700, 0x1, 0x44, 0x138E39, 0x80A }, + [ATHOS_B_6G_LUT_CHAN_617625_IDX] = { 24705, 0x1, 0x44, 0x140000, 0x80B }, + [ATHOS_B_6G_LUT_CHAN_617750_IDX] = { 24710, 0x1, 0x44, 0x1471C7, 0x80B }, + [ATHOS_B_6G_LUT_CHAN_617875_IDX] = { 24715, 0x1, 0x44, 0x14E38E, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618000_IDX] = { 24720, 0x1, 0x44, 0x155555, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618125_IDX] = { 24725, 0x1, 0x44, 0x15C71C, 0x80C }, + [ATHOS_B_6G_LUT_CHAN_618250_IDX] = { 24730, 0x1, 0x44, 0x1638E4, 0x80D }, + [ATHOS_B_6G_LUT_CHAN_618375_IDX] = { 24735, 0x1, 0x44, 0x16AAAB, 0x80D }, + [ATHOS_B_6G_LUT_CHAN_618500_IDX] = { 24740, 0x1, 0x44, 0x171C72, 0x80E }, + [ATHOS_B_6G_LUT_CHAN_618625_IDX] = { 24745, 0x1, 0x44, 0x178E39, 0x80E }, + [ATHOS_B_6G_LUT_CHAN_618750_IDX] = { 24750, 0x1, 0x44, 0x180000, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_618875_IDX] = { 24755, 0x1, 0x44, 0x1871C7, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_619000_IDX] = { 24760, 0x1, 0x44, 0x18E38E, 0x80F }, + [ATHOS_B_6G_LUT_CHAN_619125_IDX] = { 24765, 0x1, 0x44, 0x195555, 0x810 }, + [ATHOS_B_6G_LUT_CHAN_619250_IDX] = { 24770, 0x1, 0x44, 0x19C71C, 0x810 }, + [ATHOS_B_6G_LUT_CHAN_619375_IDX] = { 24775, 0x1, 0x44, 0x1A38E4, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619500_IDX] = { 24780, 0x1, 0x44, 0x1AAAAB, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619625_IDX] = { 24785, 0x1, 0x44, 0x1B1C72, 0x811 }, + [ATHOS_B_6G_LUT_CHAN_619750_IDX] = { 24790, 0x1, 0x44, 0x1B8E39, 0x812 }, + [ATHOS_B_6G_LUT_CHAN_619875_IDX] = { 24795, 0x1, 0x44, 0x1C0000, 0x812 }, + [ATHOS_B_6G_LUT_CHAN_620000_IDX] = { 24800, 0x1, 0x44, 0x1C71C7, 0x813 }, + [ATHOS_B_6G_LUT_CHAN_620125_IDX] = { 24805, 0x1, 0x44, 0x1CE38E, 0x813 }, + [ATHOS_B_6G_LUT_CHAN_620250_IDX] = { 24810, 0x1, 0x44, 0x1D5555, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620375_IDX] = { 24815, 0x1, 0x44, 0x1DC71C, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620500_IDX] = { 24820, 0x1, 0x44, 0x1E38E4, 0x814 }, + [ATHOS_B_6G_LUT_CHAN_620625_IDX] = { 24825, 0x1, 0x44, 0x1EAAAB, 0x815 }, + [ATHOS_B_6G_LUT_CHAN_620750_IDX] = { 24830, 0x1, 0x44, 0x1F1C72, 0x815 }, + [ATHOS_B_6G_LUT_CHAN_620875_IDX] = { 24835, 0x2, 0x44, 0x1F8E39, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621000_IDX] = { 24840, 0x2, 0x45, 0x0, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621125_IDX] = { 24845, 0x2, 0x45, 0x71C7, 0x816 }, + [ATHOS_B_6G_LUT_CHAN_621250_IDX] = { 24850, 0x2, 0x45, 0xE38E, 0x817 }, + [ATHOS_B_6G_LUT_CHAN_621375_IDX] = { 24855, 0x2, 0x45, 0x15555, 0x817 }, + [ATHOS_B_6G_LUT_CHAN_621500_IDX] = { 24860, 0x2, 0x45, 0x1C71C, 0x818 }, + [ATHOS_B_6G_LUT_CHAN_621625_IDX] = { 24865, 0x2, 0x45, 0x238E4, 0x818 }, + [ATHOS_B_6G_LUT_CHAN_621750_IDX] = { 24870, 0x2, 0x45, 0x2AAAB, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_621875_IDX] = { 24875, 0x2, 0x45, 0x31C72, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_622000_IDX] = { 24880, 0x2, 0x45, 0x38E39, 0x819 }, + [ATHOS_B_6G_LUT_CHAN_622125_IDX] = { 24885, 0x2, 0x45, 0x40000, 0x81A }, + [ATHOS_B_6G_LUT_CHAN_622250_IDX] = { 24890, 0x2, 0x45, 0x471C7, 0x81A }, + [ATHOS_B_6G_LUT_CHAN_622375_IDX] = { 24895, 0x2, 0x45, 0x4E38E, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622500_IDX] = { 24900, 0x2, 0x45, 0x55555, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622625_IDX] = { 24905, 0x2, 0x45, 0x5C71C, 0x81B }, + [ATHOS_B_6G_LUT_CHAN_622750_IDX] = { 24910, 0x2, 0x45, 0x638E4, 0x81C }, + [ATHOS_B_6G_LUT_CHAN_622875_IDX] = { 24915, 0x2, 0x45, 0x6AAAB, 0x81C }, + [ATHOS_B_6G_LUT_CHAN_623000_IDX] = { 24920, 0x2, 0x45, 0x71C72, 0x81D }, + [ATHOS_B_6G_LUT_CHAN_623125_IDX] = { 24925, 0x2, 0x45, 0x78E39, 0x81D }, + [ATHOS_B_6G_LUT_CHAN_623250_IDX] = { 24930, 0x2, 0x45, 0x80000, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623375_IDX] = { 24935, 0x2, 0x45, 0x871C7, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623500_IDX] = { 24940, 0x2, 0x45, 0x8E38E, 0x81E }, + [ATHOS_B_6G_LUT_CHAN_623625_IDX] = { 24945, 0x2, 0x45, 0x95555, 0x81F }, + [ATHOS_B_6G_LUT_CHAN_623750_IDX] = { 24950, 0x2, 0x45, 0x9C71C, 0x81F }, + [ATHOS_B_6G_LUT_CHAN_623875_IDX] = { 24955, 0x2, 0x45, 0xA38E4, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624000_IDX] = { 24960, 0x2, 0x45, 0xAAAAB, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624125_IDX] = { 24965, 0x2, 0x45, 0xB1C72, 0x820 }, + [ATHOS_B_6G_LUT_CHAN_624250_IDX] = { 24970, 0x2, 0x45, 0xB8E39, 0x821 }, + [ATHOS_B_6G_LUT_CHAN_624375_IDX] = { 24975, 0x2, 0x45, 0xC0000, 0x821 }, + [ATHOS_B_6G_LUT_CHAN_624500_IDX] = { 24980, 0x2, 0x45, 0xC71C7, 0x822 }, + [ATHOS_B_6G_LUT_CHAN_624625_IDX] = { 24985, 0x2, 0x45, 0xCE38E, 0x822 }, + [ATHOS_B_6G_LUT_CHAN_624750_IDX] = { 24990, 0x2, 0x45, 0xD5555, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_624875_IDX] = { 24995, 0x2, 0x45, 0xDC71C, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_625000_IDX] = { 25000, 0x2, 0x45, 0xE38E4, 0x823 }, + [ATHOS_B_6G_LUT_CHAN_625125_IDX] = { 25005, 0x2, 0x45, 0xEAAAB, 0x824 }, + [ATHOS_B_6G_LUT_CHAN_625250_IDX] = { 25010, 0x2, 0x45, 0xF1C72, 0x824 }, + [ATHOS_B_6G_LUT_CHAN_625375_IDX] = { 25015, 0x2, 0x45, 0xF8E39, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625500_IDX] = { 25020, 0x2, 0x45, 0x100000, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625625_IDX] = { 25025, 0x2, 0x45, 0x1071C7, 0x825 }, + [ATHOS_B_6G_LUT_CHAN_625750_IDX] = { 25030, 0x2, 0x45, 0x10E38E, 0x826 }, + [ATHOS_B_6G_LUT_CHAN_625875_IDX] = { 25035, 0x2, 0x45, 0x115555, 0x826 }, + [ATHOS_B_6G_LUT_CHAN_626000_IDX] = { 25040, 0x2, 0x45, 0x11C71C, 0x827 }, + [ATHOS_B_6G_LUT_CHAN_626125_IDX] = { 25045, 0x2, 0x45, 0x1238E4, 0x827 }, + [ATHOS_B_6G_LUT_CHAN_626250_IDX] = { 25050, 0x2, 0x45, 0x12AAAB, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626375_IDX] = { 25055, 0x2, 0x45, 0x131C72, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626500_IDX] = { 25060, 0x2, 0x45, 0x138E39, 0x828 }, + [ATHOS_B_6G_LUT_CHAN_626625_IDX] = { 25065, 0x2, 0x45, 0x140000, 0x829 }, + [ATHOS_B_6G_LUT_CHAN_626750_IDX] = { 25070, 0x2, 0x45, 0x1471C7, 0x829 }, + [ATHOS_B_6G_LUT_CHAN_626875_IDX] = { 25075, 0x2, 0x45, 0x14E38E, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627000_IDX] = { 25080, 0x2, 0x45, 0x155555, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627125_IDX] = { 25085, 0x2, 0x45, 0x15C71C, 0x82A }, + [ATHOS_B_6G_LUT_CHAN_627250_IDX] = { 25090, 0x2, 0x45, 0x1638E4, 0x82B }, + [ATHOS_B_6G_LUT_CHAN_627375_IDX] = { 25095, 0x2, 0x45, 0x16AAAB, 0x82B }, + [ATHOS_B_6G_LUT_CHAN_627500_IDX] = { 25100, 0x2, 0x45, 0x171C72, 0x82C }, + [ATHOS_B_6G_LUT_CHAN_627625_IDX] = { 25105, 0x2, 0x45, 0x178E39, 0x82C }, + [ATHOS_B_6G_LUT_CHAN_627750_IDX] = { 25110, 0x2, 0x45, 0x180000, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_627875_IDX] = { 25115, 0x2, 0x45, 0x1871C7, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_628000_IDX] = { 25120, 0x2, 0x45, 0x18E38E, 0x82D }, + [ATHOS_B_6G_LUT_CHAN_628125_IDX] = { 25125, 0x2, 0x45, 0x195555, 0x82E }, + [ATHOS_B_6G_LUT_CHAN_628250_IDX] = { 25130, 0x2, 0x45, 0x19C71C, 0x82E }, + [ATHOS_B_6G_LUT_CHAN_628375_IDX] = { 25135, 0x2, 0x45, 0x1A38E4, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628500_IDX] = { 25140, 0x2, 0x45, 0x1AAAAB, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628625_IDX] = { 25145, 0x2, 0x45, 0x1B1C72, 0x82F }, + [ATHOS_B_6G_LUT_CHAN_628750_IDX] = { 25150, 0x2, 0x45, 0x1B8E39, 0x830 }, + [ATHOS_B_6G_LUT_CHAN_628875_IDX] = { 25155, 0x2, 0x45, 0x1C0000, 0x830 }, + [ATHOS_B_6G_LUT_CHAN_629000_IDX] = { 25160, 0x2, 0x45, 0x1C71C7, 0x831 }, + [ATHOS_B_6G_LUT_CHAN_629125_IDX] = { 25165, 0x2, 0x45, 0x1CE38E, 0x831 }, + [ATHOS_B_6G_LUT_CHAN_629250_IDX] = { 25170, 0x2, 0x45, 0x1D5555, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629375_IDX] = { 25175, 0x2, 0x45, 0x1DC71C, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629500_IDX] = { 25180, 0x2, 0x45, 0x1E38E4, 0x832 }, + [ATHOS_B_6G_LUT_CHAN_629625_IDX] = { 25185, 0x2, 0x45, 0x1EAAAB, 0x833 }, + [ATHOS_B_6G_LUT_CHAN_629750_IDX] = { 25190, 0x2, 0x45, 0x1F1C72, 0x833 }, + [ATHOS_B_6G_LUT_CHAN_629875_IDX] = { 25195, 0x2, 0x45, 0x1F8E39, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630000_IDX] = { 25200, 0x2, 0x46, 0x0, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630125_IDX] = { 25205, 0x2, 0x46, 0x71C7, 0x834 }, + [ATHOS_B_6G_LUT_CHAN_630250_IDX] = { 25210, 0x2, 0x46, 0xE38E, 0x835 }, + [ATHOS_B_6G_LUT_CHAN_630375_IDX] = { 25215, 0x2, 0x46, 0x15555, 0x835 }, + [ATHOS_B_6G_LUT_CHAN_630500_IDX] = { 25220, 0x2, 0x46, 0x1C71C, 0x836 }, + [ATHOS_B_6G_LUT_CHAN_630625_IDX] = { 25225, 0x2, 0x46, 0x238E4, 0x836 }, + [ATHOS_B_6G_LUT_CHAN_630750_IDX] = { 25230, 0x2, 0x46, 0x2AAAB, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_630875_IDX] = { 25235, 0x2, 0x46, 0x31C72, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_631000_IDX] = { 25240, 0x2, 0x46, 0x38E39, 0x837 }, + [ATHOS_B_6G_LUT_CHAN_631125_IDX] = { 25245, 0x2, 0x46, 0x40000, 0x838 }, + [ATHOS_B_6G_LUT_CHAN_631250_IDX] = { 25250, 0x2, 0x46, 0x471C7, 0x838 }, + [ATHOS_B_6G_LUT_CHAN_631375_IDX] = { 25255, 0x2, 0x46, 0x4E38E, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631500_IDX] = { 25260, 0x2, 0x46, 0x55555, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631625_IDX] = { 25265, 0x2, 0x46, 0x5C71C, 0x839 }, + [ATHOS_B_6G_LUT_CHAN_631750_IDX] = { 25270, 0x2, 0x46, 0x638E4, 0x83A }, + [ATHOS_B_6G_LUT_CHAN_631875_IDX] = { 25275, 0x2, 0x46, 0x6AAAB, 0x83A }, + [ATHOS_B_6G_LUT_CHAN_632000_IDX] = { 25280, 0x2, 0x46, 0x71C72, 0x83B }, + [ATHOS_B_6G_LUT_CHAN_632125_IDX] = { 25285, 0x2, 0x46, 0x78E39, 0x83B }, + [ATHOS_B_6G_LUT_CHAN_632250_IDX] = { 25290, 0x2, 0x46, 0x80000, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632375_IDX] = { 25295, 0x2, 0x46, 0x871C7, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632500_IDX] = { 25300, 0x2, 0x46, 0x8E38E, 0x83C }, + [ATHOS_B_6G_LUT_CHAN_632625_IDX] = { 25305, 0x2, 0x46, 0x95555, 0x83D }, + [ATHOS_B_6G_LUT_CHAN_632750_IDX] = { 25310, 0x2, 0x46, 0x9C71C, 0x83D }, + [ATHOS_B_6G_LUT_CHAN_632875_IDX] = { 25315, 0x2, 0x46, 0xA38E4, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633000_IDX] = { 25320, 0x2, 0x46, 0xAAAAB, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633125_IDX] = { 25325, 0x2, 0x46, 0xB1C72, 0x83E }, + [ATHOS_B_6G_LUT_CHAN_633250_IDX] = { 25330, 0x2, 0x46, 0xB8E39, 0x83F }, + [ATHOS_B_6G_LUT_CHAN_633375_IDX] = { 25335, 0x2, 0x46, 0xC0000, 0x83F }, + [ATHOS_B_6G_LUT_CHAN_633500_IDX] = { 25340, 0x2, 0x46, 0xC71C7, 0x840 }, + [ATHOS_B_6G_LUT_CHAN_633625_IDX] = { 25345, 0x2, 0x46, 0xCE38E, 0x840 }, + [ATHOS_B_6G_LUT_CHAN_633750_IDX] = { 25350, 0x2, 0x46, 0xD5555, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_633875_IDX] = { 25355, 0x2, 0x46, 0xDC71C, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_634000_IDX] = { 25360, 0x2, 0x46, 0xE38E4, 0x841 }, + [ATHOS_B_6G_LUT_CHAN_634125_IDX] = { 25365, 0x2, 0x46, 0xEAAAB, 0x842 }, + [ATHOS_B_6G_LUT_CHAN_634250_IDX] = { 25370, 0x2, 0x46, 0xF1C72, 0x842 }, + [ATHOS_B_6G_LUT_CHAN_634375_IDX] = { 25375, 0x2, 0x46, 0xF8E39, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634500_IDX] = { 25380, 0x2, 0x46, 0x100000, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634625_IDX] = { 25385, 0x2, 0x46, 0x1071C7, 0x843 }, + [ATHOS_B_6G_LUT_CHAN_634750_IDX] = { 25390, 0x2, 0x46, 0x10E38E, 0x844 }, + [ATHOS_B_6G_LUT_CHAN_634875_IDX] = { 25395, 0x2, 0x46, 0x115555, 0x844 }, + [ATHOS_B_6G_LUT_CHAN_635000_IDX] = { 25400, 0x2, 0x46, 0x11C71C, 0x845 }, + [ATHOS_B_6G_LUT_CHAN_635125_IDX] = { 25405, 0x2, 0x46, 0x1238E4, 0x845 }, + [ATHOS_B_6G_LUT_CHAN_635250_IDX] = { 25410, 0x2, 0x46, 0x12AAAB, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635375_IDX] = { 25415, 0x2, 0x46, 0x131C72, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635500_IDX] = { 25420, 0x2, 0x46, 0x138E39, 0x846 }, + [ATHOS_B_6G_LUT_CHAN_635625_IDX] = { 25425, 0x2, 0x46, 0x140000, 0x847 }, + [ATHOS_B_6G_LUT_CHAN_635750_IDX] = { 25430, 0x2, 0x46, 0x1471C7, 0x847 }, + [ATHOS_B_6G_LUT_CHAN_635875_IDX] = { 25435, 0x2, 0x46, 0x14E38E, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636000_IDX] = { 25440, 0x2, 0x46, 0x155555, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636125_IDX] = { 25445, 0x2, 0x46, 0x15C71C, 0x848 }, + [ATHOS_B_6G_LUT_CHAN_636250_IDX] = { 25450, 0x2, 0x46, 0x1638E4, 0x849 }, + [ATHOS_B_6G_LUT_CHAN_636375_IDX] = { 25455, 0x2, 0x46, 0x16AAAB, 0x849 }, + [ATHOS_B_6G_LUT_CHAN_636500_IDX] = { 25460, 0x2, 0x46, 0x171C72, 0x84A }, + [ATHOS_B_6G_LUT_CHAN_636625_IDX] = { 25465, 0x2, 0x46, 0x178E39, 0x84A }, + [ATHOS_B_6G_LUT_CHAN_636750_IDX] = { 25470, 0x2, 0x46, 0x180000, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_636875_IDX] = { 25475, 0x2, 0x46, 0x1871C7, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_637000_IDX] = { 25480, 0x2, 0x46, 0x18E38E, 0x84B }, + [ATHOS_B_6G_LUT_CHAN_637125_IDX] = { 25485, 0x2, 0x46, 0x195555, 0x84C }, + [ATHOS_B_6G_LUT_CHAN_637250_IDX] = { 25490, 0x2, 0x46, 0x19C71C, 0x84C }, + [ATHOS_B_6G_LUT_CHAN_637375_IDX] = { 25495, 0x2, 0x46, 0x1A38E4, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637500_IDX] = { 25500, 0x2, 0x46, 0x1AAAAB, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637625_IDX] = { 25505, 0x2, 0x46, 0x1B1C72, 0x84D }, + [ATHOS_B_6G_LUT_CHAN_637750_IDX] = { 25510, 0x2, 0x46, 0x1B8E39, 0x84E }, + [ATHOS_B_6G_LUT_CHAN_637875_IDX] = { 25515, 0x2, 0x46, 0x1C0000, 0x84E }, + [ATHOS_B_6G_LUT_CHAN_638000_IDX] = { 25520, 0x2, 0x46, 0x1C71C7, 0x84F }, + [ATHOS_B_6G_LUT_CHAN_638125_IDX] = { 25525, 0x2, 0x46, 0x1CE38E, 0x84F }, + [ATHOS_B_6G_LUT_CHAN_638250_IDX] = { 25530, 0x2, 0x46, 0x1D5555, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638375_IDX] = { 25535, 0x2, 0x46, 0x1DC71C, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638500_IDX] = { 25540, 0x2, 0x46, 0x1E38E4, 0x850 }, + [ATHOS_B_6G_LUT_CHAN_638625_IDX] = { 25545, 0x2, 0x46, 0x1EAAAB, 0x851 }, + [ATHOS_B_6G_LUT_CHAN_638750_IDX] = { 25550, 0x2, 0x46, 0x1F1C72, 0x851 }, + [ATHOS_B_6G_LUT_CHAN_638875_IDX] = { 25555, 0x2, 0x46, 0x1F8E39, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639000_IDX] = { 25560, 0x2, 0x47, 0x0, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639125_IDX] = { 25565, 0x2, 0x47, 0x71C7, 0x852 }, + [ATHOS_B_6G_LUT_CHAN_639250_IDX] = { 25570, 0x2, 0x47, 0xE38E, 0x853 }, + [ATHOS_B_6G_LUT_CHAN_639375_IDX] = { 25575, 0x2, 0x47, 0x15555, 0x853 }, + [ATHOS_B_6G_LUT_CHAN_639500_IDX] = { 25580, 0x2, 0x47, 0x1C71C, 0x854 }, + [ATHOS_B_6G_LUT_CHAN_639625_IDX] = { 25585, 0x2, 0x47, 0x238E4, 0x854 }, + [ATHOS_B_6G_LUT_CHAN_639750_IDX] = { 25590, 0x2, 0x47, 0x2AAAB, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_639875_IDX] = { 25595, 0x2, 0x47, 0x31C72, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_640000_IDX] = { 25600, 0x2, 0x47, 0x38E39, 0x855 }, + [ATHOS_B_6G_LUT_CHAN_640125_IDX] = { 25605, 0x2, 0x47, 0x40000, 0x856 }, + [ATHOS_B_6G_LUT_CHAN_640250_IDX] = { 25610, 0x2, 0x47, 0x471C7, 0x856 }, + [ATHOS_B_6G_LUT_CHAN_640375_IDX] = { 25615, 0x2, 0x47, 0x4E38E, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640500_IDX] = { 25620, 0x2, 0x47, 0x55555, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640625_IDX] = { 25625, 0x2, 0x47, 0x5C71C, 0x857 }, + [ATHOS_B_6G_LUT_CHAN_640750_IDX] = { 25630, 0x2, 0x47, 0x638E4, 0x858 }, + [ATHOS_B_6G_LUT_CHAN_640875_IDX] = { 25635, 0x2, 0x47, 0x6AAAB, 0x858 }, + [ATHOS_B_6G_LUT_CHAN_641000_IDX] = { 25640, 0x2, 0x47, 0x71C72, 0x859 }, + [ATHOS_B_6G_LUT_CHAN_641125_IDX] = { 25645, 0x2, 0x47, 0x78E39, 0x859 }, + [ATHOS_B_6G_LUT_CHAN_641250_IDX] = { 25650, 0x2, 0x47, 0x80000, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641375_IDX] = { 25655, 0x2, 0x47, 0x871C7, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641500_IDX] = { 25660, 0x2, 0x47, 0x8E38E, 0x85A }, + [ATHOS_B_6G_LUT_CHAN_641625_IDX] = { 25665, 0x2, 0x47, 0x95555, 0x85B }, + [ATHOS_B_6G_LUT_CHAN_641750_IDX] = { 25670, 0x2, 0x47, 0x9C71C, 0x85B }, + [ATHOS_B_6G_LUT_CHAN_641875_IDX] = { 25675, 0x2, 0x47, 0xA38E4, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642000_IDX] = { 25680, 0x2, 0x47, 0xAAAAB, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642125_IDX] = { 25685, 0x2, 0x47, 0xB1C72, 0x85C }, + [ATHOS_B_6G_LUT_CHAN_642250_IDX] = { 25690, 0x2, 0x47, 0xB8E39, 0x85D }, + [ATHOS_B_6G_LUT_CHAN_642375_IDX] = { 25695, 0x2, 0x47, 0xC0000, 0x85D }, + [ATHOS_B_6G_LUT_CHAN_642500_IDX] = { 25700, 0x2, 0x47, 0xC71C7, 0x85E }, + [ATHOS_B_6G_LUT_CHAN_642625_IDX] = { 25705, 0x2, 0x47, 0xCE38E, 0x85E }, + [ATHOS_B_6G_LUT_CHAN_642750_IDX] = { 25710, 0x2, 0x47, 0xD5555, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_642875_IDX] = { 25715, 0x2, 0x47, 0xDC71C, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_643000_IDX] = { 25720, 0x2, 0x47, 0xE38E4, 0x85F }, + [ATHOS_B_6G_LUT_CHAN_643125_IDX] = { 25725, 0x2, 0x47, 0xEAAAB, 0x860 }, + [ATHOS_B_6G_LUT_CHAN_643250_IDX] = { 25730, 0x2, 0x47, 0xF1C72, 0x860 }, + [ATHOS_B_6G_LUT_CHAN_643375_IDX] = { 25735, 0x2, 0x47, 0xF8E39, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643500_IDX] = { 25740, 0x2, 0x47, 0x100000, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643625_IDX] = { 25745, 0x2, 0x47, 0x1071C7, 0x861 }, + [ATHOS_B_6G_LUT_CHAN_643750_IDX] = { 25750, 0x2, 0x47, 0x10E38E, 0x862 }, + [ATHOS_B_6G_LUT_CHAN_643875_IDX] = { 25755, 0x2, 0x47, 0x115555, 0x862 }, + [ATHOS_B_6G_LUT_CHAN_644000_IDX] = { 25760, 0x2, 0x47, 0x11C71C, 0x863 }, + [ATHOS_B_6G_LUT_CHAN_644125_IDX] = { 25765, 0x2, 0x47, 0x1238E4, 0x863 }, + [ATHOS_B_6G_LUT_CHAN_644250_IDX] = { 25770, 0x2, 0x47, 0x12AAAB, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644375_IDX] = { 25775, 0x2, 0x47, 0x131C72, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644500_IDX] = { 25780, 0x2, 0x47, 0x138E39, 0x864 }, + [ATHOS_B_6G_LUT_CHAN_644625_IDX] = { 25785, 0x2, 0x47, 0x140000, 0x865 }, + [ATHOS_B_6G_LUT_CHAN_644750_IDX] = { 25790, 0x2, 0x47, 0x1471C7, 0x865 }, + [ATHOS_B_6G_LUT_CHAN_644875_IDX] = { 25795, 0x2, 0x47, 0x14E38E, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645000_IDX] = { 25800, 0x2, 0x47, 0x155555, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645125_IDX] = { 25805, 0x2, 0x47, 0x15C71C, 0x866 }, + [ATHOS_B_6G_LUT_CHAN_645250_IDX] = { 25810, 0x2, 0x47, 0x1638E4, 0x867 }, + [ATHOS_B_6G_LUT_CHAN_645375_IDX] = { 25815, 0x2, 0x47, 0x16AAAB, 0x867 }, + [ATHOS_B_6G_LUT_CHAN_645500_IDX] = { 25820, 0x2, 0x47, 0x171C72, 0x868 }, + [ATHOS_B_6G_LUT_CHAN_645625_IDX] = { 25825, 0x2, 0x47, 0x178E39, 0x868 }, + [ATHOS_B_6G_LUT_CHAN_645750_IDX] = { 25830, 0x2, 0x47, 0x180000, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_645875_IDX] = { 25835, 0x2, 0x47, 0x1871C7, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_646000_IDX] = { 25840, 0x2, 0x47, 0x18E38E, 0x869 }, + [ATHOS_B_6G_LUT_CHAN_646125_IDX] = { 25845, 0x2, 0x47, 0x195555, 0x86A }, + [ATHOS_B_6G_LUT_CHAN_646250_IDX] = { 25850, 0x2, 0x47, 0x19C71C, 0x86A }, + [ATHOS_B_6G_LUT_CHAN_646375_IDX] = { 25855, 0x2, 0x47, 0x1A38E4, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646500_IDX] = { 25860, 0x2, 0x47, 0x1AAAAB, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646625_IDX] = { 25865, 0x2, 0x47, 0x1B1C72, 0x86B }, + [ATHOS_B_6G_LUT_CHAN_646750_IDX] = { 25870, 0x2, 0x47, 0x1B8E39, 0x86C }, + [ATHOS_B_6G_LUT_CHAN_646875_IDX] = { 25875, 0x2, 0x47, 0x1C0000, 0x86C }, + [ATHOS_B_6G_LUT_CHAN_647000_IDX] = { 25880, 0x2, 0x47, 0x1C71C7, 0x86D }, + [ATHOS_B_6G_LUT_CHAN_647125_IDX] = { 25885, 0x2, 0x47, 0x1CE38E, 0x86D }, + [ATHOS_B_6G_LUT_CHAN_647250_IDX] = { 25890, 0x2, 0x47, 0x1D5555, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647375_IDX] = { 25895, 0x2, 0x47, 0x1DC71C, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647500_IDX] = { 25900, 0x2, 0x47, 0x1E38E4, 0x86E }, + [ATHOS_B_6G_LUT_CHAN_647625_IDX] = { 25905, 0x2, 0x47, 0x1EAAAB, 0x86F }, + [ATHOS_B_6G_LUT_CHAN_647750_IDX] = { 25910, 0x2, 0x47, 0x1F1C72, 0x86F }, + [ATHOS_B_6G_LUT_CHAN_647875_IDX] = { 25915, 0x2, 0x47, 0x1F8E39, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648000_IDX] = { 25920, 0x2, 0x48, 0x0, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648125_IDX] = { 25925, 0x2, 0x48, 0x71C7, 0x870 }, + [ATHOS_B_6G_LUT_CHAN_648250_IDX] = { 25930, 0x2, 0x48, 0xE38E, 0x871 }, + [ATHOS_B_6G_LUT_CHAN_648375_IDX] = { 25935, 0x2, 0x48, 0x15555, 0x871 }, + [ATHOS_B_6G_LUT_CHAN_648500_IDX] = { 25940, 0x2, 0x48, 0x1C71C, 0x872 }, + [ATHOS_B_6G_LUT_CHAN_648625_IDX] = { 25945, 0x2, 0x48, 0x238E4, 0x872 }, + [ATHOS_B_6G_LUT_CHAN_648750_IDX] = { 25950, 0x2, 0x48, 0x2AAAB, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_648875_IDX] = { 25955, 0x2, 0x48, 0x31C72, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_649000_IDX] = { 25960, 0x2, 0x48, 0x38E39, 0x873 }, + [ATHOS_B_6G_LUT_CHAN_649125_IDX] = { 25965, 0x2, 0x48, 0x40000, 0x874 }, + [ATHOS_B_6G_LUT_CHAN_649250_IDX] = { 25970, 0x2, 0x48, 0x471C7, 0x874 }, + [ATHOS_B_6G_LUT_CHAN_649375_IDX] = { 25975, 0x2, 0x48, 0x4E38E, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649500_IDX] = { 25980, 0x2, 0x48, 0x55555, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649625_IDX] = { 25985, 0x2, 0x48, 0x5C71C, 0x875 }, + [ATHOS_B_6G_LUT_CHAN_649750_IDX] = { 25990, 0x2, 0x48, 0x638E4, 0x876 }, + [ATHOS_B_6G_LUT_CHAN_649875_IDX] = { 25995, 0x2, 0x48, 0x6AAAB, 0x876 }, + [ATHOS_B_6G_LUT_CHAN_650000_IDX] = { 26000, 0x2, 0x48, 0x71C72, 0x877 }, + [ATHOS_B_6G_LUT_CHAN_650125_IDX] = { 26005, 0x2, 0x48, 0x78E39, 0x877 }, + [ATHOS_B_6G_LUT_CHAN_650250_IDX] = { 26010, 0x2, 0x48, 0x80000, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650375_IDX] = { 26015, 0x2, 0x48, 0x871C7, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650500_IDX] = { 26020, 0x2, 0x48, 0x8E38E, 0x878 }, + [ATHOS_B_6G_LUT_CHAN_650625_IDX] = { 26025, 0x2, 0x48, 0x95555, 0x879 }, + [ATHOS_B_6G_LUT_CHAN_650750_IDX] = { 26030, 0x2, 0x48, 0x9C71C, 0x879 }, + [ATHOS_B_6G_LUT_CHAN_650875_IDX] = { 26035, 0x2, 0x48, 0xA38E4, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651000_IDX] = { 26040, 0x2, 0x48, 0xAAAAB, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651125_IDX] = { 26045, 0x2, 0x48, 0xB1C72, 0x87A }, + [ATHOS_B_6G_LUT_CHAN_651250_IDX] = { 26050, 0x2, 0x48, 0xB8E39, 0x87B }, + [ATHOS_B_6G_LUT_CHAN_651375_IDX] = { 26055, 0x2, 0x48, 0xC0000, 0x87B }, + [ATHOS_B_6G_LUT_CHAN_651500_IDX] = { 26060, 0x2, 0x48, 0xC71C7, 0x87C }, + [ATHOS_B_6G_LUT_CHAN_651625_IDX] = { 26065, 0x2, 0x48, 0xCE38E, 0x87C }, + [ATHOS_B_6G_LUT_CHAN_651750_IDX] = { 26070, 0x2, 0x48, 0xD5555, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_651875_IDX] = { 26075, 0x2, 0x48, 0xDC71C, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_652000_IDX] = { 26080, 0x2, 0x48, 0xE38E4, 0x87D }, + [ATHOS_B_6G_LUT_CHAN_652125_IDX] = { 26085, 0x2, 0x48, 0xEAAAB, 0x87E }, + [ATHOS_B_6G_LUT_CHAN_652250_IDX] = { 26090, 0x2, 0x48, 0xF1C72, 0x87E }, + [ATHOS_B_6G_LUT_CHAN_652375_IDX] = { 26095, 0x2, 0x48, 0xF8E39, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652500_IDX] = { 26100, 0x2, 0x48, 0x100000, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652625_IDX] = { 26105, 0x2, 0x48, 0x1071C7, 0x87F }, + [ATHOS_B_6G_LUT_CHAN_652750_IDX] = { 26110, 0x2, 0x48, 0x10E38E, 0x880 }, + [ATHOS_B_6G_LUT_CHAN_652875_IDX] = { 26115, 0x2, 0x48, 0x115555, 0x880 }, + [ATHOS_B_6G_LUT_CHAN_653000_IDX] = { 26120, 0x2, 0x48, 0x11C71C, 0x881 }, + [ATHOS_B_6G_LUT_CHAN_653125_IDX] = { 26125, 0x2, 0x48, 0x1238E4, 0x881 }, + [ATHOS_B_6G_LUT_CHAN_653250_IDX] = { 26130, 0x2, 0x48, 0x12AAAB, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653375_IDX] = { 26135, 0x2, 0x48, 0x131C72, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653500_IDX] = { 26140, 0x2, 0x48, 0x138E39, 0x882 }, + [ATHOS_B_6G_LUT_CHAN_653625_IDX] = { 26145, 0x2, 0x48, 0x140000, 0x883 }, + [ATHOS_B_6G_LUT_CHAN_653750_IDX] = { 26150, 0x2, 0x48, 0x1471C7, 0x883 }, + [ATHOS_B_6G_LUT_CHAN_653875_IDX] = { 26155, 0x2, 0x48, 0x14E38E, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654000_IDX] = { 26160, 0x2, 0x48, 0x155555, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654125_IDX] = { 26165, 0x2, 0x48, 0x15C71C, 0x884 }, + [ATHOS_B_6G_LUT_CHAN_654250_IDX] = { 26170, 0x2, 0x48, 0x1638E4, 0x885 }, + [ATHOS_B_6G_LUT_CHAN_654375_IDX] = { 26175, 0x2, 0x48, 0x16AAAB, 0x885 }, + [ATHOS_B_6G_LUT_CHAN_654500_IDX] = { 26180, 0x2, 0x48, 0x171C72, 0x886 }, + [ATHOS_B_6G_LUT_CHAN_654625_IDX] = { 26185, 0x2, 0x48, 0x178E39, 0x886 }, + [ATHOS_B_6G_LUT_CHAN_654750_IDX] = { 26190, 0x2, 0x48, 0x180000, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_654875_IDX] = { 26195, 0x2, 0x48, 0x1871C7, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_655000_IDX] = { 26200, 0x2, 0x48, 0x18E38E, 0x887 }, + [ATHOS_B_6G_LUT_CHAN_655125_IDX] = { 26205, 0x2, 0x48, 0x195555, 0x888 }, + [ATHOS_B_6G_LUT_CHAN_655250_IDX] = { 26210, 0x2, 0x48, 0x19C71C, 0x888 }, + [ATHOS_B_6G_LUT_CHAN_655375_IDX] = { 26215, 0x2, 0x48, 0x1A38E4, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655500_IDX] = { 26220, 0x2, 0x48, 0x1AAAAB, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655625_IDX] = { 26225, 0x2, 0x48, 0x1B1C72, 0x889 }, + [ATHOS_B_6G_LUT_CHAN_655750_IDX] = { 26230, 0x2, 0x48, 0x1B8E39, 0x88A }, + [ATHOS_B_6G_LUT_CHAN_655875_IDX] = { 26235, 0x2, 0x48, 0x1C0000, 0x88A }, + [ATHOS_B_6G_LUT_CHAN_656000_IDX] = { 26240, 0x2, 0x48, 0x1C71C7, 0x88B }, + [ATHOS_B_6G_LUT_CHAN_656125_IDX] = { 26245, 0x2, 0x48, 0x1CE38E, 0x88B }, + [ATHOS_B_6G_LUT_CHAN_656250_IDX] = { 26250, 0x2, 0x48, 0x1D5555, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656375_IDX] = { 26255, 0x2, 0x48, 0x1DC71C, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656500_IDX] = { 26260, 0x2, 0x48, 0x1E38E4, 0x88C }, + [ATHOS_B_6G_LUT_CHAN_656625_IDX] = { 26265, 0x2, 0x48, 0x1EAAAB, 0x88D }, + [ATHOS_B_6G_LUT_CHAN_656750_IDX] = { 26270, 0x2, 0x48, 0x1F1C72, 0x88D }, + [ATHOS_B_6G_LUT_CHAN_656875_IDX] = { 26275, 0x2, 0x48, 0x1F8E39, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657000_IDX] = { 26280, 0x2, 0x49, 0x0, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657125_IDX] = { 26285, 0x2, 0x49, 0x71C7, 0x88E }, + [ATHOS_B_6G_LUT_CHAN_657250_IDX] = { 26290, 0x2, 0x49, 0xE38E, 0x88F }, + [ATHOS_B_6G_LUT_CHAN_657375_IDX] = { 26295, 0x2, 0x49, 0x15555, 0x88F }, + [ATHOS_B_6G_LUT_CHAN_657500_IDX] = { 26300, 0x2, 0x49, 0x1C71C, 0x890 }, + [ATHOS_B_6G_LUT_CHAN_657625_IDX] = { 26305, 0x2, 0x49, 0x238E4, 0x890 }, + [ATHOS_B_6G_LUT_CHAN_657750_IDX] = { 26310, 0x2, 0x49, 0x2AAAB, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_657875_IDX] = { 26315, 0x2, 0x49, 0x31C72, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_658000_IDX] = { 26320, 0x2, 0x49, 0x38E39, 0x891 }, + [ATHOS_B_6G_LUT_CHAN_658125_IDX] = { 26325, 0x2, 0x49, 0x40000, 0x892 }, + [ATHOS_B_6G_LUT_CHAN_658250_IDX] = { 26330, 0x2, 0x49, 0x471C7, 0x892 }, + [ATHOS_B_6G_LUT_CHAN_658375_IDX] = { 26335, 0x2, 0x49, 0x4E38E, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658500_IDX] = { 26340, 0x2, 0x49, 0x55555, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658625_IDX] = { 26345, 0x2, 0x49, 0x5C71C, 0x893 }, + [ATHOS_B_6G_LUT_CHAN_658750_IDX] = { 26350, 0x2, 0x49, 0x638E4, 0x894 }, + [ATHOS_B_6G_LUT_CHAN_658875_IDX] = { 26355, 0x2, 0x49, 0x6AAAB, 0x894 }, + [ATHOS_B_6G_LUT_CHAN_659000_IDX] = { 26360, 0x2, 0x49, 0x71C72, 0x895 }, + [ATHOS_B_6G_LUT_CHAN_659125_IDX] = { 26365, 0x2, 0x49, 0x78E39, 0x895 }, + [ATHOS_B_6G_LUT_CHAN_659250_IDX] = { 26370, 0x2, 0x49, 0x80000, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659375_IDX] = { 26375, 0x2, 0x49, 0x871C7, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659500_IDX] = { 26380, 0x2, 0x49, 0x8E38E, 0x896 }, + [ATHOS_B_6G_LUT_CHAN_659625_IDX] = { 26385, 0x2, 0x49, 0x95555, 0x897 }, + [ATHOS_B_6G_LUT_CHAN_659750_IDX] = { 26390, 0x2, 0x49, 0x9C71C, 0x897 }, + [ATHOS_B_6G_LUT_CHAN_659875_IDX] = { 26395, 0x2, 0x49, 0xA38E4, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660000_IDX] = { 26400, 0x2, 0x49, 0xAAAAB, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660125_IDX] = { 26405, 0x2, 0x49, 0xB1C72, 0x898 }, + [ATHOS_B_6G_LUT_CHAN_660250_IDX] = { 26410, 0x2, 0x49, 0xB8E39, 0x899 }, + [ATHOS_B_6G_LUT_CHAN_660375_IDX] = { 26415, 0x2, 0x49, 0xC0000, 0x899 }, + [ATHOS_B_6G_LUT_CHAN_660500_IDX] = { 26420, 0x2, 0x49, 0xC71C7, 0x89A }, + [ATHOS_B_6G_LUT_CHAN_660625_IDX] = { 26425, 0x2, 0x49, 0xCE38E, 0x89A }, + [ATHOS_B_6G_LUT_CHAN_660750_IDX] = { 26430, 0x2, 0x49, 0xD5555, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_660875_IDX] = { 26435, 0x2, 0x49, 0xDC71C, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_661000_IDX] = { 26440, 0x2, 0x49, 0xE38E4, 0x89B }, + [ATHOS_B_6G_LUT_CHAN_661125_IDX] = { 26445, 0x2, 0x49, 0xEAAAB, 0x89C }, + [ATHOS_B_6G_LUT_CHAN_661250_IDX] = { 26450, 0x2, 0x49, 0xF1C72, 0x89C }, + [ATHOS_B_6G_LUT_CHAN_661375_IDX] = { 26455, 0x2, 0x49, 0xF8E39, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661500_IDX] = { 26460, 0x2, 0x49, 0x100000, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661625_IDX] = { 26465, 0x2, 0x49, 0x1071C7, 0x89D }, + [ATHOS_B_6G_LUT_CHAN_661750_IDX] = { 26470, 0x2, 0x49, 0x10E38E, 0x89E }, + [ATHOS_B_6G_LUT_CHAN_661875_IDX] = { 26475, 0x2, 0x49, 0x115555, 0x89E }, + [ATHOS_B_6G_LUT_CHAN_662000_IDX] = { 26480, 0x2, 0x49, 0x11C71C, 0x89F }, + [ATHOS_B_6G_LUT_CHAN_662125_IDX] = { 26485, 0x2, 0x49, 0x1238E4, 0x89F }, + [ATHOS_B_6G_LUT_CHAN_662250_IDX] = { 26490, 0x2, 0x49, 0x12AAAB, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662375_IDX] = { 26495, 0x2, 0x49, 0x131C72, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662500_IDX] = { 26500, 0x2, 0x49, 0x138E39, 0x8A0 }, + [ATHOS_B_6G_LUT_CHAN_662625_IDX] = { 26505, 0x2, 0x49, 0x140000, 0x8A1 }, + [ATHOS_B_6G_LUT_CHAN_662750_IDX] = { 26510, 0x2, 0x49, 0x1471C7, 0x8A1 }, + [ATHOS_B_6G_LUT_CHAN_662875_IDX] = { 26515, 0x2, 0x49, 0x14E38E, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663000_IDX] = { 26520, 0x2, 0x49, 0x155555, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663125_IDX] = { 26525, 0x2, 0x49, 0x15C71C, 0x8A2 }, + [ATHOS_B_6G_LUT_CHAN_663250_IDX] = { 26530, 0x2, 0x49, 0x1638E4, 0x8A3 }, + [ATHOS_B_6G_LUT_CHAN_663375_IDX] = { 26535, 0x2, 0x49, 0x16AAAB, 0x8A3 }, + [ATHOS_B_6G_LUT_CHAN_663500_IDX] = { 26540, 0x2, 0x49, 0x171C72, 0x8A4 }, + [ATHOS_B_6G_LUT_CHAN_663625_IDX] = { 26545, 0x2, 0x49, 0x178E39, 0x8A4 }, + [ATHOS_B_6G_LUT_CHAN_663750_IDX] = { 26550, 0x2, 0x49, 0x180000, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_663875_IDX] = { 26555, 0x2, 0x49, 0x1871C7, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_664000_IDX] = { 26560, 0x2, 0x49, 0x18E38E, 0x8A5 }, + [ATHOS_B_6G_LUT_CHAN_664125_IDX] = { 26565, 0x2, 0x49, 0x195555, 0x8A6 }, + [ATHOS_B_6G_LUT_CHAN_664250_IDX] = { 26570, 0x2, 0x49, 0x19C71C, 0x8A6 }, + [ATHOS_B_6G_LUT_CHAN_664375_IDX] = { 26575, 0x2, 0x49, 0x1A38E4, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664500_IDX] = { 26580, 0x2, 0x49, 0x1AAAAB, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664625_IDX] = { 26585, 0x2, 0x49, 0x1B1C72, 0x8A7 }, + [ATHOS_B_6G_LUT_CHAN_664750_IDX] = { 26590, 0x2, 0x49, 0x1B8E39, 0x8A8 }, + [ATHOS_B_6G_LUT_CHAN_664875_IDX] = { 26595, 0x2, 0x49, 0x1C0000, 0x8A8 }, + [ATHOS_B_6G_LUT_CHAN_665000_IDX] = { 26600, 0x2, 0x49, 0x1C71C7, 0x8A9 }, + [ATHOS_B_6G_LUT_CHAN_665125_IDX] = { 26605, 0x2, 0x49, 0x1CE38E, 0x8A9 }, + [ATHOS_B_6G_LUT_CHAN_665250_IDX] = { 26610, 0x2, 0x49, 0x1D5555, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665375_IDX] = { 26615, 0x2, 0x49, 0x1DC71C, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665500_IDX] = { 26620, 0x2, 0x49, 0x1E38E4, 0x8AA }, + [ATHOS_B_6G_LUT_CHAN_665625_IDX] = { 26625, 0x2, 0x49, 0x1EAAAB, 0x8AB }, + [ATHOS_B_6G_LUT_CHAN_665750_IDX] = { 26630, 0x2, 0x49, 0x1F1C72, 0x8AB }, + [ATHOS_B_6G_LUT_CHAN_665875_IDX] = { 26635, 0x2, 0x49, 0x1F8E39, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666000_IDX] = { 26640, 0x2, 0x4A, 0x0, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666125_IDX] = { 26645, 0x2, 0x4A, 0x71C7, 0x8AC }, + [ATHOS_B_6G_LUT_CHAN_666250_IDX] = { 26650, 0x2, 0x4A, 0xE38E, 0x8AD }, + [ATHOS_B_6G_LUT_CHAN_666375_IDX] = { 26655, 0x2, 0x4A, 0x15555, 0x8AD }, + [ATHOS_B_6G_LUT_CHAN_666500_IDX] = { 26660, 0x2, 0x4A, 0x1C71C, 0x8AE }, + [ATHOS_B_6G_LUT_CHAN_666625_IDX] = { 26665, 0x2, 0x4A, 0x238E4, 0x8AE }, + [ATHOS_B_6G_LUT_CHAN_666750_IDX] = { 26670, 0x2, 0x4A, 0x2AAAB, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_666875_IDX] = { 26675, 0x2, 0x4A, 0x31C72, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_667000_IDX] = { 26680, 0x2, 0x4A, 0x38E39, 0x8AF }, + [ATHOS_B_6G_LUT_CHAN_667125_IDX] = { 26685, 0x2, 0x4A, 0x40000, 0x8B0 }, + [ATHOS_B_6G_LUT_CHAN_667250_IDX] = { 26690, 0x2, 0x4A, 0x471C7, 0x8B0 }, + [ATHOS_B_6G_LUT_CHAN_667375_IDX] = { 26695, 0x2, 0x4A, 0x4E38E, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667500_IDX] = { 26700, 0x2, 0x4A, 0x55555, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667625_IDX] = { 26705, 0x2, 0x4A, 0x5C71C, 0x8B1 }, + [ATHOS_B_6G_LUT_CHAN_667750_IDX] = { 26710, 0x2, 0x4A, 0x638E4, 0x8B2 }, + [ATHOS_B_6G_LUT_CHAN_667875_IDX] = { 26715, 0x2, 0x4A, 0x6AAAB, 0x8B2 }, + [ATHOS_B_6G_LUT_CHAN_668000_IDX] = { 26720, 0x2, 0x4A, 0x71C72, 0x8B3 }, + [ATHOS_B_6G_LUT_CHAN_668125_IDX] = { 26725, 0x2, 0x4A, 0x78E39, 0x8B3 }, + [ATHOS_B_6G_LUT_CHAN_668250_IDX] = { 26730, 0x2, 0x4A, 0x80000, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668375_IDX] = { 26735, 0x2, 0x4A, 0x871C7, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668500_IDX] = { 26740, 0x2, 0x4A, 0x8E38E, 0x8B4 }, + [ATHOS_B_6G_LUT_CHAN_668625_IDX] = { 26745, 0x2, 0x4A, 0x95555, 0x8B5 }, + [ATHOS_B_6G_LUT_CHAN_668750_IDX] = { 26750, 0x2, 0x4A, 0x9C71C, 0x8B5 }, + [ATHOS_B_6G_LUT_CHAN_668875_IDX] = { 26755, 0x2, 0x4A, 0xA38E4, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669000_IDX] = { 26760, 0x2, 0x4A, 0xAAAAB, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669125_IDX] = { 26765, 0x2, 0x4A, 0xB1C72, 0x8B6 }, + [ATHOS_B_6G_LUT_CHAN_669250_IDX] = { 26770, 0x2, 0x4A, 0xB8E39, 0x8B7 }, + [ATHOS_B_6G_LUT_CHAN_669375_IDX] = { 26775, 0x2, 0x4A, 0xC0000, 0x8B7 }, + [ATHOS_B_6G_LUT_CHAN_669500_IDX] = { 26780, 0x2, 0x4A, 0xC71C7, 0x8B8 }, + [ATHOS_B_6G_LUT_CHAN_669625_IDX] = { 26785, 0x2, 0x4A, 0xCE38E, 0x8B8 }, + [ATHOS_B_6G_LUT_CHAN_669750_IDX] = { 26790, 0x2, 0x4A, 0xD5555, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_669875_IDX] = { 26795, 0x2, 0x4A, 0xDC71C, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_670000_IDX] = { 26800, 0x2, 0x4A, 0xE38E4, 0x8B9 }, + [ATHOS_B_6G_LUT_CHAN_670125_IDX] = { 26805, 0x2, 0x4A, 0xEAAAB, 0x8BA }, + [ATHOS_B_6G_LUT_CHAN_670250_IDX] = { 26810, 0x2, 0x4A, 0xF1C72, 0x8BA }, + [ATHOS_B_6G_LUT_CHAN_670375_IDX] = { 26815, 0x2, 0x4A, 0xF8E39, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670500_IDX] = { 26820, 0x2, 0x4A, 0x100000, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670625_IDX] = { 26825, 0x2, 0x4A, 0x1071C7, 0x8BB }, + [ATHOS_B_6G_LUT_CHAN_670750_IDX] = { 26830, 0x2, 0x4A, 0x10E38E, 0x8BC }, + [ATHOS_B_6G_LUT_CHAN_670875_IDX] = { 26835, 0x2, 0x4A, 0x115555, 0x8BC }, + [ATHOS_B_6G_LUT_CHAN_671000_IDX] = { 26840, 0x2, 0x4A, 0x11C71C, 0x8BD }, + [ATHOS_B_6G_LUT_CHAN_671125_IDX] = { 26845, 0x2, 0x4A, 0x1238E4, 0x8BD }, + [ATHOS_B_6G_LUT_CHAN_671250_IDX] = { 26850, 0x2, 0x4A, 0x12AAAB, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671375_IDX] = { 26855, 0x2, 0x4A, 0x131C72, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671500_IDX] = { 26860, 0x2, 0x4A, 0x138E39, 0x8BE }, + [ATHOS_B_6G_LUT_CHAN_671625_IDX] = { 26865, 0x2, 0x4A, 0x140000, 0x8BF }, + [ATHOS_B_6G_LUT_CHAN_671750_IDX] = { 26870, 0x2, 0x4A, 0x1471C7, 0x8BF }, + [ATHOS_B_6G_LUT_CHAN_671875_IDX] = { 26875, 0x2, 0x4A, 0x14E38E, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672000_IDX] = { 26880, 0x2, 0x4A, 0x155555, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672125_IDX] = { 26885, 0x2, 0x4A, 0x15C71C, 0x8C0 }, + [ATHOS_B_6G_LUT_CHAN_672250_IDX] = { 26890, 0x2, 0x4A, 0x1638E4, 0x8C1 }, + [ATHOS_B_6G_LUT_CHAN_672375_IDX] = { 26895, 0x2, 0x4A, 0x16AAAB, 0x8C1 }, + [ATHOS_B_6G_LUT_CHAN_672500_IDX] = { 26900, 0x2, 0x4A, 0x171C72, 0x8C2 }, + [ATHOS_B_6G_LUT_CHAN_672625_IDX] = { 26905, 0x2, 0x4A, 0x178E39, 0x8C2 }, + [ATHOS_B_6G_LUT_CHAN_672750_IDX] = { 26910, 0x2, 0x4A, 0x180000, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_672875_IDX] = { 26915, 0x2, 0x4A, 0x1871C7, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_673000_IDX] = { 26920, 0x2, 0x4A, 0x18E38E, 0x8C3 }, + [ATHOS_B_6G_LUT_CHAN_673125_IDX] = { 26925, 0x2, 0x4A, 0x195555, 0x8C4 }, + [ATHOS_B_6G_LUT_CHAN_673250_IDX] = { 26930, 0x2, 0x4A, 0x19C71C, 0x8C4 }, + [ATHOS_B_6G_LUT_CHAN_673375_IDX] = { 26935, 0x2, 0x4A, 0x1A38E4, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673500_IDX] = { 26940, 0x2, 0x4A, 0x1AAAAB, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673625_IDX] = { 26945, 0x2, 0x4A, 0x1B1C72, 0x8C5 }, + [ATHOS_B_6G_LUT_CHAN_673750_IDX] = { 26950, 0x2, 0x4A, 0x1B8E39, 0x8C6 }, + [ATHOS_B_6G_LUT_CHAN_673875_IDX] = { 26955, 0x2, 0x4A, 0x1C0000, 0x8C6 }, + [ATHOS_B_6G_LUT_CHAN_674000_IDX] = { 26960, 0x2, 0x4A, 0x1C71C7, 0x8C7 }, + [ATHOS_B_6G_LUT_CHAN_674125_IDX] = { 26965, 0x2, 0x4A, 0x1CE38E, 0x8C7 }, + [ATHOS_B_6G_LUT_CHAN_674250_IDX] = { 26970, 0x2, 0x4A, 0x1D5555, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674375_IDX] = { 26975, 0x2, 0x4A, 0x1DC71C, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674500_IDX] = { 26980, 0x2, 0x4A, 0x1E38E4, 0x8C8 }, + [ATHOS_B_6G_LUT_CHAN_674625_IDX] = { 26985, 0x2, 0x4A, 0x1EAAAB, 0x8C9 }, + [ATHOS_B_6G_LUT_CHAN_674750_IDX] = { 26990, 0x2, 0x4A, 0x1F1C72, 0x8C9 }, + [ATHOS_B_6G_LUT_CHAN_674875_IDX] = { 26995, 0x2, 0x4A, 0x1F8E39, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675000_IDX] = { 27000, 0x2, 0x4B, 0x0, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675125_IDX] = { 27005, 0x2, 0x4B, 0x71C7, 0x8CA }, + [ATHOS_B_6G_LUT_CHAN_675250_IDX] = { 27010, 0x2, 0x4B, 0xE38E, 0x8CB }, + [ATHOS_B_6G_LUT_CHAN_675375_IDX] = { 27015, 0x2, 0x4B, 0x15555, 0x8CB }, + [ATHOS_B_6G_LUT_CHAN_675500_IDX] = { 27020, 0x2, 0x4B, 0x1C71C, 0x8CC }, + [ATHOS_B_6G_LUT_CHAN_675625_IDX] = { 27025, 0x2, 0x4B, 0x238E4, 0x8CC }, + [ATHOS_B_6G_LUT_CHAN_675750_IDX] = { 27030, 0x2, 0x4B, 0x2AAAB, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_675875_IDX] = { 27035, 0x2, 0x4B, 0x31C72, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_676000_IDX] = { 27040, 0x2, 0x4B, 0x38E39, 0x8CD }, + [ATHOS_B_6G_LUT_CHAN_676125_IDX] = { 27045, 0x2, 0x4B, 0x40000, 0x8CE }, + [ATHOS_B_6G_LUT_CHAN_676250_IDX] = { 27050, 0x2, 0x4B, 0x471C7, 0x8CE }, + [ATHOS_B_6G_LUT_CHAN_676375_IDX] = { 27055, 0x2, 0x4B, 0x4E38E, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676500_IDX] = { 27060, 0x2, 0x4B, 0x55555, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676625_IDX] = { 27065, 0x2, 0x4B, 0x5C71C, 0x8CF }, + [ATHOS_B_6G_LUT_CHAN_676750_IDX] = { 27070, 0x2, 0x4B, 0x638E4, 0x8D0 }, + [ATHOS_B_6G_LUT_CHAN_676875_IDX] = { 27075, 0x2, 0x4B, 0x6AAAB, 0x8D0 }, + [ATHOS_B_6G_LUT_CHAN_677000_IDX] = { 27080, 0x2, 0x4B, 0x71C72, 0x8D1 }, + [ATHOS_B_6G_LUT_CHAN_677125_IDX] = { 27085, 0x2, 0x4B, 0x78E39, 0x8D1 }, + [ATHOS_B_6G_LUT_CHAN_677250_IDX] = { 27090, 0x2, 0x4B, 0x80000, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677375_IDX] = { 27095, 0x2, 0x4B, 0x871C7, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677500_IDX] = { 27100, 0x2, 0x4B, 0x8E38E, 0x8D2 }, + [ATHOS_B_6G_LUT_CHAN_677625_IDX] = { 27105, 0x2, 0x4B, 0x95555, 0x8D3 }, + [ATHOS_B_6G_LUT_CHAN_677750_IDX] = { 27110, 0x2, 0x4B, 0x9C71C, 0x8D3 }, + [ATHOS_B_6G_LUT_CHAN_677875_IDX] = { 27115, 0x2, 0x4B, 0xA38E4, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678000_IDX] = { 27120, 0x2, 0x4B, 0xAAAAB, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678125_IDX] = { 27125, 0x2, 0x4B, 0xB1C72, 0x8D4 }, + [ATHOS_B_6G_LUT_CHAN_678250_IDX] = { 27130, 0x2, 0x4B, 0xB8E39, 0x8D5 }, + [ATHOS_B_6G_LUT_CHAN_678375_IDX] = { 27135, 0x2, 0x4B, 0xC0000, 0x8D5 }, + [ATHOS_B_6G_LUT_CHAN_678500_IDX] = { 27140, 0x2, 0x4B, 0xC71C7, 0x8D6 }, + [ATHOS_B_6G_LUT_CHAN_678625_IDX] = { 27145, 0x2, 0x4B, 0xCE38E, 0x8D6 }, + [ATHOS_B_6G_LUT_CHAN_678750_IDX] = { 27150, 0x2, 0x4B, 0xD5555, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_678875_IDX] = { 27155, 0x2, 0x4B, 0xDC71C, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_679000_IDX] = { 27160, 0x2, 0x4B, 0xE38E4, 0x8D7 }, + [ATHOS_B_6G_LUT_CHAN_679125_IDX] = { 27165, 0x2, 0x4B, 0xEAAAB, 0x8D8 }, + [ATHOS_B_6G_LUT_CHAN_679250_IDX] = { 27170, 0x2, 0x4B, 0xF1C72, 0x8D8 }, + [ATHOS_B_6G_LUT_CHAN_679375_IDX] = { 27175, 0x2, 0x4B, 0xF8E39, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679500_IDX] = { 27180, 0x2, 0x4B, 0x100000, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679625_IDX] = { 27185, 0x2, 0x4B, 0x1071C7, 0x8D9 }, + [ATHOS_B_6G_LUT_CHAN_679750_IDX] = { 27190, 0x2, 0x4B, 0x10E38E, 0x8DA }, + [ATHOS_B_6G_LUT_CHAN_679875_IDX] = { 27195, 0x2, 0x4B, 0x115555, 0x8DA }, + [ATHOS_B_6G_LUT_CHAN_680000_IDX] = { 27200, 0x2, 0x4B, 0x11C71C, 0x8DB }, + [ATHOS_B_6G_LUT_CHAN_680125_IDX] = { 27205, 0x2, 0x4B, 0x1238E4, 0x8DB }, + [ATHOS_B_6G_LUT_CHAN_680250_IDX] = { 27210, 0x2, 0x4B, 0x12AAAB, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680375_IDX] = { 27215, 0x2, 0x4B, 0x131C72, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680500_IDX] = { 27220, 0x2, 0x4B, 0x138E39, 0x8DC }, + [ATHOS_B_6G_LUT_CHAN_680625_IDX] = { 27225, 0x2, 0x4B, 0x140000, 0x8DD }, + [ATHOS_B_6G_LUT_CHAN_680750_IDX] = { 27230, 0x2, 0x4B, 0x1471C7, 0x8DD }, + [ATHOS_B_6G_LUT_CHAN_680875_IDX] = { 27235, 0x2, 0x4B, 0x14E38E, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681000_IDX] = { 27240, 0x2, 0x4B, 0x155555, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681125_IDX] = { 27245, 0x2, 0x4B, 0x15C71C, 0x8DE }, + [ATHOS_B_6G_LUT_CHAN_681250_IDX] = { 27250, 0x2, 0x4B, 0x1638E4, 0x8DF }, + [ATHOS_B_6G_LUT_CHAN_681375_IDX] = { 27255, 0x2, 0x4B, 0x16AAAB, 0x8DF }, + [ATHOS_B_6G_LUT_CHAN_681500_IDX] = { 27260, 0x2, 0x4B, 0x171C72, 0x8E0 }, + [ATHOS_B_6G_LUT_CHAN_681625_IDX] = { 27265, 0x2, 0x4B, 0x178E39, 0x8E0 }, + [ATHOS_B_6G_LUT_CHAN_681750_IDX] = { 27270, 0x2, 0x4B, 0x180000, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_681875_IDX] = { 27275, 0x2, 0x4B, 0x1871C7, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_682000_IDX] = { 27280, 0x2, 0x4B, 0x18E38E, 0x8E1 }, + [ATHOS_B_6G_LUT_CHAN_682125_IDX] = { 27285, 0x2, 0x4B, 0x195555, 0x8E2 }, + [ATHOS_B_6G_LUT_CHAN_682250_IDX] = { 27290, 0x2, 0x4B, 0x19C71C, 0x8E2 }, + [ATHOS_B_6G_LUT_CHAN_682375_IDX] = { 27295, 0x2, 0x4B, 0x1A38E4, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682500_IDX] = { 27300, 0x2, 0x4B, 0x1AAAAB, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682625_IDX] = { 27305, 0x2, 0x4B, 0x1B1C72, 0x8E3 }, + [ATHOS_B_6G_LUT_CHAN_682750_IDX] = { 27310, 0x2, 0x4B, 0x1B8E39, 0x8E4 }, + [ATHOS_B_6G_LUT_CHAN_682875_IDX] = { 27315, 0x2, 0x4B, 0x1C0000, 0x8E4 }, + [ATHOS_B_6G_LUT_CHAN_683000_IDX] = { 27320, 0x2, 0x4B, 0x1C71C7, 0x8E5 }, + [ATHOS_B_6G_LUT_CHAN_683125_IDX] = { 27325, 0x2, 0x4B, 0x1CE38E, 0x8E5 }, + [ATHOS_B_6G_LUT_CHAN_683250_IDX] = { 27330, 0x2, 0x4B, 0x1D5555, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683375_IDX] = { 27335, 0x2, 0x4B, 0x1DC71C, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683500_IDX] = { 27340, 0x2, 0x4B, 0x1E38E4, 0x8E6 }, + [ATHOS_B_6G_LUT_CHAN_683625_IDX] = { 27345, 0x2, 0x4B, 0x1EAAAB, 0x8E7 }, + [ATHOS_B_6G_LUT_CHAN_683750_IDX] = { 27350, 0x2, 0x4B, 0x1F1C72, 0x8E7 }, + [ATHOS_B_6G_LUT_CHAN_683875_IDX] = { 27355, 0x2, 0x4B, 0x1F8E39, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684000_IDX] = { 27360, 0x2, 0x4C, 0x0, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684125_IDX] = { 27365, 0x2, 0x4C, 0x71C7, 0x8E8 }, + [ATHOS_B_6G_LUT_CHAN_684250_IDX] = { 27370, 0x2, 0x4C, 0xE38E, 0x8E9 }, + [ATHOS_B_6G_LUT_CHAN_684375_IDX] = { 27375, 0x2, 0x4C, 0x15555, 0x8E9 }, + [ATHOS_B_6G_LUT_CHAN_684500_IDX] = { 27380, 0x2, 0x4C, 0x1C71C, 0x8EA }, + [ATHOS_B_6G_LUT_CHAN_684625_IDX] = { 27385, 0x2, 0x4C, 0x238E4, 0x8EA }, + [ATHOS_B_6G_LUT_CHAN_684750_IDX] = { 27390, 0x2, 0x4C, 0x2AAAB, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_684875_IDX] = { 27395, 0x2, 0x4C, 0x31C72, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_685000_IDX] = { 27400, 0x2, 0x4C, 0x38E39, 0x8EB }, + [ATHOS_B_6G_LUT_CHAN_685125_IDX] = { 27405, 0x2, 0x4C, 0x40000, 0x8EC }, + [ATHOS_B_6G_LUT_CHAN_685250_IDX] = { 27410, 0x2, 0x4C, 0x471C7, 0x8EC }, + [ATHOS_B_6G_LUT_CHAN_685375_IDX] = { 27415, 0x2, 0x4C, 0x4E38E, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685500_IDX] = { 27420, 0x2, 0x4C, 0x55555, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685625_IDX] = { 27425, 0x2, 0x4C, 0x5C71C, 0x8ED }, + [ATHOS_B_6G_LUT_CHAN_685750_IDX] = { 27430, 0x2, 0x4C, 0x638E4, 0x8EE }, + [ATHOS_B_6G_LUT_CHAN_685875_IDX] = { 27435, 0x2, 0x4C, 0x6AAAB, 0x8EE }, + [ATHOS_B_6G_LUT_CHAN_686000_IDX] = { 27440, 0x2, 0x4C, 0x71C72, 0x8EF }, + [ATHOS_B_6G_LUT_CHAN_686125_IDX] = { 27445, 0x2, 0x4C, 0x78E39, 0x8EF }, + [ATHOS_B_6G_LUT_CHAN_686250_IDX] = { 27450, 0x2, 0x4C, 0x80000, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686375_IDX] = { 27455, 0x2, 0x4C, 0x871C7, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686500_IDX] = { 27460, 0x2, 0x4C, 0x8E38E, 0x8F0 }, + [ATHOS_B_6G_LUT_CHAN_686625_IDX] = { 27465, 0x2, 0x4C, 0x95555, 0x8F1 }, + [ATHOS_B_6G_LUT_CHAN_686750_IDX] = { 27470, 0x2, 0x4C, 0x9C71C, 0x8F1 }, + [ATHOS_B_6G_LUT_CHAN_686875_IDX] = { 27475, 0x2, 0x4C, 0xA38E4, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687000_IDX] = { 27480, 0x2, 0x4C, 0xAAAAB, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687125_IDX] = { 27485, 0x2, 0x4C, 0xB1C72, 0x8F2 }, + [ATHOS_B_6G_LUT_CHAN_687250_IDX] = { 27490, 0x2, 0x4C, 0xB8E39, 0x8F3 }, + [ATHOS_B_6G_LUT_CHAN_687375_IDX] = { 27495, 0x2, 0x4C, 0xC0000, 0x8F3 }, + [ATHOS_B_6G_LUT_CHAN_687500_IDX] = { 27500, 0x2, 0x4C, 0xC71C7, 0x8F4 }, + [ATHOS_B_6G_LUT_CHAN_687625_IDX] = { 27505, 0x2, 0x4C, 0xCE38E, 0x8F4 }, + [ATHOS_B_6G_LUT_CHAN_687750_IDX] = { 27510, 0x2, 0x4C, 0xD5555, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_687875_IDX] = { 27515, 0x2, 0x4C, 0xDC71C, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_688000_IDX] = { 27520, 0x2, 0x4C, 0xE38E4, 0x8F5 }, + [ATHOS_B_6G_LUT_CHAN_688125_IDX] = { 27525, 0x2, 0x4C, 0xEAAAB, 0x8F6 }, + [ATHOS_B_6G_LUT_CHAN_688250_IDX] = { 27530, 0x2, 0x4C, 0xF1C72, 0x8F6 }, + [ATHOS_B_6G_LUT_CHAN_688375_IDX] = { 27535, 0x2, 0x4C, 0xF8E39, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688500_IDX] = { 27540, 0x2, 0x4C, 0x100000, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688625_IDX] = { 27545, 0x2, 0x4C, 0x1071C7, 0x8F7 }, + [ATHOS_B_6G_LUT_CHAN_688750_IDX] = { 27550, 0x2, 0x4C, 0x10E38E, 0x8F8 }, + [ATHOS_B_6G_LUT_CHAN_688875_IDX] = { 27555, 0x2, 0x4C, 0x115555, 0x8F8 }, + [ATHOS_B_6G_LUT_CHAN_689000_IDX] = { 27560, 0x2, 0x4C, 0x11C71C, 0x8F9 }, + [ATHOS_B_6G_LUT_CHAN_689125_IDX] = { 27565, 0x2, 0x4C, 0x1238E4, 0x8F9 }, + [ATHOS_B_6G_LUT_CHAN_689250_IDX] = { 27570, 0x2, 0x4C, 0x12AAAB, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689375_IDX] = { 27575, 0x2, 0x4C, 0x131C72, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689500_IDX] = { 27580, 0x2, 0x4C, 0x138E39, 0x8FA }, + [ATHOS_B_6G_LUT_CHAN_689625_IDX] = { 27585, 0x2, 0x4C, 0x140000, 0x8FB }, + [ATHOS_B_6G_LUT_CHAN_689750_IDX] = { 27590, 0x2, 0x4C, 0x1471C7, 0x8FB }, + [ATHOS_B_6G_LUT_CHAN_689875_IDX] = { 27595, 0x2, 0x4C, 0x14E38E, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690000_IDX] = { 27600, 0x2, 0x4C, 0x155555, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690125_IDX] = { 27605, 0x2, 0x4C, 0x15C71C, 0x8FC }, + [ATHOS_B_6G_LUT_CHAN_690250_IDX] = { 27610, 0x2, 0x4C, 0x1638E4, 0x8FD }, + [ATHOS_B_6G_LUT_CHAN_690375_IDX] = { 27615, 0x2, 0x4C, 0x16AAAB, 0x8FD }, + [ATHOS_B_6G_LUT_CHAN_690500_IDX] = { 27620, 0x2, 0x4C, 0x171C72, 0x8FE }, + [ATHOS_B_6G_LUT_CHAN_690625_IDX] = { 27625, 0x2, 0x4C, 0x178E39, 0x8FE }, + [ATHOS_B_6G_LUT_CHAN_690750_IDX] = { 27630, 0x2, 0x4C, 0x180000, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_690875_IDX] = { 27635, 0x2, 0x4C, 0x1871C7, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_691000_IDX] = { 27640, 0x2, 0x4C, 0x18E38E, 0x8FF }, + [ATHOS_B_6G_LUT_CHAN_691125_IDX] = { 27645, 0x2, 0x4C, 0x195555, 0x900 }, + [ATHOS_B_6G_LUT_CHAN_691250_IDX] = { 27650, 0x2, 0x4C, 0x19C71C, 0x900 }, + [ATHOS_B_6G_LUT_CHAN_691375_IDX] = { 27655, 0x2, 0x4C, 0x1A38E4, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691500_IDX] = { 27660, 0x2, 0x4C, 0x1AAAAB, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691625_IDX] = { 27665, 0x2, 0x4C, 0x1B1C72, 0x901 }, + [ATHOS_B_6G_LUT_CHAN_691750_IDX] = { 27670, 0x2, 0x4C, 0x1B8E39, 0x902 }, + [ATHOS_B_6G_LUT_CHAN_691875_IDX] = { 27675, 0x2, 0x4C, 0x1C0000, 0x902 }, + [ATHOS_B_6G_LUT_CHAN_692000_IDX] = { 27680, 0x2, 0x4C, 0x1C71C7, 0x903 }, + [ATHOS_B_6G_LUT_CHAN_692125_IDX] = { 27685, 0x2, 0x4C, 0x1CE38E, 0x903 }, + [ATHOS_B_6G_LUT_CHAN_692250_IDX] = { 27690, 0x2, 0x4C, 0x1D5555, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692375_IDX] = { 27695, 0x2, 0x4C, 0x1DC71C, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692500_IDX] = { 27700, 0x2, 0x4C, 0x1E38E4, 0x904 }, + [ATHOS_B_6G_LUT_CHAN_692625_IDX] = { 27705, 0x2, 0x4C, 0x1EAAAB, 0x905 }, + [ATHOS_B_6G_LUT_CHAN_692750_IDX] = { 27710, 0x2, 0x4C, 0x1F1C72, 0x905 }, + [ATHOS_B_6G_LUT_CHAN_692875_IDX] = { 27715, 0x2, 0x4C, 0x1F8E39, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693000_IDX] = { 27720, 0x2, 0x4D, 0x0, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693125_IDX] = { 27725, 0x2, 0x4D, 0x71C7, 0x906 }, + [ATHOS_B_6G_LUT_CHAN_693250_IDX] = { 27730, 0x2, 0x4D, 0xE38E, 0x907 }, + [ATHOS_B_6G_LUT_CHAN_693375_IDX] = { 27735, 0x2, 0x4D, 0x15555, 0x907 }, + [ATHOS_B_6G_LUT_CHAN_693500_IDX] = { 27740, 0x2, 0x4D, 0x1C71C, 0x908 }, + [ATHOS_B_6G_LUT_CHAN_693625_IDX] = { 27745, 0x2, 0x4D, 0x238E4, 0x908 }, + [ATHOS_B_6G_LUT_CHAN_693750_IDX] = { 27750, 0x2, 0x4D, 0x2AAAB, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_693875_IDX] = { 27755, 0x2, 0x4D, 0x31C72, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_694000_IDX] = { 27760, 0x2, 0x4D, 0x38E39, 0x909 }, + [ATHOS_B_6G_LUT_CHAN_694125_IDX] = { 27765, 0x2, 0x4D, 0x40000, 0x90A }, + [ATHOS_B_6G_LUT_CHAN_694250_IDX] = { 27770, 0x2, 0x4D, 0x471C7, 0x90A }, + [ATHOS_B_6G_LUT_CHAN_694375_IDX] = { 27775, 0x2, 0x4D, 0x4E38E, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694500_IDX] = { 27780, 0x2, 0x4D, 0x55555, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694625_IDX] = { 27785, 0x2, 0x4D, 0x5C71C, 0x90B }, + [ATHOS_B_6G_LUT_CHAN_694750_IDX] = { 27790, 0x2, 0x4D, 0x638E4, 0x90C }, + [ATHOS_B_6G_LUT_CHAN_694875_IDX] = { 27795, 0x2, 0x4D, 0x6AAAB, 0x90C }, + [ATHOS_B_6G_LUT_CHAN_695000_IDX] = { 27800, 0x2, 0x4D, 0x71C72, 0x90D }, + [ATHOS_B_6G_LUT_CHAN_695125_IDX] = { 27805, 0x2, 0x4D, 0x78E39, 0x90D }, + [ATHOS_B_6G_LUT_CHAN_695250_IDX] = { 27810, 0x2, 0x4D, 0x80000, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695375_IDX] = { 27815, 0x2, 0x4D, 0x871C7, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695500_IDX] = { 27820, 0x2, 0x4D, 0x8E38E, 0x90E }, + [ATHOS_B_6G_LUT_CHAN_695625_IDX] = { 27825, 0x2, 0x4D, 0x95555, 0x90F }, + [ATHOS_B_6G_LUT_CHAN_695750_IDX] = { 27830, 0x2, 0x4D, 0x9C71C, 0x90F }, + [ATHOS_B_6G_LUT_CHAN_695875_IDX] = { 27835, 0x2, 0x4D, 0xA38E4, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696000_IDX] = { 27840, 0x2, 0x4D, 0xAAAAB, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696125_IDX] = { 27845, 0x2, 0x4D, 0xB1C72, 0x910 }, + [ATHOS_B_6G_LUT_CHAN_696250_IDX] = { 27850, 0x2, 0x4D, 0xB8E39, 0x911 }, + [ATHOS_B_6G_LUT_CHAN_696375_IDX] = { 27855, 0x2, 0x4D, 0xC0000, 0x911 }, + [ATHOS_B_6G_LUT_CHAN_696500_IDX] = { 27860, 0x2, 0x4D, 0xC71C7, 0x912 }, + [ATHOS_B_6G_LUT_CHAN_696625_IDX] = { 27865, 0x2, 0x4D, 0xCE38E, 0x912 }, + [ATHOS_B_6G_LUT_CHAN_696750_IDX] = { 27870, 0x2, 0x4D, 0xD5555, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_696875_IDX] = { 27875, 0x2, 0x4D, 0xDC71C, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_697000_IDX] = { 27880, 0x2, 0x4D, 0xE38E4, 0x913 }, + [ATHOS_B_6G_LUT_CHAN_697125_IDX] = { 27885, 0x2, 0x4D, 0xEAAAB, 0x914 }, + [ATHOS_B_6G_LUT_CHAN_697250_IDX] = { 27890, 0x2, 0x4D, 0xF1C72, 0x914 }, + [ATHOS_B_6G_LUT_CHAN_697375_IDX] = { 27895, 0x2, 0x4D, 0xF8E39, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697500_IDX] = { 27900, 0x2, 0x4D, 0x100000, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697625_IDX] = { 27905, 0x2, 0x4D, 0x1071C7, 0x915 }, + [ATHOS_B_6G_LUT_CHAN_697750_IDX] = { 27910, 0x2, 0x4D, 0x10E38E, 0x916 }, + [ATHOS_B_6G_LUT_CHAN_697875_IDX] = { 27915, 0x2, 0x4D, 0x115555, 0x916 }, + [ATHOS_B_6G_LUT_CHAN_698000_IDX] = { 27920, 0x2, 0x4D, 0x11C71C, 0x917 }, + [ATHOS_B_6G_LUT_CHAN_698125_IDX] = { 27925, 0x2, 0x4D, 0x1238E4, 0x917 }, + [ATHOS_B_6G_LUT_CHAN_698250_IDX] = { 27930, 0x2, 0x4D, 0x12AAAB, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698375_IDX] = { 27935, 0x2, 0x4D, 0x131C72, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698500_IDX] = { 27940, 0x2, 0x4D, 0x138E39, 0x918 }, + [ATHOS_B_6G_LUT_CHAN_698625_IDX] = { 27945, 0x2, 0x4D, 0x140000, 0x919 }, + [ATHOS_B_6G_LUT_CHAN_698750_IDX] = { 27950, 0x2, 0x4D, 0x1471C7, 0x919 }, + [ATHOS_B_6G_LUT_CHAN_698875_IDX] = { 27955, 0x2, 0x4D, 0x14E38E, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699000_IDX] = { 27960, 0x2, 0x4D, 0x155555, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699125_IDX] = { 27965, 0x2, 0x4D, 0x15C71C, 0x91A }, + [ATHOS_B_6G_LUT_CHAN_699250_IDX] = { 27970, 0x2, 0x4D, 0x1638E4, 0x91B }, + [ATHOS_B_6G_LUT_CHAN_699375_IDX] = { 27975, 0x2, 0x4D, 0x16AAAB, 0x91B }, + [ATHOS_B_6G_LUT_CHAN_699500_IDX] = { 27980, 0x2, 0x4D, 0x171C72, 0x91C }, + [ATHOS_B_6G_LUT_CHAN_699625_IDX] = { 27985, 0x2, 0x4D, 0x178E39, 0x91C }, + [ATHOS_B_6G_LUT_CHAN_699750_IDX] = { 27990, 0x2, 0x4D, 0x180000, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_699875_IDX] = { 27995, 0x2, 0x4D, 0x1871C7, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_700000_IDX] = { 28000, 0x2, 0x4D, 0x18E38E, 0x91D }, + [ATHOS_B_6G_LUT_CHAN_700125_IDX] = { 28005, 0x2, 0x4D, 0x195555, 0x91E }, + [ATHOS_B_6G_LUT_CHAN_700250_IDX] = { 28010, 0x2, 0x4D, 0x19C71C, 0x91E }, + [ATHOS_B_6G_LUT_CHAN_700375_IDX] = { 28015, 0x2, 0x4D, 0x1A38E4, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700500_IDX] = { 28020, 0x2, 0x4D, 0x1AAAAB, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700625_IDX] = { 28025, 0x2, 0x4D, 0x1B1C72, 0x91F }, + [ATHOS_B_6G_LUT_CHAN_700750_IDX] = { 28030, 0x2, 0x4D, 0x1B8E39, 0x920 }, + [ATHOS_B_6G_LUT_CHAN_700875_IDX] = { 28035, 0x2, 0x4D, 0x1C0000, 0x920 }, + [ATHOS_B_6G_LUT_CHAN_701000_IDX] = { 28040, 0x2, 0x4D, 0x1C71C7, 0x921 }, + [ATHOS_B_6G_LUT_CHAN_701125_IDX] = { 28045, 0x2, 0x4D, 0x1CE38E, 0x921 }, + [ATHOS_B_6G_LUT_CHAN_701250_IDX] = { 28050, 0x2, 0x4D, 0x1D5555, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701375_IDX] = { 28055, 0x2, 0x4D, 0x1DC71C, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701500_IDX] = { 28060, 0x2, 0x4D, 0x1E38E4, 0x922 }, + [ATHOS_B_6G_LUT_CHAN_701625_IDX] = { 28065, 0x2, 0x4D, 0x1EAAAB, 0x923 }, + [ATHOS_B_6G_LUT_CHAN_701750_IDX] = { 28070, 0x2, 0x4D, 0x1F1C72, 0x923 }, + [ATHOS_B_6G_LUT_CHAN_701875_IDX] = { 28075, 0x2, 0x4D, 0x1F8E39, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702000_IDX] = { 28080, 0x2, 0x4E, 0x0, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702125_IDX] = { 28085, 0x2, 0x4E, 0x71C7, 0x924 }, + [ATHOS_B_6G_LUT_CHAN_702250_IDX] = { 28090, 0x2, 0x4E, 0xE38E, 0x925 }, + [ATHOS_B_6G_LUT_CHAN_702375_IDX] = { 28095, 0x2, 0x4E, 0x15555, 0x925 }, + [ATHOS_B_6G_LUT_CHAN_702500_IDX] = { 28100, 0x2, 0x4E, 0x1C71C, 0x926 }, + [ATHOS_B_6G_LUT_CHAN_702625_IDX] = { 28105, 0x2, 0x4E, 0x238E4, 0x926 }, + [ATHOS_B_6G_LUT_CHAN_702750_IDX] = { 28110, 0x2, 0x4E, 0x2AAAB, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_702875_IDX] = { 28115, 0x2, 0x4E, 0x31C72, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_703000_IDX] = { 28120, 0x2, 0x4E, 0x38E39, 0x927 }, + [ATHOS_B_6G_LUT_CHAN_703125_IDX] = { 28125, 0x2, 0x4E, 0x40000, 0x928 }, + [ATHOS_B_6G_LUT_CHAN_703250_IDX] = { 28130, 0x2, 0x4E, 0x471C7, 0x928 }, + [ATHOS_B_6G_LUT_CHAN_703375_IDX] = { 28135, 0x2, 0x4E, 0x4E38E, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703500_IDX] = { 28140, 0x2, 0x4E, 0x55555, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703625_IDX] = { 28145, 0x2, 0x4E, 0x5C71C, 0x929 }, + [ATHOS_B_6G_LUT_CHAN_703750_IDX] = { 28150, 0x2, 0x4E, 0x638E4, 0x92A }, + [ATHOS_B_6G_LUT_CHAN_703875_IDX] = { 28155, 0x2, 0x4E, 0x6AAAB, 0x92A }, + [ATHOS_B_6G_LUT_CHAN_704000_IDX] = { 28160, 0x2, 0x4E, 0x71C72, 0x92B }, + [ATHOS_B_6G_LUT_CHAN_704125_IDX] = { 28165, 0x2, 0x4E, 0x78E39, 0x92B }, + [ATHOS_B_6G_LUT_CHAN_704250_IDX] = { 28170, 0x2, 0x4E, 0x80000, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704375_IDX] = { 28175, 0x2, 0x4E, 0x871C7, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704500_IDX] = { 28180, 0x2, 0x4E, 0x8E38E, 0x92C }, + [ATHOS_B_6G_LUT_CHAN_704625_IDX] = { 28185, 0x2, 0x4E, 0x95555, 0x92D }, + [ATHOS_B_6G_LUT_CHAN_704750_IDX] = { 28190, 0x2, 0x4E, 0x9C71C, 0x92D }, + [ATHOS_B_6G_LUT_CHAN_704875_IDX] = { 28195, 0x2, 0x4E, 0xA38E4, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705000_IDX] = { 28200, 0x2, 0x4E, 0xAAAAB, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705125_IDX] = { 28205, 0x2, 0x4E, 0xB1C72, 0x92E }, + [ATHOS_B_6G_LUT_CHAN_705250_IDX] = { 28210, 0x2, 0x4E, 0xB8E39, 0x92F }, + [ATHOS_B_6G_LUT_CHAN_705375_IDX] = { 28215, 0x2, 0x4E, 0xC0000, 0x92F }, + [ATHOS_B_6G_LUT_CHAN_705500_IDX] = { 28220, 0x2, 0x4E, 0xC71C7, 0x930 }, + [ATHOS_B_6G_LUT_CHAN_705625_IDX] = { 28225, 0x2, 0x4E, 0xCE38E, 0x930 }, + [ATHOS_B_6G_LUT_CHAN_705750_IDX] = { 28230, 0x2, 0x4E, 0xD5555, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_705875_IDX] = { 28235, 0x2, 0x4E, 0xDC71C, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_706000_IDX] = { 28240, 0x2, 0x4E, 0xE38E4, 0x931 }, + [ATHOS_B_6G_LUT_CHAN_706125_IDX] = { 28245, 0x2, 0x4E, 0xEAAAB, 0x932 }, + [ATHOS_B_6G_LUT_CHAN_706250_IDX] = { 28250, 0x2, 0x4E, 0xF1C72, 0x932 }, + [ATHOS_B_6G_LUT_CHAN_706375_IDX] = { 28255, 0x2, 0x4E, 0xF8E39, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706500_IDX] = { 28260, 0x2, 0x4E, 0x100000, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706625_IDX] = { 28265, 0x2, 0x4E, 0x1071C7, 0x933 }, + [ATHOS_B_6G_LUT_CHAN_706750_IDX] = { 28270, 0x2, 0x4E, 0x10E38E, 0x934 }, + [ATHOS_B_6G_LUT_CHAN_706875_IDX] = { 28275, 0x2, 0x4E, 0x115555, 0x934 }, + [ATHOS_B_6G_LUT_CHAN_707000_IDX] = { 28280, 0x2, 0x4E, 0x11C71C, 0x935 }, + [ATHOS_B_6G_LUT_CHAN_707125_IDX] = { 28285, 0x2, 0x4E, 0x1238E4, 0x935 }, + [ATHOS_B_6G_LUT_CHAN_707250_IDX] = { 28290, 0x2, 0x4E, 0x12AAAB, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707375_IDX] = { 28295, 0x2, 0x4E, 0x131C72, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707500_IDX] = { 28300, 0x2, 0x4E, 0x138E39, 0x936 }, + [ATHOS_B_6G_LUT_CHAN_707625_IDX] = { 28305, 0x2, 0x4E, 0x140000, 0x937 }, + [ATHOS_B_6G_LUT_CHAN_707750_IDX] = { 28310, 0x2, 0x4E, 0x1471C7, 0x937 }, + [ATHOS_B_6G_LUT_CHAN_707875_IDX] = { 28315, 0x2, 0x4E, 0x14E38E, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708000_IDX] = { 28320, 0x2, 0x4E, 0x155555, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708125_IDX] = { 28325, 0x2, 0x4E, 0x15C71C, 0x938 }, + [ATHOS_B_6G_LUT_CHAN_708250_IDX] = { 28330, 0x2, 0x4E, 0x1638E4, 0x939 }, + [ATHOS_B_6G_LUT_CHAN_708375_IDX] = { 28335, 0x2, 0x4E, 0x16AAAB, 0x939 }, + [ATHOS_B_6G_LUT_CHAN_708500_IDX] = { 28340, 0x2, 0x4E, 0x171C72, 0x93A }, + [ATHOS_B_6G_LUT_CHAN_708625_IDX] = { 28345, 0x2, 0x4E, 0x178E39, 0x93A }, + [ATHOS_B_6G_LUT_CHAN_708750_IDX] = { 28350, 0x2, 0x4E, 0x180000, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_708875_IDX] = { 28355, 0x2, 0x4E, 0x1871C7, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_709000_IDX] = { 28360, 0x2, 0x4E, 0x18E38E, 0x93B }, + [ATHOS_B_6G_LUT_CHAN_709125_IDX] = { 28365, 0x2, 0x4E, 0x195555, 0x93C }, + [ATHOS_B_6G_LUT_CHAN_709250_IDX] = { 28370, 0x2, 0x4E, 0x19C71C, 0x93C }, + [ATHOS_B_6G_LUT_CHAN_709375_IDX] = { 28375, 0x2, 0x4E, 0x1A38E4, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709500_IDX] = { 28380, 0x2, 0x4E, 0x1AAAAB, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709625_IDX] = { 28385, 0x2, 0x4E, 0x1B1C72, 0x93D }, + [ATHOS_B_6G_LUT_CHAN_709750_IDX] = { 28390, 0x2, 0x4E, 0x1B8E39, 0x93E }, + [ATHOS_B_6G_LUT_CHAN_709875_IDX] = { 28395, 0x2, 0x4E, 0x1C0000, 0x93E }, + [ATHOS_B_6G_LUT_CHAN_710000_IDX] = { 28400, 0x2, 0x4E, 0x1C71C7, 0x93F }, + [ATHOS_B_6G_LUT_CHAN_710125_IDX] = { 28405, 0x2, 0x4E, 0x1CE38E, 0x93F }, + [ATHOS_B_6G_LUT_CHAN_710250_IDX] = { 28410, 0x2, 0x4E, 0x1D5555, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710375_IDX] = { 28415, 0x2, 0x4E, 0x1DC71C, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710500_IDX] = { 28420, 0x2, 0x4E, 0x1E38E4, 0x940 }, + [ATHOS_B_6G_LUT_CHAN_710625_IDX] = { 28425, 0x2, 0x4E, 0x1EAAAB, 0x941 }, + [ATHOS_B_6G_LUT_CHAN_710750_IDX] = { 28430, 0x2, 0x4E, 0x1F1C72, 0x941 }, + [ATHOS_B_6G_LUT_CHAN_710875_IDX] = { 28435, 0x2, 0x4E, 0x1F8E39, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711000_IDX] = { 28440, 0x2, 0x4F, 0x0, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711125_IDX] = { 28445, 0x2, 0x4F, 0x71C7, 0x942 }, + [ATHOS_B_6G_LUT_CHAN_711250_IDX] = { 28450, 0x2, 0x4F, 0xE38E, 0x943 }, + [ATHOS_B_6G_LUT_CHAN_711375_IDX] = { 28455, 0x2, 0x4F, 0x15555, 0x943 }, + [ATHOS_B_6G_LUT_CHAN_711500_IDX] = { 28460, 0x2, 0x4F, 0x1C71C, 0x944 }, + [ATHOS_B_6G_LUT_CHAN_711625_IDX] = { 28465, 0x2, 0x4F, 0x238E4, 0x944 }, + [ATHOS_B_6G_LUT_CHAN_711750_IDX] = { 28470, 0x2, 0x4F, 0x2AAAB, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_711875_IDX] = { 28475, 0x2, 0x4F, 0x31C72, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_712000_IDX] = { 28480, 0x2, 0x4F, 0x38E39, 0x945 }, + [ATHOS_B_6G_LUT_CHAN_712125_IDX] = { 28485, 0x2, 0x4F, 0x40000, 0x946 }, + [ATHOS_B_6G_LUT_CHAN_712250_IDX] = { 28490, 0x2, 0x4F, 0x471C7, 0x946 }, + [ATHOS_B_6G_LUT_CHAN_712375_IDX] = { 28495, 0x2, 0x4F, 0x4E38E, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712500_IDX] = { 28500, 0x2, 0x4F, 0x55555, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712625_IDX] = { 28505, 0x2, 0x4F, 0x5C71C, 0x947 }, + [ATHOS_B_6G_LUT_CHAN_712750_IDX] = { 28510, 0x2, 0x4F, 0x638E4, 0x948 }, + [ATHOS_B_6G_LUT_CHAN_712875_IDX] = { 28515, 0x2, 0x4F, 0x6AAAB, 0x948 }, + [ATHOS_B_6G_LUT_CHAN_713000_IDX] = { 28520, 0x2, 0x4F, 0x71C72, 0x949 }, + [ATHOS_B_6G_LUT_CHAN_713125_IDX] = { 28525, 0x2, 0x4F, 0x78E39, 0x949 }, + [ATHOS_B_6G_LUT_CHAN_713250_IDX] = { 28530, 0x2, 0x4F, 0x80000, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713375_IDX] = { 28535, 0x2, 0x4F, 0x871C7, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713500_IDX] = { 28540, 0x2, 0x4F, 0x8E38E, 0x94A }, + [ATHOS_B_6G_LUT_CHAN_713625_IDX] = { 28545, 0x2, 0x4F, 0x95555, 0x94B }, + [ATHOS_B_6G_LUT_CHAN_713750_IDX] = { 28550, 0x2, 0x4F, 0x9C71C, 0x94B }, + [ATHOS_B_6G_LUT_CHAN_713875_IDX] = { 28555, 0x2, 0x4F, 0xA38E4, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714000_IDX] = { 28560, 0x2, 0x4F, 0xAAAAB, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714125_IDX] = { 28565, 0x2, 0x4F, 0xB1C72, 0x94C }, + [ATHOS_B_6G_LUT_CHAN_714250_IDX] = { 28570, 0x2, 0x4F, 0xB8E39, 0x94D }, + [ATHOS_B_6G_LUT_CHAN_714375_IDX] = { 28575, 0x2, 0x4F, 0xC0000, 0x94D }, + [ATHOS_B_6G_LUT_CHAN_714500_IDX] = { 28580, 0x2, 0x4F, 0xC71C7, 0x94E }, + [ATHOS_B_6G_LUT_CHAN_714625_IDX] = { 28585, 0x2, 0x4F, 0xCE38E, 0x94E }, + [ATHOS_B_6G_LUT_CHAN_714750_IDX] = { 28590, 0x2, 0x4F, 0xD5555, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_714875_IDX] = { 28595, 0x2, 0x4F, 0xDC71C, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_715000_IDX] = { 28600, 0x2, 0x4F, 0xE38E4, 0x94F }, + [ATHOS_B_6G_LUT_CHAN_715125_IDX] = { 28605, 0x2, 0x4F, 0xEAAAB, 0x950 }, + [ATHOS_B_6G_LUT_CHAN_715250_IDX] = { 28610, 0x2, 0x4F, 0xF1C72, 0x950 }, + [ATHOS_B_6G_LUT_CHAN_715375_IDX] = { 28615, 0x2, 0x4F, 0xF8E39, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715500_IDX] = { 28620, 0x2, 0x4F, 0x100000, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715625_IDX] = { 28625, 0x2, 0x4F, 0x1071C7, 0x951 }, + [ATHOS_B_6G_LUT_CHAN_715750_IDX] = { 28630, 0x2, 0x4F, 0x10E38E, 0x952 }, + [ATHOS_B_6G_LUT_CHAN_715875_IDX] = { 28635, 0x2, 0x4F, 0x115555, 0x952 }, + [ATHOS_B_6G_LUT_CHAN_716000_IDX] = { 28640, 0x2, 0x4F, 0x11C71C, 0x953 }, + [ATHOS_B_6G_LUT_CHAN_716125_IDX] = { 28645, 0x2, 0x4F, 0x1238E4, 0x953 }, + [ATHOS_B_6G_LUT_CHAN_716250_IDX] = { 28650, 0x2, 0x4F, 0x12AAAB, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716375_IDX] = { 28655, 0x2, 0x4F, 0x131C72, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716500_IDX] = { 28660, 0x2, 0x4F, 0x138E39, 0x954 }, + [ATHOS_B_6G_LUT_CHAN_716625_IDX] = { 28665, 0x2, 0x4F, 0x140000, 0x955 }, + [ATHOS_B_6G_LUT_CHAN_716750_IDX] = { 28670, 0x2, 0x4F, 0x1471C7, 0x955 }, + [ATHOS_B_6G_LUT_CHAN_716875_IDX] = { 28675, 0x2, 0x4F, 0x14E38E, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717000_IDX] = { 28680, 0x2, 0x4F, 0x155555, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717125_IDX] = { 28685, 0x2, 0x4F, 0x15C71C, 0x956 }, + [ATHOS_B_6G_LUT_CHAN_717250_IDX] = { 28690, 0x2, 0x4F, 0x1638E4, 0x957 }, + [ATHOS_B_6G_LUT_CHAN_717375_IDX] = { 28695, 0x2, 0x4F, 0x16AAAB, 0x957 }, + [ATHOS_B_6G_LUT_CHAN_717500_IDX] = { 28700, 0x2, 0x4F, 0x171C72, 0x958 }, + [ATHOS_B_6G_LUT_CHAN_717625_IDX] = { 28705, 0x2, 0x4F, 0x178E39, 0x958 }, + [ATHOS_B_6G_LUT_CHAN_717750_IDX] = { 28710, 0x2, 0x4F, 0x180000, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_717875_IDX] = { 28715, 0x2, 0x4F, 0x1871C7, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_718000_IDX] = { 28720, 0x2, 0x4F, 0x18E38E, 0x959 }, + [ATHOS_B_6G_LUT_CHAN_718125_IDX] = { 28725, 0x2, 0x4F, 0x195555, 0x95A }, + [ATHOS_B_6G_LUT_CHAN_718250_IDX] = { 28730, 0x2, 0x4F, 0x19C71C, 0x95A }, + [ATHOS_B_6G_LUT_CHAN_718375_IDX] = { 28735, 0x2, 0x4F, 0x1A38E4, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718500_IDX] = { 28740, 0x2, 0x4F, 0x1AAAAB, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718625_IDX] = { 28745, 0x2, 0x4F, 0x1B1C72, 0x95B }, + [ATHOS_B_6G_LUT_CHAN_718750_IDX] = { 28750, 0x2, 0x4F, 0x1B8E39, 0x95C }, + [ATHOS_B_6G_LUT_CHAN_718875_IDX] = { 28755, 0x2, 0x4F, 0x1C0000, 0x95C }, + [ATHOS_B_6G_LUT_CHAN_719000_IDX] = { 28760, 0x2, 0x4F, 0x1C71C7, 0x95D }, + [ATHOS_B_6G_LUT_CHAN_719125_IDX] = { 28765, 0x2, 0x4F, 0x1CE38E, 0x95D }, + [ATHOS_B_6G_LUT_CHAN_719250_IDX] = { 28770, 0x2, 0x4F, 0x1D5555, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719375_IDX] = { 28775, 0x2, 0x4F, 0x1DC71C, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719500_IDX] = { 28780, 0x2, 0x4F, 0x1E38E4, 0x95E }, + [ATHOS_B_6G_LUT_CHAN_719625_IDX] = { 28785, 0x2, 0x4F, 0x1EAAAB, 0x95F }, + [ATHOS_B_6G_LUT_CHAN_719750_IDX] = { 28790, 0x2, 0x4F, 0x1F1C72, 0x95F }, + [ATHOS_B_6G_LUT_CHAN_719875_IDX] = { 28795, 0x2, 0x4F, 0x1F8E39, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720000_IDX] = { 28800, 0x2, 0x50, 0x0, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720125_IDX] = { 28805, 0x2, 0x50, 0x71C7, 0x960 }, + [ATHOS_B_6G_LUT_CHAN_720250_IDX] = { 28810, 0x2, 0x50, 0xE38E, 0x961 }, + [ATHOS_B_6G_LUT_CHAN_720375_IDX] = { 28815, 0x2, 0x50, 0x15555, 0x961 }, + [ATHOS_B_6G_LUT_CHAN_720500_IDX] = { 28820, 0x2, 0x50, 0x1C71C, 0x962 }, + [ATHOS_B_6G_LUT_CHAN_720625_IDX] = { 28825, 0x2, 0x50, 0x238E4, 0x962 }, + [ATHOS_B_6G_LUT_CHAN_720750_IDX] = { 28830, 0x2, 0x50, 0x2AAAB, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_720875_IDX] = { 28835, 0x2, 0x50, 0x31C72, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_721000_IDX] = { 28840, 0x2, 0x50, 0x38E39, 0x963 }, + [ATHOS_B_6G_LUT_CHAN_721125_IDX] = { 28845, 0x2, 0x50, 0x40000, 0x964 }, + [ATHOS_B_6G_LUT_CHAN_721250_IDX] = { 28850, 0x2, 0x50, 0x471C7, 0x964 }, + [ATHOS_B_6G_LUT_CHAN_721375_IDX] = { 28855, 0x2, 0x50, 0x4E38E, 0x965 }, + [ATHOS_B_6G_LUT_CHAN_721500_IDX] = { 28860, 0x2, 0x50, 0x55555, 0x965 } +}; + +const struct common_lut_line athos_b_lut_5g_60_mhz[ATHOS_B_5G_LUT_CHAN_5G_MAX] = { + [ATHOS_B_5G_LUT_CHAN_516000_IDX] = { 20640, 0x0, 0x39, 0x11C71C, 0x6BF }, + [ATHOS_B_5G_LUT_CHAN_516125_IDX] = { 20645, 0x0, 0x39, 0xB1C72, 0x6B8 }, + [ATHOS_B_5G_LUT_CHAN_516250_IDX] = { 20650, 0x0, 0x39, 0xB8E39, 0x6B9 }, + [ATHOS_B_5G_LUT_CHAN_516375_IDX] = { 20655, 0x0, 0x39, 0xC0000, 0x6B9 }, + [ATHOS_B_5G_LUT_CHAN_516500_IDX] = { 20660, 0x0, 0x39, 0xC71C7, 0x6BA }, + [ATHOS_B_5G_LUT_CHAN_516625_IDX] = { 20665, 0x0, 0x39, 0xCE38E, 0x6BA }, + [ATHOS_B_5G_LUT_CHAN_516750_IDX] = { 20670, 0x0, 0x39, 0xD5555, 0x6BB }, + [ATHOS_B_5G_LUT_CHAN_516875_IDX] = { 20675, 0x0, 0x39, 0xDC71C, 0x6BB }, + [ATHOS_B_5G_LUT_CHAN_517000_IDX] = { 20680, 0x0, 0x39, 0xE38E4, 0x6BB }, + [ATHOS_B_5G_LUT_CHAN_517125_IDX] = { 20685, 0x0, 0x39, 0xEAAAB, 0x6BC }, + [ATHOS_B_5G_LUT_CHAN_517250_IDX] = { 20690, 0x0, 0x39, 0xF1C72, 0x6BC }, + [ATHOS_B_5G_LUT_CHAN_517375_IDX] = { 20695, 0x0, 0x39, 0xF8E39, 0x6BD }, + [ATHOS_B_5G_LUT_CHAN_517500_IDX] = { 20700, 0x0, 0x39, 0x100000, 0x6BD }, + [ATHOS_B_5G_LUT_CHAN_517625_IDX] = { 20705, 0x0, 0x39, 0x1071C7, 0x6BD }, + [ATHOS_B_5G_LUT_CHAN_517750_IDX] = { 20710, 0x0, 0x39, 0x10E38E, 0x6BE }, + [ATHOS_B_5G_LUT_CHAN_517875_IDX] = { 20715, 0x0, 0x39, 0x115555, 0x6BE }, + [ATHOS_B_5G_LUT_CHAN_518000_IDX] = { 20720, 0x0, 0x39, 0x11C71C, 0x6BF }, + [ATHOS_B_5G_LUT_CHAN_518125_IDX] = { 20725, 0x0, 0x39, 0x1238E4, 0x6BF }, + [ATHOS_B_5G_LUT_CHAN_518250_IDX] = { 20730, 0x0, 0x39, 0x12AAAB, 0x6C0 }, + [ATHOS_B_5G_LUT_CHAN_518375_IDX] = { 20735, 0x0, 0x39, 0x131C72, 0x6C0 }, + [ATHOS_B_5G_LUT_CHAN_518500_IDX] = { 20740, 0x0, 0x39, 0x138E39, 0x6C0 }, + [ATHOS_B_5G_LUT_CHAN_518625_IDX] = { 20745, 0x0, 0x39, 0x140000, 0x6C1 }, + [ATHOS_B_5G_LUT_CHAN_518750_IDX] = { 20750, 0x0, 0x39, 0x1471C7, 0x6C1 }, + [ATHOS_B_5G_LUT_CHAN_518875_IDX] = { 20755, 0x0, 0x39, 0x14E38E, 0x6C2 }, + [ATHOS_B_5G_LUT_CHAN_519000_IDX] = { 20760, 0x0, 0x39, 0x155555, 0x6C2 }, + [ATHOS_B_5G_LUT_CHAN_519125_IDX] = { 20765, 0x0, 0x39, 0x15C71C, 0x6C2 }, + [ATHOS_B_5G_LUT_CHAN_519250_IDX] = { 20770, 0x0, 0x39, 0x1638E4, 0x6C3 }, + [ATHOS_B_5G_LUT_CHAN_519375_IDX] = { 20775, 0x0, 0x39, 0x16AAAB, 0x6C3 }, + [ATHOS_B_5G_LUT_CHAN_519500_IDX] = { 20780, 0x0, 0x39, 0x171C72, 0x6C4 }, + [ATHOS_B_5G_LUT_CHAN_519625_IDX] = { 20785, 0x0, 0x39, 0x178E39, 0x6C4 }, + [ATHOS_B_5G_LUT_CHAN_519750_IDX] = { 20790, 0x0, 0x39, 0x180000, 0x6C5 }, + [ATHOS_B_5G_LUT_CHAN_519875_IDX] = { 20795, 0x0, 0x39, 0x1871C7, 0x6C5 }, + [ATHOS_B_5G_LUT_CHAN_520000_IDX] = { 20800, 0x0, 0x39, 0x18E38E, 0x6C5 }, + [ATHOS_B_5G_LUT_CHAN_520125_IDX] = { 20805, 0x0, 0x39, 0x195555, 0x6C6 }, + [ATHOS_B_5G_LUT_CHAN_520250_IDX] = { 20810, 0x0, 0x39, 0x19C71C, 0x6C6 }, + [ATHOS_B_5G_LUT_CHAN_520375_IDX] = { 20815, 0x0, 0x39, 0x1A38E4, 0x6C7 }, + [ATHOS_B_5G_LUT_CHAN_520500_IDX] = { 20820, 0x0, 0x39, 0x1AAAAB, 0x6C7 }, + [ATHOS_B_5G_LUT_CHAN_520625_IDX] = { 20825, 0x0, 0x39, 0x1B1C72, 0x6C7 }, + [ATHOS_B_5G_LUT_CHAN_520750_IDX] = { 20830, 0x0, 0x39, 0x1B8E39, 0x6C8 }, + [ATHOS_B_5G_LUT_CHAN_520875_IDX] = { 20835, 0x0, 0x39, 0x1C0000, 0x6C8 }, + [ATHOS_B_5G_LUT_CHAN_521000_IDX] = { 20840, 0x0, 0x39, 0x1C71C7, 0x6C9 }, + [ATHOS_B_5G_LUT_CHAN_521125_IDX] = { 20845, 0x0, 0x39, 0x1CE38E, 0x6C9 }, + [ATHOS_B_5G_LUT_CHAN_521250_IDX] = { 20850, 0x0, 0x39, 0x1D5555, 0x6CA }, + [ATHOS_B_5G_LUT_CHAN_521375_IDX] = { 20855, 0x0, 0x39, 0x1DC71C, 0x6CA }, + [ATHOS_B_5G_LUT_CHAN_521500_IDX] = { 20860, 0x0, 0x39, 0x1E38E4, 0x6CA }, + [ATHOS_B_5G_LUT_CHAN_521625_IDX] = { 20865, 0x0, 0x39, 0x1EAAAB, 0x6CB }, + [ATHOS_B_5G_LUT_CHAN_521750_IDX] = { 20870, 0x0, 0x39, 0x1F1C72, 0x6CB }, + [ATHOS_B_5G_LUT_CHAN_521875_IDX] = { 20875, 0x0, 0x39, 0x1F8E39, 0x6CC }, + [ATHOS_B_5G_LUT_CHAN_522000_IDX] = { 20880, 0x0, 0x3A, 0x0, 0x6CC }, + [ATHOS_B_5G_LUT_CHAN_522125_IDX] = { 20885, 0x0, 0x3A, 0x71C7, 0x6CC }, + [ATHOS_B_5G_LUT_CHAN_522250_IDX] = { 20890, 0x0, 0x3A, 0xE38E, 0x6CD }, + [ATHOS_B_5G_LUT_CHAN_522375_IDX] = { 20895, 0x0, 0x3A, 0x15555, 0x6CD }, + [ATHOS_B_5G_LUT_CHAN_522500_IDX] = { 20900, 0x0, 0x3A, 0x1C71C, 0x6CE }, + [ATHOS_B_5G_LUT_CHAN_522625_IDX] = { 20905, 0x0, 0x3A, 0x238E4, 0x6CE }, + [ATHOS_B_5G_LUT_CHAN_522750_IDX] = { 20910, 0x0, 0x3A, 0x2AAAB, 0x6CF }, + [ATHOS_B_5G_LUT_CHAN_522875_IDX] = { 20915, 0x0, 0x3A, 0x31C72, 0x6CF }, + [ATHOS_B_5G_LUT_CHAN_523000_IDX] = { 20920, 0x0, 0x3A, 0x38E39, 0x6CF }, + [ATHOS_B_5G_LUT_CHAN_523125_IDX] = { 20925, 0x0, 0x3A, 0x40000, 0x6D0 }, + [ATHOS_B_5G_LUT_CHAN_523250_IDX] = { 20930, 0x0, 0x3A, 0x471C7, 0x6D0 }, + [ATHOS_B_5G_LUT_CHAN_523375_IDX] = { 20935, 0x0, 0x3A, 0x4E38E, 0x6D1 }, + [ATHOS_B_5G_LUT_CHAN_523500_IDX] = { 20940, 0x0, 0x3A, 0x55555, 0x6D1 }, + [ATHOS_B_5G_LUT_CHAN_523625_IDX] = { 20945, 0x0, 0x3A, 0x5C71C, 0x6D1 }, + [ATHOS_B_5G_LUT_CHAN_523750_IDX] = { 20950, 0x0, 0x3A, 0x638E4, 0x6D2 }, + [ATHOS_B_5G_LUT_CHAN_523875_IDX] = { 20955, 0x0, 0x3A, 0x6AAAB, 0x6D2 }, + [ATHOS_B_5G_LUT_CHAN_524000_IDX] = { 20960, 0x0, 0x3A, 0x71C72, 0x6D3 }, + [ATHOS_B_5G_LUT_CHAN_524125_IDX] = { 20965, 0x0, 0x3A, 0x78E39, 0x6D3 }, + [ATHOS_B_5G_LUT_CHAN_524250_IDX] = { 20970, 0x0, 0x3A, 0x80000, 0x6D4 }, + [ATHOS_B_5G_LUT_CHAN_524375_IDX] = { 20975, 0x0, 0x3A, 0x871C7, 0x6D4 }, + [ATHOS_B_5G_LUT_CHAN_524500_IDX] = { 20980, 0x0, 0x3A, 0x8E38E, 0x6D4 }, + [ATHOS_B_5G_LUT_CHAN_524625_IDX] = { 20985, 0x0, 0x3A, 0x95555, 0x6D5 }, + [ATHOS_B_5G_LUT_CHAN_524750_IDX] = { 20990, 0x0, 0x3A, 0x9C71C, 0x6D5 }, + [ATHOS_B_5G_LUT_CHAN_524875_IDX] = { 20995, 0x0, 0x3A, 0xA38E4, 0x6D6 }, + [ATHOS_B_5G_LUT_CHAN_525000_IDX] = { 21000, 0x0, 0x3A, 0xAAAAB, 0x6D6 }, + [ATHOS_B_5G_LUT_CHAN_525125_IDX] = { 21005, 0x0, 0x3A, 0xB1C72, 0x6D6 }, + [ATHOS_B_5G_LUT_CHAN_525250_IDX] = { 21010, 0x0, 0x3A, 0xB8E39, 0x6D7 }, + [ATHOS_B_5G_LUT_CHAN_525375_IDX] = { 21015, 0x0, 0x3A, 0xC0000, 0x6D7 }, + [ATHOS_B_5G_LUT_CHAN_525500_IDX] = { 21020, 0x0, 0x3A, 0xC71C7, 0x6D8 }, + [ATHOS_B_5G_LUT_CHAN_525625_IDX] = { 21025, 0x0, 0x3A, 0xCE38E, 0x6D8 }, + [ATHOS_B_5G_LUT_CHAN_525750_IDX] = { 21030, 0x0, 0x3A, 0xD5555, 0x6D9 }, + [ATHOS_B_5G_LUT_CHAN_525875_IDX] = { 21035, 0x0, 0x3A, 0xDC71C, 0x6D9 }, + [ATHOS_B_5G_LUT_CHAN_526000_IDX] = { 21040, 0x0, 0x3A, 0xE38E4, 0x6D9 }, + [ATHOS_B_5G_LUT_CHAN_526125_IDX] = { 21045, 0x0, 0x3A, 0xEAAAB, 0x6DA }, + [ATHOS_B_5G_LUT_CHAN_526250_IDX] = { 21050, 0x0, 0x3A, 0xF1C72, 0x6DA }, + [ATHOS_B_5G_LUT_CHAN_526375_IDX] = { 21055, 0x0, 0x3A, 0xF8E39, 0x6DB }, + [ATHOS_B_5G_LUT_CHAN_526500_IDX] = { 21060, 0x0, 0x3A, 0x100000, 0x6DB }, + [ATHOS_B_5G_LUT_CHAN_526625_IDX] = { 21065, 0x0, 0x3A, 0x1071C7, 0x6DB }, + [ATHOS_B_5G_LUT_CHAN_526750_IDX] = { 21070, 0x0, 0x3A, 0x10E38E, 0x6DC }, + [ATHOS_B_5G_LUT_CHAN_526875_IDX] = { 21075, 0x0, 0x3A, 0x115555, 0x6DC }, + [ATHOS_B_5G_LUT_CHAN_527000_IDX] = { 21080, 0x0, 0x3A, 0x11C71C, 0x6DD }, + [ATHOS_B_5G_LUT_CHAN_527125_IDX] = { 21085, 0x0, 0x3A, 0x1238E4, 0x6DD }, + [ATHOS_B_5G_LUT_CHAN_527250_IDX] = { 21090, 0x0, 0x3A, 0x12AAAB, 0x6DE }, + [ATHOS_B_5G_LUT_CHAN_527375_IDX] = { 21095, 0x0, 0x3A, 0x131C72, 0x6DE }, + [ATHOS_B_5G_LUT_CHAN_527500_IDX] = { 21100, 0x0, 0x3A, 0x138E39, 0x6DE }, + [ATHOS_B_5G_LUT_CHAN_527625_IDX] = { 21105, 0x0, 0x3A, 0x140000, 0x6DF }, + [ATHOS_B_5G_LUT_CHAN_527750_IDX] = { 21110, 0x0, 0x3A, 0x1471C7, 0x6DF }, + [ATHOS_B_5G_LUT_CHAN_527875_IDX] = { 21115, 0x0, 0x3A, 0x14E38E, 0x6E0 }, + [ATHOS_B_5G_LUT_CHAN_528000_IDX] = { 21120, 0x0, 0x3A, 0x155555, 0x6E0 }, + [ATHOS_B_5G_LUT_CHAN_528125_IDX] = { 21125, 0x0, 0x3A, 0x15C71C, 0x6E0 }, + [ATHOS_B_5G_LUT_CHAN_528250_IDX] = { 21130, 0x0, 0x3A, 0x1638E4, 0x6E1 }, + [ATHOS_B_5G_LUT_CHAN_528375_IDX] = { 21135, 0x0, 0x3A, 0x16AAAB, 0x6E1 }, + [ATHOS_B_5G_LUT_CHAN_528500_IDX] = { 21140, 0x0, 0x3A, 0x171C72, 0x6E2 }, + [ATHOS_B_5G_LUT_CHAN_528625_IDX] = { 21145, 0x0, 0x3A, 0x178E39, 0x6E2 }, + [ATHOS_B_5G_LUT_CHAN_528750_IDX] = { 21150, 0x0, 0x3A, 0x180000, 0x6E3 }, + [ATHOS_B_5G_LUT_CHAN_528875_IDX] = { 21155, 0x0, 0x3A, 0x1871C7, 0x6E3 }, + [ATHOS_B_5G_LUT_CHAN_529000_IDX] = { 21160, 0x0, 0x3A, 0x18E38E, 0x6E3 }, + [ATHOS_B_5G_LUT_CHAN_529125_IDX] = { 21165, 0x0, 0x3A, 0x195555, 0x6E4 }, + [ATHOS_B_5G_LUT_CHAN_529250_IDX] = { 21170, 0x0, 0x3A, 0x19C71C, 0x6E4 }, + [ATHOS_B_5G_LUT_CHAN_529375_IDX] = { 21175, 0x0, 0x3A, 0x1A38E4, 0x6E5 }, + [ATHOS_B_5G_LUT_CHAN_529500_IDX] = { 21180, 0x0, 0x3A, 0x1AAAAB, 0x6E5 }, + [ATHOS_B_5G_LUT_CHAN_529625_IDX] = { 21185, 0x0, 0x3A, 0x1B1C72, 0x6E5 }, + [ATHOS_B_5G_LUT_CHAN_529750_IDX] = { 21190, 0x0, 0x3A, 0x1B8E39, 0x6E6 }, + [ATHOS_B_5G_LUT_CHAN_529875_IDX] = { 21195, 0x0, 0x3A, 0x1C0000, 0x6E6 }, + [ATHOS_B_5G_LUT_CHAN_530000_IDX] = { 21200, 0x0, 0x3A, 0x1C71C7, 0x6E7 }, + [ATHOS_B_5G_LUT_CHAN_530125_IDX] = { 21205, 0x0, 0x3A, 0x1CE38E, 0x6E7 }, + [ATHOS_B_5G_LUT_CHAN_530250_IDX] = { 21210, 0x0, 0x3A, 0x1D5555, 0x6E8 }, + [ATHOS_B_5G_LUT_CHAN_530375_IDX] = { 21215, 0x0, 0x3A, 0x1DC71C, 0x6E8 }, + [ATHOS_B_5G_LUT_CHAN_530500_IDX] = { 21220, 0x0, 0x3A, 0x1E38E4, 0x6E8 }, + [ATHOS_B_5G_LUT_CHAN_530625_IDX] = { 21225, 0x0, 0x3A, 0x1EAAAB, 0x6E9 }, + [ATHOS_B_5G_LUT_CHAN_530750_IDX] = { 21230, 0x0, 0x3A, 0x1F1C72, 0x6E9 }, + [ATHOS_B_5G_LUT_CHAN_530875_IDX] = { 21235, 0x0, 0x3A, 0x1F8E39, 0x6EA }, + [ATHOS_B_5G_LUT_CHAN_531000_IDX] = { 21240, 0x0, 0x3B, 0x0, 0x6EA }, + [ATHOS_B_5G_LUT_CHAN_531125_IDX] = { 21245, 0x0, 0x3B, 0x71C7, 0x6EA }, + [ATHOS_B_5G_LUT_CHAN_531250_IDX] = { 21250, 0x0, 0x3B, 0xE38E, 0x6EB }, + [ATHOS_B_5G_LUT_CHAN_531375_IDX] = { 21255, 0x0, 0x3B, 0x15555, 0x6EB }, + [ATHOS_B_5G_LUT_CHAN_531500_IDX] = { 21260, 0x0, 0x3B, 0x1C71C, 0x6EC }, + [ATHOS_B_5G_LUT_CHAN_531625_IDX] = { 21265, 0x0, 0x3B, 0x238E4, 0x6EC }, + [ATHOS_B_5G_LUT_CHAN_531750_IDX] = { 21270, 0x0, 0x3B, 0x2AAAB, 0x6ED }, + [ATHOS_B_5G_LUT_CHAN_531875_IDX] = { 21275, 0x0, 0x3B, 0x31C72, 0x6ED }, + [ATHOS_B_5G_LUT_CHAN_532000_IDX] = { 21280, 0x0, 0x3B, 0x38E39, 0x6ED }, + [ATHOS_B_5G_LUT_CHAN_532125_IDX] = { 21285, 0x0, 0x3B, 0x40000, 0x6EE }, + [ATHOS_B_5G_LUT_CHAN_532250_IDX] = { 21290, 0x0, 0x3B, 0x471C7, 0x6EE }, + [ATHOS_B_5G_LUT_CHAN_532375_IDX] = { 21295, 0x0, 0x3B, 0x4E38E, 0x6EF }, + [ATHOS_B_5G_LUT_CHAN_532500_IDX] = { 21300, 0x0, 0x3B, 0x55555, 0x6EF }, + [ATHOS_B_5G_LUT_CHAN_532625_IDX] = { 21305, 0x0, 0x3B, 0x5C71C, 0x6EF }, + [ATHOS_B_5G_LUT_CHAN_532750_IDX] = { 21310, 0x0, 0x3B, 0x638E4, 0x6F0 }, + [ATHOS_B_5G_LUT_CHAN_532875_IDX] = { 21315, 0x0, 0x3B, 0x6AAAB, 0x6F0 }, + [ATHOS_B_5G_LUT_CHAN_533000_IDX] = { 21320, 0x0, 0x3B, 0x71C72, 0x6F1 }, + [ATHOS_B_5G_LUT_CHAN_533125_IDX] = { 21325, 0x0, 0x3B, 0x78E39, 0x6F1 }, + [ATHOS_B_5G_LUT_CHAN_533250_IDX] = { 21330, 0x0, 0x3B, 0x80000, 0x6F2 }, + [ATHOS_B_5G_LUT_CHAN_533375_IDX] = { 21335, 0x0, 0x3B, 0x871C7, 0x6F2 }, + [ATHOS_B_5G_LUT_CHAN_533500_IDX] = { 21340, 0x0, 0x3B, 0x8E38E, 0x6F2 }, + [ATHOS_B_5G_LUT_CHAN_533625_IDX] = { 21345, 0x0, 0x3B, 0x95555, 0x6F3 }, + [ATHOS_B_5G_LUT_CHAN_533750_IDX] = { 21350, 0x0, 0x3B, 0x9C71C, 0x6F3 }, + [ATHOS_B_5G_LUT_CHAN_533875_IDX] = { 21355, 0x0, 0x3B, 0xA38E4, 0x6F4 }, + [ATHOS_B_5G_LUT_CHAN_534000_IDX] = { 21360, 0x0, 0x3B, 0xAAAAB, 0x6F4 }, + [ATHOS_B_5G_LUT_CHAN_534125_IDX] = { 21365, 0x0, 0x3B, 0xB1C72, 0x6F4 }, + [ATHOS_B_5G_LUT_CHAN_534250_IDX] = { 21370, 0x0, 0x3B, 0xB8E39, 0x6F5 }, + [ATHOS_B_5G_LUT_CHAN_534375_IDX] = { 21375, 0x0, 0x3B, 0xC0000, 0x6F5 }, + [ATHOS_B_5G_LUT_CHAN_534500_IDX] = { 21380, 0x0, 0x3B, 0xC71C7, 0x6F6 }, + [ATHOS_B_5G_LUT_CHAN_534625_IDX] = { 21385, 0x0, 0x3B, 0xCE38E, 0x6F6 }, + [ATHOS_B_5G_LUT_CHAN_534750_IDX] = { 21390, 0x0, 0x3B, 0xD5555, 0x6F7 }, + [ATHOS_B_5G_LUT_CHAN_534875_IDX] = { 21395, 0x0, 0x3B, 0xDC71C, 0x6F7 }, + [ATHOS_B_5G_LUT_CHAN_535000_IDX] = { 21400, 0x0, 0x3B, 0xE38E4, 0x6F7 }, + [ATHOS_B_5G_LUT_CHAN_535125_IDX] = { 21405, 0x0, 0x3B, 0xEAAAB, 0x6F8 }, + [ATHOS_B_5G_LUT_CHAN_535250_IDX] = { 21410, 0x0, 0x3B, 0xF1C72, 0x6F8 }, + [ATHOS_B_5G_LUT_CHAN_535375_IDX] = { 21415, 0x0, 0x3B, 0xF8E39, 0x6F9 }, + [ATHOS_B_5G_LUT_CHAN_535500_IDX] = { 21420, 0x0, 0x3B, 0x100000, 0x6F9 }, + [ATHOS_B_5G_LUT_CHAN_535625_IDX] = { 21425, 0x0, 0x3B, 0x1071C7, 0x6F9 }, + [ATHOS_B_5G_LUT_CHAN_535750_IDX] = { 21430, 0x0, 0x3B, 0x10E38E, 0x6FA }, + [ATHOS_B_5G_LUT_CHAN_535875_IDX] = { 21435, 0x0, 0x3B, 0x115555, 0x6FA }, + [ATHOS_B_5G_LUT_CHAN_536000_IDX] = { 21440, 0x0, 0x3B, 0x11C71C, 0x6FB }, + [ATHOS_B_5G_LUT_CHAN_536125_IDX] = { 21445, 0x0, 0x3B, 0x1238E4, 0x6FB }, + [ATHOS_B_5G_LUT_CHAN_536250_IDX] = { 21450, 0x0, 0x3B, 0x12AAAB, 0x6FC }, + [ATHOS_B_5G_LUT_CHAN_536375_IDX] = { 21455, 0x0, 0x3B, 0x131C72, 0x6FC }, + [ATHOS_B_5G_LUT_CHAN_536500_IDX] = { 21460, 0x0, 0x3B, 0x138E39, 0x6FC }, + [ATHOS_B_5G_LUT_CHAN_536625_IDX] = { 21465, 0x0, 0x3B, 0x140000, 0x6FD }, + [ATHOS_B_5G_LUT_CHAN_536750_IDX] = { 21470, 0x0, 0x3B, 0x1471C7, 0x6FD }, + [ATHOS_B_5G_LUT_CHAN_536875_IDX] = { 21475, 0x0, 0x3B, 0x14E38E, 0x6FE }, + [ATHOS_B_5G_LUT_CHAN_537000_IDX] = { 21480, 0x0, 0x3B, 0x155555, 0x6FE }, + [ATHOS_B_5G_LUT_CHAN_537125_IDX] = { 21485, 0x0, 0x3B, 0x15C71C, 0x6FE }, + [ATHOS_B_5G_LUT_CHAN_537250_IDX] = { 21490, 0x0, 0x3B, 0x1638E4, 0x6FF }, + [ATHOS_B_5G_LUT_CHAN_537375_IDX] = { 21495, 0x0, 0x3B, 0x16AAAB, 0x6FF }, + [ATHOS_B_5G_LUT_CHAN_537500_IDX] = { 21500, 0x0, 0x3B, 0x171C72, 0x700 }, + [ATHOS_B_5G_LUT_CHAN_537625_IDX] = { 21505, 0x0, 0x3B, 0x178E39, 0x700 }, + [ATHOS_B_5G_LUT_CHAN_537750_IDX] = { 21510, 0x0, 0x3B, 0x180000, 0x701 }, + [ATHOS_B_5G_LUT_CHAN_537875_IDX] = { 21515, 0x0, 0x3B, 0x1871C7, 0x701 }, + [ATHOS_B_5G_LUT_CHAN_538000_IDX] = { 21520, 0x0, 0x3B, 0x18E38E, 0x701 }, + [ATHOS_B_5G_LUT_CHAN_538125_IDX] = { 21525, 0x0, 0x3B, 0x195555, 0x702 }, + [ATHOS_B_5G_LUT_CHAN_538250_IDX] = { 21530, 0x0, 0x3B, 0x19C71C, 0x702 }, + [ATHOS_B_5G_LUT_CHAN_538375_IDX] = { 21535, 0x0, 0x3B, 0x1A38E4, 0x703 }, + [ATHOS_B_5G_LUT_CHAN_538500_IDX] = { 21540, 0x0, 0x3B, 0x1AAAAB, 0x703 }, + [ATHOS_B_5G_LUT_CHAN_538625_IDX] = { 21545, 0x0, 0x3B, 0x1B1C72, 0x703 }, + [ATHOS_B_5G_LUT_CHAN_538750_IDX] = { 21550, 0x0, 0x3B, 0x1B8E39, 0x704 }, + [ATHOS_B_5G_LUT_CHAN_538875_IDX] = { 21555, 0x0, 0x3B, 0x1C0000, 0x704 }, + [ATHOS_B_5G_LUT_CHAN_539000_IDX] = { 21560, 0x0, 0x3B, 0x1C71C7, 0x705 }, + [ATHOS_B_5G_LUT_CHAN_539125_IDX] = { 21565, 0x0, 0x3B, 0x1CE38E, 0x705 }, + [ATHOS_B_5G_LUT_CHAN_539250_IDX] = { 21570, 0x0, 0x3B, 0x1D5555, 0x706 }, + [ATHOS_B_5G_LUT_CHAN_539375_IDX] = { 21575, 0x0, 0x3B, 0x1DC71C, 0x706 }, + [ATHOS_B_5G_LUT_CHAN_539500_IDX] = { 21580, 0x0, 0x3B, 0x1E38E4, 0x706 }, + [ATHOS_B_5G_LUT_CHAN_539625_IDX] = { 21585, 0x0, 0x3B, 0x1EAAAB, 0x707 }, + [ATHOS_B_5G_LUT_CHAN_539750_IDX] = { 21590, 0x0, 0x3B, 0x1F1C72, 0x707 }, + [ATHOS_B_5G_LUT_CHAN_539875_IDX] = { 21595, 0x0, 0x3B, 0x1F8E39, 0x708 }, + [ATHOS_B_5G_LUT_CHAN_540000_IDX] = { 21600, 0x0, 0x3C, 0x0, 0x708 }, + [ATHOS_B_5G_LUT_CHAN_540125_IDX] = { 21605, 0x0, 0x3C, 0x71C7, 0x708 }, + [ATHOS_B_5G_LUT_CHAN_540250_IDX] = { 21610, 0x0, 0x3C, 0xE38E, 0x709 }, + [ATHOS_B_5G_LUT_CHAN_540375_IDX] = { 21615, 0x0, 0x3C, 0x15555, 0x709 }, + [ATHOS_B_5G_LUT_CHAN_540500_IDX] = { 21620, 0x0, 0x3C, 0x1C71C, 0x70A }, + [ATHOS_B_5G_LUT_CHAN_540625_IDX] = { 21625, 0x0, 0x3C, 0x238E4, 0x70A }, + [ATHOS_B_5G_LUT_CHAN_540750_IDX] = { 21630, 0x0, 0x3C, 0x2AAAB, 0x70B }, + [ATHOS_B_5G_LUT_CHAN_540875_IDX] = { 21635, 0x0, 0x3C, 0x31C72, 0x70B }, + [ATHOS_B_5G_LUT_CHAN_541000_IDX] = { 21640, 0x0, 0x3C, 0x38E39, 0x70B }, + [ATHOS_B_5G_LUT_CHAN_541125_IDX] = { 21645, 0x0, 0x3C, 0x40000, 0x70C }, + [ATHOS_B_5G_LUT_CHAN_541250_IDX] = { 21650, 0x0, 0x3C, 0x471C7, 0x70C }, + [ATHOS_B_5G_LUT_CHAN_541375_IDX] = { 21655, 0x0, 0x3C, 0x4E38E, 0x70D }, + [ATHOS_B_5G_LUT_CHAN_541500_IDX] = { 21660, 0x0, 0x3C, 0x55555, 0x70D }, + [ATHOS_B_5G_LUT_CHAN_541625_IDX] = { 21665, 0x0, 0x3C, 0x5C71C, 0x70D }, + [ATHOS_B_5G_LUT_CHAN_541750_IDX] = { 21670, 0x0, 0x3C, 0x638E4, 0x70E }, + [ATHOS_B_5G_LUT_CHAN_541875_IDX] = { 21675, 0x0, 0x3C, 0x6AAAB, 0x70E }, + [ATHOS_B_5G_LUT_CHAN_542000_IDX] = { 21680, 0x0, 0x3C, 0x71C72, 0x70F }, + [ATHOS_B_5G_LUT_CHAN_542125_IDX] = { 21685, 0x0, 0x3C, 0x78E39, 0x70F }, + [ATHOS_B_5G_LUT_CHAN_542250_IDX] = { 21690, 0x0, 0x3C, 0x80000, 0x710 }, + [ATHOS_B_5G_LUT_CHAN_542375_IDX] = { 21695, 0x0, 0x3C, 0x871C7, 0x710 }, + [ATHOS_B_5G_LUT_CHAN_542500_IDX] = { 21700, 0x0, 0x3C, 0x8E38E, 0x710 }, + [ATHOS_B_5G_LUT_CHAN_542625_IDX] = { 21705, 0x0, 0x3C, 0x95555, 0x711 }, + [ATHOS_B_5G_LUT_CHAN_542750_IDX] = { 21710, 0x0, 0x3C, 0x9C71C, 0x711 }, + [ATHOS_B_5G_LUT_CHAN_542875_IDX] = { 21715, 0x0, 0x3C, 0xA38E4, 0x712 }, + [ATHOS_B_5G_LUT_CHAN_543000_IDX] = { 21720, 0x0, 0x3C, 0xAAAAB, 0x712 }, + [ATHOS_B_5G_LUT_CHAN_543125_IDX] = { 21725, 0x0, 0x3C, 0xB1C72, 0x712 }, + [ATHOS_B_5G_LUT_CHAN_543250_IDX] = { 21730, 0x0, 0x3C, 0xB8E39, 0x713 }, + [ATHOS_B_5G_LUT_CHAN_543375_IDX] = { 21735, 0x0, 0x3C, 0xC0000, 0x713 }, + [ATHOS_B_5G_LUT_CHAN_543500_IDX] = { 21740, 0x0, 0x3C, 0xC71C7, 0x714 }, + [ATHOS_B_5G_LUT_CHAN_543625_IDX] = { 21745, 0x0, 0x3C, 0xCE38E, 0x714 }, + [ATHOS_B_5G_LUT_CHAN_543750_IDX] = { 21750, 0x0, 0x3C, 0xD5555, 0x715 }, + [ATHOS_B_5G_LUT_CHAN_543875_IDX] = { 21755, 0x0, 0x3C, 0xDC71C, 0x715 }, + [ATHOS_B_5G_LUT_CHAN_544000_IDX] = { 21760, 0x0, 0x3C, 0xE38E4, 0x715 }, + [ATHOS_B_5G_LUT_CHAN_544125_IDX] = { 21765, 0x0, 0x3C, 0xEAAAB, 0x716 }, + [ATHOS_B_5G_LUT_CHAN_544250_IDX] = { 21770, 0x0, 0x3C, 0xF1C72, 0x716 }, + [ATHOS_B_5G_LUT_CHAN_544375_IDX] = { 21775, 0x0, 0x3C, 0xF8E39, 0x717 }, + [ATHOS_B_5G_LUT_CHAN_544500_IDX] = { 21780, 0x0, 0x3C, 0x100000, 0x717 }, + [ATHOS_B_5G_LUT_CHAN_544625_IDX] = { 21785, 0x0, 0x3C, 0x1071C7, 0x717 }, + [ATHOS_B_5G_LUT_CHAN_544750_IDX] = { 21790, 0x0, 0x3C, 0x10E38E, 0x718 }, + [ATHOS_B_5G_LUT_CHAN_544875_IDX] = { 21795, 0x0, 0x3C, 0x115555, 0x718 }, + [ATHOS_B_5G_LUT_CHAN_545000_IDX] = { 21800, 0x0, 0x3C, 0x11C71C, 0x719 }, + [ATHOS_B_5G_LUT_CHAN_545125_IDX] = { 21805, 0x0, 0x3C, 0x1238E4, 0x719 }, + [ATHOS_B_5G_LUT_CHAN_545250_IDX] = { 21810, 0x0, 0x3C, 0x12AAAB, 0x71A }, + [ATHOS_B_5G_LUT_CHAN_545375_IDX] = { 21815, 0x0, 0x3C, 0x131C72, 0x71A }, + [ATHOS_B_5G_LUT_CHAN_545500_IDX] = { 21820, 0x0, 0x3C, 0x138E39, 0x71A }, + [ATHOS_B_5G_LUT_CHAN_545625_IDX] = { 21825, 0x0, 0x3C, 0x140000, 0x71B }, + [ATHOS_B_5G_LUT_CHAN_545750_IDX] = { 21830, 0x0, 0x3C, 0x1471C7, 0x71B }, + [ATHOS_B_5G_LUT_CHAN_545875_IDX] = { 21835, 0x0, 0x3C, 0x14E38E, 0x71C }, + [ATHOS_B_5G_LUT_CHAN_546000_IDX] = { 21840, 0x0, 0x3C, 0x155555, 0x71C }, + [ATHOS_B_5G_LUT_CHAN_546125_IDX] = { 21845, 0x0, 0x3C, 0x15C71C, 0x71C }, + [ATHOS_B_5G_LUT_CHAN_546250_IDX] = { 21850, 0x0, 0x3C, 0x1638E4, 0x71D }, + [ATHOS_B_5G_LUT_CHAN_546375_IDX] = { 21855, 0x0, 0x3C, 0x16AAAB, 0x71D }, + [ATHOS_B_5G_LUT_CHAN_546500_IDX] = { 21860, 0x0, 0x3C, 0x171C72, 0x71E }, + [ATHOS_B_5G_LUT_CHAN_546625_IDX] = { 21865, 0x0, 0x3C, 0x178E39, 0x71E }, + [ATHOS_B_5G_LUT_CHAN_546750_IDX] = { 21870, 0x0, 0x3C, 0x180000, 0x71F }, + [ATHOS_B_5G_LUT_CHAN_546875_IDX] = { 21875, 0x0, 0x3C, 0x1871C7, 0x71F }, + [ATHOS_B_5G_LUT_CHAN_547000_IDX] = { 21880, 0x0, 0x3C, 0x18E38E, 0x71F }, + [ATHOS_B_5G_LUT_CHAN_547125_IDX] = { 21885, 0x0, 0x3C, 0x195555, 0x720 }, + [ATHOS_B_5G_LUT_CHAN_547250_IDX] = { 21890, 0x0, 0x3C, 0x19C71C, 0x720 }, + [ATHOS_B_5G_LUT_CHAN_547375_IDX] = { 21895, 0x0, 0x3C, 0x1A38E4, 0x721 }, + [ATHOS_B_5G_LUT_CHAN_547500_IDX] = { 21900, 0x0, 0x3C, 0x1AAAAB, 0x721 }, + [ATHOS_B_5G_LUT_CHAN_547625_IDX] = { 21905, 0x0, 0x3C, 0x1B1C72, 0x721 }, + [ATHOS_B_5G_LUT_CHAN_547750_IDX] = { 21910, 0x0, 0x3C, 0x1B8E39, 0x722 }, + [ATHOS_B_5G_LUT_CHAN_547875_IDX] = { 21915, 0x0, 0x3C, 0x1C0000, 0x722 }, + [ATHOS_B_5G_LUT_CHAN_548000_IDX] = { 21920, 0x0, 0x3C, 0x1C71C7, 0x723 }, + [ATHOS_B_5G_LUT_CHAN_548125_IDX] = { 21925, 0x0, 0x3C, 0x1CE38E, 0x723 }, + [ATHOS_B_5G_LUT_CHAN_548250_IDX] = { 21930, 0x0, 0x3C, 0x1D5555, 0x724 }, + [ATHOS_B_5G_LUT_CHAN_548375_IDX] = { 21935, 0x0, 0x3C, 0x1DC71C, 0x724 }, + [ATHOS_B_5G_LUT_CHAN_548500_IDX] = { 21940, 0x0, 0x3C, 0x1E38E4, 0x724 }, + [ATHOS_B_5G_LUT_CHAN_548625_IDX] = { 21945, 0x0, 0x3C, 0x1EAAAB, 0x725 }, + [ATHOS_B_5G_LUT_CHAN_548750_IDX] = { 21950, 0x0, 0x3C, 0x1F1C72, 0x725 }, + [ATHOS_B_5G_LUT_CHAN_548875_IDX] = { 21955, 0x0, 0x3C, 0x1F8E39, 0x726 }, + [ATHOS_B_5G_LUT_CHAN_549000_IDX] = { 21960, 0x0, 0x3D, 0x0, 0x726 }, + [ATHOS_B_5G_LUT_CHAN_549125_IDX] = { 21965, 0x0, 0x3D, 0x71C7, 0x726 }, + [ATHOS_B_5G_LUT_CHAN_549250_IDX] = { 21970, 0x0, 0x3D, 0xE38E, 0x727 }, + [ATHOS_B_5G_LUT_CHAN_549375_IDX] = { 21975, 0x0, 0x3D, 0x15555, 0x727 }, + [ATHOS_B_5G_LUT_CHAN_549500_IDX] = { 21980, 0x0, 0x3D, 0x1C71C, 0x728 }, + [ATHOS_B_5G_LUT_CHAN_549625_IDX] = { 21985, 0x0, 0x3D, 0x238E4, 0x728 }, + [ATHOS_B_5G_LUT_CHAN_549750_IDX] = { 21990, 0x0, 0x3D, 0x2AAAB, 0x729 }, + [ATHOS_B_5G_LUT_CHAN_549875_IDX] = { 21995, 0x0, 0x3D, 0x31C72, 0x729 }, + [ATHOS_B_5G_LUT_CHAN_550000_IDX] = { 22000, 0x0, 0x3D, 0x38E39, 0x729 }, + [ATHOS_B_5G_LUT_CHAN_550125_IDX] = { 22005, 0x0, 0x3D, 0x40000, 0x72A }, + [ATHOS_B_5G_LUT_CHAN_550250_IDX] = { 22010, 0x0, 0x3D, 0x471C7, 0x72A }, + [ATHOS_B_5G_LUT_CHAN_550375_IDX] = { 22015, 0x0, 0x3D, 0x4E38E, 0x72B }, + [ATHOS_B_5G_LUT_CHAN_550500_IDX] = { 22020, 0x0, 0x3D, 0x55555, 0x72B }, + [ATHOS_B_5G_LUT_CHAN_550625_IDX] = { 22025, 0x0, 0x3D, 0x5C71C, 0x72B }, + [ATHOS_B_5G_LUT_CHAN_550750_IDX] = { 22030, 0x0, 0x3D, 0x638E4, 0x72C }, + [ATHOS_B_5G_LUT_CHAN_550875_IDX] = { 22035, 0x0, 0x3D, 0x6AAAB, 0x72C }, + [ATHOS_B_5G_LUT_CHAN_551000_IDX] = { 22040, 0x0, 0x3D, 0x71C72, 0x72D }, + [ATHOS_B_5G_LUT_CHAN_551125_IDX] = { 22045, 0x0, 0x3D, 0x78E39, 0x72D }, + [ATHOS_B_5G_LUT_CHAN_551250_IDX] = { 22050, 0x0, 0x3D, 0x80000, 0x72E }, + [ATHOS_B_5G_LUT_CHAN_551375_IDX] = { 22055, 0x0, 0x3D, 0x871C7, 0x72E }, + [ATHOS_B_5G_LUT_CHAN_551500_IDX] = { 22060, 0x0, 0x3D, 0x8E38E, 0x72E }, + [ATHOS_B_5G_LUT_CHAN_551625_IDX] = { 22065, 0x0, 0x3D, 0x95555, 0x72F }, + [ATHOS_B_5G_LUT_CHAN_551750_IDX] = { 22070, 0x0, 0x3D, 0x9C71C, 0x72F }, + [ATHOS_B_5G_LUT_CHAN_551875_IDX] = { 22075, 0x0, 0x3D, 0xA38E4, 0x730 }, + [ATHOS_B_5G_LUT_CHAN_552000_IDX] = { 22080, 0x0, 0x3D, 0xAAAAB, 0x730 }, + [ATHOS_B_5G_LUT_CHAN_552125_IDX] = { 22085, 0x0, 0x3D, 0xB1C72, 0x730 }, + [ATHOS_B_5G_LUT_CHAN_552250_IDX] = { 22090, 0x0, 0x3D, 0xB8E39, 0x731 }, + [ATHOS_B_5G_LUT_CHAN_552375_IDX] = { 22095, 0x0, 0x3D, 0xC0000, 0x731 }, + [ATHOS_B_5G_LUT_CHAN_552500_IDX] = { 22100, 0x0, 0x3D, 0xC71C7, 0x732 }, + [ATHOS_B_5G_LUT_CHAN_552625_IDX] = { 22105, 0x0, 0x3D, 0xCE38E, 0x732 }, + [ATHOS_B_5G_LUT_CHAN_552750_IDX] = { 22110, 0x0, 0x3D, 0xD5555, 0x733 }, + [ATHOS_B_5G_LUT_CHAN_552875_IDX] = { 22115, 0x0, 0x3D, 0xDC71C, 0x733 }, + [ATHOS_B_5G_LUT_CHAN_553000_IDX] = { 22120, 0x0, 0x3D, 0xE38E4, 0x733 }, + [ATHOS_B_5G_LUT_CHAN_553125_IDX] = { 22125, 0x0, 0x3D, 0xEAAAB, 0x734 }, + [ATHOS_B_5G_LUT_CHAN_553250_IDX] = { 22130, 0x0, 0x3D, 0xF1C72, 0x734 }, + [ATHOS_B_5G_LUT_CHAN_553375_IDX] = { 22135, 0x0, 0x3D, 0xF8E39, 0x735 }, + [ATHOS_B_5G_LUT_CHAN_553500_IDX] = { 22140, 0x0, 0x3D, 0x100000, 0x735 }, + [ATHOS_B_5G_LUT_CHAN_553625_IDX] = { 22145, 0x0, 0x3D, 0x1071C7, 0x735 }, + [ATHOS_B_5G_LUT_CHAN_553750_IDX] = { 22150, 0x0, 0x3D, 0x10E38E, 0x736 }, + [ATHOS_B_5G_LUT_CHAN_553875_IDX] = { 22155, 0x0, 0x3D, 0x115555, 0x736 }, + [ATHOS_B_5G_LUT_CHAN_554000_IDX] = { 22160, 0x0, 0x3D, 0x11C71C, 0x737 }, + [ATHOS_B_5G_LUT_CHAN_554125_IDX] = { 22165, 0x0, 0x3D, 0x1238E4, 0x737 }, + [ATHOS_B_5G_LUT_CHAN_554250_IDX] = { 22170, 0x0, 0x3D, 0x12AAAB, 0x738 }, + [ATHOS_B_5G_LUT_CHAN_554375_IDX] = { 22175, 0x0, 0x3D, 0x131C72, 0x738 }, + [ATHOS_B_5G_LUT_CHAN_554500_IDX] = { 22180, 0x0, 0x3D, 0x138E39, 0x738 }, + [ATHOS_B_5G_LUT_CHAN_554625_IDX] = { 22185, 0x0, 0x3D, 0x140000, 0x739 }, + [ATHOS_B_5G_LUT_CHAN_554750_IDX] = { 22190, 0x0, 0x3D, 0x1471C7, 0x739 }, + [ATHOS_B_5G_LUT_CHAN_554875_IDX] = { 22195, 0x0, 0x3D, 0x14E38E, 0x73A }, + [ATHOS_B_5G_LUT_CHAN_555000_IDX] = { 22200, 0x0, 0x3D, 0x155555, 0x73A }, + [ATHOS_B_5G_LUT_CHAN_555125_IDX] = { 22205, 0x0, 0x3D, 0x15C71C, 0x73A }, + [ATHOS_B_5G_LUT_CHAN_555250_IDX] = { 22210, 0x0, 0x3D, 0x1638E4, 0x73B }, + [ATHOS_B_5G_LUT_CHAN_555375_IDX] = { 22215, 0x0, 0x3D, 0x16AAAB, 0x73B }, + [ATHOS_B_5G_LUT_CHAN_555500_IDX] = { 22220, 0x0, 0x3D, 0x171C72, 0x73C }, + [ATHOS_B_5G_LUT_CHAN_555625_IDX] = { 22225, 0x0, 0x3D, 0x178E39, 0x73C }, + [ATHOS_B_5G_LUT_CHAN_555750_IDX] = { 22230, 0x0, 0x3D, 0x180000, 0x73D }, + [ATHOS_B_5G_LUT_CHAN_555875_IDX] = { 22235, 0x0, 0x3D, 0x1871C7, 0x73D }, + [ATHOS_B_5G_LUT_CHAN_556000_IDX] = { 22240, 0x0, 0x3D, 0x18E38E, 0x73D }, + [ATHOS_B_5G_LUT_CHAN_556125_IDX] = { 22245, 0x0, 0x3D, 0x195555, 0x73E }, + [ATHOS_B_5G_LUT_CHAN_556250_IDX] = { 22250, 0x0, 0x3D, 0x19C71C, 0x73E }, + [ATHOS_B_5G_LUT_CHAN_556375_IDX] = { 22255, 0x0, 0x3D, 0x1A38E4, 0x73F }, + [ATHOS_B_5G_LUT_CHAN_556500_IDX] = { 22260, 0x0, 0x3D, 0x1AAAAB, 0x73F }, + [ATHOS_B_5G_LUT_CHAN_556625_IDX] = { 22265, 0x0, 0x3D, 0x1B1C72, 0x73F }, + [ATHOS_B_5G_LUT_CHAN_556750_IDX] = { 22270, 0x0, 0x3D, 0x1B8E39, 0x740 }, + [ATHOS_B_5G_LUT_CHAN_556875_IDX] = { 22275, 0x0, 0x3D, 0x1C0000, 0x740 }, + [ATHOS_B_5G_LUT_CHAN_557000_IDX] = { 22280, 0x0, 0x3D, 0x1C71C7, 0x741 }, + [ATHOS_B_5G_LUT_CHAN_557125_IDX] = { 22285, 0x0, 0x3D, 0x1CE38E, 0x741 }, + [ATHOS_B_5G_LUT_CHAN_557250_IDX] = { 22290, 0x0, 0x3D, 0x1D5555, 0x742 }, + [ATHOS_B_5G_LUT_CHAN_557375_IDX] = { 22295, 0x0, 0x3D, 0x1DC71C, 0x742 }, + [ATHOS_B_5G_LUT_CHAN_557500_IDX] = { 22300, 0x0, 0x3D, 0x1E38E4, 0x742 }, + [ATHOS_B_5G_LUT_CHAN_557625_IDX] = { 22305, 0x0, 0x3D, 0x1EAAAB, 0x743 }, + [ATHOS_B_5G_LUT_CHAN_557750_IDX] = { 22310, 0x0, 0x3D, 0x1F1C72, 0x743 }, + [ATHOS_B_5G_LUT_CHAN_557875_IDX] = { 22315, 0x0, 0x3D, 0x1F8E39, 0x744 }, + [ATHOS_B_5G_LUT_CHAN_558000_IDX] = { 22320, 0x0, 0x3E, 0x0, 0x744 }, + [ATHOS_B_5G_LUT_CHAN_558125_IDX] = { 22325, 0x0, 0x3E, 0x71C7, 0x744 }, + [ATHOS_B_5G_LUT_CHAN_558250_IDX] = { 22330, 0x0, 0x3E, 0xE38E, 0x745 }, + [ATHOS_B_5G_LUT_CHAN_558375_IDX] = { 22335, 0x0, 0x3E, 0x15555, 0x745 }, + [ATHOS_B_5G_LUT_CHAN_558500_IDX] = { 22340, 0x0, 0x3E, 0x1C71C, 0x746 }, + [ATHOS_B_5G_LUT_CHAN_558625_IDX] = { 22345, 0x0, 0x3E, 0x238E4, 0x746 }, + [ATHOS_B_5G_LUT_CHAN_558750_IDX] = { 22350, 0x0, 0x3E, 0x2AAAB, 0x747 }, + [ATHOS_B_5G_LUT_CHAN_558875_IDX] = { 22355, 0x0, 0x3E, 0x31C72, 0x747 }, + [ATHOS_B_5G_LUT_CHAN_559000_IDX] = { 22360, 0x0, 0x3E, 0x38E39, 0x747 }, + [ATHOS_B_5G_LUT_CHAN_559125_IDX] = { 22365, 0x0, 0x3E, 0x40000, 0x748 }, + [ATHOS_B_5G_LUT_CHAN_559250_IDX] = { 22370, 0x0, 0x3E, 0x471C7, 0x748 }, + [ATHOS_B_5G_LUT_CHAN_559375_IDX] = { 22375, 0x0, 0x3E, 0x4E38E, 0x749 }, + [ATHOS_B_5G_LUT_CHAN_559500_IDX] = { 22380, 0x0, 0x3E, 0x55555, 0x749 }, + [ATHOS_B_5G_LUT_CHAN_559625_IDX] = { 22385, 0x0, 0x3E, 0x5C71C, 0x749 }, + [ATHOS_B_5G_LUT_CHAN_559750_IDX] = { 22390, 0x0, 0x3E, 0x638E4, 0x74A }, + [ATHOS_B_5G_LUT_CHAN_559875_IDX] = { 22395, 0x0, 0x3E, 0x6AAAB, 0x74A }, + [ATHOS_B_5G_LUT_CHAN_560000_IDX] = { 22400, 0x0, 0x3E, 0x71C72, 0x74B }, + [ATHOS_B_5G_LUT_CHAN_560125_IDX] = { 22405, 0x0, 0x3E, 0x78E39, 0x74B }, + [ATHOS_B_5G_LUT_CHAN_560250_IDX] = { 22410, 0x0, 0x3E, 0x80000, 0x74C }, + [ATHOS_B_5G_LUT_CHAN_560375_IDX] = { 22415, 0x0, 0x3E, 0x871C7, 0x74C }, + [ATHOS_B_5G_LUT_CHAN_560500_IDX] = { 22420, 0x0, 0x3E, 0x8E38E, 0x74C }, + [ATHOS_B_5G_LUT_CHAN_560625_IDX] = { 22425, 0x0, 0x3E, 0x95555, 0x74D }, + [ATHOS_B_5G_LUT_CHAN_560750_IDX] = { 22430, 0x0, 0x3E, 0x9C71C, 0x74D }, + [ATHOS_B_5G_LUT_CHAN_560875_IDX] = { 22435, 0x0, 0x3E, 0xA38E4, 0x74E }, + [ATHOS_B_5G_LUT_CHAN_561000_IDX] = { 22440, 0x0, 0x3E, 0xAAAAB, 0x74E }, + [ATHOS_B_5G_LUT_CHAN_561125_IDX] = { 22445, 0x0, 0x3E, 0xB1C72, 0x74E }, + [ATHOS_B_5G_LUT_CHAN_561250_IDX] = { 22450, 0x0, 0x3E, 0xB8E39, 0x74F }, + [ATHOS_B_5G_LUT_CHAN_561375_IDX] = { 22455, 0x0, 0x3E, 0xC0000, 0x74F }, + [ATHOS_B_5G_LUT_CHAN_561500_IDX] = { 22460, 0x0, 0x3E, 0xC71C7, 0x750 }, + [ATHOS_B_5G_LUT_CHAN_561625_IDX] = { 22465, 0x0, 0x3E, 0xCE38E, 0x750 }, + [ATHOS_B_5G_LUT_CHAN_561750_IDX] = { 22470, 0x0, 0x3E, 0xD5555, 0x751 }, + [ATHOS_B_5G_LUT_CHAN_561875_IDX] = { 22475, 0x0, 0x3E, 0xDC71C, 0x751 }, + [ATHOS_B_5G_LUT_CHAN_562000_IDX] = { 22480, 0x0, 0x3E, 0xE38E4, 0x751 }, + [ATHOS_B_5G_LUT_CHAN_562125_IDX] = { 22485, 0x0, 0x3E, 0xEAAAB, 0x752 }, + [ATHOS_B_5G_LUT_CHAN_562250_IDX] = { 22490, 0x0, 0x3E, 0xF1C72, 0x752 }, + [ATHOS_B_5G_LUT_CHAN_562375_IDX] = { 22495, 0x0, 0x3E, 0xF8E39, 0x753 }, + [ATHOS_B_5G_LUT_CHAN_562500_IDX] = { 22500, 0x0, 0x3E, 0x100000, 0x753 }, + [ATHOS_B_5G_LUT_CHAN_562625_IDX] = { 22505, 0x0, 0x3E, 0x1071C7, 0x753 }, + [ATHOS_B_5G_LUT_CHAN_562750_IDX] = { 22510, 0x0, 0x3E, 0x10E38E, 0x754 }, + [ATHOS_B_5G_LUT_CHAN_562875_IDX] = { 22515, 0x0, 0x3E, 0x115555, 0x754 }, + [ATHOS_B_5G_LUT_CHAN_563000_IDX] = { 22520, 0x0, 0x3E, 0x11C71C, 0x755 }, + [ATHOS_B_5G_LUT_CHAN_563125_IDX] = { 22525, 0x0, 0x3E, 0x1238E4, 0x755 }, + [ATHOS_B_5G_LUT_CHAN_563250_IDX] = { 22530, 0x0, 0x3E, 0x12AAAB, 0x756 }, + [ATHOS_B_5G_LUT_CHAN_563375_IDX] = { 22535, 0x0, 0x3E, 0x131C72, 0x756 }, + [ATHOS_B_5G_LUT_CHAN_563500_IDX] = { 22540, 0x0, 0x3E, 0x138E39, 0x756 }, + [ATHOS_B_5G_LUT_CHAN_563625_IDX] = { 22545, 0x0, 0x3E, 0x140000, 0x757 }, + [ATHOS_B_5G_LUT_CHAN_563750_IDX] = { 22550, 0x0, 0x3E, 0x1471C7, 0x757 }, + [ATHOS_B_5G_LUT_CHAN_563875_IDX] = { 22555, 0x0, 0x3E, 0x14E38E, 0x758 }, + [ATHOS_B_5G_LUT_CHAN_564000_IDX] = { 22560, 0x0, 0x3E, 0x155555, 0x758 }, + [ATHOS_B_5G_LUT_CHAN_564125_IDX] = { 22565, 0x0, 0x3E, 0x15C71C, 0x758 }, + [ATHOS_B_5G_LUT_CHAN_564250_IDX] = { 22570, 0x0, 0x3E, 0x1638E4, 0x759 }, + [ATHOS_B_5G_LUT_CHAN_564375_IDX] = { 22575, 0x0, 0x3E, 0x16AAAB, 0x759 }, + [ATHOS_B_5G_LUT_CHAN_564500_IDX] = { 22580, 0x0, 0x3E, 0x171C72, 0x75A }, + [ATHOS_B_5G_LUT_CHAN_564625_IDX] = { 22585, 0x0, 0x3E, 0x178E39, 0x75A }, + [ATHOS_B_5G_LUT_CHAN_564750_IDX] = { 22590, 0x0, 0x3E, 0x180000, 0x75B }, + [ATHOS_B_5G_LUT_CHAN_564875_IDX] = { 22595, 0x0, 0x3E, 0x1871C7, 0x75B }, + [ATHOS_B_5G_LUT_CHAN_565000_IDX] = { 22600, 0x0, 0x3E, 0x18E38E, 0x75B }, + [ATHOS_B_5G_LUT_CHAN_565125_IDX] = { 22605, 0x0, 0x3E, 0x195555, 0x75C }, + [ATHOS_B_5G_LUT_CHAN_565250_IDX] = { 22610, 0x0, 0x3E, 0x19C71C, 0x75C }, + [ATHOS_B_5G_LUT_CHAN_565375_IDX] = { 22615, 0x0, 0x3E, 0x1A38E4, 0x75D }, + [ATHOS_B_5G_LUT_CHAN_565500_IDX] = { 22620, 0x0, 0x3E, 0x1AAAAB, 0x75D }, + [ATHOS_B_5G_LUT_CHAN_565625_IDX] = { 22625, 0x0, 0x3E, 0x1B1C72, 0x75D }, + [ATHOS_B_5G_LUT_CHAN_565750_IDX] = { 22630, 0x0, 0x3E, 0x1B8E39, 0x75E }, + [ATHOS_B_5G_LUT_CHAN_565875_IDX] = { 22635, 0x0, 0x3E, 0x1C0000, 0x75E }, + [ATHOS_B_5G_LUT_CHAN_566000_IDX] = { 22640, 0x0, 0x3E, 0x1C71C7, 0x75F }, + [ATHOS_B_5G_LUT_CHAN_566125_IDX] = { 22645, 0x0, 0x3E, 0x1CE38E, 0x75F }, + [ATHOS_B_5G_LUT_CHAN_566250_IDX] = { 22650, 0x0, 0x3E, 0x1D5555, 0x760 }, + [ATHOS_B_5G_LUT_CHAN_566375_IDX] = { 22655, 0x0, 0x3E, 0x1DC71C, 0x760 }, + [ATHOS_B_5G_LUT_CHAN_566500_IDX] = { 22660, 0x0, 0x3E, 0x1E38E4, 0x760 }, + [ATHOS_B_5G_LUT_CHAN_566625_IDX] = { 22665, 0x0, 0x3E, 0x1EAAAB, 0x761 }, + [ATHOS_B_5G_LUT_CHAN_566750_IDX] = { 22670, 0x0, 0x3E, 0x1F1C72, 0x761 }, + [ATHOS_B_5G_LUT_CHAN_566875_IDX] = { 22675, 0x0, 0x3E, 0x1F8E39, 0x762 }, + [ATHOS_B_5G_LUT_CHAN_567000_IDX] = { 22680, 0x0, 0x3F, 0x0, 0x762 }, + [ATHOS_B_5G_LUT_CHAN_567125_IDX] = { 22685, 0x0, 0x3F, 0x71C7, 0x762 }, + [ATHOS_B_5G_LUT_CHAN_567250_IDX] = { 22690, 0x0, 0x3F, 0xE38E, 0x763 }, + [ATHOS_B_5G_LUT_CHAN_567375_IDX] = { 22695, 0x0, 0x3F, 0x15555, 0x763 }, + [ATHOS_B_5G_LUT_CHAN_567500_IDX] = { 22700, 0x0, 0x3F, 0x1C71C, 0x764 }, + [ATHOS_B_5G_LUT_CHAN_567625_IDX] = { 22705, 0x0, 0x3F, 0x238E4, 0x764 }, + [ATHOS_B_5G_LUT_CHAN_567750_IDX] = { 22710, 0x0, 0x3F, 0x2AAAB, 0x765 }, + [ATHOS_B_5G_LUT_CHAN_567875_IDX] = { 22715, 0x0, 0x3F, 0x31C72, 0x765 }, + [ATHOS_B_5G_LUT_CHAN_568000_IDX] = { 22720, 0x0, 0x3F, 0x38E39, 0x765 }, + [ATHOS_B_5G_LUT_CHAN_568125_IDX] = { 22725, 0x0, 0x3F, 0x40000, 0x766 }, + [ATHOS_B_5G_LUT_CHAN_568250_IDX] = { 22730, 0x0, 0x3F, 0x471C7, 0x766 }, + [ATHOS_B_5G_LUT_CHAN_568375_IDX] = { 22735, 0x0, 0x3F, 0x4E38E, 0x767 }, + [ATHOS_B_5G_LUT_CHAN_568500_IDX] = { 22740, 0x0, 0x3F, 0x55555, 0x767 }, + [ATHOS_B_5G_LUT_CHAN_568625_IDX] = { 22745, 0x0, 0x3F, 0x5C71C, 0x767 }, + [ATHOS_B_5G_LUT_CHAN_568750_IDX] = { 22750, 0x0, 0x3F, 0x638E4, 0x768 }, + [ATHOS_B_5G_LUT_CHAN_568875_IDX] = { 22755, 0x0, 0x3F, 0x6AAAB, 0x768 }, + [ATHOS_B_5G_LUT_CHAN_569000_IDX] = { 22760, 0x0, 0x3F, 0x71C72, 0x769 }, + [ATHOS_B_5G_LUT_CHAN_569125_IDX] = { 22765, 0x0, 0x3F, 0x78E39, 0x769 }, + [ATHOS_B_5G_LUT_CHAN_569250_IDX] = { 22770, 0x0, 0x3F, 0x80000, 0x76A }, + [ATHOS_B_5G_LUT_CHAN_569375_IDX] = { 22775, 0x0, 0x3F, 0x871C7, 0x76A }, + [ATHOS_B_5G_LUT_CHAN_569500_IDX] = { 22780, 0x0, 0x3F, 0x8E38E, 0x76A }, + [ATHOS_B_5G_LUT_CHAN_569625_IDX] = { 22785, 0x0, 0x3F, 0x95555, 0x76B }, + [ATHOS_B_5G_LUT_CHAN_569750_IDX] = { 22790, 0x0, 0x3F, 0x9C71C, 0x76B }, + [ATHOS_B_5G_LUT_CHAN_569875_IDX] = { 22795, 0x0, 0x3F, 0xA38E4, 0x76C }, + [ATHOS_B_5G_LUT_CHAN_570000_IDX] = { 22800, 0x0, 0x3F, 0xAAAAB, 0x76C }, + [ATHOS_B_5G_LUT_CHAN_570125_IDX] = { 22805, 0x0, 0x3F, 0xB1C72, 0x76C }, + [ATHOS_B_5G_LUT_CHAN_570250_IDX] = { 22810, 0x0, 0x3F, 0xB8E39, 0x76D }, + [ATHOS_B_5G_LUT_CHAN_570375_IDX] = { 22815, 0x0, 0x3F, 0xC0000, 0x76D }, + [ATHOS_B_5G_LUT_CHAN_570500_IDX] = { 22820, 0x0, 0x3F, 0xC71C7, 0x76E }, + [ATHOS_B_5G_LUT_CHAN_570625_IDX] = { 22825, 0x0, 0x3F, 0xCE38E, 0x76E }, + [ATHOS_B_5G_LUT_CHAN_570750_IDX] = { 22830, 0x0, 0x3F, 0xD5555, 0x76F }, + [ATHOS_B_5G_LUT_CHAN_570875_IDX] = { 22835, 0x0, 0x3F, 0xDC71C, 0x76F }, + [ATHOS_B_5G_LUT_CHAN_571000_IDX] = { 22840, 0x0, 0x3F, 0xE38E4, 0x76F }, + [ATHOS_B_5G_LUT_CHAN_571125_IDX] = { 22845, 0x0, 0x3F, 0xEAAAB, 0x770 }, + [ATHOS_B_5G_LUT_CHAN_571250_IDX] = { 22850, 0x0, 0x3F, 0xF1C72, 0x770 }, + [ATHOS_B_5G_LUT_CHAN_571375_IDX] = { 22855, 0x0, 0x3F, 0xF8E39, 0x771 }, + [ATHOS_B_5G_LUT_CHAN_571500_IDX] = { 22860, 0x0, 0x3F, 0x100000, 0x771 }, + [ATHOS_B_5G_LUT_CHAN_571625_IDX] = { 22865, 0x0, 0x3F, 0x1071C7, 0x771 }, + [ATHOS_B_5G_LUT_CHAN_571750_IDX] = { 22870, 0x0, 0x3F, 0x10E38E, 0x772 }, + [ATHOS_B_5G_LUT_CHAN_571875_IDX] = { 22875, 0x0, 0x3F, 0x115555, 0x772 }, + [ATHOS_B_5G_LUT_CHAN_572000_IDX] = { 22880, 0x0, 0x3F, 0x11C71C, 0x773 }, + [ATHOS_B_5G_LUT_CHAN_572125_IDX] = { 22885, 0x0, 0x3F, 0x1238E4, 0x773 }, + [ATHOS_B_5G_LUT_CHAN_572250_IDX] = { 22890, 0x0, 0x3F, 0x12AAAB, 0x774 }, + [ATHOS_B_5G_LUT_CHAN_572375_IDX] = { 22895, 0x0, 0x3F, 0x131C72, 0x774 }, + [ATHOS_B_5G_LUT_CHAN_572500_IDX] = { 22900, 0x0, 0x3F, 0x138E39, 0x774 }, + [ATHOS_B_5G_LUT_CHAN_572625_IDX] = { 22905, 0x0, 0x3F, 0x140000, 0x775 }, + [ATHOS_B_5G_LUT_CHAN_572750_IDX] = { 22910, 0x0, 0x3F, 0x1471C7, 0x775 }, + [ATHOS_B_5G_LUT_CHAN_572875_IDX] = { 22915, 0x0, 0x3F, 0x14E38E, 0x776 }, + [ATHOS_B_5G_LUT_CHAN_573000_IDX] = { 22920, 0x0, 0x3F, 0x155555, 0x776 }, + [ATHOS_B_5G_LUT_CHAN_573125_IDX] = { 22925, 0x0, 0x3F, 0x15C71C, 0x776 }, + [ATHOS_B_5G_LUT_CHAN_573250_IDX] = { 22930, 0x0, 0x3F, 0x1638E4, 0x777 }, + [ATHOS_B_5G_LUT_CHAN_573375_IDX] = { 22935, 0x0, 0x3F, 0x16AAAB, 0x777 }, + [ATHOS_B_5G_LUT_CHAN_573500_IDX] = { 22940, 0x0, 0x3F, 0x171C72, 0x778 }, + [ATHOS_B_5G_LUT_CHAN_573625_IDX] = { 22945, 0x0, 0x3F, 0x178E39, 0x778 }, + [ATHOS_B_5G_LUT_CHAN_573750_IDX] = { 22950, 0x0, 0x3F, 0x180000, 0x779 }, + [ATHOS_B_5G_LUT_CHAN_573875_IDX] = { 22955, 0x0, 0x3F, 0x1871C7, 0x779 }, + [ATHOS_B_5G_LUT_CHAN_574000_IDX] = { 22960, 0x0, 0x3F, 0x18E38E, 0x779 }, + [ATHOS_B_5G_LUT_CHAN_574125_IDX] = { 22965, 0x0, 0x3F, 0x195555, 0x77A }, + [ATHOS_B_5G_LUT_CHAN_574250_IDX] = { 22970, 0x0, 0x3F, 0x19C71C, 0x77A }, + [ATHOS_B_5G_LUT_CHAN_574375_IDX] = { 22975, 0x0, 0x3F, 0x1A38E4, 0x77B }, + [ATHOS_B_5G_LUT_CHAN_574500_IDX] = { 22980, 0x0, 0x3F, 0x1AAAAB, 0x77B }, + [ATHOS_B_5G_LUT_CHAN_574625_IDX] = { 22985, 0x0, 0x3F, 0x1B1C72, 0x77B }, + [ATHOS_B_5G_LUT_CHAN_574750_IDX] = { 22990, 0x0, 0x3F, 0x1B8E39, 0x77C }, + [ATHOS_B_5G_LUT_CHAN_574875_IDX] = { 22995, 0x0, 0x3F, 0x1C0000, 0x77C }, + [ATHOS_B_5G_LUT_CHAN_575000_IDX] = { 23000, 0x0, 0x3F, 0x1C71C7, 0x77D }, + [ATHOS_B_5G_LUT_CHAN_575125_IDX] = { 23005, 0x0, 0x3F, 0x1CE38E, 0x77D }, + [ATHOS_B_5G_LUT_CHAN_575250_IDX] = { 23010, 0x0, 0x3F, 0x1D5555, 0x77E }, + [ATHOS_B_5G_LUT_CHAN_575375_IDX] = { 23015, 0x0, 0x3F, 0x1DC71C, 0x77E }, + [ATHOS_B_5G_LUT_CHAN_575500_IDX] = { 23020, 0x0, 0x3F, 0x1E38E4, 0x77E }, + [ATHOS_B_5G_LUT_CHAN_575625_IDX] = { 23025, 0x0, 0x3F, 0x1EAAAB, 0x77F }, + [ATHOS_B_5G_LUT_CHAN_575750_IDX] = { 23030, 0x0, 0x3F, 0x1F1C72, 0x77F }, + [ATHOS_B_5G_LUT_CHAN_575875_IDX] = { 23035, 0x0, 0x3F, 0x1F8E39, 0x780 }, + [ATHOS_B_5G_LUT_CHAN_576000_IDX] = { 23040, 0x0, 0x40, 0x0, 0x780 }, + [ATHOS_B_5G_LUT_CHAN_576125_IDX] = { 23045, 0x0, 0x40, 0x71C7, 0x780 }, + [ATHOS_B_5G_LUT_CHAN_576250_IDX] = { 23050, 0x0, 0x40, 0xE38E, 0x781 }, + [ATHOS_B_5G_LUT_CHAN_576375_IDX] = { 23055, 0x0, 0x40, 0x15555, 0x781 }, + [ATHOS_B_5G_LUT_CHAN_576500_IDX] = { 23060, 0x0, 0x40, 0x1C71C, 0x782 }, + [ATHOS_B_5G_LUT_CHAN_576625_IDX] = { 23065, 0x0, 0x40, 0x238E4, 0x782 }, + [ATHOS_B_5G_LUT_CHAN_576750_IDX] = { 23070, 0x0, 0x40, 0x2AAAB, 0x783 }, + [ATHOS_B_5G_LUT_CHAN_576875_IDX] = { 23075, 0x0, 0x40, 0x31C72, 0x783 }, + [ATHOS_B_5G_LUT_CHAN_577000_IDX] = { 23080, 0x0, 0x40, 0x38E39, 0x783 }, + [ATHOS_B_5G_LUT_CHAN_577125_IDX] = { 23085, 0x0, 0x40, 0x40000, 0x784 }, + [ATHOS_B_5G_LUT_CHAN_577250_IDX] = { 23090, 0x0, 0x40, 0x471C7, 0x784 }, + [ATHOS_B_5G_LUT_CHAN_577375_IDX] = { 23095, 0x0, 0x40, 0x4E38E, 0x785 }, + [ATHOS_B_5G_LUT_CHAN_577500_IDX] = { 23100, 0x0, 0x40, 0x55555, 0x785 }, + [ATHOS_B_5G_LUT_CHAN_577625_IDX] = { 23105, 0x0, 0x40, 0x5C71C, 0x785 }, + [ATHOS_B_5G_LUT_CHAN_577750_IDX] = { 23110, 0x0, 0x40, 0x638E4, 0x786 }, + [ATHOS_B_5G_LUT_CHAN_577875_IDX] = { 23115, 0x0, 0x40, 0x6AAAB, 0x786 }, + [ATHOS_B_5G_LUT_CHAN_578000_IDX] = { 23120, 0x0, 0x40, 0x71C72, 0x787 }, + [ATHOS_B_5G_LUT_CHAN_578125_IDX] = { 23125, 0x0, 0x40, 0x78E39, 0x787 }, + [ATHOS_B_5G_LUT_CHAN_578250_IDX] = { 23130, 0x0, 0x40, 0x80000, 0x788 }, + [ATHOS_B_5G_LUT_CHAN_578375_IDX] = { 23135, 0x0, 0x40, 0x871C7, 0x788 }, + [ATHOS_B_5G_LUT_CHAN_578500_IDX] = { 23140, 0x0, 0x40, 0x8E38E, 0x788 }, + [ATHOS_B_5G_LUT_CHAN_578625_IDX] = { 23145, 0x0, 0x40, 0x95555, 0x789 }, + [ATHOS_B_5G_LUT_CHAN_578750_IDX] = { 23150, 0x0, 0x40, 0x9C71C, 0x789 }, + [ATHOS_B_5G_LUT_CHAN_578875_IDX] = { 23155, 0x0, 0x40, 0xA38E4, 0x78A }, + [ATHOS_B_5G_LUT_CHAN_579000_IDX] = { 23160, 0x0, 0x40, 0xAAAAB, 0x78A }, + [ATHOS_B_5G_LUT_CHAN_579125_IDX] = { 23165, 0x0, 0x40, 0xB1C72, 0x78A }, + [ATHOS_B_5G_LUT_CHAN_579250_IDX] = { 23170, 0x0, 0x40, 0xB8E39, 0x78B }, + [ATHOS_B_5G_LUT_CHAN_579375_IDX] = { 23175, 0x0, 0x40, 0xC0000, 0x78B }, + [ATHOS_B_5G_LUT_CHAN_579500_IDX] = { 23180, 0x0, 0x40, 0xC71C7, 0x78C }, + [ATHOS_B_5G_LUT_CHAN_579625_IDX] = { 23185, 0x0, 0x40, 0xCE38E, 0x78C }, + [ATHOS_B_5G_LUT_CHAN_579750_IDX] = { 23190, 0x0, 0x40, 0xD5555, 0x78D }, + [ATHOS_B_5G_LUT_CHAN_579875_IDX] = { 23195, 0x0, 0x40, 0xDC71C, 0x78D }, + [ATHOS_B_5G_LUT_CHAN_580000_IDX] = { 23200, 0x0, 0x40, 0xE38E4, 0x78D }, + [ATHOS_B_5G_LUT_CHAN_580125_IDX] = { 23205, 0x0, 0x40, 0xEAAAB, 0x78E }, + [ATHOS_B_5G_LUT_CHAN_580250_IDX] = { 23210, 0x0, 0x40, 0xF1C72, 0x78E }, + [ATHOS_B_5G_LUT_CHAN_580375_IDX] = { 23215, 0x0, 0x40, 0xF8E39, 0x78F }, + [ATHOS_B_5G_LUT_CHAN_580500_IDX] = { 23220, 0x0, 0x40, 0x100000, 0x78F }, + [ATHOS_B_5G_LUT_CHAN_580625_IDX] = { 23225, 0x0, 0x40, 0x1071C7, 0x78F }, + [ATHOS_B_5G_LUT_CHAN_580750_IDX] = { 23230, 0x0, 0x40, 0x10E38E, 0x790 }, + [ATHOS_B_5G_LUT_CHAN_580875_IDX] = { 23235, 0x0, 0x40, 0x115555, 0x790 }, + [ATHOS_B_5G_LUT_CHAN_581000_IDX] = { 23240, 0x0, 0x40, 0x11C71C, 0x791 }, + [ATHOS_B_5G_LUT_CHAN_581125_IDX] = { 23245, 0x0, 0x40, 0x1238E4, 0x791 }, + [ATHOS_B_5G_LUT_CHAN_581250_IDX] = { 23250, 0x0, 0x40, 0x12AAAB, 0x792 }, + [ATHOS_B_5G_LUT_CHAN_581375_IDX] = { 23255, 0x0, 0x40, 0x131C72, 0x792 }, + [ATHOS_B_5G_LUT_CHAN_581500_IDX] = { 23260, 0x0, 0x40, 0x138E39, 0x792 }, + [ATHOS_B_5G_LUT_CHAN_581625_IDX] = { 23265, 0x0, 0x40, 0x140000, 0x793 }, + [ATHOS_B_5G_LUT_CHAN_581750_IDX] = { 23270, 0x0, 0x40, 0x1471C7, 0x793 }, + [ATHOS_B_5G_LUT_CHAN_581875_IDX] = { 23275, 0x0, 0x40, 0x14E38E, 0x794 }, + [ATHOS_B_5G_LUT_CHAN_582000_IDX] = { 23280, 0x0, 0x40, 0x155555, 0x794 }, + [ATHOS_B_5G_LUT_CHAN_582125_IDX] = { 23285, 0x0, 0x40, 0x15C71C, 0x794 }, + [ATHOS_B_5G_LUT_CHAN_582250_IDX] = { 23290, 0x0, 0x40, 0x1638E4, 0x795 }, + [ATHOS_B_5G_LUT_CHAN_582375_IDX] = { 23295, 0x0, 0x40, 0x16AAAB, 0x795 }, + [ATHOS_B_5G_LUT_CHAN_582500_IDX] = { 23300, 0x0, 0x40, 0x171C72, 0x796 }, + [ATHOS_B_5G_LUT_CHAN_582625_IDX] = { 23305, 0x0, 0x40, 0x178E39, 0x796 }, + [ATHOS_B_5G_LUT_CHAN_582750_IDX] = { 23310, 0x0, 0x40, 0x180000, 0x797 }, + [ATHOS_B_5G_LUT_CHAN_582875_IDX] = { 23315, 0x0, 0x40, 0x1871C7, 0x797 }, + [ATHOS_B_5G_LUT_CHAN_583000_IDX] = { 23320, 0x0, 0x40, 0x18E38E, 0x797 }, + [ATHOS_B_5G_LUT_CHAN_583125_IDX] = { 23325, 0x0, 0x40, 0x195555, 0x798 }, + [ATHOS_B_5G_LUT_CHAN_583250_IDX] = { 23330, 0x0, 0x40, 0x19C71C, 0x798 }, + [ATHOS_B_5G_LUT_CHAN_583375_IDX] = { 23335, 0x0, 0x40, 0x1A38E4, 0x799 }, + [ATHOS_B_5G_LUT_CHAN_583500_IDX] = { 23340, 0x0, 0x40, 0x1AAAAB, 0x799 }, + [ATHOS_B_5G_LUT_CHAN_583625_IDX] = { 23345, 0x0, 0x40, 0x1B1C72, 0x799 }, + [ATHOS_B_5G_LUT_CHAN_583750_IDX] = { 23350, 0x0, 0x40, 0x1B8E39, 0x79A }, + [ATHOS_B_5G_LUT_CHAN_583875_IDX] = { 23355, 0x0, 0x40, 0x1C0000, 0x79A }, + [ATHOS_B_5G_LUT_CHAN_584000_IDX] = { 23360, 0x0, 0x40, 0x1C71C7, 0x79B }, + [ATHOS_B_5G_LUT_CHAN_584125_IDX] = { 23365, 0x0, 0x40, 0x1CE38E, 0x79B }, + [ATHOS_B_5G_LUT_CHAN_584250_IDX] = { 23370, 0x0, 0x40, 0x1D5555, 0x79C }, + [ATHOS_B_5G_LUT_CHAN_584375_IDX] = { 23375, 0x0, 0x40, 0x1DC71C, 0x79C }, + [ATHOS_B_5G_LUT_CHAN_584500_IDX] = { 23380, 0x0, 0x40, 0x1E38E4, 0x79C }, + [ATHOS_B_5G_LUT_CHAN_584625_IDX] = { 23385, 0x0, 0x40, 0x1EAAAB, 0x79D }, + [ATHOS_B_5G_LUT_CHAN_584750_IDX] = { 23390, 0x0, 0x40, 0x1F1C72, 0x79D }, + [ATHOS_B_5G_LUT_CHAN_584875_IDX] = { 23395, 0x0, 0x40, 0x1F8E39, 0x79E }, + [ATHOS_B_5G_LUT_CHAN_585000_IDX] = { 23400, 0x0, 0x41, 0x0, 0x79E }, + [ATHOS_B_5G_LUT_CHAN_585125_IDX] = { 23405, 0x0, 0x41, 0x71C7, 0x79E }, + [ATHOS_B_5G_LUT_CHAN_585250_IDX] = { 23410, 0x0, 0x41, 0xE38E, 0x79F }, + [ATHOS_B_5G_LUT_CHAN_585375_IDX] = { 23415, 0x0, 0x41, 0x15555, 0x79F }, + [ATHOS_B_5G_LUT_CHAN_585500_IDX] = { 23420, 0x0, 0x41, 0x1C71C, 0x7A0 }, + [ATHOS_B_5G_LUT_CHAN_585625_IDX] = { 23425, 0x0, 0x41, 0x238E4, 0x7A0 }, + [ATHOS_B_5G_LUT_CHAN_585750_IDX] = { 23430, 0x0, 0x41, 0x2AAAB, 0x7A1 }, + [ATHOS_B_5G_LUT_CHAN_585875_IDX] = { 23435, 0x0, 0x41, 0x31C72, 0x7A1 }, + [ATHOS_B_5G_LUT_CHAN_586000_IDX] = { 23440, 0x0, 0x41, 0x38E39, 0x7A1 }, + [ATHOS_B_5G_LUT_CHAN_586125_IDX] = { 23445, 0x0, 0x41, 0x40000, 0x7A2 }, + [ATHOS_B_5G_LUT_CHAN_586250_IDX] = { 23450, 0x0, 0x41, 0x471C7, 0x7A2 }, + [ATHOS_B_5G_LUT_CHAN_586375_IDX] = { 23455, 0x0, 0x41, 0x4E38E, 0x7A3 }, + [ATHOS_B_5G_LUT_CHAN_586500_IDX] = { 23460, 0x0, 0x41, 0x55555, 0x7A3 }, + [ATHOS_B_5G_LUT_CHAN_586625_IDX] = { 23465, 0x0, 0x41, 0x5C71C, 0x7A3 }, + [ATHOS_B_5G_LUT_CHAN_586750_IDX] = { 23470, 0x0, 0x41, 0x638E4, 0x7A4 }, + [ATHOS_B_5G_LUT_CHAN_586875_IDX] = { 23475, 0x0, 0x41, 0x6AAAB, 0x7A4 }, + [ATHOS_B_5G_LUT_CHAN_587000_IDX] = { 23480, 0x0, 0x41, 0x71C72, 0x7A5 }, + [ATHOS_B_5G_LUT_CHAN_587125_IDX] = { 23485, 0x0, 0x41, 0x78E39, 0x7A5 }, + [ATHOS_B_5G_LUT_CHAN_587250_IDX] = { 23490, 0x0, 0x41, 0x80000, 0x7A6 }, + [ATHOS_B_5G_LUT_CHAN_587375_IDX] = { 23495, 0x0, 0x41, 0x871C7, 0x7A6 }, + [ATHOS_B_5G_LUT_CHAN_587500_IDX] = { 23500, 0x0, 0x41, 0x8E38E, 0x7A6 }, + [ATHOS_B_5G_LUT_CHAN_587625_IDX] = { 23505, 0x0, 0x41, 0x95555, 0x7A7 }, + [ATHOS_B_5G_LUT_CHAN_587750_IDX] = { 23510, 0x0, 0x41, 0x9C71C, 0x7A7 }, + [ATHOS_B_5G_LUT_CHAN_587875_IDX] = { 23515, 0x0, 0x41, 0xA38E4, 0x7A8 }, + [ATHOS_B_5G_LUT_CHAN_588000_IDX] = { 23520, 0x0, 0x41, 0xAAAAB, 0x7A8 }, + [ATHOS_B_5G_LUT_CHAN_588125_IDX] = { 23525, 0x0, 0x41, 0xB1C72, 0x7A8 }, + [ATHOS_B_5G_LUT_CHAN_588250_IDX] = { 23530, 0x0, 0x41, 0xB8E39, 0x7A9 }, + [ATHOS_B_5G_LUT_CHAN_588375_IDX] = { 23535, 0x0, 0x41, 0xC0000, 0x7A9 }, + [ATHOS_B_5G_LUT_CHAN_588500_IDX] = { 23540, 0x0, 0x41, 0xC71C7, 0x7AA }, + [ATHOS_B_5G_LUT_CHAN_588625_IDX] = { 23545, 0x0, 0x41, 0xCE38E, 0x7AA }, + [ATHOS_B_5G_LUT_CHAN_588750_IDX] = { 23550, 0x0, 0x41, 0xD5555, 0x7AB }, + [ATHOS_B_5G_LUT_CHAN_588875_IDX] = { 23555, 0x0, 0x41, 0xDC71C, 0x7AB }, + [ATHOS_B_5G_LUT_CHAN_589000_IDX] = { 23560, 0x0, 0x41, 0xE38E4, 0x7AB }, + [ATHOS_B_5G_LUT_CHAN_589125_IDX] = { 23565, 0x0, 0x41, 0xEAAAB, 0x7AC }, + [ATHOS_B_5G_LUT_CHAN_589250_IDX] = { 23570, 0x0, 0x41, 0xF1C72, 0x7AC }, + [ATHOS_B_5G_LUT_CHAN_589375_IDX] = { 23575, 0x0, 0x41, 0xF8E39, 0x7AD }, + [ATHOS_B_5G_LUT_CHAN_589500_IDX] = { 23580, 0x0, 0x41, 0x100000, 0x7AD }, + [ATHOS_B_5G_LUT_CHAN_589625_IDX] = { 23585, 0x0, 0x41, 0x1071C7, 0x7AD }, + [ATHOS_B_5G_LUT_CHAN_589750_IDX] = { 23590, 0x0, 0x41, 0x10E38E, 0x7AE }, + [ATHOS_B_5G_LUT_CHAN_589875_IDX] = { 23595, 0x0, 0x41, 0x115555, 0x7AE }, + [ATHOS_B_5G_LUT_CHAN_590000_IDX] = { 23600, 0x0, 0x41, 0x11C71C, 0x7AF }, + [ATHOS_B_5G_LUT_CHAN_590125_IDX] = { 23605, 0x0, 0x41, 0x1238E4, 0x7AF }, + [ATHOS_B_5G_LUT_CHAN_590250_IDX] = { 23610, 0x0, 0x41, 0x12AAAB, 0x7B0 }, + [ATHOS_B_5G_LUT_CHAN_590375_IDX] = { 23615, 0x0, 0x41, 0x131C72, 0x7B0 }, + [ATHOS_B_5G_LUT_CHAN_590500_IDX] = { 23620, 0x0, 0x41, 0x138E39, 0x7B0 }, + [ATHOS_B_5G_LUT_CHAN_590625_IDX] = { 23625, 0x0, 0x41, 0x140000, 0x7B1 }, + [ATHOS_B_5G_LUT_CHAN_590750_IDX] = { 23630, 0x0, 0x41, 0x1471C7, 0x7B1 }, + [ATHOS_B_5G_LUT_CHAN_590875_IDX] = { 23635, 0x0, 0x41, 0x14E38E, 0x7B2 }, + [ATHOS_B_5G_LUT_CHAN_591000_IDX] = { 23640, 0x0, 0x41, 0x155555, 0x7B2 }, + [ATHOS_B_5G_LUT_CHAN_591125_IDX] = { 23645, 0x0, 0x41, 0x15C71C, 0x7B2 }, + [ATHOS_B_5G_LUT_CHAN_591250_IDX] = { 23650, 0x0, 0x41, 0x1638E4, 0x7B3 }, + [ATHOS_B_5G_LUT_CHAN_591375_IDX] = { 23655, 0x0, 0x41, 0x16AAAB, 0x7B3 }, + [ATHOS_B_5G_LUT_CHAN_591500_IDX] = { 23660, 0x0, 0x41, 0x171C72, 0x7B4 }, + [ATHOS_B_5G_LUT_CHAN_591625_IDX] = { 23665, 0x0, 0x41, 0x178E39, 0x7B4 }, + [ATHOS_B_5G_LUT_CHAN_591750_IDX] = { 23670, 0x0, 0x41, 0x180000, 0x7B5 }, + [ATHOS_B_5G_LUT_CHAN_591875_IDX] = { 23675, 0x0, 0x41, 0x1871C7, 0x7B5 }, + [ATHOS_B_5G_LUT_CHAN_592000_IDX] = { 23680, 0x0, 0x41, 0x18E38E, 0x7B5 }, + [ATHOS_B_5G_LUT_CHAN_592125_IDX] = { 23685, 0x0, 0x41, 0x195555, 0x7B6 }, + [ATHOS_B_5G_LUT_CHAN_592250_IDX] = { 23690, 0x0, 0x41, 0x19C71C, 0x7B6 }, + [ATHOS_B_5G_LUT_CHAN_592375_IDX] = { 23695, 0x0, 0x41, 0x1A38E4, 0x7B7 }, + [ATHOS_B_5G_LUT_CHAN_592500_IDX] = { 23700, 0x0, 0x41, 0x1AAAAB, 0x7B7 }, + [ATHOS_B_5G_LUT_CHAN_592625_IDX] = { 23705, 0x0, 0x41, 0x1B1C72, 0x7B7 }, + [ATHOS_B_5G_LUT_CHAN_592750_IDX] = { 23710, 0x0, 0x41, 0x1B8E39, 0x7B8 }, + [ATHOS_B_5G_LUT_CHAN_592875_IDX] = { 23715, 0x0, 0x41, 0x1C0000, 0x7B8 }, + [ATHOS_B_5G_LUT_CHAN_593000_IDX] = { 23720, 0x0, 0x41, 0x1C71C7, 0x7B9 }, + [ATHOS_B_5G_LUT_CHAN_593125_IDX] = { 23725, 0x0, 0x41, 0x1CE38E, 0x7B9 }, + [ATHOS_B_5G_LUT_CHAN_593250_IDX] = { 23730, 0x0, 0x41, 0x1D5555, 0x7BA }, + [ATHOS_B_5G_LUT_CHAN_593375_IDX] = { 23735, 0x0, 0x41, 0x1DC71C, 0x7BA }, + [ATHOS_B_5G_LUT_CHAN_593500_IDX] = { 23740, 0x0, 0x41, 0x1E38E4, 0x7BA }, + [ATHOS_B_5G_LUT_CHAN_593625_IDX] = { 23745, 0x0, 0x41, 0x1EAAAB, 0x7BB }, + [ATHOS_B_5G_LUT_CHAN_593750_IDX] = { 23750, 0x0, 0x41, 0x1F1C72, 0x7BB }, + [ATHOS_B_5G_LUT_CHAN_593875_IDX] = { 23755, 0x0, 0x41, 0x1F8E39, 0x7BC }, + [ATHOS_B_5G_LUT_CHAN_594000_IDX] = { 23760, 0x0, 0x42, 0x0, 0x7BC }, + [ATHOS_B_5G_LUT_CHAN_594125_IDX] = { 23765, 0x0, 0x42, 0x71C7, 0x7BC }, + [ATHOS_B_5G_LUT_CHAN_594250_IDX] = { 23770, 0x0, 0x42, 0xE38E, 0x7BD }, + [ATHOS_B_5G_LUT_CHAN_594375_IDX] = { 23775, 0x0, 0x42, 0x15555, 0x7BD }, + [ATHOS_B_5G_LUT_CHAN_594500_IDX] = { 23780, 0x0, 0x42, 0x1C71C, 0x7BE }, + [ATHOS_B_5G_LUT_CHAN_594625_IDX] = { 23785, 0x0, 0x42, 0x238E4, 0x7BE }, + [ATHOS_B_5G_LUT_CHAN_594750_IDX] = { 23790, 0x0, 0x42, 0x2AAAB, 0x7BF }, + [ATHOS_B_5G_LUT_CHAN_594875_IDX] = { 23795, 0x0, 0x42, 0x31C72, 0x7BF }, + [ATHOS_B_5G_LUT_CHAN_595000_IDX] = { 23800, 0x0, 0x42, 0x38E39, 0x7BF } +}; + +const struct common_lut_line olympus_lut_5g_40_mhz[OLYMPUS_LUT_CHAN_5G_MAX] = { + [OLYMPUS_LUT_CHAN_516000_IDX] = { 20640, 0x0, 0x56, 0x0, 0x6B8 }, + [OLYMPUS_LUT_CHAN_516125_IDX] = { 20645, 0x0, 0x56, 0xAAAB, 0x6B8 }, + [OLYMPUS_LUT_CHAN_516250_IDX] = { 20650, 0x0, 0x56, 0x15555, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516375_IDX] = { 20655, 0x0, 0x56, 0x20000, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516500_IDX] = { 20660, 0x0, 0x56, 0x2AAAB, 0x6BA }, + [OLYMPUS_LUT_CHAN_516625_IDX] = { 20665, 0x0, 0x56, 0x35555, 0x6BA }, + [OLYMPUS_LUT_CHAN_516750_IDX] = { 20670, 0x0, 0x56, 0x40000, 0x6BB }, + [OLYMPUS_LUT_CHAN_516875_IDX] = { 20675, 0x0, 0x56, 0x4AAAB, 0x6BB }, + [OLYMPUS_LUT_CHAN_517000_IDX] = { 20680, 0x0, 0x56, 0x55555, 0x6BB }, + [OLYMPUS_LUT_CHAN_517125_IDX] = { 20685, 0x0, 0x56, 0x60000, 0x6BC }, + [OLYMPUS_LUT_CHAN_517250_IDX] = { 20690, 0x0, 0x56, 0x6AAAB, 0x6BC }, + [OLYMPUS_LUT_CHAN_517375_IDX] = { 20695, 0x0, 0x56, 0x75555, 0x6BD }, + [OLYMPUS_LUT_CHAN_517500_IDX] = { 20700, 0x0, 0x56, 0x80000, 0x6BD }, + [OLYMPUS_LUT_CHAN_517625_IDX] = { 20705, 0x0, 0x56, 0x8AAAB, 0x6BD }, + [OLYMPUS_LUT_CHAN_517750_IDX] = { 20710, 0x0, 0x56, 0x95555, 0x6BE }, + [OLYMPUS_LUT_CHAN_517875_IDX] = { 20715, 0x0, 0x56, 0xA0000, 0x6BE }, + [OLYMPUS_LUT_CHAN_518000_IDX] = { 20720, 0x1, 0x56, 0xAAAAB, 0x6BF }, + [OLYMPUS_LUT_CHAN_518125_IDX] = { 20725, 0x1, 0x56, 0xB5555, 0x6BF }, + [OLYMPUS_LUT_CHAN_518250_IDX] = { 20730, 0x1, 0x56, 0xC0000, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518375_IDX] = { 20735, 0x1, 0x56, 0xCAAAB, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518500_IDX] = { 20740, 0x1, 0x56, 0xD5555, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518625_IDX] = { 20745, 0x1, 0x56, 0xE0000, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518750_IDX] = { 20750, 0x1, 0x56, 0xEAAAB, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518875_IDX] = { 20755, 0x1, 0x56, 0xF5555, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519000_IDX] = { 20760, 0x1, 0x56, 0x100000, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519125_IDX] = { 20765, 0x1, 0x56, 0x10AAAB, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519250_IDX] = { 20770, 0x1, 0x56, 0x115555, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519375_IDX] = { 20775, 0x1, 0x56, 0x120000, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519500_IDX] = { 20780, 0x1, 0x56, 0x12AAAB, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519625_IDX] = { 20785, 0x1, 0x56, 0x135555, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519750_IDX] = { 20790, 0x1, 0x56, 0x140000, 0x6C5 }, + [OLYMPUS_LUT_CHAN_519875_IDX] = { 20795, 0x1, 0x56, 0x14AAAB, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520000_IDX] = { 20800, 0x1, 0x56, 0x155555, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520125_IDX] = { 20805, 0x1, 0x56, 0x160000, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520250_IDX] = { 20810, 0x1, 0x56, 0x16AAAB, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520375_IDX] = { 20815, 0x1, 0x56, 0x175555, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520500_IDX] = { 20820, 0x1, 0x56, 0x180000, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520625_IDX] = { 20825, 0x1, 0x56, 0x18AAAB, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520750_IDX] = { 20830, 0x1, 0x56, 0x195555, 0x6C8 }, + [OLYMPUS_LUT_CHAN_520875_IDX] = { 20835, 0x1, 0x56, 0x1A0000, 0x6C8 }, + [OLYMPUS_LUT_CHAN_521000_IDX] = { 20840, 0x1, 0x56, 0x1AAAAB, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521125_IDX] = { 20845, 0x1, 0x56, 0x1B5555, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521250_IDX] = { 20850, 0x1, 0x56, 0x1C0000, 0x6CA }, + [OLYMPUS_LUT_CHAN_521375_IDX] = { 20855, 0x1, 0x56, 0x1CAAAB, 0x6CA }, + [OLYMPUS_LUT_CHAN_521500_IDX] = { 20860, 0x1, 0x56, 0x1D5555, 0x6CA }, + [OLYMPUS_LUT_CHAN_521625_IDX] = { 20865, 0x1, 0x56, 0x1E0000, 0x6CB }, + [OLYMPUS_LUT_CHAN_521750_IDX] = { 20870, 0x1, 0x56, 0x1EAAAB, 0x6CB }, + [OLYMPUS_LUT_CHAN_521875_IDX] = { 20875, 0x1, 0x56, 0x1F5555, 0x6CC }, + [OLYMPUS_LUT_CHAN_522000_IDX] = { 20880, 0x1, 0x57, 0x0, 0x6CC }, + [OLYMPUS_LUT_CHAN_522125_IDX] = { 20885, 0x1, 0x57, 0xAAAB, 0x6CC }, + [OLYMPUS_LUT_CHAN_522250_IDX] = { 20890, 0x1, 0x57, 0x15555, 0x6CD }, + [OLYMPUS_LUT_CHAN_522375_IDX] = { 20895, 0x1, 0x57, 0x20000, 0x6CD }, + [OLYMPUS_LUT_CHAN_522500_IDX] = { 20900, 0x1, 0x57, 0x2AAAB, 0x6CE }, + [OLYMPUS_LUT_CHAN_522625_IDX] = { 20905, 0x1, 0x57, 0x35555, 0x6CE }, + [OLYMPUS_LUT_CHAN_522750_IDX] = { 20910, 0x1, 0x57, 0x40000, 0x6CF }, + [OLYMPUS_LUT_CHAN_522875_IDX] = { 20915, 0x1, 0x57, 0x4AAAB, 0x6CF }, + [OLYMPUS_LUT_CHAN_523000_IDX] = { 20920, 0x1, 0x57, 0x55555, 0x6CF }, + [OLYMPUS_LUT_CHAN_523125_IDX] = { 20925, 0x1, 0x57, 0x60000, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523250_IDX] = { 20930, 0x1, 0x57, 0x6AAAB, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523375_IDX] = { 20935, 0x1, 0x57, 0x75555, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523500_IDX] = { 20940, 0x1, 0x57, 0x80000, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523625_IDX] = { 20945, 0x1, 0x57, 0x8AAAB, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523750_IDX] = { 20950, 0x1, 0x57, 0x95555, 0x6D2 }, + [OLYMPUS_LUT_CHAN_523875_IDX] = { 20955, 0x1, 0x57, 0xA0000, 0x6D2 }, + [OLYMPUS_LUT_CHAN_524000_IDX] = { 20960, 0x1, 0x57, 0xAAAAB, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524125_IDX] = { 20965, 0x1, 0x57, 0xB5555, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524250_IDX] = { 20970, 0x1, 0x57, 0xC0000, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524375_IDX] = { 20975, 0x1, 0x57, 0xCAAAB, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524500_IDX] = { 20980, 0x1, 0x57, 0xD5555, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524625_IDX] = { 20985, 0x1, 0x57, 0xE0000, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524750_IDX] = { 20990, 0x1, 0x57, 0xEAAAB, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524875_IDX] = { 20995, 0x1, 0x57, 0xF5555, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525000_IDX] = { 21000, 0x1, 0x57, 0x100000, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525125_IDX] = { 21005, 0x1, 0x57, 0x10AAAB, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525250_IDX] = { 21010, 0x1, 0x57, 0x115555, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525375_IDX] = { 21015, 0x1, 0x57, 0x120000, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525500_IDX] = { 21020, 0x1, 0x57, 0x12AAAB, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525625_IDX] = { 21025, 0x1, 0x57, 0x135555, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525750_IDX] = { 21030, 0x1, 0x57, 0x140000, 0x6D9 }, + [OLYMPUS_LUT_CHAN_525875_IDX] = { 21035, 0x1, 0x57, 0x14AAAB, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526000_IDX] = { 21040, 0x1, 0x57, 0x155555, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526125_IDX] = { 21045, 0x1, 0x57, 0x160000, 0x6DA }, + [OLYMPUS_LUT_CHAN_526250_IDX] = { 21050, 0x1, 0x57, 0x16AAAB, 0x6DA }, + [OLYMPUS_LUT_CHAN_526375_IDX] = { 21055, 0x1, 0x57, 0x175555, 0x6DB }, + [OLYMPUS_LUT_CHAN_526500_IDX] = { 21060, 0x1, 0x57, 0x180000, 0x6DB }, + [OLYMPUS_LUT_CHAN_526625_IDX] = { 21065, 0x1, 0x57, 0x18AAAB, 0x6DB }, + [OLYMPUS_LUT_CHAN_526750_IDX] = { 21070, 0x1, 0x57, 0x195555, 0x6DC }, + [OLYMPUS_LUT_CHAN_526875_IDX] = { 21075, 0x1, 0x57, 0x1A0000, 0x6DC }, + [OLYMPUS_LUT_CHAN_527000_IDX] = { 21080, 0x1, 0x57, 0x1AAAAB, 0x6DD }, + [OLYMPUS_LUT_CHAN_527125_IDX] = { 21085, 0x1, 0x57, 0x1B5555, 0x6DD }, + [OLYMPUS_LUT_CHAN_527250_IDX] = { 21090, 0x1, 0x57, 0x1C0000, 0x6DE }, + [OLYMPUS_LUT_CHAN_527375_IDX] = { 21095, 0x1, 0x57, 0x1CAAAB, 0x6DE }, + [OLYMPUS_LUT_CHAN_527500_IDX] = { 21100, 0x1, 0x57, 0x1D5555, 0x6DE }, + [OLYMPUS_LUT_CHAN_527625_IDX] = { 21105, 0x1, 0x57, 0x1E0000, 0x6DF }, + [OLYMPUS_LUT_CHAN_527750_IDX] = { 21110, 0x1, 0x57, 0x1EAAAB, 0x6DF }, + [OLYMPUS_LUT_CHAN_527875_IDX] = { 21115, 0x1, 0x57, 0x1F5555, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528000_IDX] = { 21120, 0x1, 0x58, 0x0, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528125_IDX] = { 21125, 0x1, 0x58, 0xAAAB, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528250_IDX] = { 21130, 0x1, 0x58, 0x15555, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528375_IDX] = { 21135, 0x1, 0x58, 0x20000, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528500_IDX] = { 21140, 0x1, 0x58, 0x2AAAB, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528625_IDX] = { 21145, 0x1, 0x58, 0x35555, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528750_IDX] = { 21150, 0x1, 0x58, 0x40000, 0x6E3 }, + [OLYMPUS_LUT_CHAN_528875_IDX] = { 21155, 0x1, 0x58, 0x4AAAB, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529000_IDX] = { 21160, 0x1, 0x58, 0x55555, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529125_IDX] = { 21165, 0x1, 0x58, 0x60000, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529250_IDX] = { 21170, 0x1, 0x58, 0x6AAAB, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529375_IDX] = { 21175, 0x1, 0x58, 0x75555, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529500_IDX] = { 21180, 0x1, 0x58, 0x80000, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529625_IDX] = { 21185, 0x1, 0x58, 0x8AAAB, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529750_IDX] = { 21190, 0x1, 0x58, 0x95555, 0x6E6 }, + [OLYMPUS_LUT_CHAN_529875_IDX] = { 21195, 0x1, 0x58, 0xA0000, 0x6E6 }, + [OLYMPUS_LUT_CHAN_530000_IDX] = { 21200, 0x1, 0x58, 0xAAAAB, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530125_IDX] = { 21205, 0x1, 0x58, 0xB5555, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530250_IDX] = { 21210, 0x1, 0x58, 0xC0000, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530375_IDX] = { 21215, 0x1, 0x58, 0xCAAAB, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530500_IDX] = { 21220, 0x1, 0x58, 0xD5555, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530625_IDX] = { 21225, 0x1, 0x58, 0xE0000, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530750_IDX] = { 21230, 0x1, 0x58, 0xEAAAB, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530875_IDX] = { 21235, 0x1, 0x58, 0xF5555, 0x6EA }, + [OLYMPUS_LUT_CHAN_531000_IDX] = { 21240, 0x1, 0x58, 0x100000, 0x6EA }, + [OLYMPUS_LUT_CHAN_531125_IDX] = { 21245, 0x1, 0x58, 0x10AAAB, 0x6EA }, + [OLYMPUS_LUT_CHAN_531250_IDX] = { 21250, 0x1, 0x58, 0x115555, 0x6EB }, + [OLYMPUS_LUT_CHAN_531375_IDX] = { 21255, 0x1, 0x58, 0x120000, 0x6EB }, + [OLYMPUS_LUT_CHAN_531500_IDX] = { 21260, 0x1, 0x58, 0x12AAAB, 0x6EC }, + [OLYMPUS_LUT_CHAN_531625_IDX] = { 21265, 0x1, 0x58, 0x135555, 0x6EC }, + [OLYMPUS_LUT_CHAN_531750_IDX] = { 21270, 0x1, 0x58, 0x140000, 0x6ED }, + [OLYMPUS_LUT_CHAN_531875_IDX] = { 21275, 0x1, 0x58, 0x14AAAB, 0x6ED }, + [OLYMPUS_LUT_CHAN_532000_IDX] = { 21280, 0x1, 0x58, 0x155555, 0x6ED }, + [OLYMPUS_LUT_CHAN_532125_IDX] = { 21285, 0x1, 0x58, 0x160000, 0x6EE }, + [OLYMPUS_LUT_CHAN_532250_IDX] = { 21290, 0x1, 0x58, 0x16AAAB, 0x6EE }, + [OLYMPUS_LUT_CHAN_532375_IDX] = { 21295, 0x1, 0x58, 0x175555, 0x6EF }, + [OLYMPUS_LUT_CHAN_532500_IDX] = { 21300, 0x1, 0x58, 0x180000, 0x6EF }, + [OLYMPUS_LUT_CHAN_532625_IDX] = { 21305, 0x1, 0x58, 0x18AAAB, 0x6EF }, + [OLYMPUS_LUT_CHAN_532750_IDX] = { 21310, 0x1, 0x58, 0x195555, 0x6F0 }, + [OLYMPUS_LUT_CHAN_532875_IDX] = { 21315, 0x1, 0x58, 0x1A0000, 0x6F0 }, + [OLYMPUS_LUT_CHAN_533000_IDX] = { 21320, 0x1, 0x58, 0x1AAAAB, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533125_IDX] = { 21325, 0x1, 0x58, 0x1B5555, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533250_IDX] = { 21330, 0x1, 0x58, 0x1C0000, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533375_IDX] = { 21335, 0x1, 0x58, 0x1CAAAB, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533500_IDX] = { 21340, 0x1, 0x58, 0x1D5555, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533625_IDX] = { 21345, 0x1, 0x58, 0x1E0000, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533750_IDX] = { 21350, 0x1, 0x58, 0x1EAAAB, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533875_IDX] = { 21355, 0x1, 0x58, 0x1F5555, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534000_IDX] = { 21360, 0x1, 0x59, 0x0, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534125_IDX] = { 21365, 0x1, 0x59, 0xAAAB, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534250_IDX] = { 21370, 0x1, 0x59, 0x15555, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534375_IDX] = { 21375, 0x1, 0x59, 0x20000, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534500_IDX] = { 21380, 0x1, 0x59, 0x2AAAB, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534625_IDX] = { 21385, 0x1, 0x59, 0x35555, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534750_IDX] = { 21390, 0x1, 0x59, 0x40000, 0x6F7 }, + [OLYMPUS_LUT_CHAN_534875_IDX] = { 21395, 0x1, 0x59, 0x4AAAB, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535000_IDX] = { 21400, 0x1, 0x59, 0x55555, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535125_IDX] = { 21405, 0x1, 0x59, 0x60000, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535250_IDX] = { 21410, 0x1, 0x59, 0x6AAAB, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535375_IDX] = { 21415, 0x1, 0x59, 0x75555, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535500_IDX] = { 21420, 0x1, 0x59, 0x80000, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535625_IDX] = { 21425, 0x1, 0x59, 0x8AAAB, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535750_IDX] = { 21430, 0x1, 0x59, 0x95555, 0x6FA }, + [OLYMPUS_LUT_CHAN_535875_IDX] = { 21435, 0x1, 0x59, 0xA0000, 0x6FA }, + [OLYMPUS_LUT_CHAN_536000_IDX] = { 21440, 0x1, 0x59, 0xAAAAB, 0x6FB }, + [OLYMPUS_LUT_CHAN_536125_IDX] = { 21445, 0x1, 0x59, 0xB5555, 0x6FB }, + [OLYMPUS_LUT_CHAN_536250_IDX] = { 21450, 0x1, 0x59, 0xC0000, 0x6FC }, + [OLYMPUS_LUT_CHAN_536375_IDX] = { 21455, 0x1, 0x59, 0xCAAAB, 0x6FC }, + [OLYMPUS_LUT_CHAN_536500_IDX] = { 21460, 0x1, 0x59, 0xD5555, 0x6FC }, + [OLYMPUS_LUT_CHAN_536625_IDX] = { 21465, 0x1, 0x59, 0xE0000, 0x6FD }, + [OLYMPUS_LUT_CHAN_536750_IDX] = { 21470, 0x1, 0x59, 0xEAAAB, 0x6FD }, + [OLYMPUS_LUT_CHAN_536875_IDX] = { 21475, 0x1, 0x59, 0xF5555, 0x6FE }, + [OLYMPUS_LUT_CHAN_537000_IDX] = { 21480, 0x1, 0x59, 0x100000, 0x6FE }, + [OLYMPUS_LUT_CHAN_537125_IDX] = { 21485, 0x1, 0x59, 0x10AAAB, 0x6FE }, + [OLYMPUS_LUT_CHAN_537250_IDX] = { 21490, 0x1, 0x59, 0x115555, 0x6FF }, + [OLYMPUS_LUT_CHAN_537375_IDX] = { 21495, 0x1, 0x59, 0x120000, 0x6FF }, + [OLYMPUS_LUT_CHAN_537500_IDX] = { 21500, 0x1, 0x59, 0x12AAAB, 0x700 }, + [OLYMPUS_LUT_CHAN_537625_IDX] = { 21505, 0x1, 0x59, 0x135555, 0x700 }, + [OLYMPUS_LUT_CHAN_537750_IDX] = { 21510, 0x1, 0x59, 0x140000, 0x701 }, + [OLYMPUS_LUT_CHAN_537875_IDX] = { 21515, 0x1, 0x59, 0x14AAAB, 0x701 }, + [OLYMPUS_LUT_CHAN_538000_IDX] = { 21520, 0x1, 0x59, 0x155555, 0x701 }, + [OLYMPUS_LUT_CHAN_538125_IDX] = { 21525, 0x1, 0x59, 0x160000, 0x702 }, + [OLYMPUS_LUT_CHAN_538250_IDX] = { 21530, 0x1, 0x59, 0x16AAAB, 0x702 }, + [OLYMPUS_LUT_CHAN_538375_IDX] = { 21535, 0x1, 0x59, 0x175555, 0x703 }, + [OLYMPUS_LUT_CHAN_538500_IDX] = { 21540, 0x1, 0x59, 0x180000, 0x703 }, + [OLYMPUS_LUT_CHAN_538625_IDX] = { 21545, 0x1, 0x59, 0x18AAAB, 0x703 }, + [OLYMPUS_LUT_CHAN_538750_IDX] = { 21550, 0x1, 0x59, 0x195555, 0x704 }, + [OLYMPUS_LUT_CHAN_538875_IDX] = { 21555, 0x1, 0x59, 0x1A0000, 0x704 }, + [OLYMPUS_LUT_CHAN_539000_IDX] = { 21560, 0x1, 0x59, 0x1AAAAB, 0x705 }, + [OLYMPUS_LUT_CHAN_539125_IDX] = { 21565, 0x1, 0x59, 0x1B5555, 0x705 }, + [OLYMPUS_LUT_CHAN_539250_IDX] = { 21570, 0x1, 0x59, 0x1C0000, 0x706 }, + [OLYMPUS_LUT_CHAN_539375_IDX] = { 21575, 0x1, 0x59, 0x1CAAAB, 0x706 }, + [OLYMPUS_LUT_CHAN_539500_IDX] = { 21580, 0x1, 0x59, 0x1D5555, 0x706 }, + [OLYMPUS_LUT_CHAN_539625_IDX] = { 21585, 0x1, 0x59, 0x1E0000, 0x707 }, + [OLYMPUS_LUT_CHAN_539750_IDX] = { 21590, 0x1, 0x59, 0x1EAAAB, 0x707 }, + [OLYMPUS_LUT_CHAN_539875_IDX] = { 21595, 0x1, 0x59, 0x1F5555, 0x708 }, + [OLYMPUS_LUT_CHAN_540000_IDX] = { 21600, 0x1, 0x5A, 0x0, 0x708 }, + [OLYMPUS_LUT_CHAN_540125_IDX] = { 21605, 0x1, 0x5A, 0xAAAB, 0x708 }, + [OLYMPUS_LUT_CHAN_540250_IDX] = { 21610, 0x1, 0x5A, 0x15555, 0x709 }, + [OLYMPUS_LUT_CHAN_540375_IDX] = { 21615, 0x1, 0x5A, 0x20000, 0x709 }, + [OLYMPUS_LUT_CHAN_540500_IDX] = { 21620, 0x1, 0x5A, 0x2AAAB, 0x70A }, + [OLYMPUS_LUT_CHAN_540625_IDX] = { 21625, 0x1, 0x5A, 0x35555, 0x70A }, + [OLYMPUS_LUT_CHAN_540750_IDX] = { 21630, 0x1, 0x5A, 0x40000, 0x70B }, + [OLYMPUS_LUT_CHAN_540875_IDX] = { 21635, 0x1, 0x5A, 0x4AAAB, 0x70B }, + [OLYMPUS_LUT_CHAN_541000_IDX] = { 21640, 0x1, 0x5A, 0x55555, 0x70B }, + [OLYMPUS_LUT_CHAN_541125_IDX] = { 21645, 0x1, 0x5A, 0x60000, 0x70C }, + [OLYMPUS_LUT_CHAN_541250_IDX] = { 21650, 0x1, 0x5A, 0x6AAAB, 0x70C }, + [OLYMPUS_LUT_CHAN_541375_IDX] = { 21655, 0x1, 0x5A, 0x75555, 0x70D }, + [OLYMPUS_LUT_CHAN_541500_IDX] = { 21660, 0x1, 0x5A, 0x80000, 0x70D }, + [OLYMPUS_LUT_CHAN_541625_IDX] = { 21665, 0x1, 0x5A, 0x8AAAB, 0x70D }, + [OLYMPUS_LUT_CHAN_541750_IDX] = { 21670, 0x1, 0x5A, 0x95555, 0x70E }, + [OLYMPUS_LUT_CHAN_541875_IDX] = { 21675, 0x1, 0x5A, 0xA0000, 0x70E }, + [OLYMPUS_LUT_CHAN_542000_IDX] = { 21680, 0x1, 0x5A, 0xAAAAB, 0x70F }, + [OLYMPUS_LUT_CHAN_542125_IDX] = { 21685, 0x1, 0x5A, 0xB5555, 0x70F }, + [OLYMPUS_LUT_CHAN_542250_IDX] = { 21690, 0x1, 0x5A, 0xC0000, 0x710 }, + [OLYMPUS_LUT_CHAN_542375_IDX] = { 21695, 0x1, 0x5A, 0xCAAAB, 0x710 }, + [OLYMPUS_LUT_CHAN_542500_IDX] = { 21700, 0x1, 0x5A, 0xD5555, 0x710 }, + [OLYMPUS_LUT_CHAN_542625_IDX] = { 21705, 0x1, 0x5A, 0xE0000, 0x711 }, + [OLYMPUS_LUT_CHAN_542750_IDX] = { 21710, 0x1, 0x5A, 0xEAAAB, 0x711 }, + [OLYMPUS_LUT_CHAN_542875_IDX] = { 21715, 0x1, 0x5A, 0xF5555, 0x712 }, + [OLYMPUS_LUT_CHAN_543000_IDX] = { 21720, 0x1, 0x5A, 0x100000, 0x712 }, + [OLYMPUS_LUT_CHAN_543125_IDX] = { 21725, 0x1, 0x5A, 0x10AAAB, 0x712 }, + [OLYMPUS_LUT_CHAN_543250_IDX] = { 21730, 0x1, 0x5A, 0x115555, 0x713 }, + [OLYMPUS_LUT_CHAN_543375_IDX] = { 21735, 0x1, 0x5A, 0x120000, 0x713 }, + [OLYMPUS_LUT_CHAN_543500_IDX] = { 21740, 0x1, 0x5A, 0x12AAAB, 0x714 }, + [OLYMPUS_LUT_CHAN_543625_IDX] = { 21745, 0x1, 0x5A, 0x135555, 0x714 }, + [OLYMPUS_LUT_CHAN_543750_IDX] = { 21750, 0x1, 0x5A, 0x140000, 0x715 }, + [OLYMPUS_LUT_CHAN_543875_IDX] = { 21755, 0x1, 0x5A, 0x14AAAB, 0x715 }, + [OLYMPUS_LUT_CHAN_544000_IDX] = { 21760, 0x1, 0x5A, 0x155555, 0x715 }, + [OLYMPUS_LUT_CHAN_544125_IDX] = { 21765, 0x1, 0x5A, 0x160000, 0x716 }, + [OLYMPUS_LUT_CHAN_544250_IDX] = { 21770, 0x1, 0x5A, 0x16AAAB, 0x716 }, + [OLYMPUS_LUT_CHAN_544375_IDX] = { 21775, 0x1, 0x5A, 0x175555, 0x717 }, + [OLYMPUS_LUT_CHAN_544500_IDX] = { 21780, 0x1, 0x5A, 0x180000, 0x717 }, + [OLYMPUS_LUT_CHAN_544625_IDX] = { 21785, 0x1, 0x5A, 0x18AAAB, 0x717 }, + [OLYMPUS_LUT_CHAN_544750_IDX] = { 21790, 0x1, 0x5A, 0x195555, 0x718 }, + [OLYMPUS_LUT_CHAN_544875_IDX] = { 21795, 0x1, 0x5A, 0x1A0000, 0x718 }, + [OLYMPUS_LUT_CHAN_545000_IDX] = { 21800, 0x1, 0x5A, 0x1AAAAB, 0x719 }, + [OLYMPUS_LUT_CHAN_545125_IDX] = { 21805, 0x1, 0x5A, 0x1B5555, 0x719 }, + [OLYMPUS_LUT_CHAN_545250_IDX] = { 21810, 0x1, 0x5A, 0x1C0000, 0x71A }, + [OLYMPUS_LUT_CHAN_545375_IDX] = { 21815, 0x1, 0x5A, 0x1CAAAB, 0x71A }, + [OLYMPUS_LUT_CHAN_545500_IDX] = { 21820, 0x1, 0x5A, 0x1D5555, 0x71A }, + [OLYMPUS_LUT_CHAN_545625_IDX] = { 21825, 0x1, 0x5A, 0x1E0000, 0x71B }, + [OLYMPUS_LUT_CHAN_545750_IDX] = { 21830, 0x1, 0x5A, 0x1EAAAB, 0x71B }, + [OLYMPUS_LUT_CHAN_545875_IDX] = { 21835, 0x1, 0x5A, 0x1F5555, 0x71C }, + [OLYMPUS_LUT_CHAN_546000_IDX] = { 21840, 0x1, 0x5B, 0x0, 0x71C }, + [OLYMPUS_LUT_CHAN_546125_IDX] = { 21845, 0x1, 0x5B, 0xAAAB, 0x71C }, + [OLYMPUS_LUT_CHAN_546250_IDX] = { 21850, 0x1, 0x5B, 0x15555, 0x71D }, + [OLYMPUS_LUT_CHAN_546375_IDX] = { 21855, 0x1, 0x5B, 0x20000, 0x71D }, + [OLYMPUS_LUT_CHAN_546500_IDX] = { 21860, 0x1, 0x5B, 0x2AAAB, 0x71E }, + [OLYMPUS_LUT_CHAN_546625_IDX] = { 21865, 0x1, 0x5B, 0x35555, 0x71E }, + [OLYMPUS_LUT_CHAN_546750_IDX] = { 21870, 0x1, 0x5B, 0x40000, 0x71F }, + [OLYMPUS_LUT_CHAN_546875_IDX] = { 21875, 0x1, 0x5B, 0x4AAAB, 0x71F }, + [OLYMPUS_LUT_CHAN_547000_IDX] = { 21880, 0x1, 0x5B, 0x55555, 0x71F }, + [OLYMPUS_LUT_CHAN_547125_IDX] = { 21885, 0x1, 0x5B, 0x60000, 0x720 }, + [OLYMPUS_LUT_CHAN_547250_IDX] = { 21890, 0x1, 0x5B, 0x6AAAB, 0x720 }, + [OLYMPUS_LUT_CHAN_547375_IDX] = { 21895, 0x1, 0x5B, 0x75555, 0x721 }, + [OLYMPUS_LUT_CHAN_547500_IDX] = { 21900, 0x1, 0x5B, 0x80000, 0x721 }, + [OLYMPUS_LUT_CHAN_547625_IDX] = { 21905, 0x1, 0x5B, 0x8AAAB, 0x721 }, + [OLYMPUS_LUT_CHAN_547750_IDX] = { 21910, 0x1, 0x5B, 0x95555, 0x722 }, + [OLYMPUS_LUT_CHAN_547875_IDX] = { 21915, 0x1, 0x5B, 0xA0000, 0x722 }, + [OLYMPUS_LUT_CHAN_548000_IDX] = { 21920, 0x1, 0x5B, 0xAAAAB, 0x723 }, + [OLYMPUS_LUT_CHAN_548125_IDX] = { 21925, 0x1, 0x5B, 0xB5555, 0x723 }, + [OLYMPUS_LUT_CHAN_548250_IDX] = { 21930, 0x1, 0x5B, 0xC0000, 0x724 }, + [OLYMPUS_LUT_CHAN_548375_IDX] = { 21935, 0x1, 0x5B, 0xCAAAB, 0x724 }, + [OLYMPUS_LUT_CHAN_548500_IDX] = { 21940, 0x1, 0x5B, 0xD5555, 0x724 }, + [OLYMPUS_LUT_CHAN_548625_IDX] = { 21945, 0x1, 0x5B, 0xE0000, 0x725 }, + [OLYMPUS_LUT_CHAN_548750_IDX] = { 21950, 0x1, 0x5B, 0xEAAAB, 0x725 }, + [OLYMPUS_LUT_CHAN_548875_IDX] = { 21955, 0x1, 0x5B, 0xF5555, 0x726 }, + [OLYMPUS_LUT_CHAN_549000_IDX] = { 21960, 0x1, 0x5B, 0x100000, 0x726 }, + [OLYMPUS_LUT_CHAN_549125_IDX] = { 21965, 0x1, 0x5B, 0x10AAAB, 0x726 }, + [OLYMPUS_LUT_CHAN_549250_IDX] = { 21970, 0x1, 0x5B, 0x115555, 0x727 }, + [OLYMPUS_LUT_CHAN_549375_IDX] = { 21975, 0x1, 0x5B, 0x120000, 0x727 }, + [OLYMPUS_LUT_CHAN_549500_IDX] = { 21980, 0x1, 0x5B, 0x12AAAB, 0x728 }, + [OLYMPUS_LUT_CHAN_549625_IDX] = { 21985, 0x1, 0x5B, 0x135555, 0x728 }, + [OLYMPUS_LUT_CHAN_549750_IDX] = { 21990, 0x1, 0x5B, 0x140000, 0x729 }, + [OLYMPUS_LUT_CHAN_549875_IDX] = { 21995, 0x1, 0x5B, 0x14AAAB, 0x729 }, + [OLYMPUS_LUT_CHAN_550000_IDX] = { 22000, 0x1, 0x5B, 0x155555, 0x729 }, + [OLYMPUS_LUT_CHAN_550125_IDX] = { 22005, 0x1, 0x5B, 0x160000, 0x72A }, + [OLYMPUS_LUT_CHAN_550250_IDX] = { 22010, 0x1, 0x5B, 0x16AAAB, 0x72A }, + [OLYMPUS_LUT_CHAN_550375_IDX] = { 22015, 0x1, 0x5B, 0x175555, 0x72B }, + [OLYMPUS_LUT_CHAN_550500_IDX] = { 22020, 0x1, 0x5B, 0x180000, 0x72B }, + [OLYMPUS_LUT_CHAN_550625_IDX] = { 22025, 0x1, 0x5B, 0x18AAAB, 0x72B }, + [OLYMPUS_LUT_CHAN_550750_IDX] = { 22030, 0x1, 0x5B, 0x195555, 0x72C }, + [OLYMPUS_LUT_CHAN_550875_IDX] = { 22035, 0x1, 0x5B, 0x1A0000, 0x72C }, + [OLYMPUS_LUT_CHAN_551000_IDX] = { 22040, 0x1, 0x5B, 0x1AAAAB, 0x72D }, + [OLYMPUS_LUT_CHAN_551125_IDX] = { 22045, 0x1, 0x5B, 0x1B5555, 0x72D }, + [OLYMPUS_LUT_CHAN_551250_IDX] = { 22050, 0x1, 0x5B, 0x1C0000, 0x72E }, + [OLYMPUS_LUT_CHAN_551375_IDX] = { 22055, 0x1, 0x5B, 0x1CAAAB, 0x72E }, + [OLYMPUS_LUT_CHAN_551500_IDX] = { 22060, 0x1, 0x5B, 0x1D5555, 0x72E }, + [OLYMPUS_LUT_CHAN_551625_IDX] = { 22065, 0x1, 0x5B, 0x1E0000, 0x72F }, + [OLYMPUS_LUT_CHAN_551750_IDX] = { 22070, 0x1, 0x5B, 0x1EAAAB, 0x72F }, + [OLYMPUS_LUT_CHAN_551875_IDX] = { 22075, 0x1, 0x5B, 0x1F5555, 0x730 }, + [OLYMPUS_LUT_CHAN_552000_IDX] = { 22080, 0x1, 0x5C, 0x0, 0x730 }, + [OLYMPUS_LUT_CHAN_552125_IDX] = { 22085, 0x1, 0x5C, 0xAAAB, 0x730 }, + [OLYMPUS_LUT_CHAN_552250_IDX] = { 22090, 0x1, 0x5C, 0x15555, 0x731 }, + [OLYMPUS_LUT_CHAN_552375_IDX] = { 22095, 0x1, 0x5C, 0x20000, 0x731 }, + [OLYMPUS_LUT_CHAN_552500_IDX] = { 22100, 0x1, 0x5C, 0x2AAAB, 0x732 }, + [OLYMPUS_LUT_CHAN_552625_IDX] = { 22105, 0x1, 0x5C, 0x35555, 0x732 }, + [OLYMPUS_LUT_CHAN_552750_IDX] = { 22110, 0x1, 0x5C, 0x40000, 0x733 }, + [OLYMPUS_LUT_CHAN_552875_IDX] = { 22115, 0x1, 0x5C, 0x4AAAB, 0x733 }, + [OLYMPUS_LUT_CHAN_553000_IDX] = { 22120, 0x1, 0x5C, 0x55555, 0x733 }, + [OLYMPUS_LUT_CHAN_553125_IDX] = { 22125, 0x1, 0x5C, 0x60000, 0x734 }, + [OLYMPUS_LUT_CHAN_553250_IDX] = { 22130, 0x1, 0x5C, 0x6AAAB, 0x734 }, + [OLYMPUS_LUT_CHAN_553375_IDX] = { 22135, 0x1, 0x5C, 0x75555, 0x735 }, + [OLYMPUS_LUT_CHAN_553500_IDX] = { 22140, 0x1, 0x5C, 0x80000, 0x735 }, + [OLYMPUS_LUT_CHAN_553625_IDX] = { 22145, 0x1, 0x5C, 0x8AAAB, 0x735 }, + [OLYMPUS_LUT_CHAN_553750_IDX] = { 22150, 0x1, 0x5C, 0x95555, 0x736 }, + [OLYMPUS_LUT_CHAN_553875_IDX] = { 22155, 0x1, 0x5C, 0xA0000, 0x736 }, + [OLYMPUS_LUT_CHAN_554000_IDX] = { 22160, 0x1, 0x5C, 0xAAAAB, 0x737 }, + [OLYMPUS_LUT_CHAN_554125_IDX] = { 22165, 0x1, 0x5C, 0xB5555, 0x737 }, + [OLYMPUS_LUT_CHAN_554250_IDX] = { 22170, 0x1, 0x5C, 0xC0000, 0x738 }, + [OLYMPUS_LUT_CHAN_554375_IDX] = { 22175, 0x1, 0x5C, 0xCAAAB, 0x738 }, + [OLYMPUS_LUT_CHAN_554500_IDX] = { 22180, 0x1, 0x5C, 0xD5555, 0x738 }, + [OLYMPUS_LUT_CHAN_554625_IDX] = { 22185, 0x1, 0x5C, 0xE0000, 0x739 }, + [OLYMPUS_LUT_CHAN_554750_IDX] = { 22190, 0x1, 0x5C, 0xEAAAB, 0x739 }, + [OLYMPUS_LUT_CHAN_554875_IDX] = { 22195, 0x1, 0x5C, 0xF5555, 0x73A }, + [OLYMPUS_LUT_CHAN_555000_IDX] = { 22200, 0x1, 0x5C, 0x100000, 0x73A }, + [OLYMPUS_LUT_CHAN_555125_IDX] = { 22205, 0x1, 0x5C, 0x10AAAB, 0x73A }, + [OLYMPUS_LUT_CHAN_555250_IDX] = { 22210, 0x1, 0x5C, 0x115555, 0x73B }, + [OLYMPUS_LUT_CHAN_555375_IDX] = { 22215, 0x1, 0x5C, 0x120000, 0x73B }, + [OLYMPUS_LUT_CHAN_555500_IDX] = { 22220, 0x1, 0x5C, 0x12AAAB, 0x73C }, + [OLYMPUS_LUT_CHAN_555625_IDX] = { 22225, 0x1, 0x5C, 0x135555, 0x73C }, + [OLYMPUS_LUT_CHAN_555750_IDX] = { 22230, 0x1, 0x5C, 0x140000, 0x73D }, + [OLYMPUS_LUT_CHAN_555875_IDX] = { 22235, 0x1, 0x5C, 0x14AAAB, 0x73D }, + [OLYMPUS_LUT_CHAN_556000_IDX] = { 22240, 0x1, 0x5C, 0x155555, 0x73D }, + [OLYMPUS_LUT_CHAN_556125_IDX] = { 22245, 0x1, 0x5C, 0x160000, 0x73E }, + [OLYMPUS_LUT_CHAN_556250_IDX] = { 22250, 0x1, 0x5C, 0x16AAAB, 0x73E }, + [OLYMPUS_LUT_CHAN_556375_IDX] = { 22255, 0x1, 0x5C, 0x175555, 0x73F }, + [OLYMPUS_LUT_CHAN_556500_IDX] = { 22260, 0x1, 0x5C, 0x180000, 0x73F }, + [OLYMPUS_LUT_CHAN_556625_IDX] = { 22265, 0x1, 0x5C, 0x18AAAB, 0x73F }, + [OLYMPUS_LUT_CHAN_556750_IDX] = { 22270, 0x1, 0x5C, 0x195555, 0x740 }, + [OLYMPUS_LUT_CHAN_556875_IDX] = { 22275, 0x1, 0x5C, 0x1A0000, 0x740 }, + [OLYMPUS_LUT_CHAN_557000_IDX] = { 22280, 0x1, 0x5C, 0x1AAAAB, 0x741 }, + [OLYMPUS_LUT_CHAN_557125_IDX] = { 22285, 0x1, 0x5C, 0x1B5555, 0x741 }, + [OLYMPUS_LUT_CHAN_557250_IDX] = { 22290, 0x1, 0x5C, 0x1C0000, 0x742 }, + [OLYMPUS_LUT_CHAN_557375_IDX] = { 22295, 0x1, 0x5C, 0x1CAAAB, 0x742 }, + [OLYMPUS_LUT_CHAN_557500_IDX] = { 22300, 0x1, 0x5C, 0x1D5555, 0x742 }, + [OLYMPUS_LUT_CHAN_557625_IDX] = { 22305, 0x1, 0x5C, 0x1E0000, 0x743 }, + [OLYMPUS_LUT_CHAN_557750_IDX] = { 22310, 0x1, 0x5C, 0x1EAAAB, 0x743 }, + [OLYMPUS_LUT_CHAN_557875_IDX] = { 22315, 0x1, 0x5C, 0x1F5555, 0x744 }, + [OLYMPUS_LUT_CHAN_558000_IDX] = { 22320, 0x1, 0x5D, 0x0, 0x744 }, + [OLYMPUS_LUT_CHAN_558125_IDX] = { 22325, 0x1, 0x5D, 0xAAAB, 0x744 }, + [OLYMPUS_LUT_CHAN_558250_IDX] = { 22330, 0x1, 0x5D, 0x15555, 0x745 }, + [OLYMPUS_LUT_CHAN_558375_IDX] = { 22335, 0x1, 0x5D, 0x20000, 0x745 }, + [OLYMPUS_LUT_CHAN_558500_IDX] = { 22340, 0x1, 0x5D, 0x2AAAB, 0x746 }, + [OLYMPUS_LUT_CHAN_558625_IDX] = { 22345, 0x1, 0x5D, 0x35555, 0x746 }, + [OLYMPUS_LUT_CHAN_558750_IDX] = { 22350, 0x1, 0x5D, 0x40000, 0x747 }, + [OLYMPUS_LUT_CHAN_558875_IDX] = { 22355, 0x1, 0x5D, 0x4AAAB, 0x747 }, + [OLYMPUS_LUT_CHAN_559000_IDX] = { 22360, 0x1, 0x5D, 0x55555, 0x747 }, + [OLYMPUS_LUT_CHAN_559125_IDX] = { 22365, 0x1, 0x5D, 0x60000, 0x748 }, + [OLYMPUS_LUT_CHAN_559250_IDX] = { 22370, 0x1, 0x5D, 0x6AAAB, 0x748 }, + [OLYMPUS_LUT_CHAN_559375_IDX] = { 22375, 0x1, 0x5D, 0x75555, 0x749 }, + [OLYMPUS_LUT_CHAN_559500_IDX] = { 22380, 0x1, 0x5D, 0x80000, 0x749 }, + [OLYMPUS_LUT_CHAN_559625_IDX] = { 22385, 0x1, 0x5D, 0x8AAAB, 0x749 }, + [OLYMPUS_LUT_CHAN_559750_IDX] = { 22390, 0x1, 0x5D, 0x95555, 0x74A }, + [OLYMPUS_LUT_CHAN_559875_IDX] = { 22395, 0x1, 0x5D, 0xA0000, 0x74A }, + [OLYMPUS_LUT_CHAN_560000_IDX] = { 22400, 0x1, 0x5D, 0xAAAAB, 0x74B }, + [OLYMPUS_LUT_CHAN_560125_IDX] = { 22405, 0x1, 0x5D, 0xB5555, 0x74B }, + [OLYMPUS_LUT_CHAN_560250_IDX] = { 22410, 0x1, 0x5D, 0xC0000, 0x74C }, + [OLYMPUS_LUT_CHAN_560375_IDX] = { 22415, 0x1, 0x5D, 0xCAAAB, 0x74C }, + [OLYMPUS_LUT_CHAN_560500_IDX] = { 22420, 0x1, 0x5D, 0xD5555, 0x74C }, + [OLYMPUS_LUT_CHAN_560625_IDX] = { 22425, 0x1, 0x5D, 0xE0000, 0x74D }, + [OLYMPUS_LUT_CHAN_560750_IDX] = { 22430, 0x1, 0x5D, 0xEAAAB, 0x74D }, + [OLYMPUS_LUT_CHAN_560875_IDX] = { 22435, 0x1, 0x5D, 0xF5555, 0x74E }, + [OLYMPUS_LUT_CHAN_561000_IDX] = { 22440, 0x1, 0x5D, 0x100000, 0x74E }, + [OLYMPUS_LUT_CHAN_561125_IDX] = { 22445, 0x1, 0x5D, 0x10AAAB, 0x74E }, + [OLYMPUS_LUT_CHAN_561250_IDX] = { 22450, 0x1, 0x5D, 0x115555, 0x74F }, + [OLYMPUS_LUT_CHAN_561375_IDX] = { 22455, 0x1, 0x5D, 0x120000, 0x74F }, + [OLYMPUS_LUT_CHAN_561500_IDX] = { 22460, 0x1, 0x5D, 0x12AAAB, 0x750 }, + [OLYMPUS_LUT_CHAN_561625_IDX] = { 22465, 0x1, 0x5D, 0x135555, 0x750 }, + [OLYMPUS_LUT_CHAN_561750_IDX] = { 22470, 0x1, 0x5D, 0x140000, 0x751 }, + [OLYMPUS_LUT_CHAN_561875_IDX] = { 22475, 0x1, 0x5D, 0x14AAAB, 0x751 }, + [OLYMPUS_LUT_CHAN_562000_IDX] = { 22480, 0x1, 0x5D, 0x155555, 0x751 }, + [OLYMPUS_LUT_CHAN_562125_IDX] = { 22485, 0x1, 0x5D, 0x160000, 0x752 }, + [OLYMPUS_LUT_CHAN_562250_IDX] = { 22490, 0x1, 0x5D, 0x16AAAB, 0x752 }, + [OLYMPUS_LUT_CHAN_562375_IDX] = { 22495, 0x1, 0x5D, 0x175555, 0x753 }, + [OLYMPUS_LUT_CHAN_562500_IDX] = { 22500, 0x1, 0x5D, 0x180000, 0x753 }, + [OLYMPUS_LUT_CHAN_562625_IDX] = { 22505, 0x1, 0x5D, 0x18AAAB, 0x753 }, + [OLYMPUS_LUT_CHAN_562750_IDX] = { 22510, 0x1, 0x5D, 0x195555, 0x754 }, + [OLYMPUS_LUT_CHAN_562875_IDX] = { 22515, 0x1, 0x5D, 0x1A0000, 0x754 }, + [OLYMPUS_LUT_CHAN_563000_IDX] = { 22520, 0x1, 0x5D, 0x1AAAAB, 0x755 }, + [OLYMPUS_LUT_CHAN_563125_IDX] = { 22525, 0x1, 0x5D, 0x1B5555, 0x755 }, + [OLYMPUS_LUT_CHAN_563250_IDX] = { 22530, 0x1, 0x5D, 0x1C0000, 0x756 }, + [OLYMPUS_LUT_CHAN_563375_IDX] = { 22535, 0x1, 0x5D, 0x1CAAAB, 0x756 }, + [OLYMPUS_LUT_CHAN_563500_IDX] = { 22540, 0x1, 0x5D, 0x1D5555, 0x756 }, + [OLYMPUS_LUT_CHAN_563625_IDX] = { 22545, 0x1, 0x5D, 0x1E0000, 0x757 }, + [OLYMPUS_LUT_CHAN_563750_IDX] = { 22550, 0x1, 0x5D, 0x1EAAAB, 0x757 }, + [OLYMPUS_LUT_CHAN_563875_IDX] = { 22555, 0x1, 0x5D, 0x1F5555, 0x758 }, + [OLYMPUS_LUT_CHAN_564000_IDX] = { 22560, 0x1, 0x5E, 0x0, 0x758 }, + [OLYMPUS_LUT_CHAN_564125_IDX] = { 22565, 0x1, 0x5E, 0xAAAB, 0x758 }, + [OLYMPUS_LUT_CHAN_564250_IDX] = { 22570, 0x1, 0x5E, 0x15555, 0x759 }, + [OLYMPUS_LUT_CHAN_564375_IDX] = { 22575, 0x1, 0x5E, 0x20000, 0x759 }, + [OLYMPUS_LUT_CHAN_564500_IDX] = { 22580, 0x1, 0x5E, 0x2AAAB, 0x75A }, + [OLYMPUS_LUT_CHAN_564625_IDX] = { 22585, 0x1, 0x5E, 0x35555, 0x75A }, + [OLYMPUS_LUT_CHAN_564750_IDX] = { 22590, 0x1, 0x5E, 0x40000, 0x75B }, + [OLYMPUS_LUT_CHAN_564875_IDX] = { 22595, 0x1, 0x5E, 0x4AAAB, 0x75B }, + [OLYMPUS_LUT_CHAN_565000_IDX] = { 22600, 0x1, 0x5E, 0x55555, 0x75B }, + [OLYMPUS_LUT_CHAN_565125_IDX] = { 22605, 0x1, 0x5E, 0x60000, 0x75C }, + [OLYMPUS_LUT_CHAN_565250_IDX] = { 22610, 0x1, 0x5E, 0x6AAAB, 0x75C }, + [OLYMPUS_LUT_CHAN_565375_IDX] = { 22615, 0x1, 0x5E, 0x75555, 0x75D }, + [OLYMPUS_LUT_CHAN_565500_IDX] = { 22620, 0x1, 0x5E, 0x80000, 0x75D }, + [OLYMPUS_LUT_CHAN_565625_IDX] = { 22625, 0x1, 0x5E, 0x8AAAB, 0x75D }, + [OLYMPUS_LUT_CHAN_565750_IDX] = { 22630, 0x1, 0x5E, 0x95555, 0x75E }, + [OLYMPUS_LUT_CHAN_565875_IDX] = { 22635, 0x1, 0x5E, 0xA0000, 0x75E }, + [OLYMPUS_LUT_CHAN_566000_IDX] = { 22640, 0x1, 0x5E, 0xAAAAB, 0x75F }, + [OLYMPUS_LUT_CHAN_566125_IDX] = { 22645, 0x1, 0x5E, 0xB5555, 0x75F }, + [OLYMPUS_LUT_CHAN_566250_IDX] = { 22650, 0x1, 0x5E, 0xC0000, 0x760 }, + [OLYMPUS_LUT_CHAN_566375_IDX] = { 22655, 0x1, 0x5E, 0xCAAAB, 0x760 }, + [OLYMPUS_LUT_CHAN_566500_IDX] = { 22660, 0x1, 0x5E, 0xD5555, 0x760 }, + [OLYMPUS_LUT_CHAN_566625_IDX] = { 22665, 0x1, 0x5E, 0xE0000, 0x761 }, + [OLYMPUS_LUT_CHAN_566750_IDX] = { 22670, 0x1, 0x5E, 0xEAAAB, 0x761 }, + [OLYMPUS_LUT_CHAN_566875_IDX] = { 22675, 0x1, 0x5E, 0xF5555, 0x762 }, + [OLYMPUS_LUT_CHAN_567000_IDX] = { 22680, 0x1, 0x5E, 0x100000, 0x762 }, + [OLYMPUS_LUT_CHAN_567125_IDX] = { 22685, 0x1, 0x5E, 0x10AAAB, 0x762 }, + [OLYMPUS_LUT_CHAN_567250_IDX] = { 22690, 0x1, 0x5E, 0x115555, 0x763 }, + [OLYMPUS_LUT_CHAN_567375_IDX] = { 22695, 0x1, 0x5E, 0x120000, 0x763 }, + [OLYMPUS_LUT_CHAN_567500_IDX] = { 22700, 0x1, 0x5E, 0x12AAAB, 0x764 }, + [OLYMPUS_LUT_CHAN_567625_IDX] = { 22705, 0x1, 0x5E, 0x135555, 0x764 }, + [OLYMPUS_LUT_CHAN_567750_IDX] = { 22710, 0x1, 0x5E, 0x140000, 0x765 }, + [OLYMPUS_LUT_CHAN_567875_IDX] = { 22715, 0x1, 0x5E, 0x14AAAB, 0x765 }, + [OLYMPUS_LUT_CHAN_568000_IDX] = { 22720, 0x1, 0x5E, 0x155555, 0x765 }, + [OLYMPUS_LUT_CHAN_568125_IDX] = { 22725, 0x1, 0x5E, 0x160000, 0x766 }, + [OLYMPUS_LUT_CHAN_568250_IDX] = { 22730, 0x1, 0x5E, 0x16AAAB, 0x766 }, + [OLYMPUS_LUT_CHAN_568375_IDX] = { 22735, 0x1, 0x5E, 0x175555, 0x767 }, + [OLYMPUS_LUT_CHAN_568500_IDX] = { 22740, 0x1, 0x5E, 0x180000, 0x767 }, + [OLYMPUS_LUT_CHAN_568625_IDX] = { 22745, 0x1, 0x5E, 0x18AAAB, 0x767 }, + [OLYMPUS_LUT_CHAN_568750_IDX] = { 22750, 0x1, 0x5E, 0x195555, 0x768 }, + [OLYMPUS_LUT_CHAN_568875_IDX] = { 22755, 0x1, 0x5E, 0x1A0000, 0x768 }, + [OLYMPUS_LUT_CHAN_569000_IDX] = { 22760, 0x1, 0x5E, 0x1AAAAB, 0x769 }, + [OLYMPUS_LUT_CHAN_569125_IDX] = { 22765, 0x1, 0x5E, 0x1B5555, 0x769 }, + [OLYMPUS_LUT_CHAN_569250_IDX] = { 22770, 0x1, 0x5E, 0x1C0000, 0x76A }, + [OLYMPUS_LUT_CHAN_569375_IDX] = { 22775, 0x1, 0x5E, 0x1CAAAB, 0x76A }, + [OLYMPUS_LUT_CHAN_569500_IDX] = { 22780, 0x1, 0x5E, 0x1D5555, 0x76A }, + [OLYMPUS_LUT_CHAN_569625_IDX] = { 22785, 0x1, 0x5E, 0x1E0000, 0x76B }, + [OLYMPUS_LUT_CHAN_569750_IDX] = { 22790, 0x1, 0x5E, 0x1EAAAB, 0x76B }, + [OLYMPUS_LUT_CHAN_569875_IDX] = { 22795, 0x1, 0x5E, 0x1F5555, 0x76C }, + [OLYMPUS_LUT_CHAN_570000_IDX] = { 22800, 0x1, 0x5F, 0x0, 0x76C }, + [OLYMPUS_LUT_CHAN_570125_IDX] = { 22805, 0x1, 0x5F, 0xAAAB, 0x76C }, + [OLYMPUS_LUT_CHAN_570250_IDX] = { 22810, 0x1, 0x5F, 0x15555, 0x76D }, + [OLYMPUS_LUT_CHAN_570375_IDX] = { 22815, 0x1, 0x5F, 0x20000, 0x76D }, + [OLYMPUS_LUT_CHAN_570500_IDX] = { 22820, 0x1, 0x5F, 0x2AAAB, 0x76E }, + [OLYMPUS_LUT_CHAN_570625_IDX] = { 22825, 0x1, 0x5F, 0x35555, 0x76E }, + [OLYMPUS_LUT_CHAN_570750_IDX] = { 22830, 0x1, 0x5F, 0x40000, 0x76F }, + [OLYMPUS_LUT_CHAN_570875_IDX] = { 22835, 0x1, 0x5F, 0x4AAAB, 0x76F }, + [OLYMPUS_LUT_CHAN_571000_IDX] = { 22840, 0x1, 0x5F, 0x55555, 0x76F }, + [OLYMPUS_LUT_CHAN_571125_IDX] = { 22845, 0x1, 0x5F, 0x60000, 0x770 }, + [OLYMPUS_LUT_CHAN_571250_IDX] = { 22850, 0x1, 0x5F, 0x6AAAB, 0x770 }, + [OLYMPUS_LUT_CHAN_571375_IDX] = { 22855, 0x1, 0x5F, 0x75555, 0x771 }, + [OLYMPUS_LUT_CHAN_571500_IDX] = { 22860, 0x1, 0x5F, 0x80000, 0x771 }, + [OLYMPUS_LUT_CHAN_571625_IDX] = { 22865, 0x1, 0x5F, 0x8AAAB, 0x771 }, + [OLYMPUS_LUT_CHAN_571750_IDX] = { 22870, 0x1, 0x5F, 0x95555, 0x772 }, + [OLYMPUS_LUT_CHAN_571875_IDX] = { 22875, 0x1, 0x5F, 0xA0000, 0x772 }, + [OLYMPUS_LUT_CHAN_572000_IDX] = { 22880, 0x1, 0x5F, 0xAAAAB, 0x773 }, + [OLYMPUS_LUT_CHAN_572125_IDX] = { 22885, 0x1, 0x5F, 0xB5555, 0x773 }, + [OLYMPUS_LUT_CHAN_572250_IDX] = { 22890, 0x1, 0x5F, 0xC0000, 0x774 }, + [OLYMPUS_LUT_CHAN_572375_IDX] = { 22895, 0x1, 0x5F, 0xCAAAB, 0x774 }, + [OLYMPUS_LUT_CHAN_572500_IDX] = { 22900, 0x1, 0x5F, 0xD5555, 0x774 }, + [OLYMPUS_LUT_CHAN_572625_IDX] = { 22905, 0x1, 0x5F, 0xE0000, 0x775 }, + [OLYMPUS_LUT_CHAN_572750_IDX] = { 22910, 0x1, 0x5F, 0xEAAAB, 0x775 }, + [OLYMPUS_LUT_CHAN_572875_IDX] = { 22915, 0x1, 0x5F, 0xF5555, 0x776 }, + [OLYMPUS_LUT_CHAN_573000_IDX] = { 22920, 0x1, 0x5F, 0x100000, 0x776 }, + [OLYMPUS_LUT_CHAN_573125_IDX] = { 22925, 0x1, 0x5F, 0x10AAAB, 0x776 }, + [OLYMPUS_LUT_CHAN_573250_IDX] = { 22930, 0x1, 0x5F, 0x115555, 0x777 }, + [OLYMPUS_LUT_CHAN_573375_IDX] = { 22935, 0x1, 0x5F, 0x120000, 0x777 }, + [OLYMPUS_LUT_CHAN_573500_IDX] = { 22940, 0x1, 0x5F, 0x12AAAB, 0x778 }, + [OLYMPUS_LUT_CHAN_573625_IDX] = { 22945, 0x1, 0x5F, 0x135555, 0x778 }, + [OLYMPUS_LUT_CHAN_573750_IDX] = { 22950, 0x1, 0x5F, 0x140000, 0x779 }, + [OLYMPUS_LUT_CHAN_573875_IDX] = { 22955, 0x1, 0x5F, 0x14AAAB, 0x779 }, + [OLYMPUS_LUT_CHAN_574000_IDX] = { 22960, 0x1, 0x5F, 0x155555, 0x779 }, + [OLYMPUS_LUT_CHAN_574125_IDX] = { 22965, 0x1, 0x5F, 0x160000, 0x77A }, + [OLYMPUS_LUT_CHAN_574250_IDX] = { 22970, 0x1, 0x5F, 0x16AAAB, 0x77A }, + [OLYMPUS_LUT_CHAN_574375_IDX] = { 22975, 0x1, 0x5F, 0x175555, 0x77B }, + [OLYMPUS_LUT_CHAN_574500_IDX] = { 22980, 0x1, 0x5F, 0x180000, 0x77B }, + [OLYMPUS_LUT_CHAN_574625_IDX] = { 22985, 0x1, 0x5F, 0x18AAAB, 0x77B }, + [OLYMPUS_LUT_CHAN_574750_IDX] = { 22990, 0x1, 0x5F, 0x195555, 0x77C }, + [OLYMPUS_LUT_CHAN_574875_IDX] = { 22995, 0x1, 0x5F, 0x1A0000, 0x77C }, + [OLYMPUS_LUT_CHAN_575000_IDX] = { 23000, 0x1, 0x5F, 0x1AAAAB, 0x77D }, + [OLYMPUS_LUT_CHAN_575125_IDX] = { 23005, 0x1, 0x5F, 0x1B5555, 0x77D }, + [OLYMPUS_LUT_CHAN_575250_IDX] = { 23010, 0x1, 0x5F, 0x1C0000, 0x77E }, + [OLYMPUS_LUT_CHAN_575375_IDX] = { 23015, 0x1, 0x5F, 0x1CAAAB, 0x77E }, + [OLYMPUS_LUT_CHAN_575500_IDX] = { 23020, 0x1, 0x5F, 0x1D5555, 0x77E }, + [OLYMPUS_LUT_CHAN_575625_IDX] = { 23025, 0x1, 0x5F, 0x1E0000, 0x77F }, + [OLYMPUS_LUT_CHAN_575750_IDX] = { 23030, 0x1, 0x5F, 0x1EAAAB, 0x77F }, + [OLYMPUS_LUT_CHAN_575875_IDX] = { 23035, 0x1, 0x5F, 0x1F5555, 0x780 }, + [OLYMPUS_LUT_CHAN_576000_IDX] = { 23040, 0x1, 0x60, 0x0, 0x780 }, + [OLYMPUS_LUT_CHAN_576125_IDX] = { 23045, 0x1, 0x60, 0xAAAB, 0x780 }, + [OLYMPUS_LUT_CHAN_576250_IDX] = { 23050, 0x1, 0x60, 0x15555, 0x781 }, + [OLYMPUS_LUT_CHAN_576375_IDX] = { 23055, 0x1, 0x60, 0x20000, 0x781 }, + [OLYMPUS_LUT_CHAN_576500_IDX] = { 23060, 0x1, 0x60, 0x2AAAB, 0x782 }, + [OLYMPUS_LUT_CHAN_576625_IDX] = { 23065, 0x1, 0x60, 0x35555, 0x782 }, + [OLYMPUS_LUT_CHAN_576750_IDX] = { 23070, 0x1, 0x60, 0x40000, 0x783 }, + [OLYMPUS_LUT_CHAN_576875_IDX] = { 23075, 0x1, 0x60, 0x4AAAB, 0x783 }, + [OLYMPUS_LUT_CHAN_577000_IDX] = { 23080, 0x1, 0x60, 0x55555, 0x783 }, + [OLYMPUS_LUT_CHAN_577125_IDX] = { 23085, 0x1, 0x60, 0x60000, 0x784 }, + [OLYMPUS_LUT_CHAN_577250_IDX] = { 23090, 0x1, 0x60, 0x6AAAB, 0x784 }, + [OLYMPUS_LUT_CHAN_577375_IDX] = { 23095, 0x1, 0x60, 0x75555, 0x785 }, + [OLYMPUS_LUT_CHAN_577500_IDX] = { 23100, 0x1, 0x60, 0x80000, 0x785 }, + [OLYMPUS_LUT_CHAN_577625_IDX] = { 23105, 0x1, 0x60, 0x8AAAB, 0x785 }, + [OLYMPUS_LUT_CHAN_577750_IDX] = { 23110, 0x1, 0x60, 0x95555, 0x786 }, + [OLYMPUS_LUT_CHAN_577875_IDX] = { 23115, 0x1, 0x60, 0xA0000, 0x786 }, + [OLYMPUS_LUT_CHAN_578000_IDX] = { 23120, 0x1, 0x60, 0xAAAAB, 0x787 }, + [OLYMPUS_LUT_CHAN_578125_IDX] = { 23125, 0x1, 0x60, 0xB5555, 0x787 }, + [OLYMPUS_LUT_CHAN_578250_IDX] = { 23130, 0x1, 0x60, 0xC0000, 0x788 }, + [OLYMPUS_LUT_CHAN_578375_IDX] = { 23135, 0x1, 0x60, 0xCAAAB, 0x788 }, + [OLYMPUS_LUT_CHAN_578500_IDX] = { 23140, 0x1, 0x60, 0xD5555, 0x788 }, + [OLYMPUS_LUT_CHAN_578625_IDX] = { 23145, 0x1, 0x60, 0xE0000, 0x789 }, + [OLYMPUS_LUT_CHAN_578750_IDX] = { 23150, 0x1, 0x60, 0xEAAAB, 0x789 }, + [OLYMPUS_LUT_CHAN_578875_IDX] = { 23155, 0x1, 0x60, 0xF5555, 0x78A }, + [OLYMPUS_LUT_CHAN_579000_IDX] = { 23160, 0x1, 0x60, 0x100000, 0x78A }, + [OLYMPUS_LUT_CHAN_579125_IDX] = { 23165, 0x1, 0x60, 0x10AAAB, 0x78A }, + [OLYMPUS_LUT_CHAN_579250_IDX] = { 23170, 0x1, 0x60, 0x115555, 0x78B }, + [OLYMPUS_LUT_CHAN_579375_IDX] = { 23175, 0x1, 0x60, 0x120000, 0x78B }, + [OLYMPUS_LUT_CHAN_579500_IDX] = { 23180, 0x1, 0x60, 0x12AAAB, 0x78C }, + [OLYMPUS_LUT_CHAN_579625_IDX] = { 23185, 0x1, 0x60, 0x135555, 0x78C }, + [OLYMPUS_LUT_CHAN_579750_IDX] = { 23190, 0x1, 0x60, 0x140000, 0x78D }, + [OLYMPUS_LUT_CHAN_579875_IDX] = { 23195, 0x1, 0x60, 0x14AAAB, 0x78D }, + [OLYMPUS_LUT_CHAN_580000_IDX] = { 23200, 0x1, 0x60, 0x155555, 0x78D }, + [OLYMPUS_LUT_CHAN_580125_IDX] = { 23205, 0x1, 0x60, 0x160000, 0x78E }, + [OLYMPUS_LUT_CHAN_580250_IDX] = { 23210, 0x1, 0x60, 0x16AAAB, 0x78E }, + [OLYMPUS_LUT_CHAN_580375_IDX] = { 23215, 0x1, 0x60, 0x175555, 0x78F }, + [OLYMPUS_LUT_CHAN_580500_IDX] = { 23220, 0x1, 0x60, 0x180000, 0x78F }, + [OLYMPUS_LUT_CHAN_580625_IDX] = { 23225, 0x1, 0x60, 0x18AAAB, 0x78F }, + [OLYMPUS_LUT_CHAN_580750_IDX] = { 23230, 0x1, 0x60, 0x195555, 0x790 }, + [OLYMPUS_LUT_CHAN_580875_IDX] = { 23235, 0x1, 0x60, 0x1A0000, 0x790 }, + [OLYMPUS_LUT_CHAN_581000_IDX] = { 23240, 0x1, 0x60, 0x1AAAAB, 0x791 }, + [OLYMPUS_LUT_CHAN_581125_IDX] = { 23245, 0x1, 0x60, 0x1B5555, 0x791 }, + [OLYMPUS_LUT_CHAN_581250_IDX] = { 23250, 0x1, 0x60, 0x1C0000, 0x792 }, + [OLYMPUS_LUT_CHAN_581375_IDX] = { 23255, 0x1, 0x60, 0x1CAAAB, 0x792 }, + [OLYMPUS_LUT_CHAN_581500_IDX] = { 23260, 0x1, 0x60, 0x1D5555, 0x792 }, + [OLYMPUS_LUT_CHAN_581625_IDX] = { 23265, 0x1, 0x60, 0x1E0000, 0x793 }, + [OLYMPUS_LUT_CHAN_581750_IDX] = { 23270, 0x1, 0x60, 0x1EAAAB, 0x793 }, + [OLYMPUS_LUT_CHAN_581875_IDX] = { 23275, 0x1, 0x60, 0x1F5555, 0x794 }, + [OLYMPUS_LUT_CHAN_582000_IDX] = { 23280, 0x1, 0x61, 0x0, 0x794 }, + [OLYMPUS_LUT_CHAN_582125_IDX] = { 23285, 0x1, 0x61, 0xAAAB, 0x794 }, + [OLYMPUS_LUT_CHAN_582250_IDX] = { 23290, 0x1, 0x61, 0x15555, 0x795 }, + [OLYMPUS_LUT_CHAN_582375_IDX] = { 23295, 0x1, 0x61, 0x20000, 0x795 }, + [OLYMPUS_LUT_CHAN_582500_IDX] = { 23300, 0x1, 0x61, 0x2AAAB, 0x796 }, + [OLYMPUS_LUT_CHAN_582625_IDX] = { 23305, 0x1, 0x61, 0x35555, 0x796 }, + [OLYMPUS_LUT_CHAN_582750_IDX] = { 23310, 0x1, 0x61, 0x40000, 0x797 }, + [OLYMPUS_LUT_CHAN_582875_IDX] = { 23315, 0x1, 0x61, 0x4AAAB, 0x797 }, + [OLYMPUS_LUT_CHAN_583000_IDX] = { 23320, 0x1, 0x61, 0x55555, 0x797 }, + [OLYMPUS_LUT_CHAN_583125_IDX] = { 23325, 0x1, 0x61, 0x60000, 0x798 }, + [OLYMPUS_LUT_CHAN_583250_IDX] = { 23330, 0x1, 0x61, 0x6AAAB, 0x798 }, + [OLYMPUS_LUT_CHAN_583375_IDX] = { 23335, 0x1, 0x61, 0x75555, 0x799 }, + [OLYMPUS_LUT_CHAN_583500_IDX] = { 23340, 0x1, 0x61, 0x80000, 0x799 }, + [OLYMPUS_LUT_CHAN_583625_IDX] = { 23345, 0x1, 0x61, 0x8AAAB, 0x799 }, + [OLYMPUS_LUT_CHAN_583750_IDX] = { 23350, 0x1, 0x61, 0x95555, 0x79A }, + [OLYMPUS_LUT_CHAN_583875_IDX] = { 23355, 0x1, 0x61, 0xA0000, 0x79A }, + [OLYMPUS_LUT_CHAN_584000_IDX] = { 23360, 0x1, 0x61, 0xAAAAB, 0x79B }, + [OLYMPUS_LUT_CHAN_584125_IDX] = { 23365, 0x1, 0x61, 0xB5555, 0x79B }, + [OLYMPUS_LUT_CHAN_584250_IDX] = { 23370, 0x1, 0x61, 0xC0000, 0x79C }, + [OLYMPUS_LUT_CHAN_584375_IDX] = { 23375, 0x1, 0x61, 0xCAAAB, 0x79C }, + [OLYMPUS_LUT_CHAN_584500_IDX] = { 23380, 0x1, 0x61, 0xD5555, 0x79C }, + [OLYMPUS_LUT_CHAN_584625_IDX] = { 23385, 0x1, 0x61, 0xE0000, 0x79D }, + [OLYMPUS_LUT_CHAN_584750_IDX] = { 23390, 0x1, 0x61, 0xEAAAB, 0x79D }, + [OLYMPUS_LUT_CHAN_584875_IDX] = { 23395, 0x1, 0x61, 0xF5555, 0x79E }, + [OLYMPUS_LUT_CHAN_585000_IDX] = { 23400, 0x1, 0x61, 0x100000, 0x79E }, + [OLYMPUS_LUT_CHAN_585125_IDX] = { 23405, 0x1, 0x61, 0x10AAAB, 0x79E }, + [OLYMPUS_LUT_CHAN_585250_IDX] = { 23410, 0x1, 0x61, 0x115555, 0x79F }, + [OLYMPUS_LUT_CHAN_585375_IDX] = { 23415, 0x1, 0x61, 0x120000, 0x79F }, + [OLYMPUS_LUT_CHAN_585500_IDX] = { 23420, 0x1, 0x61, 0x12AAAB, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585625_IDX] = { 23425, 0x1, 0x61, 0x135555, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585750_IDX] = { 23430, 0x1, 0x61, 0x140000, 0x7A1 }, + [OLYMPUS_LUT_CHAN_585875_IDX] = { 23435, 0x1, 0x61, 0x14AAAB, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586000_IDX] = { 23440, 0x1, 0x61, 0x155555, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586125_IDX] = { 23445, 0x1, 0x61, 0x160000, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586250_IDX] = { 23450, 0x1, 0x61, 0x16AAAB, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586375_IDX] = { 23455, 0x1, 0x61, 0x175555, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586500_IDX] = { 23460, 0x1, 0x61, 0x180000, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586625_IDX] = { 23465, 0x1, 0x61, 0x18AAAB, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586750_IDX] = { 23470, 0x1, 0x61, 0x195555, 0x7A4 }, + [OLYMPUS_LUT_CHAN_586875_IDX] = { 23475, 0x1, 0x61, 0x1A0000, 0x7A4 }, + [OLYMPUS_LUT_CHAN_587000_IDX] = { 23480, 0x1, 0x61, 0x1AAAAB, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587125_IDX] = { 23485, 0x1, 0x61, 0x1B5555, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587250_IDX] = { 23490, 0x1, 0x61, 0x1C0000, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587375_IDX] = { 23495, 0x1, 0x61, 0x1CAAAB, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587500_IDX] = { 23500, 0x1, 0x61, 0x1D5555, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587625_IDX] = { 23505, 0x1, 0x61, 0x1E0000, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587750_IDX] = { 23510, 0x1, 0x61, 0x1EAAAB, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587875_IDX] = { 23515, 0x1, 0x61, 0x1F5555, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588000_IDX] = { 23520, 0x1, 0x62, 0x0, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588125_IDX] = { 23525, 0x1, 0x62, 0xAAAB, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588250_IDX] = { 23530, 0x1, 0x62, 0x15555, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588375_IDX] = { 23535, 0x1, 0x62, 0x20000, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588500_IDX] = { 23540, 0x1, 0x62, 0x2AAAB, 0x7AA }, + [OLYMPUS_LUT_CHAN_588625_IDX] = { 23545, 0x1, 0x62, 0x35555, 0x7AA }, + [OLYMPUS_LUT_CHAN_588750_IDX] = { 23550, 0x1, 0x62, 0x40000, 0x7AB }, + [OLYMPUS_LUT_CHAN_588875_IDX] = { 23555, 0x1, 0x62, 0x4AAAB, 0x7AB }, + [OLYMPUS_LUT_CHAN_589000_IDX] = { 23560, 0x1, 0x62, 0x55555, 0x7AB }, + [OLYMPUS_LUT_CHAN_589125_IDX] = { 23565, 0x1, 0x62, 0x60000, 0x7AC }, + [OLYMPUS_LUT_CHAN_589250_IDX] = { 23570, 0x1, 0x62, 0x6AAAB, 0x7AC }, + [OLYMPUS_LUT_CHAN_589375_IDX] = { 23575, 0x1, 0x62, 0x75555, 0x7AD }, + [OLYMPUS_LUT_CHAN_589500_IDX] = { 23580, 0x1, 0x62, 0x80000, 0x7AD }, + [OLYMPUS_LUT_CHAN_589625_IDX] = { 23585, 0x1, 0x62, 0x8AAAB, 0x7AD }, + [OLYMPUS_LUT_CHAN_589750_IDX] = { 23590, 0x1, 0x62, 0x95555, 0x7AE }, + [OLYMPUS_LUT_CHAN_589875_IDX] = { 23595, 0x1, 0x62, 0xA0000, 0x7AE }, + [OLYMPUS_LUT_CHAN_590000_IDX] = { 23600, 0x1, 0x62, 0xAAAAB, 0x7AF }, + [OLYMPUS_LUT_CHAN_590125_IDX] = { 23605, 0x1, 0x62, 0xB5555, 0x7AF }, + [OLYMPUS_LUT_CHAN_590250_IDX] = { 23610, 0x1, 0x62, 0xC0000, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590375_IDX] = { 23615, 0x1, 0x62, 0xCAAAB, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590500_IDX] = { 23620, 0x1, 0x62, 0xD5555, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590625_IDX] = { 23625, 0x1, 0x62, 0xE0000, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590750_IDX] = { 23630, 0x1, 0x62, 0xEAAAB, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590875_IDX] = { 23635, 0x1, 0x62, 0xF5555, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591000_IDX] = { 23640, 0x1, 0x62, 0x100000, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591125_IDX] = { 23645, 0x1, 0x62, 0x10AAAB, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591250_IDX] = { 23650, 0x1, 0x62, 0x115555, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591375_IDX] = { 23655, 0x1, 0x62, 0x120000, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591500_IDX] = { 23660, 0x1, 0x62, 0x12AAAB, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591625_IDX] = { 23665, 0x1, 0x62, 0x135555, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591750_IDX] = { 23670, 0x1, 0x62, 0x140000, 0x7B5 }, + [OLYMPUS_LUT_CHAN_591875_IDX] = { 23675, 0x1, 0x62, 0x14AAAB, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592000_IDX] = { 23680, 0x1, 0x62, 0x155555, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592125_IDX] = { 23685, 0x1, 0x62, 0x160000, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592250_IDX] = { 23690, 0x1, 0x62, 0x16AAAB, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592375_IDX] = { 23695, 0x1, 0x62, 0x175555, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592500_IDX] = { 23700, 0x1, 0x62, 0x180000, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592625_IDX] = { 23705, 0x1, 0x62, 0x18AAAB, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592750_IDX] = { 23710, 0x1, 0x62, 0x195555, 0x7B8 }, + [OLYMPUS_LUT_CHAN_592875_IDX] = { 23715, 0x1, 0x62, 0x1A0000, 0x7B8 }, + [OLYMPUS_LUT_CHAN_593000_IDX] = { 23720, 0x1, 0x62, 0x1AAAAB, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593125_IDX] = { 23725, 0x1, 0x62, 0x1B5555, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593250_IDX] = { 23730, 0x1, 0x62, 0x1C0000, 0x7BA }, + [OLYMPUS_LUT_CHAN_593375_IDX] = { 23735, 0x1, 0x62, 0x1CAAAB, 0x7BA }, + [OLYMPUS_LUT_CHAN_593500_IDX] = { 23740, 0x1, 0x62, 0x1D5555, 0x7BA }, + [OLYMPUS_LUT_CHAN_593625_IDX] = { 23745, 0x1, 0x62, 0x1E0000, 0x7BB }, + [OLYMPUS_LUT_CHAN_593750_IDX] = { 23750, 0x1, 0x62, 0x1EAAAB, 0x7BB }, + [OLYMPUS_LUT_CHAN_593875_IDX] = { 23755, 0x1, 0x62, 0x1F5555, 0x7BC }, + [OLYMPUS_LUT_CHAN_594000_IDX] = { 23760, 0x1, 0x63, 0x0, 0x7BC }, + [OLYMPUS_LUT_CHAN_594125_IDX] = { 23765, 0x1, 0x63, 0xAAAB, 0x7BC }, + [OLYMPUS_LUT_CHAN_594250_IDX] = { 23770, 0x1, 0x63, 0x15555, 0x7BD }, + [OLYMPUS_LUT_CHAN_594375_IDX] = { 23775, 0x1, 0x63, 0x20000, 0x7BD }, + [OLYMPUS_LUT_CHAN_594500_IDX] = { 23780, 0x1, 0x63, 0x2AAAB, 0x7BE }, + [OLYMPUS_LUT_CHAN_594625_IDX] = { 23785, 0x1, 0x63, 0x35555, 0x7BE }, + [OLYMPUS_LUT_CHAN_594750_IDX] = { 23790, 0x1, 0x63, 0x40000, 0x7BF }, + [OLYMPUS_LUT_CHAN_594875_IDX] = { 23795, 0x1, 0x63, 0x4AAAB, 0x7BF }, + [OLYMPUS_LUT_CHAN_595000_IDX] = { 23800, 0x1, 0x63, 0x55555, 0x7BF }, + [OLYMPUS_LUT_CHAN_595125_IDX] = { 23805, 0x1, 0x63, 0x60000, 0x7C0 }, + [OLYMPUS_LUT_CHAN_595250_IDX] = { 23810, 0x1, 0x63, 0x6AAAB, 0x7C0 }, + [OLYMPUS_LUT_CHAN_595375_IDX] = { 23815, 0x1, 0x63, 0x75555, 0x7C1 }, + [OLYMPUS_LUT_CHAN_595500_IDX] = { 23820, 0x1, 0x63, 0x80000, 0x7C1 }, + [OLYMPUS_LUT_CHAN_595625_IDX] = { 23825, 0x1, 0x63, 0x8AAAB, 0x7C1 }, + [OLYMPUS_LUT_CHAN_595750_IDX] = { 23830, 0x1, 0x63, 0x95555, 0x7C2 }, + [OLYMPUS_LUT_CHAN_595875_IDX] = { 23835, 0x1, 0x63, 0xA0000, 0x7C2 }, + [OLYMPUS_LUT_CHAN_596000_IDX] = { 23840, 0x1, 0x63, 0xAAAAB, 0x7C3 }, + [OLYMPUS_LUT_CHAN_596125_IDX] = { 23845, 0x1, 0x63, 0xB5555, 0x7C3 }, + [OLYMPUS_LUT_CHAN_596250_IDX] = { 23850, 0x1, 0x63, 0xC0000, 0x7C4 }, + [OLYMPUS_LUT_CHAN_596375_IDX] = { 23855, 0x1, 0x63, 0xCAAAB, 0x7C4 }, + [OLYMPUS_LUT_CHAN_596500_IDX] = { 23860, 0x1, 0x63, 0xD5555, 0x7C4 }, + [OLYMPUS_LUT_CHAN_596625_IDX] = { 23865, 0x1, 0x63, 0xE0000, 0x7C5 }, + [OLYMPUS_LUT_CHAN_596750_IDX] = { 23870, 0x1, 0x63, 0xEAAAB, 0x7C5 }, + [OLYMPUS_LUT_CHAN_596875_IDX] = { 23875, 0x1, 0x63, 0xF5555, 0x7C6 }, + [OLYMPUS_LUT_CHAN_597000_IDX] = { 23880, 0x1, 0x63, 0x100000, 0x7C6 }, + [OLYMPUS_LUT_CHAN_597125_IDX] = { 23885, 0x1, 0x63, 0x10AAAB, 0x7C6 }, + [OLYMPUS_LUT_CHAN_597250_IDX] = { 23890, 0x1, 0x63, 0x115555, 0x7C7 }, + [OLYMPUS_LUT_CHAN_597375_IDX] = { 23895, 0x1, 0x63, 0x120000, 0x7C7 }, + [OLYMPUS_LUT_CHAN_597500_IDX] = { 23900, 0x1, 0x63, 0x12AAAB, 0x7C8 }, + [OLYMPUS_LUT_CHAN_597625_IDX] = { 23905, 0x1, 0x63, 0x135555, 0x7C8 }, + [OLYMPUS_LUT_CHAN_597750_IDX] = { 23910, 0x1, 0x63, 0x140000, 0x7C9 }, + [OLYMPUS_LUT_CHAN_597875_IDX] = { 23915, 0x1, 0x63, 0x14AAAB, 0x7C9 }, + [OLYMPUS_LUT_CHAN_598000_IDX] = { 23920, 0x1, 0x63, 0x155555, 0x7C9 }, + [OLYMPUS_LUT_CHAN_598125_IDX] = { 23925, 0x1, 0x63, 0x160000, 0x7CA }, + [OLYMPUS_LUT_CHAN_598250_IDX] = { 23930, 0x1, 0x63, 0x16AAAB, 0x7CA }, + [OLYMPUS_LUT_CHAN_598375_IDX] = { 23935, 0x1, 0x63, 0x175555, 0x7CB }, + [OLYMPUS_LUT_CHAN_598500_IDX] = { 23940, 0x1, 0x63, 0x180000, 0x7CB }, + [OLYMPUS_LUT_CHAN_598625_IDX] = { 23945, 0x1, 0x63, 0x18AAAB, 0x7CB }, + [OLYMPUS_LUT_CHAN_598750_IDX] = { 23950, 0x1, 0x63, 0x195555, 0x7CC }, + [OLYMPUS_LUT_CHAN_598875_IDX] = { 23955, 0x1, 0x63, 0x1A0000, 0x7CC }, + [OLYMPUS_LUT_CHAN_599000_IDX] = { 23960, 0x1, 0x63, 0x1AAAAB, 0x7CD }, + [OLYMPUS_LUT_CHAN_599125_IDX] = { 23965, 0x1, 0x63, 0x1B5555, 0x7CD }, + [OLYMPUS_LUT_CHAN_599250_IDX] = { 23970, 0x1, 0x63, 0x1C0000, 0x7CE }, + [OLYMPUS_LUT_CHAN_599375_IDX] = { 23975, 0x1, 0x63, 0x1CAAAB, 0x7CE }, + [OLYMPUS_LUT_CHAN_599500_IDX] = { 23980, 0x1, 0x63, 0x1D5555, 0x7CE }, + [OLYMPUS_LUT_CHAN_599625_IDX] = { 23985, 0x1, 0x63, 0x1E0000, 0x7CF }, + [OLYMPUS_LUT_CHAN_599750_IDX] = { 23990, 0x1, 0x63, 0x1EAAAB, 0x7CF }, + [OLYMPUS_LUT_CHAN_599875_IDX] = { 23995, 0x1, 0x63, 0x1F5555, 0x7D0 }, + [OLYMPUS_LUT_CHAN_600000_IDX] = { 24000, 0x1, 0x64, 0x0, 0x7D0 } +}; + +const struct common_lut_line olympus_lut_5g_60_mhz_s1[OLYMPUS_LUT_CHAN_5G_MAX] = { + [OLYMPUS_LUT_CHAN_516000_IDX] = { 20640, 0x0, 0x39, 0x11C71C, 0x6BF }, + [OLYMPUS_LUT_CHAN_516125_IDX] = { 20645, 0x0, 0x39, 0xB1C72, 0x6B8 }, + [OLYMPUS_LUT_CHAN_516250_IDX] = { 20650, 0x0, 0x39, 0xB8E39, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516375_IDX] = { 20655, 0x0, 0x39, 0xC0000, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516500_IDX] = { 20660, 0x0, 0x39, 0xC71C7, 0x6BA }, + [OLYMPUS_LUT_CHAN_516625_IDX] = { 20665, 0x0, 0x39, 0xCE38E, 0x6BA }, + [OLYMPUS_LUT_CHAN_516750_IDX] = { 20670, 0x0, 0x39, 0xD5555, 0x6BB }, + [OLYMPUS_LUT_CHAN_516875_IDX] = { 20675, 0x0, 0x39, 0xDC71C, 0x6BB }, + [OLYMPUS_LUT_CHAN_517000_IDX] = { 20680, 0x0, 0x39, 0xE38E4, 0x6BB }, + [OLYMPUS_LUT_CHAN_517125_IDX] = { 20685, 0x0, 0x39, 0xEAAAB, 0x6BC }, + [OLYMPUS_LUT_CHAN_517250_IDX] = { 20690, 0x0, 0x39, 0xF1C72, 0x6BC }, + [OLYMPUS_LUT_CHAN_517375_IDX] = { 20695, 0x0, 0x39, 0xF8E39, 0x6BD }, + [OLYMPUS_LUT_CHAN_517500_IDX] = { 20700, 0x0, 0x39, 0x100000, 0x6BD }, + [OLYMPUS_LUT_CHAN_517625_IDX] = { 20705, 0x0, 0x39, 0x1071C7, 0x6BD }, + [OLYMPUS_LUT_CHAN_517750_IDX] = { 20710, 0x0, 0x39, 0x10E38E, 0x6BE }, + [OLYMPUS_LUT_CHAN_517875_IDX] = { 20715, 0x0, 0x39, 0x115555, 0x6BE }, + [OLYMPUS_LUT_CHAN_518000_IDX] = { 20720, 0x1, 0x39, 0x11C71C, 0x6BF }, + [OLYMPUS_LUT_CHAN_518125_IDX] = { 20725, 0x1, 0x39, 0x1238E4, 0x6BF }, + [OLYMPUS_LUT_CHAN_518250_IDX] = { 20730, 0x1, 0x39, 0x12AAAB, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518375_IDX] = { 20735, 0x1, 0x39, 0x131C72, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518500_IDX] = { 20740, 0x1, 0x39, 0x138E39, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518625_IDX] = { 20745, 0x1, 0x39, 0x140000, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518750_IDX] = { 20750, 0x1, 0x39, 0x1471C7, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518875_IDX] = { 20755, 0x1, 0x39, 0x14E38E, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519000_IDX] = { 20760, 0x1, 0x39, 0x155555, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519125_IDX] = { 20765, 0x1, 0x39, 0x15C71C, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519250_IDX] = { 20770, 0x1, 0x39, 0x1638E4, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519375_IDX] = { 20775, 0x1, 0x39, 0x16AAAB, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519500_IDX] = { 20780, 0x1, 0x39, 0x171C72, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519625_IDX] = { 20785, 0x1, 0x39, 0x178E39, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519750_IDX] = { 20790, 0x1, 0x39, 0x180000, 0x6C5 }, + [OLYMPUS_LUT_CHAN_519875_IDX] = { 20795, 0x1, 0x39, 0x1871C7, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520000_IDX] = { 20800, 0x1, 0x39, 0x18E38E, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520125_IDX] = { 20805, 0x1, 0x39, 0x195555, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520250_IDX] = { 20810, 0x1, 0x39, 0x19C71C, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520375_IDX] = { 20815, 0x1, 0x39, 0x1A38E4, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520500_IDX] = { 20820, 0x1, 0x39, 0x1AAAAB, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520625_IDX] = { 20825, 0x1, 0x39, 0x1B1C72, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520750_IDX] = { 20830, 0x1, 0x39, 0x1B8E39, 0x6C8 }, + [OLYMPUS_LUT_CHAN_520875_IDX] = { 20835, 0x1, 0x39, 0x1C0000, 0x6C8 }, + [OLYMPUS_LUT_CHAN_521000_IDX] = { 20840, 0x1, 0x39, 0x1C71C7, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521125_IDX] = { 20845, 0x1, 0x39, 0x1CE38E, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521250_IDX] = { 20850, 0x1, 0x39, 0x1D5555, 0x6CA }, + [OLYMPUS_LUT_CHAN_521375_IDX] = { 20855, 0x1, 0x39, 0x1DC71C, 0x6CA }, + [OLYMPUS_LUT_CHAN_521500_IDX] = { 20860, 0x1, 0x39, 0x1E38E4, 0x6CA }, + [OLYMPUS_LUT_CHAN_521625_IDX] = { 20865, 0x1, 0x39, 0x1EAAAB, 0x6CB }, + [OLYMPUS_LUT_CHAN_521750_IDX] = { 20870, 0x1, 0x39, 0x1F1C72, 0x6CB }, + [OLYMPUS_LUT_CHAN_521875_IDX] = { 20875, 0x1, 0x39, 0x1F8E39, 0x6CC }, + [OLYMPUS_LUT_CHAN_522000_IDX] = { 20880, 0x1, 0x3A, 0x0, 0x6CC }, + [OLYMPUS_LUT_CHAN_522125_IDX] = { 20885, 0x1, 0x3A, 0x71C7, 0x6CC }, + [OLYMPUS_LUT_CHAN_522250_IDX] = { 20890, 0x1, 0x3A, 0xE38E, 0x6CD }, + [OLYMPUS_LUT_CHAN_522375_IDX] = { 20895, 0x1, 0x3A, 0x15555, 0x6CD }, + [OLYMPUS_LUT_CHAN_522500_IDX] = { 20900, 0x1, 0x3A, 0x1C71C, 0x6CE }, + [OLYMPUS_LUT_CHAN_522625_IDX] = { 20905, 0x1, 0x3A, 0x238E4, 0x6CE }, + [OLYMPUS_LUT_CHAN_522750_IDX] = { 20910, 0x1, 0x3A, 0x2AAAB, 0x6CF }, + [OLYMPUS_LUT_CHAN_522875_IDX] = { 20915, 0x1, 0x3A, 0x31C72, 0x6CF }, + [OLYMPUS_LUT_CHAN_523000_IDX] = { 20920, 0x1, 0x3A, 0x38E39, 0x6CF }, + [OLYMPUS_LUT_CHAN_523125_IDX] = { 20925, 0x1, 0x3A, 0x40000, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523250_IDX] = { 20930, 0x1, 0x3A, 0x471C7, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523375_IDX] = { 20935, 0x1, 0x3A, 0x4E38E, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523500_IDX] = { 20940, 0x1, 0x3A, 0x55555, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523625_IDX] = { 20945, 0x1, 0x3A, 0x5C71C, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523750_IDX] = { 20950, 0x1, 0x3A, 0x638E4, 0x6D2 }, + [OLYMPUS_LUT_CHAN_523875_IDX] = { 20955, 0x1, 0x3A, 0x6AAAB, 0x6D2 }, + [OLYMPUS_LUT_CHAN_524000_IDX] = { 20960, 0x1, 0x3A, 0x71C72, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524125_IDX] = { 20965, 0x1, 0x3A, 0x78E39, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524250_IDX] = { 20970, 0x1, 0x3A, 0x80000, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524375_IDX] = { 20975, 0x1, 0x3A, 0x871C7, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524500_IDX] = { 20980, 0x1, 0x3A, 0x8E38E, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524625_IDX] = { 20985, 0x1, 0x3A, 0x95555, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524750_IDX] = { 20990, 0x1, 0x3A, 0x9C71C, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524875_IDX] = { 20995, 0x1, 0x3A, 0xA38E4, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525000_IDX] = { 21000, 0x1, 0x3A, 0xAAAAB, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525125_IDX] = { 21005, 0x1, 0x3A, 0xB1C72, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525250_IDX] = { 21010, 0x1, 0x3A, 0xB8E39, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525375_IDX] = { 21015, 0x1, 0x3A, 0xC0000, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525500_IDX] = { 21020, 0x1, 0x3A, 0xC71C7, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525625_IDX] = { 21025, 0x1, 0x3A, 0xCE38E, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525750_IDX] = { 21030, 0x1, 0x3A, 0xD5555, 0x6D9 }, + [OLYMPUS_LUT_CHAN_525875_IDX] = { 21035, 0x1, 0x3A, 0xDC71C, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526000_IDX] = { 21040, 0x1, 0x3A, 0xE38E4, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526125_IDX] = { 21045, 0x1, 0x3A, 0xEAAAB, 0x6DA }, + [OLYMPUS_LUT_CHAN_526250_IDX] = { 21050, 0x1, 0x3A, 0xF1C72, 0x6DA }, + [OLYMPUS_LUT_CHAN_526375_IDX] = { 21055, 0x1, 0x3A, 0xF8E39, 0x6DB }, + [OLYMPUS_LUT_CHAN_526500_IDX] = { 21060, 0x1, 0x3A, 0x100000, 0x6DB }, + [OLYMPUS_LUT_CHAN_526625_IDX] = { 21065, 0x1, 0x3A, 0x1071C7, 0x6DB }, + [OLYMPUS_LUT_CHAN_526750_IDX] = { 21070, 0x1, 0x3A, 0x10E38E, 0x6DC }, + [OLYMPUS_LUT_CHAN_526875_IDX] = { 21075, 0x1, 0x3A, 0x115555, 0x6DC }, + [OLYMPUS_LUT_CHAN_527000_IDX] = { 21080, 0x1, 0x3A, 0x11C71C, 0x6DD }, + [OLYMPUS_LUT_CHAN_527125_IDX] = { 21085, 0x1, 0x3A, 0x1238E4, 0x6DD }, + [OLYMPUS_LUT_CHAN_527250_IDX] = { 21090, 0x1, 0x3A, 0x12AAAB, 0x6DE }, + [OLYMPUS_LUT_CHAN_527375_IDX] = { 21095, 0x1, 0x3A, 0x131C72, 0x6DE }, + [OLYMPUS_LUT_CHAN_527500_IDX] = { 21100, 0x1, 0x3A, 0x138E39, 0x6DE }, + [OLYMPUS_LUT_CHAN_527625_IDX] = { 21105, 0x1, 0x3A, 0x140000, 0x6DF }, + [OLYMPUS_LUT_CHAN_527750_IDX] = { 21110, 0x1, 0x3A, 0x1471C7, 0x6DF }, + [OLYMPUS_LUT_CHAN_527875_IDX] = { 21115, 0x1, 0x3A, 0x14E38E, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528000_IDX] = { 21120, 0x1, 0x3A, 0x155555, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528125_IDX] = { 21125, 0x1, 0x3A, 0x15C71C, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528250_IDX] = { 21130, 0x1, 0x3A, 0x1638E4, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528375_IDX] = { 21135, 0x1, 0x3A, 0x16AAAB, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528500_IDX] = { 21140, 0x1, 0x3A, 0x171C72, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528625_IDX] = { 21145, 0x1, 0x3A, 0x178E39, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528750_IDX] = { 21150, 0x1, 0x3A, 0x180000, 0x6E3 }, + [OLYMPUS_LUT_CHAN_528875_IDX] = { 21155, 0x1, 0x3A, 0x1871C7, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529000_IDX] = { 21160, 0x1, 0x3A, 0x18E38E, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529125_IDX] = { 21165, 0x1, 0x3A, 0x195555, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529250_IDX] = { 21170, 0x1, 0x3A, 0x19C71C, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529375_IDX] = { 21175, 0x1, 0x3A, 0x1A38E4, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529500_IDX] = { 21180, 0x1, 0x3A, 0x1AAAAB, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529625_IDX] = { 21185, 0x1, 0x3A, 0x1B1C72, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529750_IDX] = { 21190, 0x1, 0x3A, 0x1B8E39, 0x6E6 }, + [OLYMPUS_LUT_CHAN_529875_IDX] = { 21195, 0x1, 0x3A, 0x1C0000, 0x6E6 }, + [OLYMPUS_LUT_CHAN_530000_IDX] = { 21200, 0x1, 0x3A, 0x1C71C7, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530125_IDX] = { 21205, 0x1, 0x3A, 0x1CE38E, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530250_IDX] = { 21210, 0x1, 0x3A, 0x1D5555, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530375_IDX] = { 21215, 0x1, 0x3A, 0x1DC71C, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530500_IDX] = { 21220, 0x1, 0x3A, 0x1E38E4, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530625_IDX] = { 21225, 0x1, 0x3A, 0x1EAAAB, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530750_IDX] = { 21230, 0x1, 0x3A, 0x1F1C72, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530875_IDX] = { 21235, 0x1, 0x3A, 0x1F8E39, 0x6EA }, + [OLYMPUS_LUT_CHAN_531000_IDX] = { 21240, 0x1, 0x3B, 0x0, 0x6EA }, + [OLYMPUS_LUT_CHAN_531125_IDX] = { 21245, 0x1, 0x3B, 0x71C7, 0x6EA }, + [OLYMPUS_LUT_CHAN_531250_IDX] = { 21250, 0x1, 0x3B, 0xE38E, 0x6EB }, + [OLYMPUS_LUT_CHAN_531375_IDX] = { 21255, 0x1, 0x3B, 0x15555, 0x6EB }, + [OLYMPUS_LUT_CHAN_531500_IDX] = { 21260, 0x1, 0x3B, 0x1C71C, 0x6EC }, + [OLYMPUS_LUT_CHAN_531625_IDX] = { 21265, 0x1, 0x3B, 0x238E4, 0x6EC }, + [OLYMPUS_LUT_CHAN_531750_IDX] = { 21270, 0x1, 0x3B, 0x2AAAB, 0x6ED }, + [OLYMPUS_LUT_CHAN_531875_IDX] = { 21275, 0x1, 0x3B, 0x31C72, 0x6ED }, + [OLYMPUS_LUT_CHAN_532000_IDX] = { 21280, 0x1, 0x3B, 0x38E39, 0x6ED }, + [OLYMPUS_LUT_CHAN_532125_IDX] = { 21285, 0x1, 0x3B, 0x40000, 0x6EE }, + [OLYMPUS_LUT_CHAN_532250_IDX] = { 21290, 0x1, 0x3B, 0x471C7, 0x6EE }, + [OLYMPUS_LUT_CHAN_532375_IDX] = { 21295, 0x1, 0x3B, 0x4E38E, 0x6EF }, + [OLYMPUS_LUT_CHAN_532500_IDX] = { 21300, 0x1, 0x3B, 0x55555, 0x6EF }, + [OLYMPUS_LUT_CHAN_532625_IDX] = { 21305, 0x1, 0x3B, 0x5C71C, 0x6EF }, + [OLYMPUS_LUT_CHAN_532750_IDX] = { 21310, 0x1, 0x3B, 0x638E4, 0x6F0 }, + [OLYMPUS_LUT_CHAN_532875_IDX] = { 21315, 0x1, 0x3B, 0x6AAAB, 0x6F0 }, + [OLYMPUS_LUT_CHAN_533000_IDX] = { 21320, 0x1, 0x3B, 0x71C72, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533125_IDX] = { 21325, 0x1, 0x3B, 0x78E39, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533250_IDX] = { 21330, 0x1, 0x3B, 0x80000, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533375_IDX] = { 21335, 0x1, 0x3B, 0x871C7, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533500_IDX] = { 21340, 0x1, 0x3B, 0x8E38E, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533625_IDX] = { 21345, 0x1, 0x3B, 0x95555, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533750_IDX] = { 21350, 0x1, 0x3B, 0x9C71C, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533875_IDX] = { 21355, 0x1, 0x3B, 0xA38E4, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534000_IDX] = { 21360, 0x1, 0x3B, 0xAAAAB, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534125_IDX] = { 21365, 0x1, 0x3B, 0xB1C72, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534250_IDX] = { 21370, 0x1, 0x3B, 0xB8E39, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534375_IDX] = { 21375, 0x1, 0x3B, 0xC0000, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534500_IDX] = { 21380, 0x1, 0x3B, 0xC71C7, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534625_IDX] = { 21385, 0x1, 0x3B, 0xCE38E, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534750_IDX] = { 21390, 0x1, 0x3B, 0xD5555, 0x6F7 }, + [OLYMPUS_LUT_CHAN_534875_IDX] = { 21395, 0x1, 0x3B, 0xDC71C, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535000_IDX] = { 21400, 0x1, 0x3B, 0xE38E4, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535125_IDX] = { 21405, 0x1, 0x3B, 0xEAAAB, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535250_IDX] = { 21410, 0x1, 0x3B, 0xF1C72, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535375_IDX] = { 21415, 0x1, 0x3B, 0xF8E39, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535500_IDX] = { 21420, 0x1, 0x3B, 0x100000, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535625_IDX] = { 21425, 0x1, 0x3B, 0x1071C7, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535750_IDX] = { 21430, 0x1, 0x3B, 0x10E38E, 0x6FA }, + [OLYMPUS_LUT_CHAN_535875_IDX] = { 21435, 0x1, 0x3B, 0x115555, 0x6FA }, + [OLYMPUS_LUT_CHAN_536000_IDX] = { 21440, 0x1, 0x3B, 0x11C71C, 0x6FB }, + [OLYMPUS_LUT_CHAN_536125_IDX] = { 21445, 0x1, 0x3B, 0x1238E4, 0x6FB }, + [OLYMPUS_LUT_CHAN_536250_IDX] = { 21450, 0x1, 0x3B, 0x12AAAB, 0x6FC }, + [OLYMPUS_LUT_CHAN_536375_IDX] = { 21455, 0x1, 0x3B, 0x131C72, 0x6FC }, + [OLYMPUS_LUT_CHAN_536500_IDX] = { 21460, 0x1, 0x3B, 0x138E39, 0x6FC }, + [OLYMPUS_LUT_CHAN_536625_IDX] = { 21465, 0x1, 0x3B, 0x140000, 0x6FD }, + [OLYMPUS_LUT_CHAN_536750_IDX] = { 21470, 0x1, 0x3B, 0x1471C7, 0x6FD }, + [OLYMPUS_LUT_CHAN_536875_IDX] = { 21475, 0x1, 0x3B, 0x14E38E, 0x6FE }, + [OLYMPUS_LUT_CHAN_537000_IDX] = { 21480, 0x1, 0x3B, 0x155555, 0x6FE }, + [OLYMPUS_LUT_CHAN_537125_IDX] = { 21485, 0x1, 0x3B, 0x15C71C, 0x6FE }, + [OLYMPUS_LUT_CHAN_537250_IDX] = { 21490, 0x1, 0x3B, 0x1638E4, 0x6FF }, + [OLYMPUS_LUT_CHAN_537375_IDX] = { 21495, 0x1, 0x3B, 0x16AAAB, 0x6FF }, + [OLYMPUS_LUT_CHAN_537500_IDX] = { 21500, 0x1, 0x3B, 0x171C72, 0x700 }, + [OLYMPUS_LUT_CHAN_537625_IDX] = { 21505, 0x1, 0x3B, 0x178E39, 0x700 }, + [OLYMPUS_LUT_CHAN_537750_IDX] = { 21510, 0x1, 0x3B, 0x180000, 0x701 }, + [OLYMPUS_LUT_CHAN_537875_IDX] = { 21515, 0x1, 0x3B, 0x1871C7, 0x701 }, + [OLYMPUS_LUT_CHAN_538000_IDX] = { 21520, 0x1, 0x3B, 0x18E38E, 0x701 }, + [OLYMPUS_LUT_CHAN_538125_IDX] = { 21525, 0x1, 0x3B, 0x195555, 0x702 }, + [OLYMPUS_LUT_CHAN_538250_IDX] = { 21530, 0x1, 0x3B, 0x19C71C, 0x702 }, + [OLYMPUS_LUT_CHAN_538375_IDX] = { 21535, 0x1, 0x3B, 0x1A38E4, 0x703 }, + [OLYMPUS_LUT_CHAN_538500_IDX] = { 21540, 0x1, 0x3B, 0x1AAAAB, 0x703 }, + [OLYMPUS_LUT_CHAN_538625_IDX] = { 21545, 0x1, 0x3B, 0x1B1C72, 0x703 }, + [OLYMPUS_LUT_CHAN_538750_IDX] = { 21550, 0x1, 0x3B, 0x1B8E39, 0x704 }, + [OLYMPUS_LUT_CHAN_538875_IDX] = { 21555, 0x1, 0x3B, 0x1C0000, 0x704 }, + [OLYMPUS_LUT_CHAN_539000_IDX] = { 21560, 0x1, 0x3B, 0x1C71C7, 0x705 }, + [OLYMPUS_LUT_CHAN_539125_IDX] = { 21565, 0x1, 0x3B, 0x1CE38E, 0x705 }, + [OLYMPUS_LUT_CHAN_539250_IDX] = { 21570, 0x1, 0x3B, 0x1D5555, 0x706 }, + [OLYMPUS_LUT_CHAN_539375_IDX] = { 21575, 0x1, 0x3B, 0x1DC71C, 0x706 }, + [OLYMPUS_LUT_CHAN_539500_IDX] = { 21580, 0x1, 0x3B, 0x1E38E4, 0x706 }, + [OLYMPUS_LUT_CHAN_539625_IDX] = { 21585, 0x1, 0x3B, 0x1EAAAB, 0x707 }, + [OLYMPUS_LUT_CHAN_539750_IDX] = { 21590, 0x1, 0x3B, 0x1F1C72, 0x707 }, + [OLYMPUS_LUT_CHAN_539875_IDX] = { 21595, 0x1, 0x3B, 0x1F8E39, 0x708 }, + [OLYMPUS_LUT_CHAN_540000_IDX] = { 21600, 0x1, 0x3C, 0x0, 0x708 }, + [OLYMPUS_LUT_CHAN_540125_IDX] = { 21605, 0x1, 0x3C, 0x71C7, 0x708 }, + [OLYMPUS_LUT_CHAN_540250_IDX] = { 21610, 0x1, 0x3C, 0xE38E, 0x709 }, + [OLYMPUS_LUT_CHAN_540375_IDX] = { 21615, 0x1, 0x3C, 0x15555, 0x709 }, + [OLYMPUS_LUT_CHAN_540500_IDX] = { 21620, 0x1, 0x3C, 0x1C71C, 0x70A }, + [OLYMPUS_LUT_CHAN_540625_IDX] = { 21625, 0x1, 0x3C, 0x238E4, 0x70A }, + [OLYMPUS_LUT_CHAN_540750_IDX] = { 21630, 0x1, 0x3C, 0x2AAAB, 0x70B }, + [OLYMPUS_LUT_CHAN_540875_IDX] = { 21635, 0x1, 0x3C, 0x31C72, 0x70B }, + [OLYMPUS_LUT_CHAN_541000_IDX] = { 21640, 0x1, 0x3C, 0x38E39, 0x70B }, + [OLYMPUS_LUT_CHAN_541125_IDX] = { 21645, 0x1, 0x3C, 0x40000, 0x70C }, + [OLYMPUS_LUT_CHAN_541250_IDX] = { 21650, 0x1, 0x3C, 0x471C7, 0x70C }, + [OLYMPUS_LUT_CHAN_541375_IDX] = { 21655, 0x1, 0x3C, 0x4E38E, 0x70D }, + [OLYMPUS_LUT_CHAN_541500_IDX] = { 21660, 0x1, 0x3C, 0x55555, 0x70D }, + [OLYMPUS_LUT_CHAN_541625_IDX] = { 21665, 0x1, 0x3C, 0x5C71C, 0x70D }, + [OLYMPUS_LUT_CHAN_541750_IDX] = { 21670, 0x1, 0x3C, 0x638E4, 0x70E }, + [OLYMPUS_LUT_CHAN_541875_IDX] = { 21675, 0x1, 0x3C, 0x6AAAB, 0x70E }, + [OLYMPUS_LUT_CHAN_542000_IDX] = { 21680, 0x1, 0x3C, 0x71C72, 0x70F }, + [OLYMPUS_LUT_CHAN_542125_IDX] = { 21685, 0x1, 0x3C, 0x78E39, 0x70F }, + [OLYMPUS_LUT_CHAN_542250_IDX] = { 21690, 0x1, 0x3C, 0x80000, 0x710 }, + [OLYMPUS_LUT_CHAN_542375_IDX] = { 21695, 0x1, 0x3C, 0x871C7, 0x710 }, + [OLYMPUS_LUT_CHAN_542500_IDX] = { 21700, 0x1, 0x3C, 0x8E38E, 0x710 }, + [OLYMPUS_LUT_CHAN_542625_IDX] = { 21705, 0x1, 0x3C, 0x95555, 0x711 }, + [OLYMPUS_LUT_CHAN_542750_IDX] = { 21710, 0x1, 0x3C, 0x9C71C, 0x711 }, + [OLYMPUS_LUT_CHAN_542875_IDX] = { 21715, 0x1, 0x3C, 0xA38E4, 0x712 }, + [OLYMPUS_LUT_CHAN_543000_IDX] = { 21720, 0x1, 0x3C, 0xAAAAB, 0x712 }, + [OLYMPUS_LUT_CHAN_543125_IDX] = { 21725, 0x1, 0x3C, 0xB1C72, 0x712 }, + [OLYMPUS_LUT_CHAN_543250_IDX] = { 21730, 0x1, 0x3C, 0xB8E39, 0x713 }, + [OLYMPUS_LUT_CHAN_543375_IDX] = { 21735, 0x1, 0x3C, 0xC0000, 0x713 }, + [OLYMPUS_LUT_CHAN_543500_IDX] = { 21740, 0x1, 0x3C, 0xC71C7, 0x714 }, + [OLYMPUS_LUT_CHAN_543625_IDX] = { 21745, 0x1, 0x3C, 0xCE38E, 0x714 }, + [OLYMPUS_LUT_CHAN_543750_IDX] = { 21750, 0x1, 0x3C, 0xD5555, 0x715 }, + [OLYMPUS_LUT_CHAN_543875_IDX] = { 21755, 0x1, 0x3C, 0xDC71C, 0x715 }, + [OLYMPUS_LUT_CHAN_544000_IDX] = { 21760, 0x1, 0x3C, 0xE38E4, 0x715 }, + [OLYMPUS_LUT_CHAN_544125_IDX] = { 21765, 0x1, 0x3C, 0xEAAAB, 0x716 }, + [OLYMPUS_LUT_CHAN_544250_IDX] = { 21770, 0x1, 0x3C, 0xF1C72, 0x716 }, + [OLYMPUS_LUT_CHAN_544375_IDX] = { 21775, 0x1, 0x3C, 0xF8E39, 0x717 }, + [OLYMPUS_LUT_CHAN_544500_IDX] = { 21780, 0x1, 0x3C, 0x100000, 0x717 }, + [OLYMPUS_LUT_CHAN_544625_IDX] = { 21785, 0x1, 0x3C, 0x1071C7, 0x717 }, + [OLYMPUS_LUT_CHAN_544750_IDX] = { 21790, 0x1, 0x3C, 0x10E38E, 0x718 }, + [OLYMPUS_LUT_CHAN_544875_IDX] = { 21795, 0x1, 0x3C, 0x115555, 0x718 }, + [OLYMPUS_LUT_CHAN_545000_IDX] = { 21800, 0x1, 0x3C, 0x11C71C, 0x719 }, + [OLYMPUS_LUT_CHAN_545125_IDX] = { 21805, 0x1, 0x3C, 0x1238E4, 0x719 }, + [OLYMPUS_LUT_CHAN_545250_IDX] = { 21810, 0x1, 0x3C, 0x12AAAB, 0x71A }, + [OLYMPUS_LUT_CHAN_545375_IDX] = { 21815, 0x1, 0x3C, 0x131C72, 0x71A }, + [OLYMPUS_LUT_CHAN_545500_IDX] = { 21820, 0x1, 0x3C, 0x138E39, 0x71A }, + [OLYMPUS_LUT_CHAN_545625_IDX] = { 21825, 0x1, 0x3C, 0x140000, 0x71B }, + [OLYMPUS_LUT_CHAN_545750_IDX] = { 21830, 0x1, 0x3C, 0x1471C7, 0x71B }, + [OLYMPUS_LUT_CHAN_545875_IDX] = { 21835, 0x1, 0x3C, 0x14E38E, 0x71C }, + [OLYMPUS_LUT_CHAN_546000_IDX] = { 21840, 0x1, 0x3C, 0x155555, 0x71C }, + [OLYMPUS_LUT_CHAN_546125_IDX] = { 21845, 0x1, 0x3C, 0x15C71C, 0x71C }, + [OLYMPUS_LUT_CHAN_546250_IDX] = { 21850, 0x1, 0x3C, 0x1638E4, 0x71D }, + [OLYMPUS_LUT_CHAN_546375_IDX] = { 21855, 0x1, 0x3C, 0x16AAAB, 0x71D }, + [OLYMPUS_LUT_CHAN_546500_IDX] = { 21860, 0x1, 0x3C, 0x171C72, 0x71E }, + [OLYMPUS_LUT_CHAN_546625_IDX] = { 21865, 0x1, 0x3C, 0x178E39, 0x71E }, + [OLYMPUS_LUT_CHAN_546750_IDX] = { 21870, 0x1, 0x3C, 0x180000, 0x71F }, + [OLYMPUS_LUT_CHAN_546875_IDX] = { 21875, 0x1, 0x3C, 0x1871C7, 0x71F }, + [OLYMPUS_LUT_CHAN_547000_IDX] = { 21880, 0x1, 0x3C, 0x18E38E, 0x71F }, + [OLYMPUS_LUT_CHAN_547125_IDX] = { 21885, 0x1, 0x3C, 0x195555, 0x720 }, + [OLYMPUS_LUT_CHAN_547250_IDX] = { 21890, 0x1, 0x3C, 0x19C71C, 0x720 }, + [OLYMPUS_LUT_CHAN_547375_IDX] = { 21895, 0x1, 0x3C, 0x1A38E4, 0x721 }, + [OLYMPUS_LUT_CHAN_547500_IDX] = { 21900, 0x1, 0x3C, 0x1AAAAB, 0x721 }, + [OLYMPUS_LUT_CHAN_547625_IDX] = { 21905, 0x1, 0x3C, 0x1B1C72, 0x721 }, + [OLYMPUS_LUT_CHAN_547750_IDX] = { 21910, 0x1, 0x3C, 0x1B8E39, 0x722 }, + [OLYMPUS_LUT_CHAN_547875_IDX] = { 21915, 0x1, 0x3C, 0x1C0000, 0x722 }, + [OLYMPUS_LUT_CHAN_548000_IDX] = { 21920, 0x1, 0x3C, 0x1C71C7, 0x723 }, + [OLYMPUS_LUT_CHAN_548125_IDX] = { 21925, 0x1, 0x3C, 0x1CE38E, 0x723 }, + [OLYMPUS_LUT_CHAN_548250_IDX] = { 21930, 0x1, 0x3C, 0x1D5555, 0x724 }, + [OLYMPUS_LUT_CHAN_548375_IDX] = { 21935, 0x1, 0x3C, 0x1DC71C, 0x724 }, + [OLYMPUS_LUT_CHAN_548500_IDX] = { 21940, 0x1, 0x3C, 0x1E38E4, 0x724 }, + [OLYMPUS_LUT_CHAN_548625_IDX] = { 21945, 0x1, 0x3C, 0x1EAAAB, 0x725 }, + [OLYMPUS_LUT_CHAN_548750_IDX] = { 21950, 0x1, 0x3C, 0x1F1C72, 0x725 }, + [OLYMPUS_LUT_CHAN_548875_IDX] = { 21955, 0x1, 0x3C, 0x1F8E39, 0x726 }, + [OLYMPUS_LUT_CHAN_549000_IDX] = { 21960, 0x1, 0x3D, 0x0, 0x726 }, + [OLYMPUS_LUT_CHAN_549125_IDX] = { 21965, 0x1, 0x3D, 0x71C7, 0x726 }, + [OLYMPUS_LUT_CHAN_549250_IDX] = { 21970, 0x1, 0x3D, 0xE38E, 0x727 }, + [OLYMPUS_LUT_CHAN_549375_IDX] = { 21975, 0x1, 0x3D, 0x15555, 0x727 }, + [OLYMPUS_LUT_CHAN_549500_IDX] = { 21980, 0x1, 0x3D, 0x1C71C, 0x728 }, + [OLYMPUS_LUT_CHAN_549625_IDX] = { 21985, 0x1, 0x3D, 0x238E4, 0x728 }, + [OLYMPUS_LUT_CHAN_549750_IDX] = { 21990, 0x1, 0x3D, 0x2AAAB, 0x729 }, + [OLYMPUS_LUT_CHAN_549875_IDX] = { 21995, 0x1, 0x3D, 0x31C72, 0x729 }, + [OLYMPUS_LUT_CHAN_550000_IDX] = { 22000, 0x1, 0x3D, 0x38E39, 0x729 }, + [OLYMPUS_LUT_CHAN_550125_IDX] = { 22005, 0x1, 0x3D, 0x40000, 0x72A }, + [OLYMPUS_LUT_CHAN_550250_IDX] = { 22010, 0x1, 0x3D, 0x471C7, 0x72A }, + [OLYMPUS_LUT_CHAN_550375_IDX] = { 22015, 0x1, 0x3D, 0x4E38E, 0x72B }, + [OLYMPUS_LUT_CHAN_550500_IDX] = { 22020, 0x1, 0x3D, 0x55555, 0x72B }, + [OLYMPUS_LUT_CHAN_550625_IDX] = { 22025, 0x1, 0x3D, 0x5C71C, 0x72B }, + [OLYMPUS_LUT_CHAN_550750_IDX] = { 22030, 0x1, 0x3D, 0x638E4, 0x72C }, + [OLYMPUS_LUT_CHAN_550875_IDX] = { 22035, 0x1, 0x3D, 0x6AAAB, 0x72C }, + [OLYMPUS_LUT_CHAN_551000_IDX] = { 22040, 0x1, 0x3D, 0x71C72, 0x72D }, + [OLYMPUS_LUT_CHAN_551125_IDX] = { 22045, 0x1, 0x3D, 0x78E39, 0x72D }, + [OLYMPUS_LUT_CHAN_551250_IDX] = { 22050, 0x1, 0x3D, 0x80000, 0x72E }, + [OLYMPUS_LUT_CHAN_551375_IDX] = { 22055, 0x1, 0x3D, 0x871C7, 0x72E }, + [OLYMPUS_LUT_CHAN_551500_IDX] = { 22060, 0x1, 0x3D, 0x8E38E, 0x72E }, + [OLYMPUS_LUT_CHAN_551625_IDX] = { 22065, 0x1, 0x3D, 0x95555, 0x72F }, + [OLYMPUS_LUT_CHAN_551750_IDX] = { 22070, 0x1, 0x3D, 0x9C71C, 0x72F }, + [OLYMPUS_LUT_CHAN_551875_IDX] = { 22075, 0x1, 0x3D, 0xA38E4, 0x730 }, + [OLYMPUS_LUT_CHAN_552000_IDX] = { 22080, 0x1, 0x3D, 0xAAAAB, 0x730 }, + [OLYMPUS_LUT_CHAN_552125_IDX] = { 22085, 0x1, 0x3D, 0xB1C72, 0x730 }, + [OLYMPUS_LUT_CHAN_552250_IDX] = { 22090, 0x1, 0x3D, 0xB8E39, 0x731 }, + [OLYMPUS_LUT_CHAN_552375_IDX] = { 22095, 0x1, 0x3D, 0xC0000, 0x731 }, + [OLYMPUS_LUT_CHAN_552500_IDX] = { 22100, 0x1, 0x3D, 0xC71C7, 0x732 }, + [OLYMPUS_LUT_CHAN_552625_IDX] = { 22105, 0x1, 0x3D, 0xCE38E, 0x732 }, + [OLYMPUS_LUT_CHAN_552750_IDX] = { 22110, 0x1, 0x3D, 0xD5555, 0x733 }, + [OLYMPUS_LUT_CHAN_552875_IDX] = { 22115, 0x1, 0x3D, 0xDC71C, 0x733 }, + [OLYMPUS_LUT_CHAN_553000_IDX] = { 22120, 0x1, 0x3D, 0xE38E4, 0x733 }, + [OLYMPUS_LUT_CHAN_553125_IDX] = { 22125, 0x1, 0x3D, 0xEAAAB, 0x734 }, + [OLYMPUS_LUT_CHAN_553250_IDX] = { 22130, 0x1, 0x3D, 0xF1C72, 0x734 }, + [OLYMPUS_LUT_CHAN_553375_IDX] = { 22135, 0x1, 0x3D, 0xF8E39, 0x735 }, + [OLYMPUS_LUT_CHAN_553500_IDX] = { 22140, 0x1, 0x3D, 0x100000, 0x735 }, + [OLYMPUS_LUT_CHAN_553625_IDX] = { 22145, 0x1, 0x3D, 0x1071C7, 0x735 }, + [OLYMPUS_LUT_CHAN_553750_IDX] = { 22150, 0x1, 0x3D, 0x10E38E, 0x736 }, + [OLYMPUS_LUT_CHAN_553875_IDX] = { 22155, 0x1, 0x3D, 0x115555, 0x736 }, + [OLYMPUS_LUT_CHAN_554000_IDX] = { 22160, 0x1, 0x3D, 0x11C71C, 0x737 }, + [OLYMPUS_LUT_CHAN_554125_IDX] = { 22165, 0x1, 0x3D, 0x1238E4, 0x737 }, + [OLYMPUS_LUT_CHAN_554250_IDX] = { 22170, 0x1, 0x3D, 0x12AAAB, 0x738 }, + [OLYMPUS_LUT_CHAN_554375_IDX] = { 22175, 0x1, 0x3D, 0x131C72, 0x738 }, + [OLYMPUS_LUT_CHAN_554500_IDX] = { 22180, 0x1, 0x3D, 0x138E39, 0x738 }, + [OLYMPUS_LUT_CHAN_554625_IDX] = { 22185, 0x1, 0x3D, 0x140000, 0x739 }, + [OLYMPUS_LUT_CHAN_554750_IDX] = { 22190, 0x1, 0x3D, 0x1471C7, 0x739 }, + [OLYMPUS_LUT_CHAN_554875_IDX] = { 22195, 0x1, 0x3D, 0x14E38E, 0x73A }, + [OLYMPUS_LUT_CHAN_555000_IDX] = { 22200, 0x1, 0x3D, 0x155555, 0x73A }, + [OLYMPUS_LUT_CHAN_555125_IDX] = { 22205, 0x1, 0x3D, 0x15C71C, 0x73A }, + [OLYMPUS_LUT_CHAN_555250_IDX] = { 22210, 0x1, 0x3D, 0x1638E4, 0x73B }, + [OLYMPUS_LUT_CHAN_555375_IDX] = { 22215, 0x1, 0x3D, 0x16AAAB, 0x73B }, + [OLYMPUS_LUT_CHAN_555500_IDX] = { 22220, 0x1, 0x3D, 0x171C72, 0x73C }, + [OLYMPUS_LUT_CHAN_555625_IDX] = { 22225, 0x1, 0x3D, 0x178E39, 0x73C }, + [OLYMPUS_LUT_CHAN_555750_IDX] = { 22230, 0x1, 0x3D, 0x180000, 0x73D }, + [OLYMPUS_LUT_CHAN_555875_IDX] = { 22235, 0x1, 0x3D, 0x1871C7, 0x73D }, + [OLYMPUS_LUT_CHAN_556000_IDX] = { 22240, 0x1, 0x3D, 0x18E38E, 0x73D }, + [OLYMPUS_LUT_CHAN_556125_IDX] = { 22245, 0x1, 0x3D, 0x195555, 0x73E }, + [OLYMPUS_LUT_CHAN_556250_IDX] = { 22250, 0x1, 0x3D, 0x19C71C, 0x73E }, + [OLYMPUS_LUT_CHAN_556375_IDX] = { 22255, 0x1, 0x3D, 0x1A38E4, 0x73F }, + [OLYMPUS_LUT_CHAN_556500_IDX] = { 22260, 0x1, 0x3D, 0x1AAAAB, 0x73F }, + [OLYMPUS_LUT_CHAN_556625_IDX] = { 22265, 0x1, 0x3D, 0x1B1C72, 0x73F }, + [OLYMPUS_LUT_CHAN_556750_IDX] = { 22270, 0x1, 0x3D, 0x1B8E39, 0x740 }, + [OLYMPUS_LUT_CHAN_556875_IDX] = { 22275, 0x1, 0x3D, 0x1C0000, 0x740 }, + [OLYMPUS_LUT_CHAN_557000_IDX] = { 22280, 0x1, 0x3D, 0x1C71C7, 0x741 }, + [OLYMPUS_LUT_CHAN_557125_IDX] = { 22285, 0x1, 0x3D, 0x1CE38E, 0x741 }, + [OLYMPUS_LUT_CHAN_557250_IDX] = { 22290, 0x1, 0x3D, 0x1D5555, 0x742 }, + [OLYMPUS_LUT_CHAN_557375_IDX] = { 22295, 0x1, 0x3D, 0x1DC71C, 0x742 }, + [OLYMPUS_LUT_CHAN_557500_IDX] = { 22300, 0x1, 0x3D, 0x1E38E4, 0x742 }, + [OLYMPUS_LUT_CHAN_557625_IDX] = { 22305, 0x1, 0x3D, 0x1EAAAB, 0x743 }, + [OLYMPUS_LUT_CHAN_557750_IDX] = { 22310, 0x1, 0x3D, 0x1F1C72, 0x743 }, + [OLYMPUS_LUT_CHAN_557875_IDX] = { 22315, 0x1, 0x3D, 0x1F8E39, 0x744 }, + [OLYMPUS_LUT_CHAN_558000_IDX] = { 22320, 0x1, 0x3E, 0x0, 0x744 }, + [OLYMPUS_LUT_CHAN_558125_IDX] = { 22325, 0x1, 0x3E, 0x71C7, 0x744 }, + [OLYMPUS_LUT_CHAN_558250_IDX] = { 22330, 0x1, 0x3E, 0xE38E, 0x745 }, + [OLYMPUS_LUT_CHAN_558375_IDX] = { 22335, 0x1, 0x3E, 0x15555, 0x745 }, + [OLYMPUS_LUT_CHAN_558500_IDX] = { 22340, 0x1, 0x3E, 0x1C71C, 0x746 }, + [OLYMPUS_LUT_CHAN_558625_IDX] = { 22345, 0x1, 0x3E, 0x238E4, 0x746 }, + [OLYMPUS_LUT_CHAN_558750_IDX] = { 22350, 0x1, 0x3E, 0x2AAAB, 0x747 }, + [OLYMPUS_LUT_CHAN_558875_IDX] = { 22355, 0x1, 0x3E, 0x31C72, 0x747 }, + [OLYMPUS_LUT_CHAN_559000_IDX] = { 22360, 0x1, 0x3E, 0x38E39, 0x747 }, + [OLYMPUS_LUT_CHAN_559125_IDX] = { 22365, 0x1, 0x3E, 0x40000, 0x748 }, + [OLYMPUS_LUT_CHAN_559250_IDX] = { 22370, 0x1, 0x3E, 0x471C7, 0x748 }, + [OLYMPUS_LUT_CHAN_559375_IDX] = { 22375, 0x1, 0x3E, 0x4E38E, 0x749 }, + [OLYMPUS_LUT_CHAN_559500_IDX] = { 22380, 0x1, 0x3E, 0x55555, 0x749 }, + [OLYMPUS_LUT_CHAN_559625_IDX] = { 22385, 0x1, 0x3E, 0x5C71C, 0x749 }, + [OLYMPUS_LUT_CHAN_559750_IDX] = { 22390, 0x1, 0x3E, 0x638E4, 0x74A }, + [OLYMPUS_LUT_CHAN_559875_IDX] = { 22395, 0x1, 0x3E, 0x6AAAB, 0x74A }, + [OLYMPUS_LUT_CHAN_560000_IDX] = { 22400, 0x1, 0x3E, 0x71C72, 0x74B }, + [OLYMPUS_LUT_CHAN_560125_IDX] = { 22405, 0x1, 0x3E, 0x78E39, 0x74B }, + [OLYMPUS_LUT_CHAN_560250_IDX] = { 22410, 0x1, 0x3E, 0x80000, 0x74C }, + [OLYMPUS_LUT_CHAN_560375_IDX] = { 22415, 0x1, 0x3E, 0x871C7, 0x74C }, + [OLYMPUS_LUT_CHAN_560500_IDX] = { 22420, 0x1, 0x3E, 0x8E38E, 0x74C }, + [OLYMPUS_LUT_CHAN_560625_IDX] = { 22425, 0x1, 0x3E, 0x95555, 0x74D }, + [OLYMPUS_LUT_CHAN_560750_IDX] = { 22430, 0x1, 0x3E, 0x9C71C, 0x74D }, + [OLYMPUS_LUT_CHAN_560875_IDX] = { 22435, 0x1, 0x3E, 0xA38E4, 0x74E }, + [OLYMPUS_LUT_CHAN_561000_IDX] = { 22440, 0x1, 0x3E, 0xAAAAB, 0x74E }, + [OLYMPUS_LUT_CHAN_561125_IDX] = { 22445, 0x1, 0x3E, 0xB1C72, 0x74E }, + [OLYMPUS_LUT_CHAN_561250_IDX] = { 22450, 0x1, 0x3E, 0xB8E39, 0x74F }, + [OLYMPUS_LUT_CHAN_561375_IDX] = { 22455, 0x1, 0x3E, 0xC0000, 0x74F }, + [OLYMPUS_LUT_CHAN_561500_IDX] = { 22460, 0x1, 0x3E, 0xC71C7, 0x750 }, + [OLYMPUS_LUT_CHAN_561625_IDX] = { 22465, 0x1, 0x3E, 0xCE38E, 0x750 }, + [OLYMPUS_LUT_CHAN_561750_IDX] = { 22470, 0x1, 0x3E, 0xD5555, 0x751 }, + [OLYMPUS_LUT_CHAN_561875_IDX] = { 22475, 0x1, 0x3E, 0xDC71C, 0x751 }, + [OLYMPUS_LUT_CHAN_562000_IDX] = { 22480, 0x1, 0x3E, 0xE38E4, 0x751 }, + [OLYMPUS_LUT_CHAN_562125_IDX] = { 22485, 0x1, 0x3E, 0xEAAAB, 0x752 }, + [OLYMPUS_LUT_CHAN_562250_IDX] = { 22490, 0x1, 0x3E, 0xF1C72, 0x752 }, + [OLYMPUS_LUT_CHAN_562375_IDX] = { 22495, 0x1, 0x3E, 0xF8E39, 0x753 }, + [OLYMPUS_LUT_CHAN_562500_IDX] = { 22500, 0x1, 0x3E, 0x100000, 0x753 }, + [OLYMPUS_LUT_CHAN_562625_IDX] = { 22505, 0x1, 0x3E, 0x1071C7, 0x753 }, + [OLYMPUS_LUT_CHAN_562750_IDX] = { 22510, 0x1, 0x3E, 0x10E38E, 0x754 }, + [OLYMPUS_LUT_CHAN_562875_IDX] = { 22515, 0x1, 0x3E, 0x115555, 0x754 }, + [OLYMPUS_LUT_CHAN_563000_IDX] = { 22520, 0x1, 0x3E, 0x11C71C, 0x755 }, + [OLYMPUS_LUT_CHAN_563125_IDX] = { 22525, 0x1, 0x3E, 0x1238E4, 0x755 }, + [OLYMPUS_LUT_CHAN_563250_IDX] = { 22530, 0x1, 0x3E, 0x12AAAB, 0x756 }, + [OLYMPUS_LUT_CHAN_563375_IDX] = { 22535, 0x1, 0x3E, 0x131C72, 0x756 }, + [OLYMPUS_LUT_CHAN_563500_IDX] = { 22540, 0x1, 0x3E, 0x138E39, 0x756 }, + [OLYMPUS_LUT_CHAN_563625_IDX] = { 22545, 0x1, 0x3E, 0x140000, 0x757 }, + [OLYMPUS_LUT_CHAN_563750_IDX] = { 22550, 0x1, 0x3E, 0x1471C7, 0x757 }, + [OLYMPUS_LUT_CHAN_563875_IDX] = { 22555, 0x1, 0x3E, 0x14E38E, 0x758 }, + [OLYMPUS_LUT_CHAN_564000_IDX] = { 22560, 0x1, 0x3E, 0x155555, 0x758 }, + [OLYMPUS_LUT_CHAN_564125_IDX] = { 22565, 0x1, 0x3E, 0x15C71C, 0x758 }, + [OLYMPUS_LUT_CHAN_564250_IDX] = { 22570, 0x1, 0x3E, 0x1638E4, 0x759 }, + [OLYMPUS_LUT_CHAN_564375_IDX] = { 22575, 0x1, 0x3E, 0x16AAAB, 0x759 }, + [OLYMPUS_LUT_CHAN_564500_IDX] = { 22580, 0x1, 0x3E, 0x171C72, 0x75A }, + [OLYMPUS_LUT_CHAN_564625_IDX] = { 22585, 0x1, 0x3E, 0x178E39, 0x75A }, + [OLYMPUS_LUT_CHAN_564750_IDX] = { 22590, 0x1, 0x3E, 0x180000, 0x75B }, + [OLYMPUS_LUT_CHAN_564875_IDX] = { 22595, 0x1, 0x3E, 0x1871C7, 0x75B }, + [OLYMPUS_LUT_CHAN_565000_IDX] = { 22600, 0x1, 0x3E, 0x18E38E, 0x75B }, + [OLYMPUS_LUT_CHAN_565125_IDX] = { 22605, 0x1, 0x3E, 0x195555, 0x75C }, + [OLYMPUS_LUT_CHAN_565250_IDX] = { 22610, 0x1, 0x3E, 0x19C71C, 0x75C }, + [OLYMPUS_LUT_CHAN_565375_IDX] = { 22615, 0x1, 0x3E, 0x1A38E4, 0x75D }, + [OLYMPUS_LUT_CHAN_565500_IDX] = { 22620, 0x1, 0x3E, 0x1AAAAB, 0x75D }, + [OLYMPUS_LUT_CHAN_565625_IDX] = { 22625, 0x1, 0x3E, 0x1B1C72, 0x75D }, + [OLYMPUS_LUT_CHAN_565750_IDX] = { 22630, 0x1, 0x3E, 0x1B8E39, 0x75E }, + [OLYMPUS_LUT_CHAN_565875_IDX] = { 22635, 0x1, 0x3E, 0x1C0000, 0x75E }, + [OLYMPUS_LUT_CHAN_566000_IDX] = { 22640, 0x1, 0x3E, 0x1C71C7, 0x75F }, + [OLYMPUS_LUT_CHAN_566125_IDX] = { 22645, 0x1, 0x3E, 0x1CE38E, 0x75F }, + [OLYMPUS_LUT_CHAN_566250_IDX] = { 22650, 0x1, 0x3E, 0x1D5555, 0x760 }, + [OLYMPUS_LUT_CHAN_566375_IDX] = { 22655, 0x1, 0x3E, 0x1DC71C, 0x760 }, + [OLYMPUS_LUT_CHAN_566500_IDX] = { 22660, 0x1, 0x3E, 0x1E38E4, 0x760 }, + [OLYMPUS_LUT_CHAN_566625_IDX] = { 22665, 0x1, 0x3E, 0x1EAAAB, 0x761 }, + [OLYMPUS_LUT_CHAN_566750_IDX] = { 22670, 0x1, 0x3E, 0x1F1C72, 0x761 }, + [OLYMPUS_LUT_CHAN_566875_IDX] = { 22675, 0x1, 0x3E, 0x1F8E39, 0x762 }, + [OLYMPUS_LUT_CHAN_567000_IDX] = { 22680, 0x1, 0x3F, 0x0, 0x762 }, + [OLYMPUS_LUT_CHAN_567125_IDX] = { 22685, 0x1, 0x3F, 0x71C7, 0x762 }, + [OLYMPUS_LUT_CHAN_567250_IDX] = { 22690, 0x1, 0x3F, 0xE38E, 0x763 }, + [OLYMPUS_LUT_CHAN_567375_IDX] = { 22695, 0x1, 0x3F, 0x15555, 0x763 }, + [OLYMPUS_LUT_CHAN_567500_IDX] = { 22700, 0x1, 0x3F, 0x1C71C, 0x764 }, + [OLYMPUS_LUT_CHAN_567625_IDX] = { 22705, 0x1, 0x3F, 0x238E4, 0x764 }, + [OLYMPUS_LUT_CHAN_567750_IDX] = { 22710, 0x1, 0x3F, 0x2AAAB, 0x765 }, + [OLYMPUS_LUT_CHAN_567875_IDX] = { 22715, 0x1, 0x3F, 0x31C72, 0x765 }, + [OLYMPUS_LUT_CHAN_568000_IDX] = { 22720, 0x1, 0x3F, 0x38E39, 0x765 }, + [OLYMPUS_LUT_CHAN_568125_IDX] = { 22725, 0x1, 0x3F, 0x40000, 0x766 }, + [OLYMPUS_LUT_CHAN_568250_IDX] = { 22730, 0x1, 0x3F, 0x471C7, 0x766 }, + [OLYMPUS_LUT_CHAN_568375_IDX] = { 22735, 0x1, 0x3F, 0x4E38E, 0x767 }, + [OLYMPUS_LUT_CHAN_568500_IDX] = { 22740, 0x1, 0x3F, 0x55555, 0x767 }, + [OLYMPUS_LUT_CHAN_568625_IDX] = { 22745, 0x1, 0x3F, 0x5C71C, 0x767 }, + [OLYMPUS_LUT_CHAN_568750_IDX] = { 22750, 0x1, 0x3F, 0x638E4, 0x768 }, + [OLYMPUS_LUT_CHAN_568875_IDX] = { 22755, 0x1, 0x3F, 0x6AAAB, 0x768 }, + [OLYMPUS_LUT_CHAN_569000_IDX] = { 22760, 0x1, 0x3F, 0x71C72, 0x769 }, + [OLYMPUS_LUT_CHAN_569125_IDX] = { 22765, 0x1, 0x3F, 0x78E39, 0x769 }, + [OLYMPUS_LUT_CHAN_569250_IDX] = { 22770, 0x1, 0x3F, 0x80000, 0x76A }, + [OLYMPUS_LUT_CHAN_569375_IDX] = { 22775, 0x1, 0x3F, 0x871C7, 0x76A }, + [OLYMPUS_LUT_CHAN_569500_IDX] = { 22780, 0x1, 0x3F, 0x8E38E, 0x76A }, + [OLYMPUS_LUT_CHAN_569625_IDX] = { 22785, 0x1, 0x3F, 0x95555, 0x76B }, + [OLYMPUS_LUT_CHAN_569750_IDX] = { 22790, 0x1, 0x3F, 0x9C71C, 0x76B }, + [OLYMPUS_LUT_CHAN_569875_IDX] = { 22795, 0x1, 0x3F, 0xA38E4, 0x76C }, + [OLYMPUS_LUT_CHAN_570000_IDX] = { 22800, 0x1, 0x3F, 0xAAAAB, 0x76C }, + [OLYMPUS_LUT_CHAN_570125_IDX] = { 22805, 0x1, 0x3F, 0xB1C72, 0x76C }, + [OLYMPUS_LUT_CHAN_570250_IDX] = { 22810, 0x1, 0x3F, 0xB8E39, 0x76D }, + [OLYMPUS_LUT_CHAN_570375_IDX] = { 22815, 0x1, 0x3F, 0xC0000, 0x76D }, + [OLYMPUS_LUT_CHAN_570500_IDX] = { 22820, 0x1, 0x3F, 0xC71C7, 0x76E }, + [OLYMPUS_LUT_CHAN_570625_IDX] = { 22825, 0x1, 0x3F, 0xCE38E, 0x76E }, + [OLYMPUS_LUT_CHAN_570750_IDX] = { 22830, 0x1, 0x3F, 0xD5555, 0x76F }, + [OLYMPUS_LUT_CHAN_570875_IDX] = { 22835, 0x1, 0x3F, 0xDC71C, 0x76F }, + [OLYMPUS_LUT_CHAN_571000_IDX] = { 22840, 0x1, 0x3F, 0xE38E4, 0x76F }, + [OLYMPUS_LUT_CHAN_571125_IDX] = { 22845, 0x1, 0x3F, 0xEAAAB, 0x770 }, + [OLYMPUS_LUT_CHAN_571250_IDX] = { 22850, 0x1, 0x3F, 0xF1C72, 0x770 }, + [OLYMPUS_LUT_CHAN_571375_IDX] = { 22855, 0x1, 0x3F, 0xF8E39, 0x771 }, + [OLYMPUS_LUT_CHAN_571500_IDX] = { 22860, 0x1, 0x3F, 0x100000, 0x771 }, + [OLYMPUS_LUT_CHAN_571625_IDX] = { 22865, 0x1, 0x3F, 0x1071C7, 0x771 }, + [OLYMPUS_LUT_CHAN_571750_IDX] = { 22870, 0x1, 0x3F, 0x10E38E, 0x772 }, + [OLYMPUS_LUT_CHAN_571875_IDX] = { 22875, 0x1, 0x3F, 0x115555, 0x772 }, + [OLYMPUS_LUT_CHAN_572000_IDX] = { 22880, 0x1, 0x3F, 0x11C71C, 0x773 }, + [OLYMPUS_LUT_CHAN_572125_IDX] = { 22885, 0x1, 0x3F, 0x1238E4, 0x773 }, + [OLYMPUS_LUT_CHAN_572250_IDX] = { 22890, 0x1, 0x3F, 0x12AAAB, 0x774 }, + [OLYMPUS_LUT_CHAN_572375_IDX] = { 22895, 0x1, 0x3F, 0x131C72, 0x774 }, + [OLYMPUS_LUT_CHAN_572500_IDX] = { 22900, 0x1, 0x3F, 0x138E39, 0x774 }, + [OLYMPUS_LUT_CHAN_572625_IDX] = { 22905, 0x1, 0x3F, 0x140000, 0x775 }, + [OLYMPUS_LUT_CHAN_572750_IDX] = { 22910, 0x1, 0x3F, 0x1471C7, 0x775 }, + [OLYMPUS_LUT_CHAN_572875_IDX] = { 22915, 0x1, 0x3F, 0x14E38E, 0x776 }, + [OLYMPUS_LUT_CHAN_573000_IDX] = { 22920, 0x1, 0x3F, 0x155555, 0x776 }, + [OLYMPUS_LUT_CHAN_573125_IDX] = { 22925, 0x1, 0x3F, 0x15C71C, 0x776 }, + [OLYMPUS_LUT_CHAN_573250_IDX] = { 22930, 0x1, 0x3F, 0x1638E4, 0x777 }, + [OLYMPUS_LUT_CHAN_573375_IDX] = { 22935, 0x1, 0x3F, 0x16AAAB, 0x777 }, + [OLYMPUS_LUT_CHAN_573500_IDX] = { 22940, 0x1, 0x3F, 0x171C72, 0x778 }, + [OLYMPUS_LUT_CHAN_573625_IDX] = { 22945, 0x1, 0x3F, 0x178E39, 0x778 }, + [OLYMPUS_LUT_CHAN_573750_IDX] = { 22950, 0x1, 0x3F, 0x180000, 0x779 }, + [OLYMPUS_LUT_CHAN_573875_IDX] = { 22955, 0x1, 0x3F, 0x1871C7, 0x779 }, + [OLYMPUS_LUT_CHAN_574000_IDX] = { 22960, 0x1, 0x3F, 0x18E38E, 0x779 }, + [OLYMPUS_LUT_CHAN_574125_IDX] = { 22965, 0x1, 0x3F, 0x195555, 0x77A }, + [OLYMPUS_LUT_CHAN_574250_IDX] = { 22970, 0x1, 0x3F, 0x19C71C, 0x77A }, + [OLYMPUS_LUT_CHAN_574375_IDX] = { 22975, 0x1, 0x3F, 0x1A38E4, 0x77B }, + [OLYMPUS_LUT_CHAN_574500_IDX] = { 22980, 0x1, 0x3F, 0x1AAAAB, 0x77B }, + [OLYMPUS_LUT_CHAN_574625_IDX] = { 22985, 0x1, 0x3F, 0x1B1C72, 0x77B }, + [OLYMPUS_LUT_CHAN_574750_IDX] = { 22990, 0x1, 0x3F, 0x1B8E39, 0x77C }, + [OLYMPUS_LUT_CHAN_574875_IDX] = { 22995, 0x1, 0x3F, 0x1C0000, 0x77C }, + [OLYMPUS_LUT_CHAN_575000_IDX] = { 23000, 0x1, 0x3F, 0x1C71C7, 0x77D }, + [OLYMPUS_LUT_CHAN_575125_IDX] = { 23005, 0x1, 0x3F, 0x1CE38E, 0x77D }, + [OLYMPUS_LUT_CHAN_575250_IDX] = { 23010, 0x1, 0x3F, 0x1D5555, 0x77E }, + [OLYMPUS_LUT_CHAN_575375_IDX] = { 23015, 0x1, 0x3F, 0x1DC71C, 0x77E }, + [OLYMPUS_LUT_CHAN_575500_IDX] = { 23020, 0x1, 0x3F, 0x1E38E4, 0x77E }, + [OLYMPUS_LUT_CHAN_575625_IDX] = { 23025, 0x1, 0x3F, 0x1EAAAB, 0x77F }, + [OLYMPUS_LUT_CHAN_575750_IDX] = { 23030, 0x1, 0x3F, 0x1F1C72, 0x77F }, + [OLYMPUS_LUT_CHAN_575875_IDX] = { 23035, 0x1, 0x3F, 0x1F8E39, 0x780 }, + [OLYMPUS_LUT_CHAN_576000_IDX] = { 23040, 0x1, 0x40, 0x0, 0x780 }, + [OLYMPUS_LUT_CHAN_576125_IDX] = { 23045, 0x1, 0x40, 0x71C7, 0x780 }, + [OLYMPUS_LUT_CHAN_576250_IDX] = { 23050, 0x1, 0x40, 0xE38E, 0x781 }, + [OLYMPUS_LUT_CHAN_576375_IDX] = { 23055, 0x1, 0x40, 0x15555, 0x781 }, + [OLYMPUS_LUT_CHAN_576500_IDX] = { 23060, 0x1, 0x40, 0x1C71C, 0x782 }, + [OLYMPUS_LUT_CHAN_576625_IDX] = { 23065, 0x1, 0x40, 0x238E4, 0x782 }, + [OLYMPUS_LUT_CHAN_576750_IDX] = { 23070, 0x1, 0x40, 0x2AAAB, 0x783 }, + [OLYMPUS_LUT_CHAN_576875_IDX] = { 23075, 0x1, 0x40, 0x31C72, 0x783 }, + [OLYMPUS_LUT_CHAN_577000_IDX] = { 23080, 0x1, 0x40, 0x38E39, 0x783 }, + [OLYMPUS_LUT_CHAN_577125_IDX] = { 23085, 0x1, 0x40, 0x40000, 0x784 }, + [OLYMPUS_LUT_CHAN_577250_IDX] = { 23090, 0x1, 0x40, 0x471C7, 0x784 }, + [OLYMPUS_LUT_CHAN_577375_IDX] = { 23095, 0x1, 0x40, 0x4E38E, 0x785 }, + [OLYMPUS_LUT_CHAN_577500_IDX] = { 23100, 0x1, 0x40, 0x55555, 0x785 }, + [OLYMPUS_LUT_CHAN_577625_IDX] = { 23105, 0x1, 0x40, 0x5C71C, 0x785 }, + [OLYMPUS_LUT_CHAN_577750_IDX] = { 23110, 0x1, 0x40, 0x638E4, 0x786 }, + [OLYMPUS_LUT_CHAN_577875_IDX] = { 23115, 0x1, 0x40, 0x6AAAB, 0x786 }, + [OLYMPUS_LUT_CHAN_578000_IDX] = { 23120, 0x1, 0x40, 0x71C72, 0x787 }, + [OLYMPUS_LUT_CHAN_578125_IDX] = { 23125, 0x1, 0x40, 0x78E39, 0x787 }, + [OLYMPUS_LUT_CHAN_578250_IDX] = { 23130, 0x1, 0x40, 0x80000, 0x788 }, + [OLYMPUS_LUT_CHAN_578375_IDX] = { 23135, 0x1, 0x40, 0x871C7, 0x788 }, + [OLYMPUS_LUT_CHAN_578500_IDX] = { 23140, 0x1, 0x40, 0x8E38E, 0x788 }, + [OLYMPUS_LUT_CHAN_578625_IDX] = { 23145, 0x1, 0x40, 0x95555, 0x789 }, + [OLYMPUS_LUT_CHAN_578750_IDX] = { 23150, 0x1, 0x40, 0x9C71C, 0x789 }, + [OLYMPUS_LUT_CHAN_578875_IDX] = { 23155, 0x1, 0x40, 0xA38E4, 0x78A }, + [OLYMPUS_LUT_CHAN_579000_IDX] = { 23160, 0x1, 0x40, 0xAAAAB, 0x78A }, + [OLYMPUS_LUT_CHAN_579125_IDX] = { 23165, 0x1, 0x40, 0xB1C72, 0x78A }, + [OLYMPUS_LUT_CHAN_579250_IDX] = { 23170, 0x1, 0x40, 0xB8E39, 0x78B }, + [OLYMPUS_LUT_CHAN_579375_IDX] = { 23175, 0x1, 0x40, 0xC0000, 0x78B }, + [OLYMPUS_LUT_CHAN_579500_IDX] = { 23180, 0x1, 0x40, 0xC71C7, 0x78C }, + [OLYMPUS_LUT_CHAN_579625_IDX] = { 23185, 0x1, 0x40, 0xCE38E, 0x78C }, + [OLYMPUS_LUT_CHAN_579750_IDX] = { 23190, 0x1, 0x40, 0xD5555, 0x78D }, + [OLYMPUS_LUT_CHAN_579875_IDX] = { 23195, 0x1, 0x40, 0xDC71C, 0x78D }, + [OLYMPUS_LUT_CHAN_580000_IDX] = { 23200, 0x1, 0x40, 0xE38E4, 0x78D }, + [OLYMPUS_LUT_CHAN_580125_IDX] = { 23205, 0x1, 0x40, 0xEAAAB, 0x78E }, + [OLYMPUS_LUT_CHAN_580250_IDX] = { 23210, 0x1, 0x40, 0xF1C72, 0x78E }, + [OLYMPUS_LUT_CHAN_580375_IDX] = { 23215, 0x1, 0x40, 0xF8E39, 0x78F }, + [OLYMPUS_LUT_CHAN_580500_IDX] = { 23220, 0x1, 0x40, 0x100000, 0x78F }, + [OLYMPUS_LUT_CHAN_580625_IDX] = { 23225, 0x1, 0x40, 0x1071C7, 0x78F }, + [OLYMPUS_LUT_CHAN_580750_IDX] = { 23230, 0x1, 0x40, 0x10E38E, 0x790 }, + [OLYMPUS_LUT_CHAN_580875_IDX] = { 23235, 0x1, 0x40, 0x115555, 0x790 }, + [OLYMPUS_LUT_CHAN_581000_IDX] = { 23240, 0x1, 0x40, 0x11C71C, 0x791 }, + [OLYMPUS_LUT_CHAN_581125_IDX] = { 23245, 0x1, 0x40, 0x1238E4, 0x791 }, + [OLYMPUS_LUT_CHAN_581250_IDX] = { 23250, 0x1, 0x40, 0x12AAAB, 0x792 }, + [OLYMPUS_LUT_CHAN_581375_IDX] = { 23255, 0x1, 0x40, 0x131C72, 0x792 }, + [OLYMPUS_LUT_CHAN_581500_IDX] = { 23260, 0x1, 0x40, 0x138E39, 0x792 }, + [OLYMPUS_LUT_CHAN_581625_IDX] = { 23265, 0x1, 0x40, 0x140000, 0x793 }, + [OLYMPUS_LUT_CHAN_581750_IDX] = { 23270, 0x1, 0x40, 0x1471C7, 0x793 }, + [OLYMPUS_LUT_CHAN_581875_IDX] = { 23275, 0x1, 0x40, 0x14E38E, 0x794 }, + [OLYMPUS_LUT_CHAN_582000_IDX] = { 23280, 0x1, 0x40, 0x155555, 0x794 }, + [OLYMPUS_LUT_CHAN_582125_IDX] = { 23285, 0x1, 0x40, 0x15C71C, 0x794 }, + [OLYMPUS_LUT_CHAN_582250_IDX] = { 23290, 0x1, 0x40, 0x1638E4, 0x795 }, + [OLYMPUS_LUT_CHAN_582375_IDX] = { 23295, 0x1, 0x40, 0x16AAAB, 0x795 }, + [OLYMPUS_LUT_CHAN_582500_IDX] = { 23300, 0x1, 0x40, 0x171C72, 0x796 }, + [OLYMPUS_LUT_CHAN_582625_IDX] = { 23305, 0x1, 0x40, 0x178E39, 0x796 }, + [OLYMPUS_LUT_CHAN_582750_IDX] = { 23310, 0x1, 0x40, 0x180000, 0x797 }, + [OLYMPUS_LUT_CHAN_582875_IDX] = { 23315, 0x1, 0x40, 0x1871C7, 0x797 }, + [OLYMPUS_LUT_CHAN_583000_IDX] = { 23320, 0x1, 0x40, 0x18E38E, 0x797 }, + [OLYMPUS_LUT_CHAN_583125_IDX] = { 23325, 0x1, 0x40, 0x195555, 0x798 }, + [OLYMPUS_LUT_CHAN_583250_IDX] = { 23330, 0x1, 0x40, 0x19C71C, 0x798 }, + [OLYMPUS_LUT_CHAN_583375_IDX] = { 23335, 0x1, 0x40, 0x1A38E4, 0x799 }, + [OLYMPUS_LUT_CHAN_583500_IDX] = { 23340, 0x1, 0x40, 0x1AAAAB, 0x799 }, + [OLYMPUS_LUT_CHAN_583625_IDX] = { 23345, 0x1, 0x40, 0x1B1C72, 0x799 }, + [OLYMPUS_LUT_CHAN_583750_IDX] = { 23350, 0x1, 0x40, 0x1B8E39, 0x79A }, + [OLYMPUS_LUT_CHAN_583875_IDX] = { 23355, 0x1, 0x40, 0x1C0000, 0x79A }, + [OLYMPUS_LUT_CHAN_584000_IDX] = { 23360, 0x1, 0x40, 0x1C71C7, 0x79B }, + [OLYMPUS_LUT_CHAN_584125_IDX] = { 23365, 0x1, 0x40, 0x1CE38E, 0x79B }, + [OLYMPUS_LUT_CHAN_584250_IDX] = { 23370, 0x1, 0x40, 0x1D5555, 0x79C }, + [OLYMPUS_LUT_CHAN_584375_IDX] = { 23375, 0x1, 0x40, 0x1DC71C, 0x79C }, + [OLYMPUS_LUT_CHAN_584500_IDX] = { 23380, 0x1, 0x40, 0x1E38E4, 0x79C }, + [OLYMPUS_LUT_CHAN_584625_IDX] = { 23385, 0x1, 0x40, 0x1EAAAB, 0x79D }, + [OLYMPUS_LUT_CHAN_584750_IDX] = { 23390, 0x1, 0x40, 0x1F1C72, 0x79D }, + [OLYMPUS_LUT_CHAN_584875_IDX] = { 23395, 0x1, 0x40, 0x1F8E39, 0x79E }, + [OLYMPUS_LUT_CHAN_585000_IDX] = { 23400, 0x1, 0x41, 0x0, 0x79E }, + [OLYMPUS_LUT_CHAN_585125_IDX] = { 23405, 0x1, 0x41, 0x71C7, 0x79E }, + [OLYMPUS_LUT_CHAN_585250_IDX] = { 23410, 0x1, 0x41, 0xE38E, 0x79F }, + [OLYMPUS_LUT_CHAN_585375_IDX] = { 23415, 0x1, 0x41, 0x15555, 0x79F }, + [OLYMPUS_LUT_CHAN_585500_IDX] = { 23420, 0x1, 0x41, 0x1C71C, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585625_IDX] = { 23425, 0x1, 0x41, 0x238E4, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585750_IDX] = { 23430, 0x1, 0x41, 0x2AAAB, 0x7A1 }, + [OLYMPUS_LUT_CHAN_585875_IDX] = { 23435, 0x1, 0x41, 0x31C72, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586000_IDX] = { 23440, 0x1, 0x41, 0x38E39, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586125_IDX] = { 23445, 0x1, 0x41, 0x40000, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586250_IDX] = { 23450, 0x1, 0x41, 0x471C7, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586375_IDX] = { 23455, 0x1, 0x41, 0x4E38E, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586500_IDX] = { 23460, 0x1, 0x41, 0x55555, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586625_IDX] = { 23465, 0x1, 0x41, 0x5C71C, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586750_IDX] = { 23470, 0x1, 0x41, 0x638E4, 0x7A4 }, + [OLYMPUS_LUT_CHAN_586875_IDX] = { 23475, 0x1, 0x41, 0x6AAAB, 0x7A4 }, + [OLYMPUS_LUT_CHAN_587000_IDX] = { 23480, 0x1, 0x41, 0x71C72, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587125_IDX] = { 23485, 0x1, 0x41, 0x78E39, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587250_IDX] = { 23490, 0x1, 0x41, 0x80000, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587375_IDX] = { 23495, 0x1, 0x41, 0x871C7, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587500_IDX] = { 23500, 0x1, 0x41, 0x8E38E, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587625_IDX] = { 23505, 0x1, 0x41, 0x95555, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587750_IDX] = { 23510, 0x1, 0x41, 0x9C71C, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587875_IDX] = { 23515, 0x1, 0x41, 0xA38E4, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588000_IDX] = { 23520, 0x1, 0x41, 0xAAAAB, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588125_IDX] = { 23525, 0x1, 0x41, 0xB1C72, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588250_IDX] = { 23530, 0x1, 0x41, 0xB8E39, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588375_IDX] = { 23535, 0x1, 0x41, 0xC0000, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588500_IDX] = { 23540, 0x1, 0x41, 0xC71C7, 0x7AA }, + [OLYMPUS_LUT_CHAN_588625_IDX] = { 23545, 0x1, 0x41, 0xCE38E, 0x7AA }, + [OLYMPUS_LUT_CHAN_588750_IDX] = { 23550, 0x1, 0x41, 0xD5555, 0x7AB }, + [OLYMPUS_LUT_CHAN_588875_IDX] = { 23555, 0x1, 0x41, 0xDC71C, 0x7AB }, + [OLYMPUS_LUT_CHAN_589000_IDX] = { 23560, 0x1, 0x41, 0xE38E4, 0x7AB }, + [OLYMPUS_LUT_CHAN_589125_IDX] = { 23565, 0x1, 0x41, 0xEAAAB, 0x7AC }, + [OLYMPUS_LUT_CHAN_589250_IDX] = { 23570, 0x1, 0x41, 0xF1C72, 0x7AC }, + [OLYMPUS_LUT_CHAN_589375_IDX] = { 23575, 0x1, 0x41, 0xF8E39, 0x7AD }, + [OLYMPUS_LUT_CHAN_589500_IDX] = { 23580, 0x1, 0x41, 0x100000, 0x7AD }, + [OLYMPUS_LUT_CHAN_589625_IDX] = { 23585, 0x1, 0x41, 0x1071C7, 0x7AD }, + [OLYMPUS_LUT_CHAN_589750_IDX] = { 23590, 0x1, 0x41, 0x10E38E, 0x7AE }, + [OLYMPUS_LUT_CHAN_589875_IDX] = { 23595, 0x1, 0x41, 0x115555, 0x7AE }, + [OLYMPUS_LUT_CHAN_590000_IDX] = { 23600, 0x1, 0x41, 0x11C71C, 0x7AF }, + [OLYMPUS_LUT_CHAN_590125_IDX] = { 23605, 0x1, 0x41, 0x1238E4, 0x7AF }, + [OLYMPUS_LUT_CHAN_590250_IDX] = { 23610, 0x1, 0x41, 0x12AAAB, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590375_IDX] = { 23615, 0x1, 0x41, 0x131C72, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590500_IDX] = { 23620, 0x1, 0x41, 0x138E39, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590625_IDX] = { 23625, 0x1, 0x41, 0x140000, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590750_IDX] = { 23630, 0x1, 0x41, 0x1471C7, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590875_IDX] = { 23635, 0x1, 0x41, 0x14E38E, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591000_IDX] = { 23640, 0x1, 0x41, 0x155555, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591125_IDX] = { 23645, 0x1, 0x41, 0x15C71C, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591250_IDX] = { 23650, 0x1, 0x41, 0x1638E4, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591375_IDX] = { 23655, 0x1, 0x41, 0x16AAAB, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591500_IDX] = { 23660, 0x1, 0x41, 0x171C72, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591625_IDX] = { 23665, 0x1, 0x41, 0x178E39, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591750_IDX] = { 23670, 0x1, 0x41, 0x180000, 0x7B5 }, + [OLYMPUS_LUT_CHAN_591875_IDX] = { 23675, 0x1, 0x41, 0x1871C7, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592000_IDX] = { 23680, 0x1, 0x41, 0x18E38E, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592125_IDX] = { 23685, 0x1, 0x41, 0x195555, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592250_IDX] = { 23690, 0x1, 0x41, 0x19C71C, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592375_IDX] = { 23695, 0x1, 0x41, 0x1A38E4, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592500_IDX] = { 23700, 0x1, 0x41, 0x1AAAAB, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592625_IDX] = { 23705, 0x1, 0x41, 0x1B1C72, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592750_IDX] = { 23710, 0x1, 0x41, 0x1B8E39, 0x7B8 }, + [OLYMPUS_LUT_CHAN_592875_IDX] = { 23715, 0x1, 0x41, 0x1C0000, 0x7B8 }, + [OLYMPUS_LUT_CHAN_593000_IDX] = { 23720, 0x1, 0x41, 0x1C71C7, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593125_IDX] = { 23725, 0x1, 0x41, 0x1CE38E, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593250_IDX] = { 23730, 0x1, 0x41, 0x1D5555, 0x7BA }, + [OLYMPUS_LUT_CHAN_593375_IDX] = { 23735, 0x1, 0x41, 0x1DC71C, 0x7BA }, + [OLYMPUS_LUT_CHAN_593500_IDX] = { 23740, 0x1, 0x41, 0x1E38E4, 0x7BA }, + [OLYMPUS_LUT_CHAN_593625_IDX] = { 23745, 0x1, 0x41, 0x1EAAAB, 0x7BB }, + [OLYMPUS_LUT_CHAN_593750_IDX] = { 23750, 0x1, 0x41, 0x1F1C72, 0x7BB }, + [OLYMPUS_LUT_CHAN_593875_IDX] = { 23755, 0x1, 0x41, 0x1F8E39, 0x7BC }, + [OLYMPUS_LUT_CHAN_594000_IDX] = { 23760, 0x1, 0x42, 0x0, 0x7BC }, + [OLYMPUS_LUT_CHAN_594125_IDX] = { 23765, 0x1, 0x42, 0x71C7, 0x7BC }, + [OLYMPUS_LUT_CHAN_594250_IDX] = { 23770, 0x1, 0x42, 0xE38E, 0x7BD }, + [OLYMPUS_LUT_CHAN_594375_IDX] = { 23775, 0x1, 0x42, 0x15555, 0x7BD }, + [OLYMPUS_LUT_CHAN_594500_IDX] = { 23780, 0x1, 0x42, 0x1C71C, 0x7BE }, + [OLYMPUS_LUT_CHAN_594625_IDX] = { 23785, 0x1, 0x42, 0x238E4, 0x7BE }, + [OLYMPUS_LUT_CHAN_594750_IDX] = { 23790, 0x1, 0x42, 0x2AAAB, 0x7BF }, + [OLYMPUS_LUT_CHAN_594875_IDX] = { 23795, 0x1, 0x42, 0x31C72, 0x7BF }, + [OLYMPUS_LUT_CHAN_595000_IDX] = { 23800, 0x1, 0x42, 0x38E39, 0x7BF } +}; + +const struct common_lut_line olympus_lut_24g_40_mhz[OLYMPUS_LUT_CHAN_24G_MAX] = { + [OLYMPUS_LUT_CHAN_240700_IDX] = { 9628, 0x0, 0x50, 0x77777, 0x645 }, + [OLYMPUS_LUT_CHAN_240825_IDX] = { 9633, 0x0, 0x50, 0x8CCCD, 0x646 }, + [OLYMPUS_LUT_CHAN_240950_IDX] = { 9638, 0x0, 0x50, 0xA2222, 0x646 }, + [OLYMPUS_LUT_CHAN_241075_IDX] = { 9643, 0x0, 0x50, 0xB7777, 0x647 }, + [OLYMPUS_LUT_CHAN_241200_IDX] = { 9648, 0x0, 0x50, 0xCCCCD, 0x648 }, + [OLYMPUS_LUT_CHAN_241325_IDX] = { 9653, 0x0, 0x50, 0xE2222, 0x649 }, + [OLYMPUS_LUT_CHAN_241450_IDX] = { 9658, 0x0, 0x50, 0xF7777, 0x64A }, + [OLYMPUS_LUT_CHAN_241575_IDX] = { 9663, 0x0, 0x50, 0x10CCCD, 0x64B }, + [OLYMPUS_LUT_CHAN_241700_IDX] = { 9668, 0x0, 0x50, 0x122222, 0x64B }, + [OLYMPUS_LUT_CHAN_241825_IDX] = { 9673, 0x0, 0x50, 0x137777, 0x64C }, + [OLYMPUS_LUT_CHAN_241950_IDX] = { 9678, 0x0, 0x50, 0x14CCCD, 0x64D }, + [OLYMPUS_LUT_CHAN_242075_IDX] = { 9683, 0x0, 0x50, 0x162222, 0x64E }, + [OLYMPUS_LUT_CHAN_242200_IDX] = { 9688, 0x0, 0x50, 0x177777, 0x64F }, + [OLYMPUS_LUT_CHAN_242325_IDX] = { 9693, 0x0, 0x50, 0x18CCCD, 0x650 }, + [OLYMPUS_LUT_CHAN_242450_IDX] = { 9698, 0x0, 0x50, 0x1A2222, 0x650 }, + [OLYMPUS_LUT_CHAN_242575_IDX] = { 9703, 0x0, 0x50, 0x1B7777, 0x651 }, + [OLYMPUS_LUT_CHAN_242700_IDX] = { 9708, 0x0, 0x50, 0x1CCCCD, 0x652 }, + [OLYMPUS_LUT_CHAN_242825_IDX] = { 9713, 0x0, 0x50, 0x1E2222, 0x653 }, + [OLYMPUS_LUT_CHAN_242950_IDX] = { 9718, 0x0, 0x50, 0x1F7777, 0x654 }, + [OLYMPUS_LUT_CHAN_243075_IDX] = { 9723, 0x0, 0x51, 0xCCCD, 0x655 }, + [OLYMPUS_LUT_CHAN_243200_IDX] = { 9728, 0x0, 0x51, 0x22222, 0x655 }, + [OLYMPUS_LUT_CHAN_243325_IDX] = { 9733, 0x0, 0x51, 0x37777, 0x656 }, + [OLYMPUS_LUT_CHAN_243450_IDX] = { 9738, 0x0, 0x51, 0x4CCCD, 0x657 }, + [OLYMPUS_LUT_CHAN_243575_IDX] = { 9743, 0x0, 0x51, 0x62222, 0x658 }, + [OLYMPUS_LUT_CHAN_243700_IDX] = { 9748, 0x0, 0x51, 0x77777, 0x659 }, + [OLYMPUS_LUT_CHAN_243825_IDX] = { 9753, 0x0, 0x51, 0x8CCCD, 0x65A }, + [OLYMPUS_LUT_CHAN_243950_IDX] = { 9758, 0x0, 0x51, 0xA2222, 0x65A }, + [OLYMPUS_LUT_CHAN_244075_IDX] = { 9763, 0x0, 0x51, 0xB7777, 0x65B }, + [OLYMPUS_LUT_CHAN_244200_IDX] = { 9768, 0x0, 0x51, 0xCCCCD, 0x65C }, + [OLYMPUS_LUT_CHAN_244325_IDX] = { 9773, 0x0, 0x51, 0xE2222, 0x65D }, + [OLYMPUS_LUT_CHAN_244450_IDX] = { 9778, 0x0, 0x51, 0xF7777, 0x65E }, + [OLYMPUS_LUT_CHAN_244575_IDX] = { 9783, 0x0, 0x51, 0x10CCCD, 0x65F }, + [OLYMPUS_LUT_CHAN_244700_IDX] = { 9788, 0x0, 0x51, 0x122222, 0x65F }, + [OLYMPUS_LUT_CHAN_244825_IDX] = { 9793, 0x0, 0x51, 0x137777, 0x660 }, + [OLYMPUS_LUT_CHAN_244950_IDX] = { 9798, 0x0, 0x51, 0x14CCCD, 0x661 }, + [OLYMPUS_LUT_CHAN_245075_IDX] = { 9803, 0x0, 0x51, 0x162222, 0x662 }, + [OLYMPUS_LUT_CHAN_245200_IDX] = { 9808, 0x0, 0x51, 0x177777, 0x663 }, + [OLYMPUS_LUT_CHAN_245325_IDX] = { 9813, 0x0, 0x51, 0x18CCCD, 0x664 }, + [OLYMPUS_LUT_CHAN_245450_IDX] = { 9818, 0x0, 0x51, 0x1A2222, 0x664 }, + [OLYMPUS_LUT_CHAN_245575_IDX] = { 9823, 0x0, 0x51, 0x1B7777, 0x665 }, + [OLYMPUS_LUT_CHAN_245700_IDX] = { 9828, 0x0, 0x51, 0x1CCCCD, 0x666 }, + [OLYMPUS_LUT_CHAN_245825_IDX] = { 9833, 0x0, 0x51, 0x1E2222, 0x667 }, + [OLYMPUS_LUT_CHAN_245950_IDX] = { 9838, 0x0, 0x51, 0x1F7777, 0x668 }, + [OLYMPUS_LUT_CHAN_246075_IDX] = { 9843, 0x0, 0x52, 0xCCCD, 0x669 }, + [OLYMPUS_LUT_CHAN_246200_IDX] = { 9848, 0x0, 0x52, 0x22222, 0x669 }, + [OLYMPUS_LUT_CHAN_246325_IDX] = { 9853, 0x0, 0x52, 0x37777, 0x66A }, + [OLYMPUS_LUT_CHAN_246450_IDX] = { 9858, 0x0, 0x52, 0x4CCCD, 0x66B }, + [OLYMPUS_LUT_CHAN_246575_IDX] = { 9863, 0x0, 0x52, 0x62222, 0x66C }, + [OLYMPUS_LUT_CHAN_246700_IDX] = { 9868, 0x0, 0x52, 0x77777, 0x66D }, + [OLYMPUS_LUT_CHAN_246825_IDX] = { 9873, 0x0, 0x52, 0x8CCCD, 0x66E }, + [OLYMPUS_LUT_CHAN_246950_IDX] = { 9878, 0x0, 0x52, 0xA2222, 0x66E }, + [OLYMPUS_LUT_CHAN_247075_IDX] = { 9883, 0x0, 0x52, 0xB7777, 0x66F }, + [OLYMPUS_LUT_CHAN_247200_IDX] = { 9888, 0x0, 0x52, 0xCCCCD, 0x670 }, + [OLYMPUS_LUT_CHAN_247325_IDX] = { 9893, 0x0, 0x52, 0xE2222, 0x671 }, + [OLYMPUS_LUT_CHAN_247450_IDX] = { 9898, 0x0, 0x52, 0xF7777, 0x672 }, + [OLYMPUS_LUT_CHAN_247575_IDX] = { 9903, 0x0, 0x52, 0x10CCCD, 0x673 }, + [OLYMPUS_LUT_CHAN_247700_IDX] = { 9908, 0x0, 0x52, 0x122222, 0x673 }, + [OLYMPUS_LUT_CHAN_247825_IDX] = { 9913, 0x0, 0x52, 0x137777, 0x674 }, + [OLYMPUS_LUT_CHAN_247950_IDX] = { 9918, 0x0, 0x52, 0x14CCCD, 0x675 }, + [OLYMPUS_LUT_CHAN_248075_IDX] = { 9923, 0x0, 0x52, 0x162222, 0x676 }, + [OLYMPUS_LUT_CHAN_248200_IDX] = { 9928, 0x0, 0x52, 0x177777, 0x677 }, + [OLYMPUS_LUT_CHAN_248325_IDX] = { 9933, 0x0, 0x52, 0x18CCCD, 0x678 }, + [OLYMPUS_LUT_CHAN_248450_IDX] = { 9938, 0x0, 0x52, 0x1A2222, 0x678 }, + [OLYMPUS_LUT_CHAN_248575_IDX] = { 9943, 0x0, 0x52, 0x1B7777, 0x679 }, + [OLYMPUS_LUT_CHAN_248700_IDX] = { 9948, 0x0, 0x52, 0x1CCCCD, 0x67A }, + [OLYMPUS_LUT_CHAN_248825_IDX] = { 9953, 0x0, 0x52, 0x1E2222, 0x67B }, + [OLYMPUS_LUT_CHAN_248950_IDX] = { 9958, 0x0, 0x52, 0x1F7777, 0x67C }, + [OLYMPUS_LUT_CHAN_249075_IDX] = { 9963, 0x0, 0x53, 0xCCCD, 0x67D }, + [OLYMPUS_LUT_CHAN_249200_IDX] = { 9968, 0x0, 0x53, 0x22222, 0x67D }, + [OLYMPUS_LUT_CHAN_249325_IDX] = { 9973, 0x0, 0x53, 0x37777, 0x67E }, + [OLYMPUS_LUT_CHAN_249450_IDX] = { 9978, 0x0, 0x53, 0x4CCCD, 0x67F }, + [OLYMPUS_LUT_CHAN_249575_IDX] = { 9983, 0x0, 0x53, 0x62222, 0x680 }, + [OLYMPUS_LUT_CHAN_249700_IDX] = { 9988, 0x0, 0x53, 0x77777, 0x681 }, + [OLYMPUS_LUT_CHAN_249825_IDX] = { 9993, 0x0, 0x53, 0x8CCCD, 0x682 }, + [OLYMPUS_LUT_CHAN_249950_IDX] = { 9998, 0x0, 0x53, 0xA2222, 0x682 }, + [OLYMPUS_LUT_CHAN_250075_IDX] = { 10003, 0x0, 0x53, 0xB7777, 0x683 } +}; + +const struct common_lut_line olympus_lut_24g_60_mhz_s0[OLYMPUS_LUT_CHAN_24G_MAX] = { + [OLYMPUS_LUT_CHAN_240700_IDX] = { 9628, 0x0, 0x6A, 0x1F49F5, 0x645 }, + [OLYMPUS_LUT_CHAN_240825_IDX] = { 9633, 0x0, 0x6B, 0x11111, 0x646 }, + [OLYMPUS_LUT_CHAN_240950_IDX] = { 9638, 0x0, 0x6B, 0x2D82E, 0x646 }, + [OLYMPUS_LUT_CHAN_241075_IDX] = { 9643, 0x0, 0x6B, 0x49F4A, 0x647 }, + [OLYMPUS_LUT_CHAN_241200_IDX] = { 9648, 0x0, 0x6B, 0x66666, 0x648 }, + [OLYMPUS_LUT_CHAN_241325_IDX] = { 9653, 0x0, 0x6B, 0x82D83, 0x649 }, + [OLYMPUS_LUT_CHAN_241450_IDX] = { 9658, 0x0, 0x6B, 0x9F49F, 0x64A }, + [OLYMPUS_LUT_CHAN_241575_IDX] = { 9663, 0x0, 0x6B, 0xBBBBC, 0x64B }, + [OLYMPUS_LUT_CHAN_241700_IDX] = { 9668, 0x0, 0x6B, 0xD82D8, 0x64B }, + [OLYMPUS_LUT_CHAN_241825_IDX] = { 9673, 0x0, 0x6B, 0xF49F5, 0x64C }, + [OLYMPUS_LUT_CHAN_241950_IDX] = { 9678, 0x0, 0x6B, 0x111111, 0x64D }, + [OLYMPUS_LUT_CHAN_242075_IDX] = { 9683, 0x0, 0x6B, 0x12D82E, 0x64E }, + [OLYMPUS_LUT_CHAN_242200_IDX] = { 9688, 0x0, 0x6B, 0x149F4A, 0x64F }, + [OLYMPUS_LUT_CHAN_242325_IDX] = { 9693, 0x0, 0x6B, 0x166666, 0x650 }, + [OLYMPUS_LUT_CHAN_242450_IDX] = { 9698, 0x0, 0x6B, 0x182D83, 0x650 }, + [OLYMPUS_LUT_CHAN_242575_IDX] = { 9703, 0x0, 0x6B, 0x19F49F, 0x651 }, + [OLYMPUS_LUT_CHAN_242700_IDX] = { 9708, 0x0, 0x6B, 0x1BBBBC, 0x652 }, + [OLYMPUS_LUT_CHAN_242825_IDX] = { 9713, 0x0, 0x6B, 0x1D82D8, 0x653 }, + [OLYMPUS_LUT_CHAN_242950_IDX] = { 9718, 0x0, 0x6B, 0x1F49F5, 0x654 }, + [OLYMPUS_LUT_CHAN_243075_IDX] = { 9723, 0x0, 0x6C, 0x11111, 0x655 }, + [OLYMPUS_LUT_CHAN_243200_IDX] = { 9728, 0x0, 0x6C, 0x2D82E, 0x655 }, + [OLYMPUS_LUT_CHAN_243325_IDX] = { 9733, 0x0, 0x6C, 0x49F4A, 0x656 }, + [OLYMPUS_LUT_CHAN_243450_IDX] = { 9738, 0x0, 0x6C, 0x66666, 0x657 }, + [OLYMPUS_LUT_CHAN_243575_IDX] = { 9743, 0x0, 0x6C, 0x82D83, 0x658 }, + [OLYMPUS_LUT_CHAN_243700_IDX] = { 9748, 0x0, 0x6C, 0x9F49F, 0x659 }, + [OLYMPUS_LUT_CHAN_243825_IDX] = { 9753, 0x0, 0x6C, 0xBBBBC, 0x65A }, + [OLYMPUS_LUT_CHAN_243950_IDX] = { 9758, 0x0, 0x6C, 0xD82D8, 0x65A }, + [OLYMPUS_LUT_CHAN_244075_IDX] = { 9763, 0x0, 0x6C, 0xF49F5, 0x65B }, + [OLYMPUS_LUT_CHAN_244200_IDX] = { 9768, 0x0, 0x6C, 0x111111, 0x65C }, + [OLYMPUS_LUT_CHAN_244325_IDX] = { 9773, 0x0, 0x6C, 0x12D82E, 0x65D }, + [OLYMPUS_LUT_CHAN_244450_IDX] = { 9778, 0x0, 0x6C, 0x149F4A, 0x65E }, + [OLYMPUS_LUT_CHAN_244575_IDX] = { 9783, 0x0, 0x6C, 0x166666, 0x65F }, + [OLYMPUS_LUT_CHAN_244700_IDX] = { 9788, 0x0, 0x6C, 0x182D83, 0x65F }, + [OLYMPUS_LUT_CHAN_244825_IDX] = { 9793, 0x0, 0x6C, 0x19F49F, 0x660 }, + [OLYMPUS_LUT_CHAN_244950_IDX] = { 9798, 0x0, 0x6C, 0x1BBBBC, 0x661 }, + [OLYMPUS_LUT_CHAN_245075_IDX] = { 9803, 0x0, 0x6C, 0x1D82D8, 0x662 }, + [OLYMPUS_LUT_CHAN_245200_IDX] = { 9808, 0x0, 0x6C, 0x1F49F5, 0x663 }, + [OLYMPUS_LUT_CHAN_245325_IDX] = { 9813, 0x0, 0x6D, 0x11111, 0x664 }, + [OLYMPUS_LUT_CHAN_245450_IDX] = { 9818, 0x0, 0x6D, 0x2D82E, 0x664 }, + [OLYMPUS_LUT_CHAN_245575_IDX] = { 9823, 0x0, 0x6D, 0x49F4A, 0x665 }, + [OLYMPUS_LUT_CHAN_245700_IDX] = { 9828, 0x0, 0x6D, 0x66666, 0x666 }, + [OLYMPUS_LUT_CHAN_245825_IDX] = { 9833, 0x0, 0x6D, 0x82D83, 0x667 }, + [OLYMPUS_LUT_CHAN_245950_IDX] = { 9838, 0x0, 0x6D, 0x9F49F, 0x668 }, + [OLYMPUS_LUT_CHAN_246075_IDX] = { 9843, 0x0, 0x6D, 0xBBBBC, 0x669 }, + [OLYMPUS_LUT_CHAN_246200_IDX] = { 9848, 0x0, 0x6D, 0xD82D8, 0x669 }, + [OLYMPUS_LUT_CHAN_246325_IDX] = { 9853, 0x0, 0x6D, 0xF49F5, 0x66A }, + [OLYMPUS_LUT_CHAN_246450_IDX] = { 9858, 0x0, 0x6D, 0x111111, 0x66B }, + [OLYMPUS_LUT_CHAN_246575_IDX] = { 9863, 0x0, 0x6D, 0x12D82E, 0x66C }, + [OLYMPUS_LUT_CHAN_246700_IDX] = { 9868, 0x0, 0x6D, 0x149F4A, 0x66D }, + [OLYMPUS_LUT_CHAN_246825_IDX] = { 9873, 0x0, 0x6D, 0x166666, 0x66E }, + [OLYMPUS_LUT_CHAN_246950_IDX] = { 9878, 0x0, 0x6D, 0x182D83, 0x66E }, + [OLYMPUS_LUT_CHAN_247075_IDX] = { 9883, 0x0, 0x6D, 0x19F49F, 0x66F }, + [OLYMPUS_LUT_CHAN_247200_IDX] = { 9888, 0x0, 0x6D, 0x1BBBBC, 0x670 }, + [OLYMPUS_LUT_CHAN_247325_IDX] = { 9893, 0x0, 0x6D, 0x1D82D8, 0x671 }, + [OLYMPUS_LUT_CHAN_247450_IDX] = { 9898, 0x0, 0x6D, 0x1F49F5, 0x672 }, + [OLYMPUS_LUT_CHAN_247575_IDX] = { 9903, 0x0, 0x6E, 0x11111, 0x673 }, + [OLYMPUS_LUT_CHAN_247700_IDX] = { 9908, 0x0, 0x6E, 0x2D82E, 0x673 }, + [OLYMPUS_LUT_CHAN_247825_IDX] = { 9913, 0x0, 0x6E, 0x49F4A, 0x674 }, + [OLYMPUS_LUT_CHAN_247950_IDX] = { 9918, 0x0, 0x6E, 0x66666, 0x675 }, + [OLYMPUS_LUT_CHAN_248075_IDX] = { 9923, 0x0, 0x6E, 0x82D83, 0x676 }, + [OLYMPUS_LUT_CHAN_248200_IDX] = { 9928, 0x0, 0x6E, 0x9F49F, 0x677 }, + [OLYMPUS_LUT_CHAN_248325_IDX] = { 9933, 0x0, 0x6E, 0xBBBBC, 0x678 }, + [OLYMPUS_LUT_CHAN_248450_IDX] = { 9938, 0x0, 0x6E, 0xD82D8, 0x678 }, + [OLYMPUS_LUT_CHAN_248575_IDX] = { 9943, 0x0, 0x6E, 0xF49F5, 0x679 }, + [OLYMPUS_LUT_CHAN_248700_IDX] = { 9948, 0x0, 0x6E, 0x111111, 0x67A }, + [OLYMPUS_LUT_CHAN_248825_IDX] = { 9953, 0x0, 0x6E, 0x12D82E, 0x67B }, + [OLYMPUS_LUT_CHAN_248950_IDX] = { 9958, 0x0, 0x6E, 0x149F4A, 0x67C }, + [OLYMPUS_LUT_CHAN_249075_IDX] = { 9963, 0x0, 0x6E, 0x166666, 0x67D }, + [OLYMPUS_LUT_CHAN_249200_IDX] = { 9968, 0x0, 0x6E, 0x182D83, 0x67D }, + [OLYMPUS_LUT_CHAN_249325_IDX] = { 9973, 0x0, 0x6E, 0x19F49F, 0x67E }, + [OLYMPUS_LUT_CHAN_249450_IDX] = { 9978, 0x0, 0x6E, 0x1BBBBC, 0x67F }, + [OLYMPUS_LUT_CHAN_249575_IDX] = { 9983, 0x0, 0x6E, 0x1D82D8, 0x680 }, + [OLYMPUS_LUT_CHAN_249700_IDX] = { 9988, 0x0, 0x6E, 0x1F49F5, 0x681 }, + [OLYMPUS_LUT_CHAN_249825_IDX] = { 9993, 0x0, 0x6F, 0x11111, 0x682 }, + [OLYMPUS_LUT_CHAN_249950_IDX] = { 9998, 0x0, 0x6F, 0x2D82E, 0x682 }, + [OLYMPUS_LUT_CHAN_250075_IDX] = { 10003, 0x0, 0x6F, 0x49F4A, 0x683 } +}; + +const struct common_lut_line olympus_lut_24g_60_mhz_s1[OLYMPUS_LUT_CHAN_24G_MAX] = { + [OLYMPUS_LUT_CHAN_240700_IDX] = { 9628, 0x0, 0x35, 0xFA4FA, 0x645 }, + [OLYMPUS_LUT_CHAN_240825_IDX] = { 9633, 0x0, 0x35, 0x108889, 0x646 }, + [OLYMPUS_LUT_CHAN_240950_IDX] = { 9638, 0x0, 0x35, 0x116C17, 0x646 }, + [OLYMPUS_LUT_CHAN_241075_IDX] = { 9643, 0x0, 0x35, 0x124FA5, 0x647 }, + [OLYMPUS_LUT_CHAN_241200_IDX] = { 9648, 0x0, 0x35, 0x133333, 0x648 }, + [OLYMPUS_LUT_CHAN_241325_IDX] = { 9653, 0x0, 0x35, 0x1416C1, 0x649 }, + [OLYMPUS_LUT_CHAN_241450_IDX] = { 9658, 0x0, 0x35, 0x14FA50, 0x64A }, + [OLYMPUS_LUT_CHAN_241575_IDX] = { 9663, 0x0, 0x35, 0x15DDDE, 0x64B }, + [OLYMPUS_LUT_CHAN_241700_IDX] = { 9668, 0x0, 0x35, 0x16C16C, 0x64B }, + [OLYMPUS_LUT_CHAN_241825_IDX] = { 9673, 0x0, 0x35, 0x17A4FA, 0x64C }, + [OLYMPUS_LUT_CHAN_241950_IDX] = { 9678, 0x0, 0x35, 0x188889, 0x64D }, + [OLYMPUS_LUT_CHAN_242075_IDX] = { 9683, 0x0, 0x35, 0x196C17, 0x64E }, + [OLYMPUS_LUT_CHAN_242200_IDX] = { 9688, 0x0, 0x35, 0x1A4FA5, 0x64F }, + [OLYMPUS_LUT_CHAN_242325_IDX] = { 9693, 0x0, 0x35, 0x1B3333, 0x650 }, + [OLYMPUS_LUT_CHAN_242450_IDX] = { 9698, 0x0, 0x35, 0x1C16C1, 0x650 }, + [OLYMPUS_LUT_CHAN_242575_IDX] = { 9703, 0x0, 0x35, 0x1CFA50, 0x651 }, + [OLYMPUS_LUT_CHAN_242700_IDX] = { 9708, 0x0, 0x35, 0x1DDDDE, 0x652 }, + [OLYMPUS_LUT_CHAN_242825_IDX] = { 9713, 0x0, 0x35, 0x1EC16C, 0x653 }, + [OLYMPUS_LUT_CHAN_242950_IDX] = { 9718, 0x0, 0x35, 0x1FA4FA, 0x654 }, + [OLYMPUS_LUT_CHAN_243075_IDX] = { 9723, 0x0, 0x36, 0x8889, 0x655 }, + [OLYMPUS_LUT_CHAN_243200_IDX] = { 9728, 0x0, 0x36, 0x16C17, 0x655 }, + [OLYMPUS_LUT_CHAN_243325_IDX] = { 9733, 0x0, 0x36, 0x24FA5, 0x656 }, + [OLYMPUS_LUT_CHAN_243450_IDX] = { 9738, 0x0, 0x36, 0x33333, 0x657 }, + [OLYMPUS_LUT_CHAN_243575_IDX] = { 9743, 0x0, 0x36, 0x416C1, 0x658 }, + [OLYMPUS_LUT_CHAN_243700_IDX] = { 9748, 0x0, 0x36, 0x4FA50, 0x659 }, + [OLYMPUS_LUT_CHAN_243825_IDX] = { 9753, 0x0, 0x36, 0x5DDDE, 0x65A }, + [OLYMPUS_LUT_CHAN_243950_IDX] = { 9758, 0x0, 0x36, 0x6C16C, 0x65A }, + [OLYMPUS_LUT_CHAN_244075_IDX] = { 9763, 0x0, 0x36, 0x7A4FA, 0x65B }, + [OLYMPUS_LUT_CHAN_244200_IDX] = { 9768, 0x0, 0x36, 0x88889, 0x65C }, + [OLYMPUS_LUT_CHAN_244325_IDX] = { 9773, 0x0, 0x36, 0x96C17, 0x65D }, + [OLYMPUS_LUT_CHAN_244450_IDX] = { 9778, 0x0, 0x36, 0xA4FA5, 0x65E }, + [OLYMPUS_LUT_CHAN_244575_IDX] = { 9783, 0x0, 0x36, 0xB3333, 0x65F }, + [OLYMPUS_LUT_CHAN_244700_IDX] = { 9788, 0x0, 0x36, 0xC16C1, 0x65F }, + [OLYMPUS_LUT_CHAN_244825_IDX] = { 9793, 0x0, 0x36, 0xCFA50, 0x660 }, + [OLYMPUS_LUT_CHAN_244950_IDX] = { 9798, 0x0, 0x36, 0xDDDDE, 0x661 }, + [OLYMPUS_LUT_CHAN_245075_IDX] = { 9803, 0x0, 0x36, 0xEC16C, 0x662 }, + [OLYMPUS_LUT_CHAN_245200_IDX] = { 9808, 0x0, 0x36, 0xFA4FA, 0x663 }, + [OLYMPUS_LUT_CHAN_245325_IDX] = { 9813, 0x0, 0x36, 0x108889, 0x664 }, + [OLYMPUS_LUT_CHAN_245450_IDX] = { 9818, 0x0, 0x36, 0x116C17, 0x664 }, + [OLYMPUS_LUT_CHAN_245575_IDX] = { 9823, 0x0, 0x36, 0x124FA5, 0x665 }, + [OLYMPUS_LUT_CHAN_245700_IDX] = { 9828, 0x0, 0x36, 0x133333, 0x666 }, + [OLYMPUS_LUT_CHAN_245825_IDX] = { 9833, 0x0, 0x36, 0x1416C1, 0x667 }, + [OLYMPUS_LUT_CHAN_245950_IDX] = { 9838, 0x0, 0x36, 0x14FA50, 0x668 }, + [OLYMPUS_LUT_CHAN_246075_IDX] = { 9843, 0x0, 0x36, 0x15DDDE, 0x669 }, + [OLYMPUS_LUT_CHAN_246200_IDX] = { 9848, 0x0, 0x36, 0x16C16C, 0x669 }, + [OLYMPUS_LUT_CHAN_246325_IDX] = { 9853, 0x0, 0x36, 0x17A4FA, 0x66A }, + [OLYMPUS_LUT_CHAN_246450_IDX] = { 9858, 0x0, 0x36, 0x188889, 0x66B }, + [OLYMPUS_LUT_CHAN_246575_IDX] = { 9863, 0x0, 0x36, 0x196C17, 0x66C }, + [OLYMPUS_LUT_CHAN_246700_IDX] = { 9868, 0x0, 0x36, 0x1A4FA5, 0x66D }, + [OLYMPUS_LUT_CHAN_246825_IDX] = { 9873, 0x0, 0x36, 0x1B3333, 0x66E }, + [OLYMPUS_LUT_CHAN_246950_IDX] = { 9878, 0x0, 0x36, 0x1C16C1, 0x66E }, + [OLYMPUS_LUT_CHAN_247075_IDX] = { 9883, 0x0, 0x36, 0x1CFA50, 0x66F }, + [OLYMPUS_LUT_CHAN_247200_IDX] = { 9888, 0x0, 0x36, 0x1DDDDE, 0x670 }, + [OLYMPUS_LUT_CHAN_247325_IDX] = { 9893, 0x0, 0x36, 0x1EC16C, 0x671 }, + [OLYMPUS_LUT_CHAN_247450_IDX] = { 9898, 0x0, 0x36, 0x1FA4FA, 0x672 }, + [OLYMPUS_LUT_CHAN_247575_IDX] = { 9903, 0x0, 0x37, 0x8889, 0x673 }, + [OLYMPUS_LUT_CHAN_247700_IDX] = { 9908, 0x0, 0x37, 0x16C17, 0x673 }, + [OLYMPUS_LUT_CHAN_247825_IDX] = { 9913, 0x0, 0x37, 0x24FA5, 0x674 }, + [OLYMPUS_LUT_CHAN_247950_IDX] = { 9918, 0x0, 0x37, 0x33333, 0x675 }, + [OLYMPUS_LUT_CHAN_248075_IDX] = { 9923, 0x0, 0x37, 0x416C1, 0x676 }, + [OLYMPUS_LUT_CHAN_248200_IDX] = { 9928, 0x0, 0x37, 0x4FA50, 0x677 }, + [OLYMPUS_LUT_CHAN_248325_IDX] = { 9933, 0x0, 0x37, 0x5DDDE, 0x678 }, + [OLYMPUS_LUT_CHAN_248450_IDX] = { 9938, 0x0, 0x37, 0x6C16C, 0x678 }, + [OLYMPUS_LUT_CHAN_248575_IDX] = { 9943, 0x0, 0x37, 0x7A4FA, 0x679 }, + [OLYMPUS_LUT_CHAN_248700_IDX] = { 9948, 0x0, 0x37, 0x88889, 0x67A }, + [OLYMPUS_LUT_CHAN_248825_IDX] = { 9953, 0x0, 0x37, 0x96C17, 0x67B }, + [OLYMPUS_LUT_CHAN_248950_IDX] = { 9958, 0x0, 0x37, 0xA4FA5, 0x67C }, + [OLYMPUS_LUT_CHAN_249075_IDX] = { 9963, 0x0, 0x37, 0xB3333, 0x67D }, + [OLYMPUS_LUT_CHAN_249200_IDX] = { 9968, 0x0, 0x37, 0xC16C1, 0x67D }, + [OLYMPUS_LUT_CHAN_249325_IDX] = { 9973, 0x0, 0x37, 0xCFA50, 0x67E }, + [OLYMPUS_LUT_CHAN_249450_IDX] = { 9978, 0x0, 0x37, 0xDDDDE, 0x67F }, + [OLYMPUS_LUT_CHAN_249575_IDX] = { 9983, 0x0, 0x37, 0xEC16C, 0x680 }, + [OLYMPUS_LUT_CHAN_249700_IDX] = { 9988, 0x0, 0x37, 0xFA4FA, 0x681 }, + [OLYMPUS_LUT_CHAN_249825_IDX] = { 9993, 0x0, 0x37, 0x108889, 0x682 }, + [OLYMPUS_LUT_CHAN_249950_IDX] = { 9998, 0x0, 0x37, 0x116C17, 0x682 }, + [OLYMPUS_LUT_CHAN_250075_IDX] = { 10003, 0x0, 0x37, 0x124FA5, 0x683 } +}; + +const struct common_lut_line olympus_lut_5g_60_mhz_s0[OLYMPUS_LUT_CHAN_5G_MAX] = { + [OLYMPUS_LUT_CHAN_516000_IDX] = { 20640, 0x0, 0x73, 0x38E39, 0x6BF }, + [OLYMPUS_LUT_CHAN_516125_IDX] = { 20645, 0x0, 0x72, 0x1638E4, 0x6B8 }, + [OLYMPUS_LUT_CHAN_516250_IDX] = { 20650, 0x0, 0x72, 0x171C72, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516375_IDX] = { 20655, 0x0, 0x72, 0x180000, 0x6B9 }, + [OLYMPUS_LUT_CHAN_516500_IDX] = { 20660, 0x0, 0x72, 0x18E38E, 0x6BA }, + [OLYMPUS_LUT_CHAN_516625_IDX] = { 20665, 0x0, 0x72, 0x19C71C, 0x6BA }, + [OLYMPUS_LUT_CHAN_516750_IDX] = { 20670, 0x0, 0x72, 0x1AAAAB, 0x6BB }, + [OLYMPUS_LUT_CHAN_516875_IDX] = { 20675, 0x0, 0x72, 0x1B8E39, 0x6BB }, + [OLYMPUS_LUT_CHAN_517000_IDX] = { 20680, 0x0, 0x72, 0x1C71C7, 0x6BB }, + [OLYMPUS_LUT_CHAN_517125_IDX] = { 20685, 0x0, 0x72, 0x1D5555, 0x6BC }, + [OLYMPUS_LUT_CHAN_517250_IDX] = { 20690, 0x0, 0x72, 0x1E38E4, 0x6BC }, + [OLYMPUS_LUT_CHAN_517375_IDX] = { 20695, 0x0, 0x72, 0x1F1C72, 0x6BD }, + [OLYMPUS_LUT_CHAN_517500_IDX] = { 20700, 0x0, 0x73, 0x0, 0x6BD }, + [OLYMPUS_LUT_CHAN_517625_IDX] = { 20705, 0x0, 0x73, 0xE38E, 0x6BD }, + [OLYMPUS_LUT_CHAN_517750_IDX] = { 20710, 0x0, 0x73, 0x1C71C, 0x6BE }, + [OLYMPUS_LUT_CHAN_517875_IDX] = { 20715, 0x0, 0x73, 0x2AAAB, 0x6BE }, + [OLYMPUS_LUT_CHAN_518000_IDX] = { 20720, 0x0, 0x73, 0x38E39, 0x6BF }, + [OLYMPUS_LUT_CHAN_518125_IDX] = { 20725, 0x0, 0x73, 0x471C7, 0x6BF }, + [OLYMPUS_LUT_CHAN_518250_IDX] = { 20730, 0x0, 0x73, 0x55555, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518375_IDX] = { 20735, 0x0, 0x73, 0x638E4, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518500_IDX] = { 20740, 0x0, 0x73, 0x71C72, 0x6C0 }, + [OLYMPUS_LUT_CHAN_518625_IDX] = { 20745, 0x0, 0x73, 0x80000, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518750_IDX] = { 20750, 0x0, 0x73, 0x8E38E, 0x6C1 }, + [OLYMPUS_LUT_CHAN_518875_IDX] = { 20755, 0x0, 0x73, 0x9C71C, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519000_IDX] = { 20760, 0x0, 0x73, 0xAAAAB, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519125_IDX] = { 20765, 0x0, 0x73, 0xB8E39, 0x6C2 }, + [OLYMPUS_LUT_CHAN_519250_IDX] = { 20770, 0x0, 0x73, 0xC71C7, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519375_IDX] = { 20775, 0x0, 0x73, 0xD5555, 0x6C3 }, + [OLYMPUS_LUT_CHAN_519500_IDX] = { 20780, 0x0, 0x73, 0xE38E4, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519625_IDX] = { 20785, 0x0, 0x73, 0xF1C72, 0x6C4 }, + [OLYMPUS_LUT_CHAN_519750_IDX] = { 20790, 0x0, 0x73, 0x100000, 0x6C5 }, + [OLYMPUS_LUT_CHAN_519875_IDX] = { 20795, 0x0, 0x73, 0x10E38E, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520000_IDX] = { 20800, 0x1, 0x73, 0x11C71C, 0x6C5 }, + [OLYMPUS_LUT_CHAN_520125_IDX] = { 20805, 0x1, 0x73, 0x12AAAB, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520250_IDX] = { 20810, 0x1, 0x73, 0x138E39, 0x6C6 }, + [OLYMPUS_LUT_CHAN_520375_IDX] = { 20815, 0x1, 0x73, 0x1471C7, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520500_IDX] = { 20820, 0x1, 0x73, 0x155555, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520625_IDX] = { 20825, 0x1, 0x73, 0x1638E4, 0x6C7 }, + [OLYMPUS_LUT_CHAN_520750_IDX] = { 20830, 0x1, 0x73, 0x171C72, 0x6C8 }, + [OLYMPUS_LUT_CHAN_520875_IDX] = { 20835, 0x1, 0x73, 0x180000, 0x6C8 }, + [OLYMPUS_LUT_CHAN_521000_IDX] = { 20840, 0x1, 0x73, 0x18E38E, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521125_IDX] = { 20845, 0x1, 0x73, 0x19C71C, 0x6C9 }, + [OLYMPUS_LUT_CHAN_521250_IDX] = { 20850, 0x1, 0x73, 0x1AAAAB, 0x6CA }, + [OLYMPUS_LUT_CHAN_521375_IDX] = { 20855, 0x1, 0x73, 0x1B8E39, 0x6CA }, + [OLYMPUS_LUT_CHAN_521500_IDX] = { 20860, 0x1, 0x73, 0x1C71C7, 0x6CA }, + [OLYMPUS_LUT_CHAN_521625_IDX] = { 20865, 0x1, 0x73, 0x1D5555, 0x6CB }, + [OLYMPUS_LUT_CHAN_521750_IDX] = { 20870, 0x1, 0x73, 0x1E38E4, 0x6CB }, + [OLYMPUS_LUT_CHAN_521875_IDX] = { 20875, 0x1, 0x73, 0x1F1C72, 0x6CC }, + [OLYMPUS_LUT_CHAN_522000_IDX] = { 20880, 0x1, 0x74, 0x0, 0x6CC }, + [OLYMPUS_LUT_CHAN_522125_IDX] = { 20885, 0x1, 0x74, 0xE38E, 0x6CC }, + [OLYMPUS_LUT_CHAN_522250_IDX] = { 20890, 0x1, 0x74, 0x1C71C, 0x6CD }, + [OLYMPUS_LUT_CHAN_522375_IDX] = { 20895, 0x1, 0x74, 0x2AAAB, 0x6CD }, + [OLYMPUS_LUT_CHAN_522500_IDX] = { 20900, 0x1, 0x74, 0x38E39, 0x6CE }, + [OLYMPUS_LUT_CHAN_522625_IDX] = { 20905, 0x1, 0x74, 0x471C7, 0x6CE }, + [OLYMPUS_LUT_CHAN_522750_IDX] = { 20910, 0x1, 0x74, 0x55555, 0x6CF }, + [OLYMPUS_LUT_CHAN_522875_IDX] = { 20915, 0x1, 0x74, 0x638E4, 0x6CF }, + [OLYMPUS_LUT_CHAN_523000_IDX] = { 20920, 0x1, 0x74, 0x71C72, 0x6CF }, + [OLYMPUS_LUT_CHAN_523125_IDX] = { 20925, 0x1, 0x74, 0x80000, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523250_IDX] = { 20930, 0x1, 0x74, 0x8E38E, 0x6D0 }, + [OLYMPUS_LUT_CHAN_523375_IDX] = { 20935, 0x1, 0x74, 0x9C71C, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523500_IDX] = { 20940, 0x1, 0x74, 0xAAAAB, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523625_IDX] = { 20945, 0x1, 0x74, 0xB8E39, 0x6D1 }, + [OLYMPUS_LUT_CHAN_523750_IDX] = { 20950, 0x1, 0x74, 0xC71C7, 0x6D2 }, + [OLYMPUS_LUT_CHAN_523875_IDX] = { 20955, 0x1, 0x74, 0xD5555, 0x6D2 }, + [OLYMPUS_LUT_CHAN_524000_IDX] = { 20960, 0x1, 0x74, 0xE38E4, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524125_IDX] = { 20965, 0x1, 0x74, 0xF1C72, 0x6D3 }, + [OLYMPUS_LUT_CHAN_524250_IDX] = { 20970, 0x1, 0x74, 0x100000, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524375_IDX] = { 20975, 0x1, 0x74, 0x10E38E, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524500_IDX] = { 20980, 0x1, 0x74, 0x11C71C, 0x6D4 }, + [OLYMPUS_LUT_CHAN_524625_IDX] = { 20985, 0x1, 0x74, 0x12AAAB, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524750_IDX] = { 20990, 0x1, 0x74, 0x138E39, 0x6D5 }, + [OLYMPUS_LUT_CHAN_524875_IDX] = { 20995, 0x1, 0x74, 0x1471C7, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525000_IDX] = { 21000, 0x1, 0x74, 0x155555, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525125_IDX] = { 21005, 0x1, 0x74, 0x1638E4, 0x6D6 }, + [OLYMPUS_LUT_CHAN_525250_IDX] = { 21010, 0x1, 0x74, 0x171C72, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525375_IDX] = { 21015, 0x1, 0x74, 0x180000, 0x6D7 }, + [OLYMPUS_LUT_CHAN_525500_IDX] = { 21020, 0x1, 0x74, 0x18E38E, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525625_IDX] = { 21025, 0x1, 0x74, 0x19C71C, 0x6D8 }, + [OLYMPUS_LUT_CHAN_525750_IDX] = { 21030, 0x1, 0x74, 0x1AAAAB, 0x6D9 }, + [OLYMPUS_LUT_CHAN_525875_IDX] = { 21035, 0x1, 0x74, 0x1B8E39, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526000_IDX] = { 21040, 0x1, 0x74, 0x1C71C7, 0x6D9 }, + [OLYMPUS_LUT_CHAN_526125_IDX] = { 21045, 0x1, 0x74, 0x1D5555, 0x6DA }, + [OLYMPUS_LUT_CHAN_526250_IDX] = { 21050, 0x1, 0x74, 0x1E38E4, 0x6DA }, + [OLYMPUS_LUT_CHAN_526375_IDX] = { 21055, 0x1, 0x74, 0x1F1C72, 0x6DB }, + [OLYMPUS_LUT_CHAN_526500_IDX] = { 21060, 0x1, 0x75, 0x0, 0x6DB }, + [OLYMPUS_LUT_CHAN_526625_IDX] = { 21065, 0x1, 0x75, 0xE38E, 0x6DB }, + [OLYMPUS_LUT_CHAN_526750_IDX] = { 21070, 0x1, 0x75, 0x1C71C, 0x6DC }, + [OLYMPUS_LUT_CHAN_526875_IDX] = { 21075, 0x1, 0x75, 0x2AAAB, 0x6DC }, + [OLYMPUS_LUT_CHAN_527000_IDX] = { 21080, 0x1, 0x75, 0x38E39, 0x6DD }, + [OLYMPUS_LUT_CHAN_527125_IDX] = { 21085, 0x1, 0x75, 0x471C7, 0x6DD }, + [OLYMPUS_LUT_CHAN_527250_IDX] = { 21090, 0x1, 0x75, 0x55555, 0x6DE }, + [OLYMPUS_LUT_CHAN_527375_IDX] = { 21095, 0x1, 0x75, 0x638E4, 0x6DE }, + [OLYMPUS_LUT_CHAN_527500_IDX] = { 21100, 0x1, 0x75, 0x71C72, 0x6DE }, + [OLYMPUS_LUT_CHAN_527625_IDX] = { 21105, 0x1, 0x75, 0x80000, 0x6DF }, + [OLYMPUS_LUT_CHAN_527750_IDX] = { 21110, 0x1, 0x75, 0x8E38E, 0x6DF }, + [OLYMPUS_LUT_CHAN_527875_IDX] = { 21115, 0x1, 0x75, 0x9C71C, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528000_IDX] = { 21120, 0x1, 0x75, 0xAAAAB, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528125_IDX] = { 21125, 0x1, 0x75, 0xB8E39, 0x6E0 }, + [OLYMPUS_LUT_CHAN_528250_IDX] = { 21130, 0x1, 0x75, 0xC71C7, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528375_IDX] = { 21135, 0x1, 0x75, 0xD5555, 0x6E1 }, + [OLYMPUS_LUT_CHAN_528500_IDX] = { 21140, 0x1, 0x75, 0xE38E4, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528625_IDX] = { 21145, 0x1, 0x75, 0xF1C72, 0x6E2 }, + [OLYMPUS_LUT_CHAN_528750_IDX] = { 21150, 0x1, 0x75, 0x100000, 0x6E3 }, + [OLYMPUS_LUT_CHAN_528875_IDX] = { 21155, 0x1, 0x75, 0x10E38E, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529000_IDX] = { 21160, 0x1, 0x75, 0x11C71C, 0x6E3 }, + [OLYMPUS_LUT_CHAN_529125_IDX] = { 21165, 0x1, 0x75, 0x12AAAB, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529250_IDX] = { 21170, 0x1, 0x75, 0x138E39, 0x6E4 }, + [OLYMPUS_LUT_CHAN_529375_IDX] = { 21175, 0x1, 0x75, 0x1471C7, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529500_IDX] = { 21180, 0x1, 0x75, 0x155555, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529625_IDX] = { 21185, 0x1, 0x75, 0x1638E4, 0x6E5 }, + [OLYMPUS_LUT_CHAN_529750_IDX] = { 21190, 0x1, 0x75, 0x171C72, 0x6E6 }, + [OLYMPUS_LUT_CHAN_529875_IDX] = { 21195, 0x1, 0x75, 0x180000, 0x6E6 }, + [OLYMPUS_LUT_CHAN_530000_IDX] = { 21200, 0x1, 0x75, 0x18E38E, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530125_IDX] = { 21205, 0x1, 0x75, 0x19C71C, 0x6E7 }, + [OLYMPUS_LUT_CHAN_530250_IDX] = { 21210, 0x1, 0x75, 0x1AAAAB, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530375_IDX] = { 21215, 0x1, 0x75, 0x1B8E39, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530500_IDX] = { 21220, 0x1, 0x75, 0x1C71C7, 0x6E8 }, + [OLYMPUS_LUT_CHAN_530625_IDX] = { 21225, 0x1, 0x75, 0x1D5555, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530750_IDX] = { 21230, 0x1, 0x75, 0x1E38E4, 0x6E9 }, + [OLYMPUS_LUT_CHAN_530875_IDX] = { 21235, 0x1, 0x75, 0x1F1C72, 0x6EA }, + [OLYMPUS_LUT_CHAN_531000_IDX] = { 21240, 0x1, 0x76, 0x0, 0x6EA }, + [OLYMPUS_LUT_CHAN_531125_IDX] = { 21245, 0x1, 0x76, 0xE38E, 0x6EA }, + [OLYMPUS_LUT_CHAN_531250_IDX] = { 21250, 0x1, 0x76, 0x1C71C, 0x6EB }, + [OLYMPUS_LUT_CHAN_531375_IDX] = { 21255, 0x1, 0x76, 0x2AAAB, 0x6EB }, + [OLYMPUS_LUT_CHAN_531500_IDX] = { 21260, 0x1, 0x76, 0x38E39, 0x6EC }, + [OLYMPUS_LUT_CHAN_531625_IDX] = { 21265, 0x1, 0x76, 0x471C7, 0x6EC }, + [OLYMPUS_LUT_CHAN_531750_IDX] = { 21270, 0x1, 0x76, 0x55555, 0x6ED }, + [OLYMPUS_LUT_CHAN_531875_IDX] = { 21275, 0x1, 0x76, 0x638E4, 0x6ED }, + [OLYMPUS_LUT_CHAN_532000_IDX] = { 21280, 0x1, 0x76, 0x71C72, 0x6ED }, + [OLYMPUS_LUT_CHAN_532125_IDX] = { 21285, 0x1, 0x76, 0x80000, 0x6EE }, + [OLYMPUS_LUT_CHAN_532250_IDX] = { 21290, 0x1, 0x76, 0x8E38E, 0x6EE }, + [OLYMPUS_LUT_CHAN_532375_IDX] = { 21295, 0x1, 0x76, 0x9C71C, 0x6EF }, + [OLYMPUS_LUT_CHAN_532500_IDX] = { 21300, 0x1, 0x76, 0xAAAAB, 0x6EF }, + [OLYMPUS_LUT_CHAN_532625_IDX] = { 21305, 0x1, 0x76, 0xB8E39, 0x6EF }, + [OLYMPUS_LUT_CHAN_532750_IDX] = { 21310, 0x1, 0x76, 0xC71C7, 0x6F0 }, + [OLYMPUS_LUT_CHAN_532875_IDX] = { 21315, 0x1, 0x76, 0xD5555, 0x6F0 }, + [OLYMPUS_LUT_CHAN_533000_IDX] = { 21320, 0x1, 0x76, 0xE38E4, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533125_IDX] = { 21325, 0x1, 0x76, 0xF1C72, 0x6F1 }, + [OLYMPUS_LUT_CHAN_533250_IDX] = { 21330, 0x1, 0x76, 0x100000, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533375_IDX] = { 21335, 0x1, 0x76, 0x10E38E, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533500_IDX] = { 21340, 0x1, 0x76, 0x11C71C, 0x6F2 }, + [OLYMPUS_LUT_CHAN_533625_IDX] = { 21345, 0x1, 0x76, 0x12AAAB, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533750_IDX] = { 21350, 0x1, 0x76, 0x138E39, 0x6F3 }, + [OLYMPUS_LUT_CHAN_533875_IDX] = { 21355, 0x1, 0x76, 0x1471C7, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534000_IDX] = { 21360, 0x1, 0x76, 0x155555, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534125_IDX] = { 21365, 0x1, 0x76, 0x1638E4, 0x6F4 }, + [OLYMPUS_LUT_CHAN_534250_IDX] = { 21370, 0x1, 0x76, 0x171C72, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534375_IDX] = { 21375, 0x1, 0x76, 0x180000, 0x6F5 }, + [OLYMPUS_LUT_CHAN_534500_IDX] = { 21380, 0x1, 0x76, 0x18E38E, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534625_IDX] = { 21385, 0x1, 0x76, 0x19C71C, 0x6F6 }, + [OLYMPUS_LUT_CHAN_534750_IDX] = { 21390, 0x1, 0x76, 0x1AAAAB, 0x6F7 }, + [OLYMPUS_LUT_CHAN_534875_IDX] = { 21395, 0x1, 0x76, 0x1B8E39, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535000_IDX] = { 21400, 0x1, 0x76, 0x1C71C7, 0x6F7 }, + [OLYMPUS_LUT_CHAN_535125_IDX] = { 21405, 0x1, 0x76, 0x1D5555, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535250_IDX] = { 21410, 0x1, 0x76, 0x1E38E4, 0x6F8 }, + [OLYMPUS_LUT_CHAN_535375_IDX] = { 21415, 0x1, 0x76, 0x1F1C72, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535500_IDX] = { 21420, 0x1, 0x77, 0x0, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535625_IDX] = { 21425, 0x1, 0x77, 0xE38E, 0x6F9 }, + [OLYMPUS_LUT_CHAN_535750_IDX] = { 21430, 0x1, 0x77, 0x1C71C, 0x6FA }, + [OLYMPUS_LUT_CHAN_535875_IDX] = { 21435, 0x1, 0x77, 0x2AAAB, 0x6FA }, + [OLYMPUS_LUT_CHAN_536000_IDX] = { 21440, 0x1, 0x77, 0x38E39, 0x6FB }, + [OLYMPUS_LUT_CHAN_536125_IDX] = { 21445, 0x1, 0x77, 0x471C7, 0x6FB }, + [OLYMPUS_LUT_CHAN_536250_IDX] = { 21450, 0x1, 0x77, 0x55555, 0x6FC }, + [OLYMPUS_LUT_CHAN_536375_IDX] = { 21455, 0x1, 0x77, 0x638E4, 0x6FC }, + [OLYMPUS_LUT_CHAN_536500_IDX] = { 21460, 0x1, 0x77, 0x71C72, 0x6FC }, + [OLYMPUS_LUT_CHAN_536625_IDX] = { 21465, 0x1, 0x77, 0x80000, 0x6FD }, + [OLYMPUS_LUT_CHAN_536750_IDX] = { 21470, 0x1, 0x77, 0x8E38E, 0x6FD }, + [OLYMPUS_LUT_CHAN_536875_IDX] = { 21475, 0x1, 0x77, 0x9C71C, 0x6FE }, + [OLYMPUS_LUT_CHAN_537000_IDX] = { 21480, 0x1, 0x77, 0xAAAAB, 0x6FE }, + [OLYMPUS_LUT_CHAN_537125_IDX] = { 21485, 0x1, 0x77, 0xB8E39, 0x6FE }, + [OLYMPUS_LUT_CHAN_537250_IDX] = { 21490, 0x1, 0x77, 0xC71C7, 0x6FF }, + [OLYMPUS_LUT_CHAN_537375_IDX] = { 21495, 0x1, 0x77, 0xD5555, 0x6FF }, + [OLYMPUS_LUT_CHAN_537500_IDX] = { 21500, 0x1, 0x77, 0xE38E4, 0x700 }, + [OLYMPUS_LUT_CHAN_537625_IDX] = { 21505, 0x1, 0x77, 0xF1C72, 0x700 }, + [OLYMPUS_LUT_CHAN_537750_IDX] = { 21510, 0x1, 0x77, 0x100000, 0x701 }, + [OLYMPUS_LUT_CHAN_537875_IDX] = { 21515, 0x1, 0x77, 0x10E38E, 0x701 }, + [OLYMPUS_LUT_CHAN_538000_IDX] = { 21520, 0x1, 0x77, 0x11C71C, 0x701 }, + [OLYMPUS_LUT_CHAN_538125_IDX] = { 21525, 0x1, 0x77, 0x12AAAB, 0x702 }, + [OLYMPUS_LUT_CHAN_538250_IDX] = { 21530, 0x1, 0x77, 0x138E39, 0x702 }, + [OLYMPUS_LUT_CHAN_538375_IDX] = { 21535, 0x1, 0x77, 0x1471C7, 0x703 }, + [OLYMPUS_LUT_CHAN_538500_IDX] = { 21540, 0x1, 0x77, 0x155555, 0x703 }, + [OLYMPUS_LUT_CHAN_538625_IDX] = { 21545, 0x1, 0x77, 0x1638E4, 0x703 }, + [OLYMPUS_LUT_CHAN_538750_IDX] = { 21550, 0x1, 0x77, 0x171C72, 0x704 }, + [OLYMPUS_LUT_CHAN_538875_IDX] = { 21555, 0x1, 0x77, 0x180000, 0x704 }, + [OLYMPUS_LUT_CHAN_539000_IDX] = { 21560, 0x1, 0x77, 0x18E38E, 0x705 }, + [OLYMPUS_LUT_CHAN_539125_IDX] = { 21565, 0x1, 0x77, 0x19C71C, 0x705 }, + [OLYMPUS_LUT_CHAN_539250_IDX] = { 21570, 0x1, 0x77, 0x1AAAAB, 0x706 }, + [OLYMPUS_LUT_CHAN_539375_IDX] = { 21575, 0x1, 0x77, 0x1B8E39, 0x706 }, + [OLYMPUS_LUT_CHAN_539500_IDX] = { 21580, 0x1, 0x77, 0x1C71C7, 0x706 }, + [OLYMPUS_LUT_CHAN_539625_IDX] = { 21585, 0x1, 0x77, 0x1D5555, 0x707 }, + [OLYMPUS_LUT_CHAN_539750_IDX] = { 21590, 0x1, 0x77, 0x1E38E4, 0x707 }, + [OLYMPUS_LUT_CHAN_539875_IDX] = { 21595, 0x1, 0x77, 0x1F1C72, 0x708 }, + [OLYMPUS_LUT_CHAN_540000_IDX] = { 21600, 0x1, 0x78, 0x0, 0x708 }, + [OLYMPUS_LUT_CHAN_540125_IDX] = { 21605, 0x1, 0x78, 0xE38E, 0x708 }, + [OLYMPUS_LUT_CHAN_540250_IDX] = { 21610, 0x1, 0x78, 0x1C71C, 0x709 }, + [OLYMPUS_LUT_CHAN_540375_IDX] = { 21615, 0x1, 0x78, 0x2AAAB, 0x709 }, + [OLYMPUS_LUT_CHAN_540500_IDX] = { 21620, 0x1, 0x78, 0x38E39, 0x70A }, + [OLYMPUS_LUT_CHAN_540625_IDX] = { 21625, 0x1, 0x78, 0x471C7, 0x70A }, + [OLYMPUS_LUT_CHAN_540750_IDX] = { 21630, 0x1, 0x78, 0x55555, 0x70B }, + [OLYMPUS_LUT_CHAN_540875_IDX] = { 21635, 0x1, 0x78, 0x638E4, 0x70B }, + [OLYMPUS_LUT_CHAN_541000_IDX] = { 21640, 0x1, 0x78, 0x71C72, 0x70B }, + [OLYMPUS_LUT_CHAN_541125_IDX] = { 21645, 0x1, 0x78, 0x80000, 0x70C }, + [OLYMPUS_LUT_CHAN_541250_IDX] = { 21650, 0x1, 0x78, 0x8E38E, 0x70C }, + [OLYMPUS_LUT_CHAN_541375_IDX] = { 21655, 0x1, 0x78, 0x9C71C, 0x70D }, + [OLYMPUS_LUT_CHAN_541500_IDX] = { 21660, 0x1, 0x78, 0xAAAAB, 0x70D }, + [OLYMPUS_LUT_CHAN_541625_IDX] = { 21665, 0x1, 0x78, 0xB8E39, 0x70D }, + [OLYMPUS_LUT_CHAN_541750_IDX] = { 21670, 0x1, 0x78, 0xC71C7, 0x70E }, + [OLYMPUS_LUT_CHAN_541875_IDX] = { 21675, 0x1, 0x78, 0xD5555, 0x70E }, + [OLYMPUS_LUT_CHAN_542000_IDX] = { 21680, 0x1, 0x78, 0xE38E4, 0x70F }, + [OLYMPUS_LUT_CHAN_542125_IDX] = { 21685, 0x1, 0x78, 0xF1C72, 0x70F }, + [OLYMPUS_LUT_CHAN_542250_IDX] = { 21690, 0x1, 0x78, 0x100000, 0x710 }, + [OLYMPUS_LUT_CHAN_542375_IDX] = { 21695, 0x1, 0x78, 0x10E38E, 0x710 }, + [OLYMPUS_LUT_CHAN_542500_IDX] = { 21700, 0x1, 0x78, 0x11C71C, 0x710 }, + [OLYMPUS_LUT_CHAN_542625_IDX] = { 21705, 0x1, 0x78, 0x12AAAB, 0x711 }, + [OLYMPUS_LUT_CHAN_542750_IDX] = { 21710, 0x1, 0x78, 0x138E39, 0x711 }, + [OLYMPUS_LUT_CHAN_542875_IDX] = { 21715, 0x1, 0x78, 0x1471C7, 0x712 }, + [OLYMPUS_LUT_CHAN_543000_IDX] = { 21720, 0x1, 0x78, 0x155555, 0x712 }, + [OLYMPUS_LUT_CHAN_543125_IDX] = { 21725, 0x1, 0x78, 0x1638E4, 0x712 }, + [OLYMPUS_LUT_CHAN_543250_IDX] = { 21730, 0x1, 0x78, 0x171C72, 0x713 }, + [OLYMPUS_LUT_CHAN_543375_IDX] = { 21735, 0x1, 0x78, 0x180000, 0x713 }, + [OLYMPUS_LUT_CHAN_543500_IDX] = { 21740, 0x1, 0x78, 0x18E38E, 0x714 }, + [OLYMPUS_LUT_CHAN_543625_IDX] = { 21745, 0x1, 0x78, 0x19C71C, 0x714 }, + [OLYMPUS_LUT_CHAN_543750_IDX] = { 21750, 0x1, 0x78, 0x1AAAAB, 0x715 }, + [OLYMPUS_LUT_CHAN_543875_IDX] = { 21755, 0x1, 0x78, 0x1B8E39, 0x715 }, + [OLYMPUS_LUT_CHAN_544000_IDX] = { 21760, 0x1, 0x78, 0x1C71C7, 0x715 }, + [OLYMPUS_LUT_CHAN_544125_IDX] = { 21765, 0x1, 0x78, 0x1D5555, 0x716 }, + [OLYMPUS_LUT_CHAN_544250_IDX] = { 21770, 0x1, 0x78, 0x1E38E4, 0x716 }, + [OLYMPUS_LUT_CHAN_544375_IDX] = { 21775, 0x1, 0x78, 0x1F1C72, 0x717 }, + [OLYMPUS_LUT_CHAN_544500_IDX] = { 21780, 0x1, 0x79, 0x0, 0x717 }, + [OLYMPUS_LUT_CHAN_544625_IDX] = { 21785, 0x1, 0x79, 0xE38E, 0x717 }, + [OLYMPUS_LUT_CHAN_544750_IDX] = { 21790, 0x1, 0x79, 0x1C71C, 0x718 }, + [OLYMPUS_LUT_CHAN_544875_IDX] = { 21795, 0x1, 0x79, 0x2AAAB, 0x718 }, + [OLYMPUS_LUT_CHAN_545000_IDX] = { 21800, 0x1, 0x79, 0x38E39, 0x719 }, + [OLYMPUS_LUT_CHAN_545125_IDX] = { 21805, 0x1, 0x79, 0x471C7, 0x719 }, + [OLYMPUS_LUT_CHAN_545250_IDX] = { 21810, 0x1, 0x79, 0x55555, 0x71A }, + [OLYMPUS_LUT_CHAN_545375_IDX] = { 21815, 0x1, 0x79, 0x638E4, 0x71A }, + [OLYMPUS_LUT_CHAN_545500_IDX] = { 21820, 0x1, 0x79, 0x71C72, 0x71A }, + [OLYMPUS_LUT_CHAN_545625_IDX] = { 21825, 0x1, 0x79, 0x80000, 0x71B }, + [OLYMPUS_LUT_CHAN_545750_IDX] = { 21830, 0x1, 0x79, 0x8E38E, 0x71B }, + [OLYMPUS_LUT_CHAN_545875_IDX] = { 21835, 0x1, 0x79, 0x9C71C, 0x71C }, + [OLYMPUS_LUT_CHAN_546000_IDX] = { 21840, 0x1, 0x79, 0xAAAAB, 0x71C }, + [OLYMPUS_LUT_CHAN_546125_IDX] = { 21845, 0x1, 0x79, 0xB8E39, 0x71C }, + [OLYMPUS_LUT_CHAN_546250_IDX] = { 21850, 0x1, 0x79, 0xC71C7, 0x71D }, + [OLYMPUS_LUT_CHAN_546375_IDX] = { 21855, 0x1, 0x79, 0xD5555, 0x71D }, + [OLYMPUS_LUT_CHAN_546500_IDX] = { 21860, 0x1, 0x79, 0xE38E4, 0x71E }, + [OLYMPUS_LUT_CHAN_546625_IDX] = { 21865, 0x1, 0x79, 0xF1C72, 0x71E }, + [OLYMPUS_LUT_CHAN_546750_IDX] = { 21870, 0x1, 0x79, 0x100000, 0x71F }, + [OLYMPUS_LUT_CHAN_546875_IDX] = { 21875, 0x1, 0x79, 0x10E38E, 0x71F }, + [OLYMPUS_LUT_CHAN_547000_IDX] = { 21880, 0x1, 0x79, 0x11C71C, 0x71F }, + [OLYMPUS_LUT_CHAN_547125_IDX] = { 21885, 0x1, 0x79, 0x12AAAB, 0x720 }, + [OLYMPUS_LUT_CHAN_547250_IDX] = { 21890, 0x1, 0x79, 0x138E39, 0x720 }, + [OLYMPUS_LUT_CHAN_547375_IDX] = { 21895, 0x1, 0x79, 0x1471C7, 0x721 }, + [OLYMPUS_LUT_CHAN_547500_IDX] = { 21900, 0x1, 0x79, 0x155555, 0x721 }, + [OLYMPUS_LUT_CHAN_547625_IDX] = { 21905, 0x1, 0x79, 0x1638E4, 0x721 }, + [OLYMPUS_LUT_CHAN_547750_IDX] = { 21910, 0x1, 0x79, 0x171C72, 0x722 }, + [OLYMPUS_LUT_CHAN_547875_IDX] = { 21915, 0x1, 0x79, 0x180000, 0x722 }, + [OLYMPUS_LUT_CHAN_548000_IDX] = { 21920, 0x1, 0x79, 0x18E38E, 0x723 }, + [OLYMPUS_LUT_CHAN_548125_IDX] = { 21925, 0x1, 0x79, 0x19C71C, 0x723 }, + [OLYMPUS_LUT_CHAN_548250_IDX] = { 21930, 0x1, 0x79, 0x1AAAAB, 0x724 }, + [OLYMPUS_LUT_CHAN_548375_IDX] = { 21935, 0x1, 0x79, 0x1B8E39, 0x724 }, + [OLYMPUS_LUT_CHAN_548500_IDX] = { 21940, 0x1, 0x79, 0x1C71C7, 0x724 }, + [OLYMPUS_LUT_CHAN_548625_IDX] = { 21945, 0x1, 0x79, 0x1D5555, 0x725 }, + [OLYMPUS_LUT_CHAN_548750_IDX] = { 21950, 0x1, 0x79, 0x1E38E4, 0x725 }, + [OLYMPUS_LUT_CHAN_548875_IDX] = { 21955, 0x1, 0x79, 0x1F1C72, 0x726 }, + [OLYMPUS_LUT_CHAN_549000_IDX] = { 21960, 0x1, 0x7A, 0x0, 0x726 }, + [OLYMPUS_LUT_CHAN_549125_IDX] = { 21965, 0x1, 0x7A, 0xE38E, 0x726 }, + [OLYMPUS_LUT_CHAN_549250_IDX] = { 21970, 0x1, 0x7A, 0x1C71C, 0x727 }, + [OLYMPUS_LUT_CHAN_549375_IDX] = { 21975, 0x1, 0x7A, 0x2AAAB, 0x727 }, + [OLYMPUS_LUT_CHAN_549500_IDX] = { 21980, 0x1, 0x7A, 0x38E39, 0x728 }, + [OLYMPUS_LUT_CHAN_549625_IDX] = { 21985, 0x1, 0x7A, 0x471C7, 0x728 }, + [OLYMPUS_LUT_CHAN_549750_IDX] = { 21990, 0x1, 0x7A, 0x55555, 0x729 }, + [OLYMPUS_LUT_CHAN_549875_IDX] = { 21995, 0x1, 0x7A, 0x638E4, 0x729 }, + [OLYMPUS_LUT_CHAN_550000_IDX] = { 22000, 0x1, 0x7A, 0x71C72, 0x729 }, + [OLYMPUS_LUT_CHAN_550125_IDX] = { 22005, 0x1, 0x7A, 0x80000, 0x72A }, + [OLYMPUS_LUT_CHAN_550250_IDX] = { 22010, 0x1, 0x7A, 0x8E38E, 0x72A }, + [OLYMPUS_LUT_CHAN_550375_IDX] = { 22015, 0x1, 0x7A, 0x9C71C, 0x72B }, + [OLYMPUS_LUT_CHAN_550500_IDX] = { 22020, 0x1, 0x7A, 0xAAAAB, 0x72B }, + [OLYMPUS_LUT_CHAN_550625_IDX] = { 22025, 0x1, 0x7A, 0xB8E39, 0x72B }, + [OLYMPUS_LUT_CHAN_550750_IDX] = { 22030, 0x1, 0x7A, 0xC71C7, 0x72C }, + [OLYMPUS_LUT_CHAN_550875_IDX] = { 22035, 0x1, 0x7A, 0xD5555, 0x72C }, + [OLYMPUS_LUT_CHAN_551000_IDX] = { 22040, 0x1, 0x7A, 0xE38E4, 0x72D }, + [OLYMPUS_LUT_CHAN_551125_IDX] = { 22045, 0x1, 0x7A, 0xF1C72, 0x72D }, + [OLYMPUS_LUT_CHAN_551250_IDX] = { 22050, 0x1, 0x7A, 0x100000, 0x72E }, + [OLYMPUS_LUT_CHAN_551375_IDX] = { 22055, 0x1, 0x7A, 0x10E38E, 0x72E }, + [OLYMPUS_LUT_CHAN_551500_IDX] = { 22060, 0x1, 0x7A, 0x11C71C, 0x72E }, + [OLYMPUS_LUT_CHAN_551625_IDX] = { 22065, 0x1, 0x7A, 0x12AAAB, 0x72F }, + [OLYMPUS_LUT_CHAN_551750_IDX] = { 22070, 0x1, 0x7A, 0x138E39, 0x72F }, + [OLYMPUS_LUT_CHAN_551875_IDX] = { 22075, 0x1, 0x7A, 0x1471C7, 0x730 }, + [OLYMPUS_LUT_CHAN_552000_IDX] = { 22080, 0x1, 0x7A, 0x155555, 0x730 }, + [OLYMPUS_LUT_CHAN_552125_IDX] = { 22085, 0x1, 0x7A, 0x1638E4, 0x730 }, + [OLYMPUS_LUT_CHAN_552250_IDX] = { 22090, 0x1, 0x7A, 0x171C72, 0x731 }, + [OLYMPUS_LUT_CHAN_552375_IDX] = { 22095, 0x1, 0x7A, 0x180000, 0x731 }, + [OLYMPUS_LUT_CHAN_552500_IDX] = { 22100, 0x1, 0x7A, 0x18E38E, 0x732 }, + [OLYMPUS_LUT_CHAN_552625_IDX] = { 22105, 0x1, 0x7A, 0x19C71C, 0x732 }, + [OLYMPUS_LUT_CHAN_552750_IDX] = { 22110, 0x1, 0x7A, 0x1AAAAB, 0x733 }, + [OLYMPUS_LUT_CHAN_552875_IDX] = { 22115, 0x1, 0x7A, 0x1B8E39, 0x733 }, + [OLYMPUS_LUT_CHAN_553000_IDX] = { 22120, 0x1, 0x7A, 0x1C71C7, 0x733 }, + [OLYMPUS_LUT_CHAN_553125_IDX] = { 22125, 0x1, 0x7A, 0x1D5555, 0x734 }, + [OLYMPUS_LUT_CHAN_553250_IDX] = { 22130, 0x1, 0x7A, 0x1E38E4, 0x734 }, + [OLYMPUS_LUT_CHAN_553375_IDX] = { 22135, 0x1, 0x7A, 0x1F1C72, 0x735 }, + [OLYMPUS_LUT_CHAN_553500_IDX] = { 22140, 0x1, 0x7B, 0x0, 0x735 }, + [OLYMPUS_LUT_CHAN_553625_IDX] = { 22145, 0x1, 0x7B, 0xE38E, 0x735 }, + [OLYMPUS_LUT_CHAN_553750_IDX] = { 22150, 0x1, 0x7B, 0x1C71C, 0x736 }, + [OLYMPUS_LUT_CHAN_553875_IDX] = { 22155, 0x1, 0x7B, 0x2AAAB, 0x736 }, + [OLYMPUS_LUT_CHAN_554000_IDX] = { 22160, 0x1, 0x7B, 0x38E39, 0x737 }, + [OLYMPUS_LUT_CHAN_554125_IDX] = { 22165, 0x1, 0x7B, 0x471C7, 0x737 }, + [OLYMPUS_LUT_CHAN_554250_IDX] = { 22170, 0x1, 0x7B, 0x55555, 0x738 }, + [OLYMPUS_LUT_CHAN_554375_IDX] = { 22175, 0x1, 0x7B, 0x638E4, 0x738 }, + [OLYMPUS_LUT_CHAN_554500_IDX] = { 22180, 0x1, 0x7B, 0x71C72, 0x738 }, + [OLYMPUS_LUT_CHAN_554625_IDX] = { 22185, 0x1, 0x7B, 0x80000, 0x739 }, + [OLYMPUS_LUT_CHAN_554750_IDX] = { 22190, 0x1, 0x7B, 0x8E38E, 0x739 }, + [OLYMPUS_LUT_CHAN_554875_IDX] = { 22195, 0x1, 0x7B, 0x9C71C, 0x73A }, + [OLYMPUS_LUT_CHAN_555000_IDX] = { 22200, 0x1, 0x7B, 0xAAAAB, 0x73A }, + [OLYMPUS_LUT_CHAN_555125_IDX] = { 22205, 0x1, 0x7B, 0xB8E39, 0x73A }, + [OLYMPUS_LUT_CHAN_555250_IDX] = { 22210, 0x1, 0x7B, 0xC71C7, 0x73B }, + [OLYMPUS_LUT_CHAN_555375_IDX] = { 22215, 0x1, 0x7B, 0xD5555, 0x73B }, + [OLYMPUS_LUT_CHAN_555500_IDX] = { 22220, 0x1, 0x7B, 0xE38E4, 0x73C }, + [OLYMPUS_LUT_CHAN_555625_IDX] = { 22225, 0x1, 0x7B, 0xF1C72, 0x73C }, + [OLYMPUS_LUT_CHAN_555750_IDX] = { 22230, 0x1, 0x7B, 0x100000, 0x73D }, + [OLYMPUS_LUT_CHAN_555875_IDX] = { 22235, 0x1, 0x7B, 0x10E38E, 0x73D }, + [OLYMPUS_LUT_CHAN_556000_IDX] = { 22240, 0x1, 0x7B, 0x11C71C, 0x73D }, + [OLYMPUS_LUT_CHAN_556125_IDX] = { 22245, 0x1, 0x7B, 0x12AAAB, 0x73E }, + [OLYMPUS_LUT_CHAN_556250_IDX] = { 22250, 0x1, 0x7B, 0x138E39, 0x73E }, + [OLYMPUS_LUT_CHAN_556375_IDX] = { 22255, 0x1, 0x7B, 0x1471C7, 0x73F }, + [OLYMPUS_LUT_CHAN_556500_IDX] = { 22260, 0x1, 0x7B, 0x155555, 0x73F }, + [OLYMPUS_LUT_CHAN_556625_IDX] = { 22265, 0x1, 0x7B, 0x1638E4, 0x73F }, + [OLYMPUS_LUT_CHAN_556750_IDX] = { 22270, 0x1, 0x7B, 0x171C72, 0x740 }, + [OLYMPUS_LUT_CHAN_556875_IDX] = { 22275, 0x1, 0x7B, 0x180000, 0x740 }, + [OLYMPUS_LUT_CHAN_557000_IDX] = { 22280, 0x1, 0x7B, 0x18E38E, 0x741 }, + [OLYMPUS_LUT_CHAN_557125_IDX] = { 22285, 0x1, 0x7B, 0x19C71C, 0x741 }, + [OLYMPUS_LUT_CHAN_557250_IDX] = { 22290, 0x1, 0x7B, 0x1AAAAB, 0x742 }, + [OLYMPUS_LUT_CHAN_557375_IDX] = { 22295, 0x1, 0x7B, 0x1B8E39, 0x742 }, + [OLYMPUS_LUT_CHAN_557500_IDX] = { 22300, 0x1, 0x7B, 0x1C71C7, 0x742 }, + [OLYMPUS_LUT_CHAN_557625_IDX] = { 22305, 0x1, 0x7B, 0x1D5555, 0x743 }, + [OLYMPUS_LUT_CHAN_557750_IDX] = { 22310, 0x1, 0x7B, 0x1E38E4, 0x743 }, + [OLYMPUS_LUT_CHAN_557875_IDX] = { 22315, 0x1, 0x7B, 0x1F1C72, 0x744 }, + [OLYMPUS_LUT_CHAN_558000_IDX] = { 22320, 0x1, 0x7C, 0x0, 0x744 }, + [OLYMPUS_LUT_CHAN_558125_IDX] = { 22325, 0x1, 0x7C, 0xE38E, 0x744 }, + [OLYMPUS_LUT_CHAN_558250_IDX] = { 22330, 0x1, 0x7C, 0x1C71C, 0x745 }, + [OLYMPUS_LUT_CHAN_558375_IDX] = { 22335, 0x1, 0x7C, 0x2AAAB, 0x745 }, + [OLYMPUS_LUT_CHAN_558500_IDX] = { 22340, 0x1, 0x7C, 0x38E39, 0x746 }, + [OLYMPUS_LUT_CHAN_558625_IDX] = { 22345, 0x1, 0x7C, 0x471C7, 0x746 }, + [OLYMPUS_LUT_CHAN_558750_IDX] = { 22350, 0x1, 0x7C, 0x55555, 0x747 }, + [OLYMPUS_LUT_CHAN_558875_IDX] = { 22355, 0x1, 0x7C, 0x638E4, 0x747 }, + [OLYMPUS_LUT_CHAN_559000_IDX] = { 22360, 0x1, 0x7C, 0x71C72, 0x747 }, + [OLYMPUS_LUT_CHAN_559125_IDX] = { 22365, 0x1, 0x7C, 0x80000, 0x748 }, + [OLYMPUS_LUT_CHAN_559250_IDX] = { 22370, 0x1, 0x7C, 0x8E38E, 0x748 }, + [OLYMPUS_LUT_CHAN_559375_IDX] = { 22375, 0x1, 0x7C, 0x9C71C, 0x749 }, + [OLYMPUS_LUT_CHAN_559500_IDX] = { 22380, 0x1, 0x7C, 0xAAAAB, 0x749 }, + [OLYMPUS_LUT_CHAN_559625_IDX] = { 22385, 0x1, 0x7C, 0xB8E39, 0x749 }, + [OLYMPUS_LUT_CHAN_559750_IDX] = { 22390, 0x1, 0x7C, 0xC71C7, 0x74A }, + [OLYMPUS_LUT_CHAN_559875_IDX] = { 22395, 0x1, 0x7C, 0xD5555, 0x74A }, + [OLYMPUS_LUT_CHAN_560000_IDX] = { 22400, 0x1, 0x7C, 0xE38E4, 0x74B }, + [OLYMPUS_LUT_CHAN_560125_IDX] = { 22405, 0x1, 0x7C, 0xF1C72, 0x74B }, + [OLYMPUS_LUT_CHAN_560250_IDX] = { 22410, 0x1, 0x7C, 0x100000, 0x74C }, + [OLYMPUS_LUT_CHAN_560375_IDX] = { 22415, 0x1, 0x7C, 0x10E38E, 0x74C }, + [OLYMPUS_LUT_CHAN_560500_IDX] = { 22420, 0x1, 0x7C, 0x11C71C, 0x74C }, + [OLYMPUS_LUT_CHAN_560625_IDX] = { 22425, 0x1, 0x7C, 0x12AAAB, 0x74D }, + [OLYMPUS_LUT_CHAN_560750_IDX] = { 22430, 0x1, 0x7C, 0x138E39, 0x74D }, + [OLYMPUS_LUT_CHAN_560875_IDX] = { 22435, 0x1, 0x7C, 0x1471C7, 0x74E }, + [OLYMPUS_LUT_CHAN_561000_IDX] = { 22440, 0x1, 0x7C, 0x155555, 0x74E }, + [OLYMPUS_LUT_CHAN_561125_IDX] = { 22445, 0x1, 0x7C, 0x1638E4, 0x74E }, + [OLYMPUS_LUT_CHAN_561250_IDX] = { 22450, 0x1, 0x7C, 0x171C72, 0x74F }, + [OLYMPUS_LUT_CHAN_561375_IDX] = { 22455, 0x1, 0x7C, 0x180000, 0x74F }, + [OLYMPUS_LUT_CHAN_561500_IDX] = { 22460, 0x1, 0x7C, 0x18E38E, 0x750 }, + [OLYMPUS_LUT_CHAN_561625_IDX] = { 22465, 0x1, 0x7C, 0x19C71C, 0x750 }, + [OLYMPUS_LUT_CHAN_561750_IDX] = { 22470, 0x1, 0x7C, 0x1AAAAB, 0x751 }, + [OLYMPUS_LUT_CHAN_561875_IDX] = { 22475, 0x1, 0x7C, 0x1B8E39, 0x751 }, + [OLYMPUS_LUT_CHAN_562000_IDX] = { 22480, 0x1, 0x7C, 0x1C71C7, 0x751 }, + [OLYMPUS_LUT_CHAN_562125_IDX] = { 22485, 0x1, 0x7C, 0x1D5555, 0x752 }, + [OLYMPUS_LUT_CHAN_562250_IDX] = { 22490, 0x1, 0x7C, 0x1E38E4, 0x752 }, + [OLYMPUS_LUT_CHAN_562375_IDX] = { 22495, 0x1, 0x7C, 0x1F1C72, 0x753 }, + [OLYMPUS_LUT_CHAN_562500_IDX] = { 22500, 0x1, 0x7D, 0x0, 0x753 }, + [OLYMPUS_LUT_CHAN_562625_IDX] = { 22505, 0x1, 0x7D, 0xE38E, 0x753 }, + [OLYMPUS_LUT_CHAN_562750_IDX] = { 22510, 0x1, 0x7D, 0x1C71C, 0x754 }, + [OLYMPUS_LUT_CHAN_562875_IDX] = { 22515, 0x1, 0x7D, 0x2AAAB, 0x754 }, + [OLYMPUS_LUT_CHAN_563000_IDX] = { 22520, 0x1, 0x7D, 0x38E39, 0x755 }, + [OLYMPUS_LUT_CHAN_563125_IDX] = { 22525, 0x1, 0x7D, 0x471C7, 0x755 }, + [OLYMPUS_LUT_CHAN_563250_IDX] = { 22530, 0x1, 0x7D, 0x55555, 0x756 }, + [OLYMPUS_LUT_CHAN_563375_IDX] = { 22535, 0x1, 0x7D, 0x638E4, 0x756 }, + [OLYMPUS_LUT_CHAN_563500_IDX] = { 22540, 0x1, 0x7D, 0x71C72, 0x756 }, + [OLYMPUS_LUT_CHAN_563625_IDX] = { 22545, 0x1, 0x7D, 0x80000, 0x757 }, + [OLYMPUS_LUT_CHAN_563750_IDX] = { 22550, 0x1, 0x7D, 0x8E38E, 0x757 }, + [OLYMPUS_LUT_CHAN_563875_IDX] = { 22555, 0x1, 0x7D, 0x9C71C, 0x758 }, + [OLYMPUS_LUT_CHAN_564000_IDX] = { 22560, 0x1, 0x7D, 0xAAAAB, 0x758 }, + [OLYMPUS_LUT_CHAN_564125_IDX] = { 22565, 0x1, 0x7D, 0xB8E39, 0x758 }, + [OLYMPUS_LUT_CHAN_564250_IDX] = { 22570, 0x1, 0x7D, 0xC71C7, 0x759 }, + [OLYMPUS_LUT_CHAN_564375_IDX] = { 22575, 0x1, 0x7D, 0xD5555, 0x759 }, + [OLYMPUS_LUT_CHAN_564500_IDX] = { 22580, 0x1, 0x7D, 0xE38E4, 0x75A }, + [OLYMPUS_LUT_CHAN_564625_IDX] = { 22585, 0x1, 0x7D, 0xF1C72, 0x75A }, + [OLYMPUS_LUT_CHAN_564750_IDX] = { 22590, 0x1, 0x7D, 0x100000, 0x75B }, + [OLYMPUS_LUT_CHAN_564875_IDX] = { 22595, 0x1, 0x7D, 0x10E38E, 0x75B }, + [OLYMPUS_LUT_CHAN_565000_IDX] = { 22600, 0x1, 0x7D, 0x11C71C, 0x75B }, + [OLYMPUS_LUT_CHAN_565125_IDX] = { 22605, 0x1, 0x7D, 0x12AAAB, 0x75C }, + [OLYMPUS_LUT_CHAN_565250_IDX] = { 22610, 0x1, 0x7D, 0x138E39, 0x75C }, + [OLYMPUS_LUT_CHAN_565375_IDX] = { 22615, 0x1, 0x7D, 0x1471C7, 0x75D }, + [OLYMPUS_LUT_CHAN_565500_IDX] = { 22620, 0x1, 0x7D, 0x155555, 0x75D }, + [OLYMPUS_LUT_CHAN_565625_IDX] = { 22625, 0x1, 0x7D, 0x1638E4, 0x75D }, + [OLYMPUS_LUT_CHAN_565750_IDX] = { 22630, 0x1, 0x7D, 0x171C72, 0x75E }, + [OLYMPUS_LUT_CHAN_565875_IDX] = { 22635, 0x1, 0x7D, 0x180000, 0x75E }, + [OLYMPUS_LUT_CHAN_566000_IDX] = { 22640, 0x1, 0x7D, 0x18E38E, 0x75F }, + [OLYMPUS_LUT_CHAN_566125_IDX] = { 22645, 0x1, 0x7D, 0x19C71C, 0x75F }, + [OLYMPUS_LUT_CHAN_566250_IDX] = { 22650, 0x1, 0x7D, 0x1AAAAB, 0x760 }, + [OLYMPUS_LUT_CHAN_566375_IDX] = { 22655, 0x1, 0x7D, 0x1B8E39, 0x760 }, + [OLYMPUS_LUT_CHAN_566500_IDX] = { 22660, 0x1, 0x7D, 0x1C71C7, 0x760 }, + [OLYMPUS_LUT_CHAN_566625_IDX] = { 22665, 0x1, 0x7D, 0x1D5555, 0x761 }, + [OLYMPUS_LUT_CHAN_566750_IDX] = { 22670, 0x1, 0x7D, 0x1E38E4, 0x761 }, + [OLYMPUS_LUT_CHAN_566875_IDX] = { 22675, 0x1, 0x7D, 0x1F1C72, 0x762 }, + [OLYMPUS_LUT_CHAN_567000_IDX] = { 22680, 0x1, 0x7E, 0x0, 0x762 }, + [OLYMPUS_LUT_CHAN_567125_IDX] = { 22685, 0x1, 0x7E, 0xE38E, 0x762 }, + [OLYMPUS_LUT_CHAN_567250_IDX] = { 22690, 0x1, 0x7E, 0x1C71C, 0x763 }, + [OLYMPUS_LUT_CHAN_567375_IDX] = { 22695, 0x1, 0x7E, 0x2AAAB, 0x763 }, + [OLYMPUS_LUT_CHAN_567500_IDX] = { 22700, 0x1, 0x7E, 0x38E39, 0x764 }, + [OLYMPUS_LUT_CHAN_567625_IDX] = { 22705, 0x1, 0x7E, 0x471C7, 0x764 }, + [OLYMPUS_LUT_CHAN_567750_IDX] = { 22710, 0x1, 0x7E, 0x55555, 0x765 }, + [OLYMPUS_LUT_CHAN_567875_IDX] = { 22715, 0x1, 0x7E, 0x638E4, 0x765 }, + [OLYMPUS_LUT_CHAN_568000_IDX] = { 22720, 0x1, 0x7E, 0x71C72, 0x765 }, + [OLYMPUS_LUT_CHAN_568125_IDX] = { 22725, 0x1, 0x7E, 0x80000, 0x766 }, + [OLYMPUS_LUT_CHAN_568250_IDX] = { 22730, 0x1, 0x7E, 0x8E38E, 0x766 }, + [OLYMPUS_LUT_CHAN_568375_IDX] = { 22735, 0x1, 0x7E, 0x9C71C, 0x767 }, + [OLYMPUS_LUT_CHAN_568500_IDX] = { 22740, 0x1, 0x7E, 0xAAAAB, 0x767 }, + [OLYMPUS_LUT_CHAN_568625_IDX] = { 22745, 0x1, 0x7E, 0xB8E39, 0x767 }, + [OLYMPUS_LUT_CHAN_568750_IDX] = { 22750, 0x1, 0x7E, 0xC71C7, 0x768 }, + [OLYMPUS_LUT_CHAN_568875_IDX] = { 22755, 0x1, 0x7E, 0xD5555, 0x768 }, + [OLYMPUS_LUT_CHAN_569000_IDX] = { 22760, 0x1, 0x7E, 0xE38E4, 0x769 }, + [OLYMPUS_LUT_CHAN_569125_IDX] = { 22765, 0x1, 0x7E, 0xF1C72, 0x769 }, + [OLYMPUS_LUT_CHAN_569250_IDX] = { 22770, 0x1, 0x7E, 0x100000, 0x76A }, + [OLYMPUS_LUT_CHAN_569375_IDX] = { 22775, 0x1, 0x7E, 0x10E38E, 0x76A }, + [OLYMPUS_LUT_CHAN_569500_IDX] = { 22780, 0x1, 0x7E, 0x11C71C, 0x76A }, + [OLYMPUS_LUT_CHAN_569625_IDX] = { 22785, 0x1, 0x7E, 0x12AAAB, 0x76B }, + [OLYMPUS_LUT_CHAN_569750_IDX] = { 22790, 0x1, 0x7E, 0x138E39, 0x76B }, + [OLYMPUS_LUT_CHAN_569875_IDX] = { 22795, 0x1, 0x7E, 0x1471C7, 0x76C }, + [OLYMPUS_LUT_CHAN_570000_IDX] = { 22800, 0x1, 0x7E, 0x155555, 0x76C }, + [OLYMPUS_LUT_CHAN_570125_IDX] = { 22805, 0x1, 0x7E, 0x1638E4, 0x76C }, + [OLYMPUS_LUT_CHAN_570250_IDX] = { 22810, 0x1, 0x7E, 0x171C72, 0x76D }, + [OLYMPUS_LUT_CHAN_570375_IDX] = { 22815, 0x1, 0x7E, 0x180000, 0x76D }, + [OLYMPUS_LUT_CHAN_570500_IDX] = { 22820, 0x1, 0x7E, 0x18E38E, 0x76E }, + [OLYMPUS_LUT_CHAN_570625_IDX] = { 22825, 0x1, 0x7E, 0x19C71C, 0x76E }, + [OLYMPUS_LUT_CHAN_570750_IDX] = { 22830, 0x1, 0x7E, 0x1AAAAB, 0x76F }, + [OLYMPUS_LUT_CHAN_570875_IDX] = { 22835, 0x1, 0x7E, 0x1B8E39, 0x76F }, + [OLYMPUS_LUT_CHAN_571000_IDX] = { 22840, 0x1, 0x7E, 0x1C71C7, 0x76F }, + [OLYMPUS_LUT_CHAN_571125_IDX] = { 22845, 0x1, 0x7E, 0x1D5555, 0x770 }, + [OLYMPUS_LUT_CHAN_571250_IDX] = { 22850, 0x1, 0x7E, 0x1E38E4, 0x770 }, + [OLYMPUS_LUT_CHAN_571375_IDX] = { 22855, 0x1, 0x7E, 0x1F1C72, 0x771 }, + [OLYMPUS_LUT_CHAN_571500_IDX] = { 22860, 0x1, 0x7F, 0x0, 0x771 }, + [OLYMPUS_LUT_CHAN_571625_IDX] = { 22865, 0x1, 0x7F, 0xE38E, 0x771 }, + [OLYMPUS_LUT_CHAN_571750_IDX] = { 22870, 0x1, 0x7F, 0x1C71C, 0x772 }, + [OLYMPUS_LUT_CHAN_571875_IDX] = { 22875, 0x1, 0x7F, 0x2AAAB, 0x772 }, + [OLYMPUS_LUT_CHAN_572000_IDX] = { 22880, 0x1, 0x7F, 0x38E39, 0x773 }, + [OLYMPUS_LUT_CHAN_572125_IDX] = { 22885, 0x1, 0x7F, 0x471C7, 0x773 }, + [OLYMPUS_LUT_CHAN_572250_IDX] = { 22890, 0x1, 0x7F, 0x55555, 0x774 }, + [OLYMPUS_LUT_CHAN_572375_IDX] = { 22895, 0x1, 0x7F, 0x638E4, 0x774 }, + [OLYMPUS_LUT_CHAN_572500_IDX] = { 22900, 0x1, 0x7F, 0x71C72, 0x774 }, + [OLYMPUS_LUT_CHAN_572625_IDX] = { 22905, 0x1, 0x7F, 0x80000, 0x775 }, + [OLYMPUS_LUT_CHAN_572750_IDX] = { 22910, 0x1, 0x7F, 0x8E38E, 0x775 }, + [OLYMPUS_LUT_CHAN_572875_IDX] = { 22915, 0x1, 0x7F, 0x9C71C, 0x776 }, + [OLYMPUS_LUT_CHAN_573000_IDX] = { 22920, 0x1, 0x7F, 0xAAAAB, 0x776 }, + [OLYMPUS_LUT_CHAN_573125_IDX] = { 22925, 0x1, 0x7F, 0xB8E39, 0x776 }, + [OLYMPUS_LUT_CHAN_573250_IDX] = { 22930, 0x1, 0x7F, 0xC71C7, 0x777 }, + [OLYMPUS_LUT_CHAN_573375_IDX] = { 22935, 0x1, 0x7F, 0xD5555, 0x777 }, + [OLYMPUS_LUT_CHAN_573500_IDX] = { 22940, 0x1, 0x7F, 0xE38E4, 0x778 }, + [OLYMPUS_LUT_CHAN_573625_IDX] = { 22945, 0x1, 0x7F, 0xF1C72, 0x778 }, + [OLYMPUS_LUT_CHAN_573750_IDX] = { 22950, 0x1, 0x7F, 0x100000, 0x779 }, + [OLYMPUS_LUT_CHAN_573875_IDX] = { 22955, 0x1, 0x7F, 0x10E38E, 0x779 }, + [OLYMPUS_LUT_CHAN_574000_IDX] = { 22960, 0x1, 0x7F, 0x11C71C, 0x779 }, + [OLYMPUS_LUT_CHAN_574125_IDX] = { 22965, 0x1, 0x7F, 0x12AAAB, 0x77A }, + [OLYMPUS_LUT_CHAN_574250_IDX] = { 22970, 0x1, 0x7F, 0x138E39, 0x77A }, + [OLYMPUS_LUT_CHAN_574375_IDX] = { 22975, 0x1, 0x7F, 0x1471C7, 0x77B }, + [OLYMPUS_LUT_CHAN_574500_IDX] = { 22980, 0x1, 0x7F, 0x155555, 0x77B }, + [OLYMPUS_LUT_CHAN_574625_IDX] = { 22985, 0x1, 0x7F, 0x1638E4, 0x77B }, + [OLYMPUS_LUT_CHAN_574750_IDX] = { 22990, 0x1, 0x7F, 0x171C72, 0x77C }, + [OLYMPUS_LUT_CHAN_574875_IDX] = { 22995, 0x1, 0x7F, 0x180000, 0x77C }, + [OLYMPUS_LUT_CHAN_575000_IDX] = { 23000, 0x1, 0x7F, 0x18E38E, 0x77D }, + [OLYMPUS_LUT_CHAN_575125_IDX] = { 23005, 0x1, 0x7F, 0x19C71C, 0x77D }, + [OLYMPUS_LUT_CHAN_575250_IDX] = { 23010, 0x1, 0x7F, 0x1AAAAB, 0x77E }, + [OLYMPUS_LUT_CHAN_575375_IDX] = { 23015, 0x1, 0x7F, 0x1B8E39, 0x77E }, + [OLYMPUS_LUT_CHAN_575500_IDX] = { 23020, 0x1, 0x7F, 0x1C71C7, 0x77E }, + [OLYMPUS_LUT_CHAN_575625_IDX] = { 23025, 0x1, 0x7F, 0x1D5555, 0x77F }, + [OLYMPUS_LUT_CHAN_575750_IDX] = { 23030, 0x1, 0x7F, 0x1E38E4, 0x77F }, + [OLYMPUS_LUT_CHAN_575875_IDX] = { 23035, 0x1, 0x7F, 0x1F1C72, 0x780 }, + [OLYMPUS_LUT_CHAN_576000_IDX] = { 23040, 0x1, 0x80, 0x0, 0x780 }, + [OLYMPUS_LUT_CHAN_576125_IDX] = { 23045, 0x1, 0x80, 0xE38E, 0x780 }, + [OLYMPUS_LUT_CHAN_576250_IDX] = { 23050, 0x1, 0x80, 0x1C71C, 0x781 }, + [OLYMPUS_LUT_CHAN_576375_IDX] = { 23055, 0x1, 0x80, 0x2AAAB, 0x781 }, + [OLYMPUS_LUT_CHAN_576500_IDX] = { 23060, 0x1, 0x80, 0x38E39, 0x782 }, + [OLYMPUS_LUT_CHAN_576625_IDX] = { 23065, 0x1, 0x80, 0x471C7, 0x782 }, + [OLYMPUS_LUT_CHAN_576750_IDX] = { 23070, 0x1, 0x80, 0x55555, 0x783 }, + [OLYMPUS_LUT_CHAN_576875_IDX] = { 23075, 0x1, 0x80, 0x638E4, 0x783 }, + [OLYMPUS_LUT_CHAN_577000_IDX] = { 23080, 0x1, 0x80, 0x71C72, 0x783 }, + [OLYMPUS_LUT_CHAN_577125_IDX] = { 23085, 0x1, 0x80, 0x80000, 0x784 }, + [OLYMPUS_LUT_CHAN_577250_IDX] = { 23090, 0x1, 0x80, 0x8E38E, 0x784 }, + [OLYMPUS_LUT_CHAN_577375_IDX] = { 23095, 0x1, 0x80, 0x9C71C, 0x785 }, + [OLYMPUS_LUT_CHAN_577500_IDX] = { 23100, 0x1, 0x80, 0xAAAAB, 0x785 }, + [OLYMPUS_LUT_CHAN_577625_IDX] = { 23105, 0x1, 0x80, 0xB8E39, 0x785 }, + [OLYMPUS_LUT_CHAN_577750_IDX] = { 23110, 0x1, 0x80, 0xC71C7, 0x786 }, + [OLYMPUS_LUT_CHAN_577875_IDX] = { 23115, 0x1, 0x80, 0xD5555, 0x786 }, + [OLYMPUS_LUT_CHAN_578000_IDX] = { 23120, 0x1, 0x80, 0xE38E4, 0x787 }, + [OLYMPUS_LUT_CHAN_578125_IDX] = { 23125, 0x1, 0x80, 0xF1C72, 0x787 }, + [OLYMPUS_LUT_CHAN_578250_IDX] = { 23130, 0x1, 0x80, 0x100000, 0x788 }, + [OLYMPUS_LUT_CHAN_578375_IDX] = { 23135, 0x1, 0x80, 0x10E38E, 0x788 }, + [OLYMPUS_LUT_CHAN_578500_IDX] = { 23140, 0x1, 0x80, 0x11C71C, 0x788 }, + [OLYMPUS_LUT_CHAN_578625_IDX] = { 23145, 0x1, 0x80, 0x12AAAB, 0x789 }, + [OLYMPUS_LUT_CHAN_578750_IDX] = { 23150, 0x1, 0x80, 0x138E39, 0x789 }, + [OLYMPUS_LUT_CHAN_578875_IDX] = { 23155, 0x1, 0x80, 0x1471C7, 0x78A }, + [OLYMPUS_LUT_CHAN_579000_IDX] = { 23160, 0x1, 0x80, 0x155555, 0x78A }, + [OLYMPUS_LUT_CHAN_579125_IDX] = { 23165, 0x1, 0x80, 0x1638E4, 0x78A }, + [OLYMPUS_LUT_CHAN_579250_IDX] = { 23170, 0x1, 0x80, 0x171C72, 0x78B }, + [OLYMPUS_LUT_CHAN_579375_IDX] = { 23175, 0x1, 0x80, 0x180000, 0x78B }, + [OLYMPUS_LUT_CHAN_579500_IDX] = { 23180, 0x1, 0x80, 0x18E38E, 0x78C }, + [OLYMPUS_LUT_CHAN_579625_IDX] = { 23185, 0x1, 0x80, 0x19C71C, 0x78C }, + [OLYMPUS_LUT_CHAN_579750_IDX] = { 23190, 0x1, 0x80, 0x1AAAAB, 0x78D }, + [OLYMPUS_LUT_CHAN_579875_IDX] = { 23195, 0x1, 0x80, 0x1B8E39, 0x78D }, + [OLYMPUS_LUT_CHAN_580000_IDX] = { 23200, 0x1, 0x80, 0x1C71C7, 0x78D }, + [OLYMPUS_LUT_CHAN_580125_IDX] = { 23205, 0x1, 0x80, 0x1D5555, 0x78E }, + [OLYMPUS_LUT_CHAN_580250_IDX] = { 23210, 0x1, 0x80, 0x1E38E4, 0x78E }, + [OLYMPUS_LUT_CHAN_580375_IDX] = { 23215, 0x1, 0x80, 0x1F1C72, 0x78F }, + [OLYMPUS_LUT_CHAN_580500_IDX] = { 23220, 0x1, 0x81, 0x0, 0x78F }, + [OLYMPUS_LUT_CHAN_580625_IDX] = { 23225, 0x1, 0x81, 0xE38E, 0x78F }, + [OLYMPUS_LUT_CHAN_580750_IDX] = { 23230, 0x1, 0x81, 0x1C71C, 0x790 }, + [OLYMPUS_LUT_CHAN_580875_IDX] = { 23235, 0x1, 0x81, 0x2AAAB, 0x790 }, + [OLYMPUS_LUT_CHAN_581000_IDX] = { 23240, 0x1, 0x81, 0x38E39, 0x791 }, + [OLYMPUS_LUT_CHAN_581125_IDX] = { 23245, 0x1, 0x81, 0x471C7, 0x791 }, + [OLYMPUS_LUT_CHAN_581250_IDX] = { 23250, 0x1, 0x81, 0x55555, 0x792 }, + [OLYMPUS_LUT_CHAN_581375_IDX] = { 23255, 0x1, 0x81, 0x638E4, 0x792 }, + [OLYMPUS_LUT_CHAN_581500_IDX] = { 23260, 0x1, 0x81, 0x71C72, 0x792 }, + [OLYMPUS_LUT_CHAN_581625_IDX] = { 23265, 0x1, 0x81, 0x80000, 0x793 }, + [OLYMPUS_LUT_CHAN_581750_IDX] = { 23270, 0x1, 0x81, 0x8E38E, 0x793 }, + [OLYMPUS_LUT_CHAN_581875_IDX] = { 23275, 0x1, 0x81, 0x9C71C, 0x794 }, + [OLYMPUS_LUT_CHAN_582000_IDX] = { 23280, 0x1, 0x81, 0xAAAAB, 0x794 }, + [OLYMPUS_LUT_CHAN_582125_IDX] = { 23285, 0x1, 0x81, 0xB8E39, 0x794 }, + [OLYMPUS_LUT_CHAN_582250_IDX] = { 23290, 0x1, 0x81, 0xC71C7, 0x795 }, + [OLYMPUS_LUT_CHAN_582375_IDX] = { 23295, 0x1, 0x81, 0xD5555, 0x795 }, + [OLYMPUS_LUT_CHAN_582500_IDX] = { 23300, 0x1, 0x81, 0xE38E4, 0x796 }, + [OLYMPUS_LUT_CHAN_582625_IDX] = { 23305, 0x1, 0x81, 0xF1C72, 0x796 }, + [OLYMPUS_LUT_CHAN_582750_IDX] = { 23310, 0x1, 0x81, 0x100000, 0x797 }, + [OLYMPUS_LUT_CHAN_582875_IDX] = { 23315, 0x1, 0x81, 0x10E38E, 0x797 }, + [OLYMPUS_LUT_CHAN_583000_IDX] = { 23320, 0x1, 0x81, 0x11C71C, 0x797 }, + [OLYMPUS_LUT_CHAN_583125_IDX] = { 23325, 0x1, 0x81, 0x12AAAB, 0x798 }, + [OLYMPUS_LUT_CHAN_583250_IDX] = { 23330, 0x1, 0x81, 0x138E39, 0x798 }, + [OLYMPUS_LUT_CHAN_583375_IDX] = { 23335, 0x1, 0x81, 0x1471C7, 0x799 }, + [OLYMPUS_LUT_CHAN_583500_IDX] = { 23340, 0x1, 0x81, 0x155555, 0x799 }, + [OLYMPUS_LUT_CHAN_583625_IDX] = { 23345, 0x1, 0x81, 0x1638E4, 0x799 }, + [OLYMPUS_LUT_CHAN_583750_IDX] = { 23350, 0x1, 0x81, 0x171C72, 0x79A }, + [OLYMPUS_LUT_CHAN_583875_IDX] = { 23355, 0x1, 0x81, 0x180000, 0x79A }, + [OLYMPUS_LUT_CHAN_584000_IDX] = { 23360, 0x1, 0x81, 0x18E38E, 0x79B }, + [OLYMPUS_LUT_CHAN_584125_IDX] = { 23365, 0x1, 0x81, 0x19C71C, 0x79B }, + [OLYMPUS_LUT_CHAN_584250_IDX] = { 23370, 0x1, 0x81, 0x1AAAAB, 0x79C }, + [OLYMPUS_LUT_CHAN_584375_IDX] = { 23375, 0x1, 0x81, 0x1B8E39, 0x79C }, + [OLYMPUS_LUT_CHAN_584500_IDX] = { 23380, 0x1, 0x81, 0x1C71C7, 0x79C }, + [OLYMPUS_LUT_CHAN_584625_IDX] = { 23385, 0x1, 0x81, 0x1D5555, 0x79D }, + [OLYMPUS_LUT_CHAN_584750_IDX] = { 23390, 0x1, 0x81, 0x1E38E4, 0x79D }, + [OLYMPUS_LUT_CHAN_584875_IDX] = { 23395, 0x1, 0x81, 0x1F1C72, 0x79E }, + [OLYMPUS_LUT_CHAN_585000_IDX] = { 23400, 0x1, 0x82, 0x0, 0x79E }, + [OLYMPUS_LUT_CHAN_585125_IDX] = { 23405, 0x1, 0x82, 0xE38E, 0x79E }, + [OLYMPUS_LUT_CHAN_585250_IDX] = { 23410, 0x1, 0x82, 0x1C71C, 0x79F }, + [OLYMPUS_LUT_CHAN_585375_IDX] = { 23415, 0x1, 0x82, 0x2AAAB, 0x79F }, + [OLYMPUS_LUT_CHAN_585500_IDX] = { 23420, 0x1, 0x82, 0x38E39, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585625_IDX] = { 23425, 0x1, 0x82, 0x471C7, 0x7A0 }, + [OLYMPUS_LUT_CHAN_585750_IDX] = { 23430, 0x1, 0x82, 0x55555, 0x7A1 }, + [OLYMPUS_LUT_CHAN_585875_IDX] = { 23435, 0x1, 0x82, 0x638E4, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586000_IDX] = { 23440, 0x1, 0x82, 0x71C72, 0x7A1 }, + [OLYMPUS_LUT_CHAN_586125_IDX] = { 23445, 0x1, 0x82, 0x80000, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586250_IDX] = { 23450, 0x1, 0x82, 0x8E38E, 0x7A2 }, + [OLYMPUS_LUT_CHAN_586375_IDX] = { 23455, 0x1, 0x82, 0x9C71C, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586500_IDX] = { 23460, 0x1, 0x82, 0xAAAAB, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586625_IDX] = { 23465, 0x1, 0x82, 0xB8E39, 0x7A3 }, + [OLYMPUS_LUT_CHAN_586750_IDX] = { 23470, 0x1, 0x82, 0xC71C7, 0x7A4 }, + [OLYMPUS_LUT_CHAN_586875_IDX] = { 23475, 0x1, 0x82, 0xD5555, 0x7A4 }, + [OLYMPUS_LUT_CHAN_587000_IDX] = { 23480, 0x1, 0x82, 0xE38E4, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587125_IDX] = { 23485, 0x1, 0x82, 0xF1C72, 0x7A5 }, + [OLYMPUS_LUT_CHAN_587250_IDX] = { 23490, 0x1, 0x82, 0x100000, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587375_IDX] = { 23495, 0x1, 0x82, 0x10E38E, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587500_IDX] = { 23500, 0x1, 0x82, 0x11C71C, 0x7A6 }, + [OLYMPUS_LUT_CHAN_587625_IDX] = { 23505, 0x1, 0x82, 0x12AAAB, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587750_IDX] = { 23510, 0x1, 0x82, 0x138E39, 0x7A7 }, + [OLYMPUS_LUT_CHAN_587875_IDX] = { 23515, 0x1, 0x82, 0x1471C7, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588000_IDX] = { 23520, 0x1, 0x82, 0x155555, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588125_IDX] = { 23525, 0x1, 0x82, 0x1638E4, 0x7A8 }, + [OLYMPUS_LUT_CHAN_588250_IDX] = { 23530, 0x1, 0x82, 0x171C72, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588375_IDX] = { 23535, 0x1, 0x82, 0x180000, 0x7A9 }, + [OLYMPUS_LUT_CHAN_588500_IDX] = { 23540, 0x1, 0x82, 0x18E38E, 0x7AA }, + [OLYMPUS_LUT_CHAN_588625_IDX] = { 23545, 0x1, 0x82, 0x19C71C, 0x7AA }, + [OLYMPUS_LUT_CHAN_588750_IDX] = { 23550, 0x1, 0x82, 0x1AAAAB, 0x7AB }, + [OLYMPUS_LUT_CHAN_588875_IDX] = { 23555, 0x1, 0x82, 0x1B8E39, 0x7AB }, + [OLYMPUS_LUT_CHAN_589000_IDX] = { 23560, 0x1, 0x82, 0x1C71C7, 0x7AB }, + [OLYMPUS_LUT_CHAN_589125_IDX] = { 23565, 0x1, 0x82, 0x1D5555, 0x7AC }, + [OLYMPUS_LUT_CHAN_589250_IDX] = { 23570, 0x1, 0x82, 0x1E38E4, 0x7AC }, + [OLYMPUS_LUT_CHAN_589375_IDX] = { 23575, 0x1, 0x82, 0x1F1C72, 0x7AD }, + [OLYMPUS_LUT_CHAN_589500_IDX] = { 23580, 0x1, 0x83, 0x0, 0x7AD }, + [OLYMPUS_LUT_CHAN_589625_IDX] = { 23585, 0x1, 0x83, 0xE38E, 0x7AD }, + [OLYMPUS_LUT_CHAN_589750_IDX] = { 23590, 0x1, 0x83, 0x1C71C, 0x7AE }, + [OLYMPUS_LUT_CHAN_589875_IDX] = { 23595, 0x1, 0x83, 0x2AAAB, 0x7AE }, + [OLYMPUS_LUT_CHAN_590000_IDX] = { 23600, 0x1, 0x83, 0x38E39, 0x7AF }, + [OLYMPUS_LUT_CHAN_590125_IDX] = { 23605, 0x1, 0x83, 0x471C7, 0x7AF }, + [OLYMPUS_LUT_CHAN_590250_IDX] = { 23610, 0x1, 0x83, 0x55555, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590375_IDX] = { 23615, 0x1, 0x83, 0x638E4, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590500_IDX] = { 23620, 0x1, 0x83, 0x71C72, 0x7B0 }, + [OLYMPUS_LUT_CHAN_590625_IDX] = { 23625, 0x1, 0x83, 0x80000, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590750_IDX] = { 23630, 0x1, 0x83, 0x8E38E, 0x7B1 }, + [OLYMPUS_LUT_CHAN_590875_IDX] = { 23635, 0x1, 0x83, 0x9C71C, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591000_IDX] = { 23640, 0x1, 0x83, 0xAAAAB, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591125_IDX] = { 23645, 0x1, 0x83, 0xB8E39, 0x7B2 }, + [OLYMPUS_LUT_CHAN_591250_IDX] = { 23650, 0x1, 0x83, 0xC71C7, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591375_IDX] = { 23655, 0x1, 0x83, 0xD5555, 0x7B3 }, + [OLYMPUS_LUT_CHAN_591500_IDX] = { 23660, 0x1, 0x83, 0xE38E4, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591625_IDX] = { 23665, 0x1, 0x83, 0xF1C72, 0x7B4 }, + [OLYMPUS_LUT_CHAN_591750_IDX] = { 23670, 0x1, 0x83, 0x100000, 0x7B5 }, + [OLYMPUS_LUT_CHAN_591875_IDX] = { 23675, 0x1, 0x83, 0x10E38E, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592000_IDX] = { 23680, 0x1, 0x83, 0x11C71C, 0x7B5 }, + [OLYMPUS_LUT_CHAN_592125_IDX] = { 23685, 0x1, 0x83, 0x12AAAB, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592250_IDX] = { 23690, 0x1, 0x83, 0x138E39, 0x7B6 }, + [OLYMPUS_LUT_CHAN_592375_IDX] = { 23695, 0x1, 0x83, 0x1471C7, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592500_IDX] = { 23700, 0x1, 0x83, 0x155555, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592625_IDX] = { 23705, 0x1, 0x83, 0x1638E4, 0x7B7 }, + [OLYMPUS_LUT_CHAN_592750_IDX] = { 23710, 0x1, 0x83, 0x171C72, 0x7B8 }, + [OLYMPUS_LUT_CHAN_592875_IDX] = { 23715, 0x1, 0x83, 0x180000, 0x7B8 }, + [OLYMPUS_LUT_CHAN_593000_IDX] = { 23720, 0x1, 0x83, 0x18E38E, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593125_IDX] = { 23725, 0x1, 0x83, 0x19C71C, 0x7B9 }, + [OLYMPUS_LUT_CHAN_593250_IDX] = { 23730, 0x1, 0x83, 0x1AAAAB, 0x7BA }, + [OLYMPUS_LUT_CHAN_593375_IDX] = { 23735, 0x1, 0x83, 0x1B8E39, 0x7BA }, + [OLYMPUS_LUT_CHAN_593500_IDX] = { 23740, 0x1, 0x83, 0x1C71C7, 0x7BA }, + [OLYMPUS_LUT_CHAN_593625_IDX] = { 23745, 0x1, 0x83, 0x1D5555, 0x7BB }, + [OLYMPUS_LUT_CHAN_593750_IDX] = { 23750, 0x1, 0x83, 0x1E38E4, 0x7BB }, + [OLYMPUS_LUT_CHAN_593875_IDX] = { 23755, 0x1, 0x83, 0x1F1C72, 0x7BC }, + [OLYMPUS_LUT_CHAN_594000_IDX] = { 23760, 0x1, 0x84, 0x0, 0x7BC }, + [OLYMPUS_LUT_CHAN_594125_IDX] = { 23765, 0x1, 0x84, 0xE38E, 0x7BC }, + [OLYMPUS_LUT_CHAN_594250_IDX] = { 23770, 0x1, 0x84, 0x1C71C, 0x7BD }, + [OLYMPUS_LUT_CHAN_594375_IDX] = { 23775, 0x1, 0x84, 0x2AAAB, 0x7BD }, + [OLYMPUS_LUT_CHAN_594500_IDX] = { 23780, 0x1, 0x84, 0x38E39, 0x7BE }, + [OLYMPUS_LUT_CHAN_594625_IDX] = { 23785, 0x1, 0x84, 0x471C7, 0x7BE }, + [OLYMPUS_LUT_CHAN_594750_IDX] = { 23790, 0x1, 0x84, 0x55555, 0x7BF }, + [OLYMPUS_LUT_CHAN_594875_IDX] = { 23795, 0x1, 0x84, 0x638E4, 0x7BF }, + [OLYMPUS_LUT_CHAN_595000_IDX] = { 23800, 0x1, 0x84, 0x71C72, 0x7BF } +}; + +static void cl_ceva_disable(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_hw_is_tcv0(cl_hw)) { + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 0); + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 0); + } else { + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 0); + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 0); + } +} + +static void cl_ceva_reset(struct cl_hw *cl_hw) +{ + if (cl_hw_is_tcv0(cl_hw)) + cmu_phy_0_rst_set(cl_hw->chip, CMU_PHY0_RST_EN); + else + cmu_phy_1_rst_set(cl_hw->chip, CMU_PHY1_RST_EN); +} + +static void cl_phy_disable(struct cl_hw *cl_hw) +{ + /* Modem GCU modules - Reset */ + + /* Disable clocks (reset is not asserted) */ + modem_gcu_mpu_set(cl_hw, MODEM_GCU_MPU_RST_N_BIT | MODEM_GCU_MPU_REG_RST_N_BIT); + modem_gcu_bpu_set(cl_hw, MODEM_GCU_BPU_RST_N_BIT | MODEM_GCU_BPU_RX_RST_N_BIT | + MODEM_GCU_BPU_TX_RST_N_BIT | MODEM_GCU_BPU_REG_RST_N_BIT); + modem_gcu_tfu_set(cl_hw, MODEM_GCU_TFU_RST_N_BIT | MODEM_GCU_TFU_REG_RST_N_BIT); + modem_gcu_smu_set(cl_hw, MODEM_GCU_SMU_RST_N_BIT | MODEM_GCU_SMU_REG_RST_N_BIT); + modem_gcu_spu_set(cl_hw, MODEM_GCU_SPU_RST_N_BIT | MODEM_GCU_SPU_REG_RST_N_BIT); + modem_gcu_bf_set(cl_hw, MODEM_GCU_BF_RST_N_BIT | MODEM_GCU_BF_REG_RST_N_BIT); + modem_gcu_epa_set(cl_hw, MODEM_GCU_EPA_RST_N_BIT | MODEM_GCU_EPA_REG_RST_N_BIT); + modem_gcu_lcu_set(cl_hw, MODEM_GCU_LCU_HLF_RST_N_BIT | MODEM_GCU_LCU_RST_N_BIT | + MODEM_GCU_LCU_REG_RST_N_BIT); + modem_gcu_mux_fic_set(cl_hw, MODEM_GCU_MUX_FIC_SOFT_RST_N_BIT | + MODEM_GCU_MUX_FIC_RST_N_BIT); + modem_gcu_riu_clk_set(cl_hw, 0); + modem_gcu_riu_clk_1_set(cl_hw, 0); + + /* Assert reset (clocks already disabled) */ + modem_gcu_mpu_set(cl_hw, 0); + modem_gcu_bpu_set(cl_hw, 0); + modem_gcu_tfu_set(cl_hw, 0); + modem_gcu_smu_set(cl_hw, 0); + modem_gcu_spu_set(cl_hw, 0); + modem_gcu_bf_set(cl_hw, 0); + modem_gcu_epa_set(cl_hw, 0); + modem_gcu_lcu_set(cl_hw, 0); + modem_gcu_mux_fic_set(cl_hw, MODEM_GCU_MUX_FIC_SOFT_RST_N_BIT); + modem_gcu_riu_rst_set(cl_hw, 0); +} + +static void _cl_phy_reset(struct cl_hw *cl_hw) +{ + /* Isolate FIC bus in case CEVA reset is not required */ + modem_gcu_mux_fic_config_fic_isolate_setf(cl_hw, 1); + while (modem_gcu_mux_fic_config_fic_isolated_getf(cl_hw) == 0) + ; + modem_gcu_mux_fic_config_fic_isolate_setf(cl_hw, 0); + + /* + * Stop the LCU recording. + * Stop on one channel actually stops the recording on all channels. + * This stop is required because PHY LCU is going to be reset. + */ + if (cl_hw_is_tcv0(cl_hw)) + lcu_phy_lcu_ch_0_stop_set(cl_hw, 1); + else + lcu_phy_lcu_ch_1_stop_set(cl_hw, 1); + + /* PHY reset sequence */ + cl_phy_disable(cl_hw); +} + +static void _cl_phy0_off(struct cl_chip *chip) +{ + /* Disable APB0 clock but keep other clocks (main clock and DSP0 clock) active */ + cmu_phy_0_clk_en_pack(chip, 1, 0, 1); + /* DSP0, MPIF0, APB0 reset */ + cmu_phy_0_rst_set(chip, CMU_PHY_0_RST_N_BIT); + /* DSP0, MPIF0 are still in reset, but take APB0 out of reset to allow writing to GCU */ + cmu_phy_0_rst_set(chip, CMU_PHY_0_RST_N_BIT | CMU_PHY_0_PRESET_N_BIT); + /* Enable APB0 clock (all other clocks are already active) */ + cmu_phy_0_clk_en_phy_0_apb_clk_en_setf(chip, 1); +} + +static void _cl_phy1_off(struct cl_chip *chip) +{ + /* Disable APB0 clock but keep other clocks (main clock and DSP0 clock) active */ + cmu_phy_1_clk_en_pack(chip, 1, 0, 1); + /* DSP0, MPIF0, APB0 reset */ + cmu_phy_1_rst_set(chip, CMU_PHY_0_RST_N_BIT); + /* DSP0, MPIF0 are still in reset, but take APB0 out of reset to allow writing to GCU */ + cmu_phy_1_rst_set(chip, CMU_PHY_0_RST_N_BIT | CMU_PHY_0_PRESET_N_BIT); + /* Enable APB0 clock (all other clocks are already active) */ + cmu_phy_1_clk_en_phy_1_apb_clk_en_setf(chip, 1); +} + +static void _cl_phy_off(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (cl_hw_is_tcv0(cl_hw)) + _cl_phy0_off(chip); + else + _cl_phy1_off(chip); + + cl_phy_disable(cl_hw); +} + +static void cl_system_ctrl_reg_reset(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + u32 regval = macsys_gcu_xt_control_get(chip); + u8 i; + + /* Set XMAC_RUN_STALL */ + regval |= cl_hw->controller_reg.run_stall; + /* Clear XMAC_OCD_HALT_ON_RESET and clear XMAC_BRESET */ + regval &= ~(cl_hw->controller_reg.ocd_halt_on_reset | cl_hw->controller_reg.breset); + + /* Reset MACHW */ + macsys_gcu_xt_control_set(chip, regval); + + for (i = 0; i < MAX_MU_CNT; i++) + mac_hw_mu_mac_cntrl_2_set(cl_hw, 1, i); +} + +void cl_phy_off(struct cl_hw *cl_hw) +{ + if (!cl_hw) + return; + + cl_system_ctrl_reg_reset(cl_hw); + _cl_phy_off(cl_hw); + cl_ceva_disable(cl_hw); +} + +static void cl_save_ela_state(struct cl_hw *cl_hw) +{ + struct cl_recovery_db *recovery_db = &cl_hw->recovery_db; + + /* Save eLA state before MAC-HW reset */ + recovery_db->ela_en = mac_hw_debug_port_en_get(cl_hw); + + if (recovery_db->ela_en) { + recovery_db->ela_sel_a = mac_hw_debug_port_sel_a_get(cl_hw); + recovery_db->ela_sel_b = mac_hw_debug_port_sel_b_get(cl_hw); + recovery_db->ela_sel_c = mac_hw_debug_port_sel_c_get(cl_hw); + } +} + +void cl_phy_reset(struct cl_hw *cl_hw) +{ + if (!cl_hw) + return; + + cl_save_ela_state(cl_hw); + cl_system_ctrl_reg_reset(cl_hw); + _cl_phy_reset(cl_hw); + cl_ceva_reset(cl_hw); +} + +int cl_phy_load_recovery(struct cl_hw *cl_hw) +{ + int ret = cl_radio_boot_recovery(cl_hw); + + if (ret) { + cl_dbg_err(cl_hw, "cl_radio_boot_recovery failed %d\n", ret); + return ret; + } + + /* Load DSP */ + ret = cl_dsp_load_recovery(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_dsp_load_recovery failed %d\n", ret); + return ret; + } + + /* + * FIXME: It looks like there is a bug in the DSP. If we poll REG_CFG_SPACE + * (0x600018) at this point to verify that DSP has been initialized + * successfully, we read '1' and continue. + * However, the calibration fails. + * + * Please note that this is a WORKAROUND, not a final fix. + * The problem should be investigated + * further by the DSP team. + */ + msleep(500); + return 0; +} + +int cl_phy_data_alloc(struct cl_hw *cl_hw) +{ + struct cl_phy_data *buf = NULL; + u32 len = (u32)PAGE_SIZE; + dma_addr_t phys_dma_addr; + + buf = dma_alloc_coherent(cl_hw->chip->dev, len, &phys_dma_addr, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + cl_hw->phy_data_info.data = buf; + cl_hw->phy_data_info.dma_addr = phys_dma_addr; + + return 0; +} + +void cl_phy_data_free(struct cl_hw *cl_hw) +{ + dma_addr_t phys_dma_addr = cl_hw->phy_data_info.dma_addr; + + if (!cl_hw->phy_data_info.data) + return; + + dma_free_coherent(cl_hw->chip->dev, PAGE_SIZE, + (void *)cl_hw->phy_data_info.data, phys_dma_addr); + cl_hw->phy_data_info.data = NULL; +} + +void cl_phy_enable(struct cl_hw *cl_hw) +{ + /* Modem GCU modules - De-assert Reset */ + if (!cl_hw) + return; + + /* De-assert reset (clocks disabled) */ + modem_gcu_mpu_set(cl_hw, MODEM_GCU_MPU_RST_N_BIT | MODEM_GCU_MPU_REG_RST_N_BIT); + modem_gcu_bpu_set(cl_hw, MODEM_GCU_BPU_RST_N_BIT | MODEM_GCU_BPU_RX_RST_N_BIT | + MODEM_GCU_BPU_TX_RST_N_BIT | MODEM_GCU_BPU_REG_RST_N_BIT); + modem_gcu_tfu_set(cl_hw, MODEM_GCU_TFU_RST_N_BIT | MODEM_GCU_TFU_REG_RST_N_BIT); + modem_gcu_smu_set(cl_hw, MODEM_GCU_SMU_RST_N_BIT | MODEM_GCU_SMU_REG_RST_N_BIT); + modem_gcu_spu_set(cl_hw, MODEM_GCU_SPU_RST_N_BIT | MODEM_GCU_SPU_REG_RST_N_BIT); + modem_gcu_bf_set(cl_hw, MODEM_GCU_BF_RST_N_BIT | MODEM_GCU_BF_REG_RST_N_BIT); + modem_gcu_epa_set(cl_hw, MODEM_GCU_EPA_RST_N_BIT | MODEM_GCU_EPA_REG_RST_N_BIT); + modem_gcu_lcu_set(cl_hw, MODEM_GCU_LCU_HLF_RST_N_BIT | MODEM_GCU_LCU_RST_N_BIT | + MODEM_GCU_LCU_REG_RST_N_BIT); + modem_gcu_mux_fic_set(cl_hw, MODEM_GCU_MUX_FIC_SOFT_RST_N_BIT | + MODEM_GCU_MUX_FIC_RST_N_BIT); + modem_gcu_riu_rst_set(cl_hw, MODEM_GCU_RIU_FE_RST_N_BIT | MODEM_GCU_RIU_AGC_RST_N_BIT | + MODEM_GCU_RIU_MDM_B_RST_N_BIT | MODEM_GCU_RIU_LB_RST_N_BIT | + MODEM_GCU_RIU_RC_RST_N_BIT | MODEM_GCU_RIU_RADAR_RST_N_BIT | + MODEM_GCU_RIU_RST_N_BIT | MODEM_GCU_RIU_REG_RST_N_BIT); + + /* Enable clocks */ + modem_gcu_mpu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_bpu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_tfu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_smu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_spu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_bf_set(cl_hw, 0xFFFFFFFF); + modem_gcu_epa_set(cl_hw, 0xFFFFFFFF); + modem_gcu_lcu_set(cl_hw, 0xFFFFFFFF); + modem_gcu_mux_fic_set(cl_hw, 0xFFFFFFFF); + modem_gcu_riu_clk_set(cl_hw, 0xFFFFFFFF); + modem_gcu_riu_clk_1_set(cl_hw, 0xFFFFFFFF); + + /* + * Configure minimum latency between 2 masters connected + * to same FIC, Read/Write transaction + */ + modem_gcu_mux_fic_config_set(cl_hw, 0x00000808); +} + +static const struct common_lut_line * +cl_phy_oly_get_lut_index(const struct common_lut_line *lut_table, + const u16 lut_table_size, u16 freq) +{ + u16 frequency_idx; + + /* Fine highest frequency in lut table that is lower or equal freq */ + for (frequency_idx = 0; + frequency_idx < lut_table_size && lut_table[frequency_idx].frequency_q2 <= freq; + ++frequency_idx) + ; + + if (frequency_idx) + frequency_idx--; + + return &lut_table[frequency_idx]; +} + +static void cl_phy_lut_2_lines_update(u16 freq, + const struct common_lut_line *lut_table_60m, + const u16 lut_table_60m_size, + const struct common_lut_line *lut_table_40m, + const u16 lut_table_40m_size, + struct mm_mac_api_lut_line *api_lut_line) +{ + /* 1. configure the 40M xco lut table */ + const struct common_lut_line *data_line = + cl_phy_oly_get_lut_index(lut_table_40m, lut_table_40m_size, freq); + + api_lut_line->rfic_specific.olympus_2_lines.xco_40M.freqmeastarg = + cpu_to_le32(data_line->freqmeastarg); + api_lut_line->rfic_specific.olympus_2_lines.xco_40M.nfrac = + cpu_to_le32(data_line->nfrac); + api_lut_line->rfic_specific.olympus_2_lines.xco_40M.nint = + data_line->nint; + api_lut_line->rfic_specific.olympus_2_lines.xco_40M.vcocalsel = + data_line->vcocalsel; + + /* 2. configure the 60M xco lut table */ + data_line = cl_phy_oly_get_lut_index(lut_table_60m, lut_table_60m_size, freq); + api_lut_line->rfic_specific.olympus_2_lines.xco_60M.freqmeastarg = + cpu_to_le32(data_line->freqmeastarg); + api_lut_line->rfic_specific.olympus_2_lines.xco_60M.nfrac = + cpu_to_le32(data_line->nfrac); + api_lut_line->rfic_specific.olympus_2_lines.xco_60M.nint = + data_line->nint; + api_lut_line->rfic_specific.olympus_2_lines.xco_60M.vcocalsel = + data_line->vcocalsel; + + /* 3. set frequency */ + api_lut_line->frequency_q2 = cpu_to_le16(freq); +} + +static void cl_phy_lut_3_lines_update(u16 freq, + const struct common_lut_line *lut_table_60m_s1, + const u16 lut_table_60m_s1_size, + const struct common_lut_line *lut_table_60m_s0, + const u16 lut_table_60m_s0_size, + const struct common_lut_line *lut_table_40m, + const u16 lut_table_40m_size, + struct mm_mac_api_lut_line *api_lut_line) +{ + /* 1. configure the 40M xco lut table */ + const struct common_lut_line *data_line = + cl_phy_oly_get_lut_index(lut_table_40m, lut_table_40m_size, freq); + + api_lut_line->rfic_specific.olympus_3_lines.xco_40M.freqmeastarg = + cpu_to_le32(data_line->freqmeastarg); + api_lut_line->rfic_specific.olympus_3_lines.xco_40M.nfrac = + cpu_to_le32(data_line->nfrac); + api_lut_line->rfic_specific.olympus_3_lines.xco_40M.nint = + data_line->nint; + api_lut_line->rfic_specific.olympus_3_lines.xco_40M.vcocalsel = + data_line->vcocalsel; + + /* 2. configure the 60M xco lut table , sxpfddesel=1*/ + data_line = cl_phy_oly_get_lut_index(lut_table_60m_s1, lut_table_60m_s1_size, freq); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s1.freqmeastarg = + cpu_to_le32(data_line->freqmeastarg); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s1.nfrac = + cpu_to_le32(data_line->nfrac); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s1.nint = + data_line->nint; + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s1.vcocalsel = + data_line->vcocalsel; + + /* 3. configure the 60M xco lut table , sxpfddesel=0*/ + data_line = cl_phy_oly_get_lut_index(lut_table_60m_s0, lut_table_60m_s0_size, freq); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s0.freqmeastarg = + cpu_to_le32(data_line->freqmeastarg); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s0.nfrac = + cpu_to_le32(data_line->nfrac); + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s0.nint = + data_line->nint; + api_lut_line->rfic_specific.olympus_3_lines.xco_60M_s0.vcocalsel = + data_line->vcocalsel; + + /* 4. set frequency */ + api_lut_line->frequency_q2 = cpu_to_le16(freq); +} + +void cl_phy_oly_lut_update(u8 rfic_version, u8 nl_band, u16 freq, + struct mm_mac_api_lut_line *api_lut_line) +{ + switch (nl_band) { + case NL80211_BAND_2GHZ: + cl_phy_lut_3_lines_update(freq, + olympus_lut_24g_60_mhz_s1, + OLYMPUS_LUT_CHAN_24G_MAX, + olympus_lut_24g_60_mhz_s0, + OLYMPUS_LUT_CHAN_24G_MAX, + olympus_lut_24g_40_mhz, + OLYMPUS_LUT_CHAN_24G_MAX, + api_lut_line); + break; + case NL80211_BAND_5GHZ: + if (rfic_version == ATHOS_B_VER) + cl_phy_lut_2_lines_update(freq, + athos_b_lut_5g_60_mhz, + ATHOS_B_5G_LUT_CHAN_5G_MAX, + athos_b_lut_5g_60_mhz, + ATHOS_B_5G_LUT_CHAN_5G_MAX, + api_lut_line); + else + cl_phy_lut_3_lines_update(freq, + olympus_lut_5g_60_mhz_s1, + OLYMPUS_LUT_CHAN_5G_MAX, + olympus_lut_5g_60_mhz_s0, + OLYMPUS_LUT_CHAN_5G_MAX, + olympus_lut_5g_40_mhz, + OLYMPUS_LUT_CHAN_5G_MAX, + api_lut_line); + break; + case NL80211_BAND_6GHZ: + if (rfic_version == ATHOS_B_VER) + cl_phy_lut_2_lines_update(freq, + athos_b_lut_6g_60_mhz, + ATHOS_B_6G_LUT_CHAN_6G_MAX, + athos_b_lut_6g_40_mhz, + ATHOS_B_6G_LUT_CHAN_6G_MAX, + api_lut_line); + else + cl_phy_lut_2_lines_update(freq, + athos_lut_6g_60_mhz, + ATHOS_LUT_CHAN_6G_MAX, + athos_lut_6g_40_mhz, + ATHOS_LUT_CHAN_6G_MAX, + api_lut_line); + break; + + default: + /* If nl_band is not supported return zero's */ + memset(api_lut_line, 0, sizeof(struct mm_mac_api_lut_line)); + api_lut_line->frequency_q2 = cpu_to_le16(freq); + } +} + +#define RICU_AFE_CTL_9_EN_DAC_REF_CL808X \ + (RICU_AFE_CTL_9_EN_DAC_REF_0_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_1_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_2_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_3_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_4_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_5_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_6_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_7_BIT) + +#define RICU_AFE_CTL_9_EN_DAC_REF_CL806X \ + (RICU_AFE_CTL_9_EN_DAC_REF_0_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_1_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_2_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_3_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_4_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_5_BIT) + +#define RICU_AFE_CTL_9_EN_DAC_REF_CL8046 \ + (RICU_AFE_CTL_9_EN_DAC_REF_0_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_1_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_2_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_3_BIT) + +#define RICU_AFE_CTL_9_EN_DAC_REF_CL8040 \ + (RICU_AFE_CTL_9_EN_DAC_REF_1_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_2_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_5_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_6_BIT) + +#define RICU_AFE_CTL_9_EN_DAC_REF_WIRING_27 \ + (RICU_AFE_CTL_9_EN_DAC_REF_0_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_1_BIT | \ + RICU_AFE_CTL_9_EN_DAC_REF_5_BIT) + +#define RICU_AFE_CTL_8_EN_BGR_CL808X \ + (RICU_AFE_CTL_8_EN_BGR_0_BIT | \ + RICU_AFE_CTL_8_EN_BGR_1_BIT | \ + RICU_AFE_CTL_8_EN_BGR_2_BIT | \ + RICU_AFE_CTL_8_EN_BGR_3_BIT | \ + RICU_AFE_CTL_8_EN_BGR_4_BIT | \ + RICU_AFE_CTL_8_EN_BGR_5_BIT | \ + RICU_AFE_CTL_8_EN_BGR_6_BIT | \ + RICU_AFE_CTL_8_EN_BGR_7_BIT) + +#define RICU_AFE_CTL_8_EN_BGR_CL806X \ + (RICU_AFE_CTL_8_EN_BGR_0_BIT | \ + RICU_AFE_CTL_8_EN_BGR_1_BIT | \ + RICU_AFE_CTL_8_EN_BGR_2_BIT | \ + RICU_AFE_CTL_8_EN_BGR_3_BIT | \ + RICU_AFE_CTL_8_EN_BGR_4_BIT | \ + RICU_AFE_CTL_8_EN_BGR_5_BIT) + +#define RICU_AFE_CTL_8_EN_BGR_CL8046 \ + (RICU_AFE_CTL_8_EN_BGR_0_BIT | \ + RICU_AFE_CTL_8_EN_BGR_1_BIT | \ + RICU_AFE_CTL_8_EN_BGR_2_BIT | \ + RICU_AFE_CTL_8_EN_BGR_3_BIT) + +#define RICU_AFE_CTL_8_EN_BGR_CL8040 \ + (RICU_AFE_CTL_8_EN_BGR_1_BIT | \ + RICU_AFE_CTL_8_EN_BGR_2_BIT | \ + RICU_AFE_CTL_8_EN_BGR_5_BIT | \ + RICU_AFE_CTL_8_EN_BGR_6_BIT) + +#define RICU_AFE_CTL_8_EN_REF_CL808X \ + (RICU_AFE_CTL_8_EN_REF_0_BIT | \ + RICU_AFE_CTL_8_EN_REF_1_BIT | \ + RICU_AFE_CTL_8_EN_REF_2_BIT | \ + RICU_AFE_CTL_8_EN_REF_3_BIT | \ + RICU_AFE_CTL_8_EN_REF_4_BIT | \ + RICU_AFE_CTL_8_EN_REF_5_BIT | \ + RICU_AFE_CTL_8_EN_REF_6_BIT | \ + RICU_AFE_CTL_8_EN_REF_7_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_WIRING_27_31 \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_5_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_WIRING_27_31 \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_5_BIT) + +#define RICU_AFE_CTL_8_EN_REF_CL806X \ + (RICU_AFE_CTL_8_EN_REF_0_BIT | \ + RICU_AFE_CTL_8_EN_REF_1_BIT | \ + RICU_AFE_CTL_8_EN_REF_2_BIT | \ + RICU_AFE_CTL_8_EN_REF_3_BIT | \ + RICU_AFE_CTL_8_EN_REF_4_BIT | \ + RICU_AFE_CTL_8_EN_REF_5_BIT) + +#define RICU_AFE_CTL_8_EN_REF_CL8046 \ + (RICU_AFE_CTL_8_EN_REF_0_BIT | \ + RICU_AFE_CTL_8_EN_REF_1_BIT | \ + RICU_AFE_CTL_8_EN_REF_2_BIT | \ + RICU_AFE_CTL_8_EN_REF_3_BIT) + +#define RICU_AFE_CTL_8_EN_REF_CL8040 \ + (RICU_AFE_CTL_8_EN_REF_1_BIT | \ + RICU_AFE_CTL_8_EN_REF_2_BIT | \ + RICU_AFE_CTL_8_EN_REF_5_BIT | \ + RICU_AFE_CTL_8_EN_REF_6_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_CL808X \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_5_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_CL806X \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_CL8046 \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_CL804X \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_WIRING_27_31 \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_5_BIT) + +#define RICU_AFE_CTRL_37_PHY_0_DAC_WIRING_33 \ + (RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_CL808X \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_5_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_CL806X \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_CL804X \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_WIRING_27_31 \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_4_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_5_BIT) + +#define RICU_AFE_CTRL_37_PHY_1_DAC_WIRING_33 \ + (RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT | \ + RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT) + +static int cl_afe_enable(struct cl_chip *chip) +{ + u32 regval; + bool tcv0_enabled = cl_chip_is_tcv0_enabled(chip); + bool tcv1_enabled = cl_chip_is_tcv1_enabled(chip); + + /* Enable PLL LDO */ + ricu_afe_ctl_1_en_pll_ldo_setf(chip, 1); + + /* Enable DAC BGR & reference */ + regval = ricu_afe_ctl_9_get(chip); + + if (chip->fem.wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1 || + chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) { + regval |= RICU_AFE_CTL_9_EN_DAC_REF_WIRING_27; + } else if (cl_chip_is_8ant(chip)) { + regval |= RICU_AFE_CTL_9_EN_DAC_REF_CL808X; + } else if (cl_chip_is_6ant(chip)) { + regval |= RICU_AFE_CTL_9_EN_DAC_REF_CL806X; + + } else { + if (cl_chip_is_6g(chip)) + regval |= RICU_AFE_CTL_9_EN_DAC_REF_CL8046; + else + regval |= RICU_AFE_CTL_9_EN_DAC_REF_CL8040; + } + + ricu_afe_ctl_9_set(chip, regval); + + /* Enable ADC BGR & Reference */ + regval = ricu_afe_ctl_8_get(chip); + + if (cl_chip_is_8ant(chip)) { + regval |= RICU_AFE_CTL_8_EN_BGR_CL808X; + regval |= RICU_AFE_CTL_8_EN_REF_CL808X; + } else if (cl_chip_is_6ant(chip)) { + regval |= RICU_AFE_CTL_8_EN_BGR_CL806X; + regval |= RICU_AFE_CTL_8_EN_REF_CL806X; + } else { + if (cl_chip_is_6g(chip)) { + regval |= RICU_AFE_CTL_8_EN_BGR_CL8046; + regval |= RICU_AFE_CTL_8_EN_REF_CL8046; + } else { + regval |= RICU_AFE_CTL_8_EN_BGR_CL8040; + regval |= RICU_AFE_CTL_8_EN_REF_CL8040; + } + } + ricu_afe_ctl_8_set(chip, regval); + + /* Enable Embedded LDO */ + if (tcv0_enabled) { + regval = ricu_afe_ctrl_36_phy_0_get(chip); + regval |= (RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_IR_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDI_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, regval); + } + + if (tcv1_enabled) { + regval = ricu_afe_ctrl_36_phy_1_get(chip); + regval |= (RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_IR_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDI_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, regval); + } + + /* Wait 2 ms PLL LDO settling time */ + usleep_range(2000, 2100); + + /* Enable the LC oscillator of the LCPLL */ + ricu_afe_ctl_2_lock_con_rev_lc_setf(chip, 1); + /* Enable the LC PBIAS of the LCPLL */ + ricu_afe_ctl_0_pbias_ctrl_en_lc_setf(chip, 1); + + /* Wait 200 us */ + usleep_range(200, 210); + + /* Power up control for LCPLL */ + ricu_afe_ctl_1_resetb_lc_setf(chip, 1); + + ricu_afe_ctl_0_lock_en_lc_setf(chip, 0x1); + + /* Wait 1 ms */ + usleep_range(1000, 1100); + + if (!cmu_pll_0_stat_pll_lock_getf(chip)) { + cl_dbg_chip_err(chip, "ERROR: pll0 is not locked !!!\n"); + return -ENOLCK; + } + + /* Enable DAC & ADC cores */ + if (tcv0_enabled) { + if (chip->fem.wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1 || + chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_WIRING_27_31); + else if (chip->fem.wiring_id == FEM_WIRING_33_TCV0_4_TCV1_4) + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_WIRING_33); + else if (cl_chip_is_8ant(chip) || cl_fem_wiring_id_is_evb(chip)) + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_CL808X); + else if (cl_chip_is_6ant(chip)) + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_CL806X); + else if (cl_chip_is_6g(chip)) + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_CL8046); + else + ricu_afe_ctrl_37_phy_0_set(chip, RICU_AFE_CTRL_37_PHY_0_DAC_CL804X); + } + + if (tcv1_enabled) { + if (chip->fem.wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1 || + chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + ricu_afe_ctrl_37_phy_1_set(chip, RICU_AFE_CTRL_37_PHY_1_DAC_WIRING_27_31); + else if (chip->fem.wiring_id == FEM_WIRING_33_TCV0_4_TCV1_4) + ricu_afe_ctrl_37_phy_1_set(chip, RICU_AFE_CTRL_37_PHY_1_DAC_WIRING_33); + else if (cl_chip_is_8ant(chip) || cl_fem_wiring_id_is_evb(chip)) + ricu_afe_ctrl_37_phy_1_set(chip, RICU_AFE_CTRL_37_PHY_1_DAC_CL808X); + else if (cl_chip_is_6ant(chip)) + ricu_afe_ctrl_37_phy_1_set(chip, RICU_AFE_CTRL_37_PHY_1_DAC_CL806X); + else + ricu_afe_ctrl_37_phy_1_set(chip, RICU_AFE_CTRL_37_PHY_1_DAC_CL804X); + } + + /* Enable DAC & ADC cores */ + if (tcv0_enabled) { + regval = ricu_afe_ctrl_36_phy_0_get(chip); + regval |= (RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, regval); + } + + if (tcv1_enabled) { + regval = ricu_afe_ctrl_36_phy_1_get(chip); + regval |= (RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, regval); + } + + /* Wait 50us */ + udelay(50); + + /* Enable Main & 2nd CDB clock generators */ + ricu_afe_ctl_0_cdb_clk_resetb_setf(chip, 1); + + return 0; +} + +static void cl_afe_disable(struct cl_chip *chip) +{ + u32 regval; + bool tcv0_enabled = cl_chip_is_tcv0_enabled(chip); + bool tcv1_enabled = cl_chip_is_tcv1_enabled(chip); + + /* Power down control for LCPLL */ + ricu_afe_ctl_1_resetb_lc_setf(chip, 0); + /* Disable PLL LDO */ + ricu_afe_ctl_1_en_pll_ldo_setf(chip, 0); + /* Disable the LC oscillator of the LCPLL */ + ricu_afe_ctl_2_lock_con_rev_lc_setf(chip, 0); + /* Disable the LC PBIAS of the LCPLL */ + ricu_afe_ctl_0_pbias_ctrl_en_lc_setf(chip, 0); + + /* Disable DAC BGR & reference */ + regval = ricu_afe_ctl_9_get(chip); + if (cl_chip_is_8ant(chip)) { + regval &= ~RICU_AFE_CTL_9_EN_DAC_REF_CL808X; + } else if (cl_chip_is_6ant(chip)) { + regval &= ~RICU_AFE_CTL_9_EN_DAC_REF_CL806X; + } else { + if (cl_chip_is_6g(chip)) + regval &= ~RICU_AFE_CTL_9_EN_DAC_REF_CL8046; + else + regval &= ~RICU_AFE_CTL_9_EN_DAC_REF_CL8040; + } + ricu_afe_ctl_9_set(chip, regval); + + /* Disable ADC BGR & Reference */ + regval = ricu_afe_ctl_8_get(chip); + if (cl_chip_is_8ant(chip)) { + regval &= ~RICU_AFE_CTL_8_EN_BGR_CL808X; + regval &= ~RICU_AFE_CTL_8_EN_REF_CL808X; + } else if (cl_chip_is_6ant(chip)) { + regval &= ~RICU_AFE_CTL_8_EN_BGR_CL806X; + regval &= ~RICU_AFE_CTL_8_EN_REF_CL806X; + } else { + if (cl_chip_is_6g(chip)) { + regval &= ~RICU_AFE_CTL_8_EN_BGR_CL8046; + regval &= ~RICU_AFE_CTL_8_EN_REF_CL8046; + } else { + regval &= ~RICU_AFE_CTL_8_EN_BGR_CL8040; + regval &= ~RICU_AFE_CTL_8_EN_REF_CL8040; + } + } + ricu_afe_ctl_8_set(chip, regval); + + /* Disable Embedded LDO */ + if (tcv0_enabled) { + regval = ricu_afe_ctrl_36_phy_0_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_IR_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDI_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, regval); + } + + if (tcv1_enabled) { + regval = ricu_afe_ctrl_36_phy_1_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_IR_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDI_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, regval); + } + + /* Disable DAC & ADC cores */ + if (tcv0_enabled) + ricu_afe_ctrl_37_phy_0_set(chip, 0); + + if (tcv1_enabled) + ricu_afe_ctrl_37_phy_1_set(chip, 0); + + /* Disable DAC & ADC cores */ + if (tcv0_enabled) { + regval = ricu_afe_ctrl_36_phy_0_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, regval); + } + + if (tcv1_enabled) { + regval = ricu_afe_ctrl_36_phy_1_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, regval); + } + + /* Disable Main & 2nd CDB clock generators */ + ricu_afe_ctl_0_cdb_clk_resetb_setf(chip, 0); +} + +static void cl_io_ctrl_config(struct cl_chip *chip) +{ + io_ctrl_fastwr_0_set(chip, 0x2338); + io_ctrl_fastwr_1_set(chip, 0x2338); + io_ctrl_fastwr_2_set(chip, 0x2338); + io_ctrl_fastwr_3_set(chip, 0x2338); + io_ctrl_fastwr_4_set(chip, 0x2338); + io_ctrl_fastwr_5_set(chip, 0x2338); + io_ctrl_fastwr_6_set(chip, 0x2338); + io_ctrl_fastwr_7_set(chip, 0x2338); + io_ctrl_fwr_en_1_set(chip, 0x338); + io_ctrl_spiclk_set(chip, 0x308); +} + +static int cl_adc_sampling_cfg_tcv0(struct cl_chip *chip, u16 adc_sampling_clk) +{ + switch (adc_sampling_clk) { + case 40: + ricu_afe_ctrl_43_freq_sel_setf(chip, 0x0); + /* Configure ADC sampling for primary chains */ + ricu_afe_ctl_25_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_26_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_27_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_33_pack(chip, 0x1, 0x3D, 0x3D); + break; + case 80: + ricu_afe_ctrl_43_freq_sel_setf(chip, 0x1); + /* Configure ADC sampling for primary chains */ + ricu_afe_ctl_25_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_26_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_27_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctl_33_pack(chip, 0x1, 0x3D, 0x3D); + break; + case 160: + ricu_afe_ctrl_43_freq_sel_setf(chip, 0x2); + /* Configure ADC sampling for primary chains */ + ricu_afe_ctl_25_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_26_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_27_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_33_pack(chip, 0x0, 0x7, 0x7); + break; + case 320: + ricu_afe_ctrl_43_freq_sel_setf(chip, 0x3); + /* Configure ADC sampling for primary chains */ + ricu_afe_ctl_25_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_26_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_27_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctl_33_pack(chip, 0x0, 0x7, 0x7); + break; + default: + CL_DBG_ERROR_CHIP(chip, "Invalid adc_sampling_clk %u\n", adc_sampling_clk); + return -EINVAL; + } + + return 0; +} + +static int cl_adc_sampling_cfg_tcv1(struct cl_chip *chip, u32 adc_sampling_clk) +{ + switch (adc_sampling_clk) { + case 40: + ricu_afe_ctrl_44_cdb_freq_sel_setf(chip, 0x0); + /* Configure ADC sampling for secondary chains */ + ricu_afe_ctrl_39_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_40_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_41_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_42_pack(chip, 0x1, 0x3D, 0x3D); + break; + case 80: + ricu_afe_ctrl_44_cdb_freq_sel_setf(chip, 0x1); + /* Configure ADC sampling for secondary chains */ + ricu_afe_ctrl_39_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_40_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_41_pack(chip, 0x1, 0x3D, 0x3D); + ricu_afe_ctrl_42_pack(chip, 0x1, 0x3D, 0x3D); + break; + case 160: + ricu_afe_ctrl_44_cdb_freq_sel_setf(chip, 0x2); + /* Configure ADC sampling for secondary chains */ + ricu_afe_ctrl_39_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_40_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_41_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_42_pack(chip, 0x0, 0x7, 0x7); + break; + case 320: + ricu_afe_ctrl_44_cdb_freq_sel_setf(chip, 0x3); + /* Configure ADC sampling for secondary chains */ + ricu_afe_ctrl_39_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_40_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_41_pack(chip, 0x0, 0x7, 0x7); + ricu_afe_ctrl_42_pack(chip, 0x0, 0x7, 0x7); + break; + default: + CL_DBG_ERROR_CHIP(chip, "Invalid adc_sampling_clk %u\n", adc_sampling_clk); + return -EINVAL; + } + + return 0; +} + +static int cl_afe_adc_and_dac_cfg(struct cl_chip *chip) +{ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + bool tcv0_enabled = cl_chip_is_tcv0_enabled(chip); + bool tcv1_enabled = cl_chip_is_tcv1_enabled(chip); + bool hw_mode = chip->conf->ci_afe_hw_mode; + u16 bw_tcv0 = 0; + u16 bw_tcv1 = 0; + u16 riu_sampling_clk_tcv0 = 0; + u16 riu_sampling_clk_tcv1 = 0; + u16 adc_sampling_clk_tcv0 = 80; + u16 adc_sampling_clk_tcv1 = 80; + u8 sb_rd_delay_tcv0 = 0; + u8 sb_rd_delay_tcv1 = 0; + u32 regval; + u8 main_sel_7_2 = 0; + + if (tcv0_enabled) { + bw_tcv0 = cl_hw_tcv0->conf->ci_cap_bandwidth; + riu_sampling_clk_tcv0 = + cl_hw_tcv0->conf->ci_hr_factor[bw_tcv0] * BW_TO_MHZ(bw_tcv0); + adc_sampling_clk_tcv0 = 2 * riu_sampling_clk_tcv0; + sb_rd_delay_tcv0 = ((riu_sampling_clk_tcv0 == 80) || + (riu_sampling_clk_tcv0 == 160)) ? 4 : 2; + } + + if (tcv1_enabled) { + bw_tcv1 = cl_hw_tcv1->conf->ci_cap_bandwidth; + riu_sampling_clk_tcv1 = + cl_hw_tcv1->conf->ci_hr_factor[bw_tcv1] * BW_TO_MHZ(bw_tcv1); + adc_sampling_clk_tcv1 = 2 * riu_sampling_clk_tcv1; + sb_rd_delay_tcv1 = ((riu_sampling_clk_tcv1 == 80) || + (riu_sampling_clk_tcv1 == 160)) ? 4 : 2; + } + + /* + * For ADC sampling CLK=40MHz set to 0 + * For ADC sampling CLK=80MHz set to 1 + * For ADC sampling CLK=160MHz set to 2 + * For ADC sampling CLK=320MHz set to 3 + * + * The sampling clock depends on the channel_bandwidth (20/40/80/160MHz) + * and hr_factor (1,2,4,8): + * ADC Sampling (MHz) = 2 * hr_factor * channel_bandwidth + * + * Select the external forced clock for ADC0..7: + * For ADC sampling CLK=40MHz/80MHz set to 1 + * For ADC sampling CLK=160MHz/320MHz set to 0 + * In our default case: rosel0-3 = 0x0; rosel4-7 = 0x1 + * + * Internal clock frequency of ADCI0..7 I (when its ROSEL is low): + * For ADC sampling CLK=40MHz/80MHz set to 7'b011_1101 + * For ADC sampling CLK=160MHz/320MHz set to 7'b000_0111 + * In our default case: roctrli0-3 = 0x7; roctrli4-7 = 0x3D + * + * Internal clock frequency of ADCQ0..7 I (when its ROSEL is low): + * For ADC sampling CLK=40MHz/80MHz set to 7'b011_1101 + * For ADC sampling CLK=160MHz/320MHz set to 7'b000_0111 + * In our default case: roctrlq0-3 = 0x7; roctrlq4-7 = 0x3D + */ + + if (cl_adc_sampling_cfg_tcv0(chip, adc_sampling_clk_tcv0)) + return -1; + if (cl_adc_sampling_cfg_tcv1(chip, adc_sampling_clk_tcv1)) + return -1; + + /* AFE_CTL_0 - AUX ADC for debug + for second band */ + regval = ricu_afe_ctl_0_get(chip); + if (chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) + regval |= (RICU_AFE_CTL_0_EN_CDB_DAC_CLK_BIT | + RICU_AFE_CTL_0_EN_CDB_ADC_CLK_BIT | + RICU_AFE_CTL_0_EN_CDB_GEN_BIT | + RICU_AFE_CTL_0_EN_GPADC_CLK_BIT | + RICU_AFE_CTL_0_EN_GPADC_BIT); + else if (cl_chip_is_4ant(chip) && cl_chip_is_6g(chip) && + !(chip->fem.wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1)) + regval |= (RICU_AFE_CTL_0_EN_GPADC_CLK_BIT | + RICU_AFE_CTL_0_EN_GPADC_BIT); + else + regval |= (RICU_AFE_CTL_0_EN_CDB_DAC_CLK_BIT | + RICU_AFE_CTL_0_EN_CDB_ADC_CLK_BIT | + RICU_AFE_CTL_0_EN_CDB_GEN_BIT | + RICU_AFE_CTL_0_EN_GPADC_CLK_BIT | + RICU_AFE_CTL_0_EN_GPADC_BIT); + ricu_afe_ctl_0_set(chip, regval); + + ricu_afe_ctl_3_cml_sel_setf(chip, chip->conf->ci_afe_cml_sel); + + /* VC_LD_AVDI0..7 */ + ricu_afe_ctl_23_set(chip, chip->conf->ci_afe_vc_avd); + /* VC_LD_AVDQ0..7 */ + ricu_afe_ctl_24_set(chip, chip->conf->ci_afe_vc_avd); + /* EN_BGR0..7 = 0x1, CH_CML_SEL0..7, EN_EXT_LOAD0..7 = 0x0, EN_REF0..7 = 0x1 */ + ricu_afe_ctl_8_set(chip, 0xff0000ff | + (chip->conf->ci_afe_ch_cml_sel << RICU_AFE_CTL_8_CH_CML_SEL_0_POS)); + /* VC_CML0..7_I */ + ricu_afe_ctl_29_set(chip, chip->conf->ci_afe_vc_cml); + /* VC_CML0..7_Q */ + ricu_afe_ctl_30_set(chip, chip->conf->ci_afe_vc_cml); + /* IC_REFSSF0..7 = 0x3, EOC_CTRL0..7 */ + ricu_afe_ctl_12_set(chip, 0x0000ffff | + (chip->conf->ci_afe_eoc_ctrl << RICU_AFE_CTL_12_EOC_CTRL_0_LSB)); + + /* + * Set channels to Transceiver0 (phy0) or Transceiver1 (phy1): + * 6'b11_0000 (Transceiver1 @CH7~6, Transceiver0 @CH5~0) + * 6'b11_1000 (Transceiver1 @CH7~5, Transceiver0 @CH4~0) + * 6'b11_1100 (Transceiver1 @CH7~4, Transceiver0 @CH3~0) + * 6'b11_1110 (Transceiver1 @CH7~3, Transceiver0 @CH3~0) + * 6'b11_1111 (Transceiver1 @CH7~2, Transceiver0 @CH2~0) + * In our default case: mainsel72 = 0x3C + */ + if (chip->cdb_mode_maj < 2 || chip->cdb_mode_maj > 6) { + main_sel_7_2 = 0x3C; + } else { + u8 chains_tcv0 = MAX_ANTENNAS - chip->cdb_mode_maj; + + /* Turn off TCV0's chains */ + chains_tcv0 = BIT(chains_tcv0) - 1; + main_sel_7_2 = 0x3F & (~chains_tcv0); + } + + ricu_afe_ctl_5_main_sel_7_2_setf(chip, main_sel_7_2); + cl_dbg_chip_trace(chip, "Set main_sel_7_2 = 0x%x\n", main_sel_7_2); + + /* + * Set 1 - b0 to MINV0/1/2/3/4/5/6/7 (DAC) + * Set 1 - b1 to TWOS0/1/2/3/4/5/6/7 (ADC) + */ + ricu_afe_ctl_10_set(chip, 0x00FF0000); + + /* Set VC_REF0/1/2/../7 */ + ricu_afe_ctl_17_set(chip, chip->conf->ci_afe_vc_ref); + + if (chip->conf->ci_afe_loopback) { + ricu_afe_ctl_13_pack(chip, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1); + ricu_afe_ctl_15_pack(chip, 6, 6, 6, 6, 6, 6, 6, 6); + /* Set COMP_CTRL0/1/2/.../7[3:0] to 4'b1001 for loopback mode */ + ricu_afe_ctl_19_set(chip, 0x99999999); + } else { + /* Set COMP_CTRL0/1/2/.../7[3:0] to 4'b1010 for normal mode */ + ricu_afe_ctl_19_set(chip, 0xAAAAAAAA); + } + + if (hw_mode) { + /* + * Disable DAC & ADC cores (To save power. + * Assuming RIU HW will control it due to HW_MODE_ADC/DAC) + */ + if (tcv0_enabled) + ricu_afe_ctrl_37_phy_0_set(chip, 0); + + if (tcv1_enabled) + ricu_afe_ctrl_37_phy_1_set(chip, 0); + + if (tcv0_enabled) { + regval = ricu_afe_ctrl_36_phy_0_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, regval); + } + + if (tcv1_enabled) { + regval = ricu_afe_ctrl_36_phy_1_get(chip); + regval &= ~(RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, regval); + } + } + + /* Sync buffer read delay, ignore fifo indication */ + if (tcv0_enabled) { + ricu_afe_ctrl_34_phy_0_adc_sb_rd_delay_setf(chip, sb_rd_delay_tcv0); + ricu_afe_ctrl_34_phy_0_adc_sb_ignore_fifo_indication_setf(chip, 1); + } + + if (tcv1_enabled) { + ricu_afe_ctrl_34_phy_1_adc_sb_rd_delay_setf(chip, sb_rd_delay_tcv1); + ricu_afe_ctrl_34_phy_1_adc_sb_ignore_fifo_indication_setf(chip, 1); + } + + /* DAC - ignore fifo indication = true */ + if (tcv0_enabled) { + ricu_afe_ctrl_35_phy_0_dac_sb_rd_delay_setf(chip, 1); + ricu_afe_ctrl_35_phy_0_dac_sb_ignore_fifo_indication_setf(chip, 1); + } + + if (tcv1_enabled) { + ricu_afe_ctrl_35_phy_1_dac_sb_rd_delay_setf(chip, 1); + ricu_afe_ctrl_35_phy_1_dac_sb_ignore_fifo_indication_setf(chip, 1); + } + + /* Set to HW/SW control mode */ + if (tcv0_enabled) { + ricu_afe_ctrl_36_phy_0_hw_mode_adc_setf(chip, hw_mode); + ricu_afe_ctrl_36_phy_0_hw_mode_dac_setf(chip, hw_mode); + } + + if (tcv1_enabled) { + ricu_afe_ctrl_36_phy_1_hw_mode_adc_setf(chip, hw_mode); + + if (chip->fem.wiring_id != FEM_WIRING_31_TCV0_2_TCV1_1) + ricu_afe_ctrl_36_phy_1_hw_mode_dac_setf(chip, hw_mode); + } + + return 0; +} + +static void cl_afe_set_cdb_mode_maj(struct cl_chip *chip, u8 maj_val) +{ + ricu_static_conf_0_cdb_mode_maj_setf(chip, maj_val); + chip->cdb_mode_maj = maj_val; +} + +static int cl_afe_set_cdb_mode(struct cl_chip *chip) +{ + /* Configure number of RF chains per PHY */ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + u8 ant_tcv0 = 0; + u8 ant_tcv1 = 0; + u8 ant_total = 0; + + if (cl_hw_tcv0 && cl_hw_tcv1) { + ant_tcv0 = cl_hw_tcv0->num_antennas; + ant_tcv1 = cl_hw_tcv1->num_antennas; + } else if (cl_hw_tcv0) { + ant_tcv0 = cl_hw_tcv0->num_antennas; + ant_tcv1 = chip->max_antennas - ant_tcv0; + } else { + ant_tcv1 = cl_hw_tcv1->num_antennas; + ant_tcv0 = chip->max_antennas - ant_tcv1; + } + + if (chip->conf->ci_phy_dev == PHY_DEV_LOOPBACK) { + cl_afe_set_cdb_mode_maj(chip, 0xf); + + return 0; + } + + if (cl_fem_wiring_id_is_evb(chip)) { + /* + * Extend the num antennas of TCV1 as if there were 8 antennas + * on the chip, for the purpose of calculating the maj value. + */ + u8 ant_ext = MAX_ANTENNAS_CHIP - chip->max_antennas; + + ant_tcv1 += ant_ext; + } else if (!cl_chip_is_8ant(chip)) { + cl_afe_set_cdb_mode_maj(chip, 0x4); + + return 0; + } + + ant_total = ant_tcv0 + ant_tcv1; + + if (ant_total < MAX_ANTENNAS_CHIP) { + if (ant_tcv0 <= 4 && ant_tcv1 <= 4) { + ant_tcv0 = 4; + ant_tcv1 = 4; + } else { + if (cl_hw_tcv0) + ant_tcv0 = min_t(u8, cl_hw_tcv0->max_antennas, + MAX_ANTENNAS_CHIP - ant_tcv1); + else + ant_tcv0 = MAX_ANTENNAS_CHIP - ant_tcv1; + + if (cl_hw_tcv1) { + ant_total = ant_tcv0 + ant_tcv1; + ant_tcv1 += min_t(u8, cl_hw_tcv1->max_antennas - + cl_hw_tcv1->num_antennas, + MAX_ANTENNAS_CHIP - ant_total); + } else { + ant_tcv1 = MAX_ANTENNAS_CHIP - ant_tcv0; + } + } + } + + if (ant_tcv0 + ant_tcv1 != 8) { + CL_DBG_ERROR_CHIP(chip, "Invalid antenna configuration (tcv0 %u) (tcv1 %u)\n", + ant_tcv0, ant_tcv1); + + return -EINVAL; + } + + cl_afe_set_cdb_mode_maj(chip, ant_tcv1); + + return 0; +} + +static int cl_afe_phy_type_and_rf_chains(struct cl_chip *chip) +{ + ricu_spi_clk_ctrl_set(chip, 0x1c); /* SPI clock bitmap */ + ricu_static_conf_0_btc_sel_setf(chip, 0); /* Clear BTC select */ + + if (cl_afe_set_cdb_mode(chip)) + return -1; + + ricu_static_conf_0_clk_save_mode_setf(chip, 1); + + if (chip->fem.wiring_id == FEM_WIRING_27_TCV0_2_TCV1_1 || + chip->fem.wiring_id == FEM_WIRING_31_TCV0_2_TCV1_1) { + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, 0x23); + } else if (cl_chip_is_8ant(chip) || cl_fem_wiring_id_is_evb(chip)) { + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, U8_MAX); + } else if (cl_chip_is_6ant(chip)) { + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, 0x3f); + } else { + if (cl_chip_is_6g(chip)) + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, 0xf); + else + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, 0x66); + } + + /* Reset RFIC */ + ricu_static_conf_0_rf_rst_n_req_setf(chip, 0x1); + + return 0; +} + +int cl_afe_cfg(struct cl_chip *chip) +{ + /* 1. Define PHY Type & RF Chains per band */ + if (cl_afe_phy_type_and_rf_chains(chip)) + return -1; + + if (!chip->conf->ci_afe_config_en) + goto fem_conf; + + /* 2. AFE Disable */ + cl_afe_disable(chip); + + /* Wait 2.5ms for AFE LDO settling time */ + usleep_range(2500, 2600); + + /* 3. AFE Enable */ + if (cl_afe_enable(chip)) + return -1; + + /* 4. ADC & DAC Configuration */ + cl_afe_adc_and_dac_cfg(chip); + + cl_io_ctrl_config(chip); + +fem_conf: + /* 5. FEM Configuration */ + cl_fem_update_conf_params(chip); + + return 0; +} + +void cl_afe_cfg_calib(struct cl_chip *chip) +{ + struct cl_afe_reg *orig_afe_reg = &chip->orig_afe_reg; + u32 reg_phy0 = 0, reg_phy1 = 0; + + orig_afe_reg->ctrl36_phy0 = ricu_afe_ctrl_36_phy_0_get(chip); + orig_afe_reg->ctrl37_phy0 = ricu_afe_ctrl_37_phy_0_get(chip); + orig_afe_reg->ctrl36_phy1 = ricu_afe_ctrl_36_phy_1_get(chip); + orig_afe_reg->ctrl37_phy1 = ricu_afe_ctrl_37_phy_1_get(chip); + orig_afe_reg->ctrl8 = ricu_afe_ctl_8_get(chip); + orig_afe_reg->ctrl9 = ricu_afe_ctl_9_get(chip); + orig_afe_reg->adc_ch_alloc = ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_getf(chip); + + /* Enable all ADC channels */ + reg_phy0 = 0xFF; + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, reg_phy0); + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_ADC_CH_ALLOC = 0x%x\n", reg_phy0); + + /* Enable DAC REF0-7 */ + reg_phy0 = orig_afe_reg->ctrl9 | 0xFF0000; + ricu_afe_ctl_9_set(chip, reg_phy0); + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTL_9 = 0x%x\n", reg_phy0); + + /* Enable ADC BGR0-7 and REF0-7 */ + reg_phy0 = orig_afe_reg->ctrl8 | RICU_AFE_CTL_8_EN_BGR_CL808X | + RICU_AFE_CTL_8_EN_REF_CL808X; + ricu_afe_ctl_8_set(chip, reg_phy0); + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTL_8 = 0x%x\n", reg_phy0); + + /* Wait PLL LDO setting time(1.5ms) + margin = 2ms */ + usleep_range(2000, 2100); + + /* Enable DAC cores */ + reg_phy0 = RICU_AFE_CTRL_37_PHY_0_DAC_CL808X; + ricu_afe_ctrl_37_phy_0_set(chip, reg_phy0); + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTRL_37_PHY_0 = 0x%x\n", reg_phy0); + + reg_phy1 = RICU_AFE_CTRL_37_PHY_1_DAC_CL808X; + ricu_afe_ctrl_37_phy_1_set(chip, reg_phy1); + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTRL_37_PHY_1 = 0x%x\n", reg_phy1); + + /* Enable ADC cores and set to SW control mode */ + reg_phy0 = orig_afe_reg->ctrl36_phy0; + reg_phy0 |= (RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_BIT); + reg_phy0 &= ~(RICU_AFE_CTRL_36_PHY_0_HW_MODE_ADC_BIT | + RICU_AFE_CTRL_36_PHY_0_HW_MODE_DAC_BIT); + ricu_afe_ctrl_36_phy_0_set(chip, reg_phy0); + + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTRL_36_PHY_0 = 0x%x\n", reg_phy0); + + /* Enable ADC cores and set to SW control mode */ + reg_phy1 = orig_afe_reg->ctrl36_phy1; + reg_phy1 |= (RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_BIT | + RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_BIT); + reg_phy1 &= ~(RICU_AFE_CTRL_36_PHY_1_HW_MODE_ADC_BIT | + RICU_AFE_CTRL_36_PHY_1_HW_MODE_DAC_BIT); + ricu_afe_ctrl_36_phy_1_set(chip, reg_phy1); + + cl_dbg_chip_trace(chip, "Setting: RICU_AFE_CTRL_36_PHY_1 = 0x%x\n", reg_phy1); +} + +void cl_afe_cfg_restore(struct cl_chip *chip) +{ + struct cl_afe_reg *orig_afe_reg = &chip->orig_afe_reg; + + ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(chip, orig_afe_reg->adc_ch_alloc); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_ADC_CH_ALLOC = 0x%x\n", + orig_afe_reg->adc_ch_alloc); + + ricu_afe_ctl_9_set(chip, orig_afe_reg->ctrl9); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTL_9 = 0x%x\n", orig_afe_reg->ctrl9); + + ricu_afe_ctl_8_set(chip, orig_afe_reg->ctrl8); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTL_8 = 0x%x\n", orig_afe_reg->ctrl8); + + ricu_afe_ctrl_37_phy_0_set(chip, orig_afe_reg->ctrl37_phy0); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTRL_37_PHY_0 = 0x%x\n", + orig_afe_reg->ctrl37_phy0); + + ricu_afe_ctrl_37_phy_1_set(chip, orig_afe_reg->ctrl37_phy1); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTRL_37_PHY_1 = 0x%x\n", + orig_afe_reg->ctrl37_phy1); + + ricu_afe_ctrl_36_phy_0_set(chip, orig_afe_reg->ctrl36_phy0); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTRL_36_PHY_0 = 0x%x\n", + orig_afe_reg->ctrl36_phy0); + + ricu_afe_ctrl_36_phy_1_set(chip, orig_afe_reg->ctrl36_phy1); + cl_dbg_chip_trace(chip, "Restoring: RICU_AFE_CTRL_36_PHY_1 = 0x%x\n", + orig_afe_reg->ctrl36_phy1); +} + +static const struct cl_fem_lna_enable_gpio lna_enable_gpio[FEM_WIRING_MAX] = { + [FEM_WIRING_0_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 }, + [FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 }, + [FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 }, + [FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 }, + [FEM_WIRING_7_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_9_TCV0_4_TCV1_4] = { .val = 0b111100000000 }, + [FEM_WIRING_10_TCV0_4_TCV1_4] = { .val = 0b111100000000 }, + [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b111100000000 }, + [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b111100000000 }, + [FEM_WIRING_13_SENSING_4RX_2TX] = { .val = 0b001111110000 }, + [FEM_WIRING_14_SENSING_4TX_2RX] = { .val = 0b111100110000 }, + [FEM_WIRING_15_CHAMELEON_4TX_4RX] = { .val = 0b001100001010 }, + [FEM_WIRING_16_TCV0_2_TCV1_2] = { .val = 0b100110111110 }, + [FEM_WIRING_17_TCV0_4_TCV1_0] = { .val = 0b111111110000 }, + [FEM_WIRING_18_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED] = { .val = 0b000011111111 }, + [FEM_WIRING_20_TCV0_2_TCV1_2] = { .val = 0b100110111110 }, + [FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2] = { .val = 0b000110111010 }, + [FEM_WIRING_22_OBSOLETE] = { .val = 0b111111000000 }, + [FEM_WIRING_23_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_24_TCV0_6_TCV1_4] = { .val = 0b000011000000 }, + [FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0] = { .val = 0b111100100000 }, + [FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1] = { .val = 0b111100100000 }, + [FEM_WIRING_27_TCV0_2_TCV1_1] = { .val = 0b111101111100 }, + [FEM_WIRING_28_TCV0_4_TCV1_2] = { .val = 0b000011111010 }, + [FEM_WIRING_29_TCV0_4_TCV1_2] = { .val = 0b111100110000 }, + [FEM_WIRING_30_TCV0_4_TCV1_2] = { .val = 0b000011111010 }, + [FEM_WIRING_31_TCV0_2_TCV1_1] = { .val = 0b111101111100 }, + [FEM_WIRING_32_TCV0_4_TCV1_0] = { .val = 0b111111110000 }, + [FEM_WIRING_33_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, +}; + +static const struct cl_fem_pa_enable_gpio pa_enable_gpio[FEM_WIRING_MAX] = { + [FEM_WIRING_0_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b000000000000 }, + [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 }, + [FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 }, + [FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 }, + [FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 }, + [FEM_WIRING_7_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_9_TCV0_4_TCV1_4] = { .val = 0b111100000000 }, + [FEM_WIRING_10_TCV0_4_TCV1_4] = { .val = 0b111100000000 }, + [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b111111110000 }, + [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b111111110000 }, + [FEM_WIRING_13_SENSING_4RX_2TX] = { .val = 0b001111110000 }, + [FEM_WIRING_14_SENSING_4TX_2RX] = { .val = 0b001111111010 }, + [FEM_WIRING_15_CHAMELEON_4TX_4RX] = { .val = 0b001111111010 }, + [FEM_WIRING_16_TCV0_2_TCV1_2] = { .val = 0b100110111110 }, + [FEM_WIRING_17_TCV0_4_TCV1_0] = { .val = 0b111111110000 }, + [FEM_WIRING_18_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED] = { .val = 0b000011111111 }, + [FEM_WIRING_20_TCV0_2_TCV1_2] = { .val = 0b100110111110 }, + [FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2] = { .val = 0b111111110000 }, + [FEM_WIRING_22_OBSOLETE] = { .val = 0b111111000000 }, + [FEM_WIRING_23_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, + [FEM_WIRING_24_TCV0_6_TCV1_4] = { .val = 0b000011000000 }, + [FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0] = { .val = 0b111100110000 }, + [FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1] = { .val = 0b111100110000 }, + [FEM_WIRING_27_TCV0_2_TCV1_1] = { .val = 0b111101111100 }, + [FEM_WIRING_28_TCV0_4_TCV1_2] = { .val = 0b000011111010 }, + [FEM_WIRING_29_TCV0_4_TCV1_2] = { .val = 0b111100110000 }, + [FEM_WIRING_30_TCV0_4_TCV1_2] = { .val = 0b000011111010 }, + [FEM_WIRING_31_TCV0_2_TCV1_1] = { .val = 0b111111111100 }, + [FEM_WIRING_32_TCV0_4_TCV1_0] = { .val = 0b111111110000 }, + [FEM_WIRING_33_TCV0_4_TCV1_4] = { .val = 0b000000111010 }, +}; + +static const struct cl_fem_rx_active_gpio rx_active_gpio[FEM_WIRING_MAX] = { + [FEM_WIRING_0_TCV0_6_TCV1_6] = { .val = 0b11000000 }, + [FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b11111111 }, + [FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6] = { .val = 0b00000000 }, /* N/A */ + [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b11111100 }, + [FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b11111111 }, + [FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b00000000 }, /* N/A */ + [FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b00000000 }, /* N/A */ + [FEM_WIRING_7_TCV0_4_TCV1_4] = { .val = 0b11110000 }, + [FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4] = { .val = 0b00000000 }, /* N/A */ + [FEM_WIRING_9_TCV0_4_TCV1_4] = { .val = 0b11111111 }, + [FEM_WIRING_10_TCV0_4_TCV1_4] = { .val = 0b00000000 }, + [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b11110000 }, + [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = { .val = 0b11111111 }, + [FEM_WIRING_13_SENSING_4RX_2TX] = { .val = 0b11000000 }, + [FEM_WIRING_14_SENSING_4TX_2RX] = { .val = 0b11110000 }, + [FEM_WIRING_15_CHAMELEON_4TX_4RX] = { .val = 0b11110000 }, + [FEM_WIRING_16_TCV0_2_TCV1_2] = { .val = 0b11111001 }, + [FEM_WIRING_17_TCV0_4_TCV1_0] = { .val = 0b11111111 }, + [FEM_WIRING_18_TCV0_4_TCV1_4] = { .val = 0b00000000 }, + [FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED] = { .val = 0b11001111 }, + [FEM_WIRING_20_TCV0_2_TCV1_2] = { .val = 0b11111111 }, + [FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2] = { .val = 0b11110000 }, + [FEM_WIRING_22_OBSOLETE] = { .val = 0b00000000 }, + [FEM_WIRING_23_TCV0_4_TCV1_4] = { .val = 0b00000000 }, + [FEM_WIRING_24_TCV0_6_TCV1_4] = { .val = 0b11000011 }, + [FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0] = { .val = 0b11001111 }, + [FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1] = { .val = 0b11001111 }, + [FEM_WIRING_27_TCV0_2_TCV1_1] = { .val = 0b11011111 }, + [FEM_WIRING_28_TCV0_4_TCV1_2] = { .val = 0b11110000 }, + [FEM_WIRING_29_TCV0_4_TCV1_2] = { .val = 0b11000000 }, + [FEM_WIRING_30_TCV0_4_TCV1_2] = { .val = 0b11111111 }, + [FEM_WIRING_31_TCV0_2_TCV1_1] = { .val = 0b11111100 }, + [FEM_WIRING_32_TCV0_4_TCV1_0] = { .val = 0b11110000 }, + [FEM_WIRING_33_TCV0_4_TCV1_4] = { .val = 0b11111111 }, +}; + +static const u32 ricu_fem_conf[FEM_WIRING_MAX][TCV_MAX] = { + [FEM_WIRING_0_TCV0_6_TCV1_6] = { 0x00AB3021, 0x0054CD89 }, + [FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6] = { 0x00AB3021, 0x0054CD89 }, + [FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6] = { 0x00AB3021, 0x0054CD89 }, + [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089 }, + [FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089 }, + [FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089 }, + [FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089 }, + [FEM_WIRING_7_TCV0_4_TCV1_4] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_9_TCV0_4_TCV1_4] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_10_TCV0_4_TCV1_4] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_13_SENSING_4RX_2TX] = { 0x00003021, 0x00890000 }, + [FEM_WIRING_14_SENSING_4TX_2RX] = { 0x00003021, 0x00000089 }, + [FEM_WIRING_15_CHAMELEON_4TX_4RX] = { 0x00AB0001, 0x00320089 }, + [FEM_WIRING_16_TCV0_2_TCV1_2] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_17_TCV0_4_TCV1_0] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_18_TCV0_4_TCV1_4] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED] = { 0x00000000, 0x00AB3289 }, + [FEM_WIRING_20_TCV0_2_TCV1_2] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2] = { 0x00AB3210, 0x00000089 }, + [FEM_WIRING_22_OBSOLETE] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_23_TCV0_4_TCV1_4] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_24_TCV0_6_TCV1_4] = { 0x00543210, 0x00ABCD00 }, + [FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0] = { 0x000A3210, 0x000000AB }, + [FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1] = { 0x000A3210, 0x000000AB }, + [FEM_WIRING_27_TCV0_2_TCV1_1] = { 0x000A3210, 0x000000AB }, + [FEM_WIRING_28_TCV0_4_TCV1_2] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_29_TCV0_4_TCV1_2] = { 0x000A3210, 0x000000AB }, + [FEM_WIRING_30_TCV0_4_TCV1_2] = { 0x00000001, 0x0032AB89 }, + [FEM_WIRING_31_TCV0_2_TCV1_1] = { 0x00000010, 0x000000AB }, + [FEM_WIRING_32_TCV0_4_TCV1_0] = { 0x000A3210, 0x000000AB }, + [FEM_WIRING_33_TCV0_4_TCV1_4] = { 0x00000001, 0x0032AB89 }, +}; + +static const u8 fem_full_list[FEM_WIRING_MAX][TCV_MAX][FEM_LUT_AMOUNT_PER_MAC] = { + [FEM_WIRING_0_TCV0_6_TCV1_6] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + }, + [FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + }, + [FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + }, + [FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC, + FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC}, + }, + [FEM_WIRING_7_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_9_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_10_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING, + FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING, + FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_13_SENSING_4RX_2TX] = { + {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING, + FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_14_SENSING_4TX_2RX] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_15_CHAMELEON_4TX_4RX] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING, + FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_16_TCV0_2_TCV1_2] = { + {FEM_LUT_EMPTY, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_17_TCV0_4_TCV1_0] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_18_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED] = { + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_20_TCV0_2_TCV1_2] = { + {FEM_LUT_EMPTY, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_22_OBSOLETE] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_23_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_24_TCV0_6_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1}, + }, + [FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_SENSING, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_27_TCV0_2_TCV1_1] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_28_TCV0_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_29_TCV0_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_30_TCV0_4_TCV1_2] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_31_TCV0_2_TCV1_1] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_SENSING, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_32_TCV0_4_TCV1_0] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY, + FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + }, + [FEM_WIRING_33_TCV0_4_TCV1_4] = { + {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0, + FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1, + FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY}, + } +}; + +static u16 cl_fem_reg_manual(struct cl_hw *cl_hw, u16 val, u8 ant_idx) +{ + u16 lut, lut0, lut1, lut2; + u8 shift = cl_hw->fem_mode * 4; + + lut = (val >> shift) & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK; + lut0 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_0_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK); + lut1 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_1_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_1_MASK); + lut2 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_2_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_2_MASK); + + return (lut0 | lut1 | lut2); +} + +int cl_fem_get_registers(struct cl_hw *cl_hw, u32 fem_reg[FEM_REGISTERS_AMOUNT]) +{ + u8 i; + u8 reg_idx; + u8 reg_shift; + u8 tcv_idx = cl_hw->tcv_idx; + u16 reg_val; + struct cl_fem_params *fem = &cl_hw->chip->fem; + u8 chain_mask = cl_hw_ant_mask_to_riu_chain_mask(cl_hw, cl_hw->mask_num_antennas); + + /* In case there's no valid wiring_id, keep the fem lut registers empty. */ + if (fem->wiring_id >= FEM_WIRING_MAX) + return 0; + + for (i = 0; i < MAX_ANTENNAS; i++) { + reg_idx = i >> 1; /* 0 - 2 */ + reg_shift = (i & 0x1) ? 16 : 0; /* even - 0. odd - 16 */ + + if (chain_mask & BIT(i)) { + if (cl_hw->fem_mode == FEM_MODE_OPERETIONAL) { + reg_val = fem->lut_registers[tcv_idx][i]; + } else { + u16 fem_val = fem->lut_registers[tcv_idx][i]; + + reg_val = cl_fem_reg_manual(cl_hw, fem_val, i); + } + } else { + reg_val = fem->lut_off_register[tcv_idx]; + } + + fem_reg[reg_idx] |= ((u32)reg_val << reg_shift); + } + + for (i = 0; i < FEM_REGISTERS_AMOUNT; i++) + cl_dbg_trace(cl_hw, "RC_RFLNALUT_%u: [0x%08X]\n", i, fem_reg[i]); + + return 0; +} + +static int cl_fem_read_lut(struct cl_chip *chip) +{ + int i; + int has_valid_fem_lut = 0; + struct cl_fem_params *fem = &chip->fem; + + /* Read FEM LUT from eeprom */ + if (cl_e2p_read(chip, (u8 *)&fem->lut, SIZE_FEM_LUT, ADDR_FEM_LUT)) + return -1; + + for (i = 0; i < FEM_TYPE_MAX; i++) { + if (fem->lut[i] == U16_MAX) + continue; + + /* Mark as valid if at least one the FEM LUTs has a valid value. */ + has_valid_fem_lut = 1; + fem->lut_off_register_list[i] = EXTRACT_BYPASS_LUT(fem->lut[i]); + fem->lut[i] &= FEM_LUT_MASK; + cl_dbg_chip_trace(chip, "lut[%d] = 0x%X, lut_off_register_list[%d] = 0x%X\n", + i, fem->lut[i], i, fem->lut_off_register_list[i]); + } + + return !has_valid_fem_lut; +} + +#define FEM_LUT_OFFSET_BYPASS 0 +#define FEM_LUT_OFFSET_TX 4 +#define FEM_LUT_OFFSET_RX 8 +#define FEM_LUT_VAL_MASK 0x7 + +static int _cl_fem_check_lut_validity(struct cl_chip *chip, enum fem_type type) +{ + u16 fem_lut = chip->fem.lut[type]; + u16 bypass = (fem_lut >> FEM_LUT_OFFSET_BYPASS) & FEM_LUT_VAL_MASK; + u16 tx = (fem_lut >> FEM_LUT_OFFSET_TX) & FEM_LUT_VAL_MASK; + u16 rx = (fem_lut >> FEM_LUT_OFFSET_RX) & FEM_LUT_VAL_MASK; + int ret = 0; + + if (fem_lut == U16_MAX) { + cl_dbg_chip_err(chip, "Wiring_id [%u] must have valid FEM LUTs for %s\n", + chip->fem.wiring_id, FEM_TYPE_STR(type)); + return -ERANGE; + } + + /* Skip uniqueness check for sensing type */ + if (type == FEM_TYPE_SENSING) + return 0; + + /* Check uniqueness of BYPASS/TX/RX/OFF */ + if (bypass == tx) { + cl_dbg_chip_err(chip, "Error: bypass (%u) and tx (%u) values are equal\n", + bypass, tx); + ret = -EIO; + } + + if (bypass == rx) { + cl_dbg_chip_err(chip, "Error: bypass (%u) and rx (%u) values are equal\n", + bypass, rx); + ret = -EIO; + } + + if (tx == rx) { + cl_dbg_chip_err(chip, "Error: tx (%u) and rx (%u) values are equal\n", + tx, rx); + ret = -EIO; + } + + return ret; +} + +static int cl_fem_check_lut_validity(struct cl_chip *chip, u8 wiring_id) +{ + if (cl_fem_read_lut(chip)) { + cl_dbg_chip_err(chip, "None of the FEM LUTs is valid. Aborting.\n"); + return -EINVAL; + } + + switch (wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_20_TCV0_2_TCV1_2: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_24_TCV0_6_TCV1_4: + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_27_TCV0_2_TCV1_1: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_29_TCV0_4_TCV1_2: + case FEM_WIRING_30_TCV0_4_TCV1_2: + case FEM_WIRING_33_TCV0_4_TCV1_4: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1)) + return -EINVAL; + break; + + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_32_TCV0_4_TCV1_0: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0)) + return -EINVAL; + break; + + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_ELASTIC)) + return -EINVAL; + break; + + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + case FEM_WIRING_31_TCV0_2_TCV1_1: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_SENSING)) + return -EINVAL; + break; + + case FEM_WIRING_13_SENSING_4RX_2TX: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_SENSING)) + return -EINVAL; + break; + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1) || + _cl_fem_check_lut_validity(chip, FEM_TYPE_SENSING)) + return -EINVAL; + break; + + case FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6: + case FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6: + case FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2: + case FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2: + case FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2: + case FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4: + case FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED: + case FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2: + case FEM_WIRING_22_OBSOLETE: + cl_dbg_chip_err(chip, "wiring_id %u is not supported\n", wiring_id); + return -EOPNOTSUPP; + + default: + cl_dbg_chip_err(chip, "Wiring_id [%u] is not valid [0..%u]\n", + wiring_id, FEM_WIRING_MAX - 1); + return -EINVAL; + } + + return 0; +} + +static int cl_fem_validate_wiring_id(struct cl_chip *chip, u8 wiring_id) +{ + switch (wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_13_SENSING_4RX_2TX: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_33_TCV0_4_TCV1_4: + return cl_chip_is_8ant(chip) ? 0 : -1; + case FEM_WIRING_24_TCV0_6_TCV1_4: + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_29_TCV0_4_TCV1_2: + case FEM_WIRING_30_TCV0_4_TCV1_2: + return cl_chip_is_6ant(chip) ? 0 : -1; + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_20_TCV0_2_TCV1_2: + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_32_TCV0_4_TCV1_0: + return cl_chip_is_4ant(chip) ? 0 : -1; + case FEM_WIRING_27_TCV0_2_TCV1_1: + case FEM_WIRING_31_TCV0_2_TCV1_1: + return cl_chip_is_4ant(chip) || cl_chip_is_3ant(chip) ? 0 : -1; + default: + cl_dbg_chip_err(chip, "wiring_id %u is not valid. [0..%u] are valid values\n", + wiring_id, (FEM_WIRING_MAX - 1)); + return -ERANGE; + } + + return -EINVAL; +} + +int cl_fem_read_wiring_id(struct cl_chip *chip) +{ + struct cl_fem_params *fem = &chip->fem; + + /* In case there's a valid wiring id in chip, no need to re-read it from EEPROM */ + if (fem->wiring_id < FEM_WIRING_MAX) + return 0; + + /* Read wiring_id from eeprom */ + if (cl_e2p_read(chip, &fem->wiring_id, SIZE_FEM_WIRING_ID, ADDR_FEM_WIRING_ID)) + return -1; + + return cl_fem_validate_wiring_id(chip, fem->wiring_id); +} + +static void cl_fem_set_registers(struct cl_chip *chip) +{ + struct cl_fem_params *fem = &chip->fem; + int i; + u8 wiring_id = fem->wiring_id; + + if (wiring_id >= FEM_WIRING_MAX) + return; + + for (i = 0; i < FEM_LUT_AMOUNT_PER_MAC; i++) { + fem->lut_registers[TCV0][i] = fem->lut[fem_full_list[wiring_id][TCV0][i]]; + fem->lut_registers[TCV1][i] = fem->lut[fem_full_list[wiring_id][TCV1][i]]; + } +} + +static int cl_fem_set_lut_off(struct cl_chip *chip) +{ + struct cl_fem_params *fem = &chip->fem; + + switch (fem->wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_20_TCV0_2_TCV1_2: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_24_TCV0_6_TCV1_4: + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + case FEM_WIRING_27_TCV0_2_TCV1_1: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_29_TCV0_4_TCV1_2: + case FEM_WIRING_30_TCV0_4_TCV1_2: + case FEM_WIRING_33_TCV0_4_TCV1_4: + fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_TCV0]; + fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_TCV1]; + break; + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_32_TCV0_4_TCV1_0: + fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_TCV0]; + break; + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_ELASTIC]; + fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_ELASTIC]; + break; + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + case FEM_WIRING_31_TCV0_2_TCV1_1: + fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_TCV0]; + fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_SENSING]; + break; + case FEM_WIRING_13_SENSING_4RX_2TX: + fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_SENSING]; + fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_TCV1]; + break; + default: + cl_dbg_chip_err(chip, "Unsupported wiring id [%u]\n", fem->wiring_id); + return -EINVAL; + } + + cl_dbg_chip_trace(chip, "wiring_id = %u, lut_off_register = [%u %u]\n", + fem->wiring_id, + fem->lut_off_register[TCV0], + fem->lut_off_register[TCV1]); + return 0; +} + +int cl_fem_init(struct cl_chip *chip) +{ + int ret = 0; + struct cl_fem_params *fem = &chip->fem; + + fem->wiring_id = FEM_WIRING_DEFAULT; + + ret = cl_fem_read_wiring_id(chip); + + if (ret) { + CL_DBG_ERROR_CHIP(chip, "Invalid wiring_id = %u. Aborting.\n", fem->wiring_id); + + if (!chip->conf->ce_production_mode) + return ret; + } + + if (cl_fem_read_lut(chip)) { + CL_DBG_ERROR_CHIP(chip, "None of the FEM_LUT registers is valid. Aborting.\n"); + + if (!chip->conf->ce_production_mode) + return -EINVAL; + } + + if (cl_fem_check_lut_validity(chip, fem->wiring_id) && + !chip->conf->ce_production_mode) + return -EINVAL; + + if (cl_fem_set_lut_off(chip) && + !chip->conf->ce_production_mode) + return -EINVAL; + + cl_dbg_chip_verbose(chip, "wiring_id = %u\n", fem->wiring_id); + cl_fem_set_registers(chip); + + ret = cl_platform_alloc(chip); + if (ret) + return ret; + + return 0; +} + +static void cl_fem_get_conf_params(struct cl_chip *chip, + u32 *ricu_fem_conf_0, + u32 *ricu_fem_conf_1) +{ + u8 wiring_id = chip->fem.wiring_id; + + *ricu_fem_conf_0 = ricu_fem_conf[wiring_id][0]; + *ricu_fem_conf_1 = ricu_fem_conf[wiring_id][1]; + + cl_dbg_chip_verbose(chip, "ricu_fem_conf_0 = 0x%08X, ricu_fem_conf_1 = 0x%08X\n", + *ricu_fem_conf_0, *ricu_fem_conf_1); +} + +static u8 get_num_antennas_tcv0(struct cl_chip *chip) +{ + if (chip->cl_hw_tcv0) + return chip->cl_hw_tcv0->num_antennas; + else + return chip->max_antennas - chip->cl_hw_tcv1->num_antennas; +} + +static void cl_update_formation_1_band_select(struct cl_chip *chip) +{ + u8 num_antennas_tcv0 = get_num_antennas_tcv0(chip); + + if (num_antennas_tcv0 == 2) { + io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + } else if (num_antennas_tcv0 == 3) { + io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + } else if (num_antennas_tcv0 == 4) { + io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + } else if (num_antennas_tcv0 == 5) { + io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0)); + io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + } else if (num_antennas_tcv0 == 6) { + io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1)); + } +} + +static u8 cl_fem_extract_val(struct cl_chip *chip, u16 fem_lut, enum fem_mode mode) +{ + switch (mode) { + case FEM_MODE_LNA_BYPASS_ONLY: + return (fem_lut >> FEM_LUT_OFFSET_BYPASS) & FEM_LUT_VAL_MASK; + case FEM_MODE_TX_ONLY: + return (fem_lut >> FEM_LUT_OFFSET_TX) & FEM_LUT_VAL_MASK; + case FEM_MODE_RX_ONLY: + return (fem_lut >> FEM_LUT_OFFSET_RX) & FEM_LUT_VAL_MASK; + default: + cl_dbg_chip_err(chip, "Invalid fem mode %u\n", mode); + } + + /* Return bypass value for invalid fem modes */ + return (fem_lut >> FEM_LUT_OFFSET_BYPASS) & FEM_LUT_VAL_MASK; +} + +static void cl_set_manual_fem_gpio(struct cl_chip *chip, enum fem_mode mode) +{ + struct cl_fem_params *fem = &chip->fem; + u8 fem_val_tcv0 = cl_fem_extract_val(chip, fem->lut[FEM_TYPE_TCV0], mode); + u8 fem_val_tcv1 = cl_fem_extract_val(chip, fem->lut[FEM_TYPE_TCV1], mode); + u8 fem_val_elastic = cl_fem_extract_val(chip, fem->lut[FEM_TYPE_ELASTIC], mode); + u8 fem_val_sensing = cl_fem_extract_val(chip, fem->lut[FEM_TYPE_SENSING], mode); + u8 pa_enable_bit_tcv0 = GET_BIT(fem_val_tcv0, PA_ENABLE_POS); + u8 pa_enable_bit_tcv1 = GET_BIT(fem_val_tcv1, PA_ENABLE_POS); + u8 pa_enable_bit_elastic = GET_BIT(fem_val_elastic, PA_ENABLE_POS); + u8 pa_enable_bit_sensing = GET_BIT(fem_val_sensing, PA_ENABLE_POS); + u8 lna_enable_bit_tcv0 = GET_BIT(fem_val_tcv0, LNA_ENABLE_POS); + u8 lna_enable_bit_tcv1 = GET_BIT(fem_val_tcv1, LNA_ENABLE_POS); + u8 lna_enable_bit_elastic = GET_BIT(fem_val_elastic, LNA_ENABLE_POS); + u8 lna_enable_bit_sensing = GET_BIT(fem_val_sensing, LNA_ENABLE_POS); + u8 rx_active_bit_tcv0 = GET_BIT(fem_val_tcv0, RX_ACTIVE_POS); + u8 rx_active_bit_tcv1 = GET_BIT(fem_val_tcv1, RX_ACTIVE_POS); + u8 rx_active_bit_sensing = GET_BIT(fem_val_sensing, RX_ACTIVE_POS); + u32 pa_enable_cfg_tcv0 = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_tcv0); + u32 pa_enable_cfg_tcv1 = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_tcv1); + u32 pa_enable_cfg_elastic = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_elastic); + u32 pa_enable_cfg_sensing = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_sensing); + u32 lna_enable_cfg_tcv0 = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_tcv0); + u32 lna_enable_cfg_tcv1 = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_tcv1); + u32 lna_enable_cfg_elastic = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_elastic); + u32 lna_enable_cfg_sensing = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_sensing); + u32 rx_active_cfg_tcv0 = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_tcv0); + u32 rx_active_cfg_tcv1 = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_tcv1); + u32 rx_active_cfg_sensing = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_sensing); + + switch (fem->wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_7_TCV0_4_TCV1_4: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_16_TCV0_2_TCV1_2: + case FEM_WIRING_17_TCV0_4_TCV1_0: + case FEM_WIRING_18_TCV0_4_TCV1_4: + case FEM_WIRING_20_TCV0_2_TCV1_2: + case FEM_WIRING_23_TCV0_4_TCV1_4: + case FEM_WIRING_28_TCV0_4_TCV1_2: + case FEM_WIRING_30_TCV0_4_TCV1_2: + case FEM_WIRING_32_TCV0_4_TCV1_0: + case FEM_WIRING_33_TCV0_4_TCV1_4: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv0); + break; + case FEM_WIRING_31_TCV0_2_TCV1_1: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv0); + break; + case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_elastic); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_elastic); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_elastic); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_elastic); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0); + break; + case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_15_CHAMELEON_4TX_4RX: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv0); + break; + case FEM_WIRING_13_SENSING_4RX_2TX: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_sensing); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_sensing); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_4_set(chip, lna_enable_cfg_tcv1); + io_ctrl_pa_enable_5_set(chip, lna_enable_cfg_tcv1); + io_ctrl_pa_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_pa_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_pa_enable_8_set(chip, lna_enable_cfg_tcv1); + io_ctrl_pa_enable_9_set(chip, lna_enable_cfg_tcv1); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_sensing); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_sensing); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_sensing); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_sensing); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1); + break; + case FEM_WIRING_24_TCV0_6_TCV1_4: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv1); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv1); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1); + break; + case FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0: + case FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1: + case FEM_WIRING_27_TCV0_2_TCV1_1: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1); + break; + case FEM_WIRING_29_TCV0_4_TCV1_2: + io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1); + io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0); + io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0); + + io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1); + io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0); + io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0); + + io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1); + io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv0); + io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv0); + break; + default: + break; + } +} + +static void cl_set_lna_bypass_gpio(struct cl_chip *chip) +{ + cl_set_manual_fem_gpio(chip, FEM_MODE_LNA_BYPASS_ONLY); +} + +static void _cl_fem_conf_gpio(struct cl_chip *chip, + const struct cl_fem_lna_enable_gpio *lna_enable_gpio, + const struct cl_fem_pa_enable_gpio *pa_enable_gpio, + const struct cl_fem_rx_active_gpio *rx_active_gpio) +{ + io_ctrl_lna_enable_0_gpio_enable_setf(chip, lna_enable_gpio->bits.b0); + io_ctrl_lna_enable_1_gpio_enable_setf(chip, lna_enable_gpio->bits.b1); + io_ctrl_lna_enable_2_gpio_enable_setf(chip, lna_enable_gpio->bits.b2); + io_ctrl_lna_enable_3_gpio_enable_setf(chip, lna_enable_gpio->bits.b3); + io_ctrl_lna_enable_4_gpio_enable_setf(chip, lna_enable_gpio->bits.b4); + io_ctrl_lna_enable_5_gpio_enable_setf(chip, lna_enable_gpio->bits.b5); + io_ctrl_lna_enable_6_gpio_enable_setf(chip, lna_enable_gpio->bits.b6); + io_ctrl_lna_enable_7_gpio_enable_setf(chip, lna_enable_gpio->bits.b7); + io_ctrl_lna_enable_8_gpio_enable_setf(chip, lna_enable_gpio->bits.b8); + io_ctrl_lna_enable_9_gpio_enable_setf(chip, lna_enable_gpio->bits.b9); + io_ctrl_lna_enable_10_gpio_enable_setf(chip, lna_enable_gpio->bits.b10); + io_ctrl_lna_enable_11_gpio_enable_setf(chip, lna_enable_gpio->bits.b11); + + io_ctrl_pa_enable_0_gpio_enable_setf(chip, pa_enable_gpio->bits.b0); + io_ctrl_pa_enable_1_gpio_enable_setf(chip, pa_enable_gpio->bits.b1); + io_ctrl_pa_enable_2_gpio_enable_setf(chip, pa_enable_gpio->bits.b2); + io_ctrl_pa_enable_3_gpio_enable_setf(chip, pa_enable_gpio->bits.b3); + io_ctrl_pa_enable_4_gpio_enable_setf(chip, pa_enable_gpio->bits.b4); + io_ctrl_pa_enable_5_gpio_enable_setf(chip, pa_enable_gpio->bits.b5); + io_ctrl_pa_enable_6_gpio_enable_setf(chip, pa_enable_gpio->bits.b6); + io_ctrl_pa_enable_7_gpio_enable_setf(chip, pa_enable_gpio->bits.b7); + io_ctrl_pa_enable_8_gpio_enable_setf(chip, pa_enable_gpio->bits.b8); + io_ctrl_pa_enable_9_gpio_enable_setf(chip, pa_enable_gpio->bits.b9); + io_ctrl_pa_enable_10_gpio_enable_setf(chip, pa_enable_gpio->bits.b10); + io_ctrl_pa_enable_11_gpio_enable_setf(chip, pa_enable_gpio->bits.b11); + + io_ctrl_rx_active_0_gpio_enable_setf(chip, rx_active_gpio->bits.b0); + io_ctrl_rx_active_1_gpio_enable_setf(chip, rx_active_gpio->bits.b1); + io_ctrl_rx_active_2_gpio_enable_setf(chip, rx_active_gpio->bits.b2); + io_ctrl_rx_active_3_gpio_enable_setf(chip, rx_active_gpio->bits.b3); + io_ctrl_rx_active_4_gpio_enable_setf(chip, rx_active_gpio->bits.b4); + io_ctrl_rx_active_5_gpio_enable_setf(chip, rx_active_gpio->bits.b5); + io_ctrl_rx_active_6_gpio_enable_setf(chip, rx_active_gpio->bits.b7); + io_ctrl_rx_active_7_gpio_enable_setf(chip, rx_active_gpio->bits.b7); +} + +static int cl_fem_conf_gpio(struct cl_chip *chip) +{ + struct cl_fem_params *fem = &chip->fem; + u8 wiring_id = fem->wiring_id; + + if (wiring_id == FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6 || + wiring_id == FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6 || + wiring_id == FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 || + wiring_id == FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 || + wiring_id == FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 || + wiring_id == FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4 || + wiring_id == FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED || + wiring_id == FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2 || + wiring_id == FEM_WIRING_22_OBSOLETE) { + cl_dbg_chip_err(chip, "Unsupported wiring id [%u]\n", wiring_id); + return -EOPNOTSUPP; + } + + if (cl_fem_validate_wiring_id(chip, wiring_id)) + return -EINVAL; + + _cl_fem_conf_gpio(chip, + &lna_enable_gpio[wiring_id], + &pa_enable_gpio[wiring_id], + &rx_active_gpio[wiring_id]); + + if (wiring_id == FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2) + cl_update_formation_1_band_select(chip); + + return 0; +} + +static int cl_fem_update_lut(struct cl_chip *chip) +{ + int ret = 0; + + ret = cl_fem_read_lut(chip); + if (ret) + return ret; + + ret = cl_fem_check_lut_validity(chip, chip->fem.wiring_id); + if (ret) + return ret; + + /* In case of invalid platform id, don't update FEM conf params*/ + ret = cl_fem_set_lut_off(chip); + if (ret) + return ret; + + cl_fem_set_registers(chip); + + return ret; +} + +void cl_fem_set_dcoc_bypass(struct cl_hw *cl_hw) +{ + cl_hw->fem_mode = FEM_MODE_LNA_BYPASS_ONLY; +} + +void cl_fem_dcoc_restore(struct cl_hw *cl_hw, u8 fem_mode) +{ + cl_hw->fem_mode = fem_mode; +} + +void cl_fem_set_iq_bypass(struct cl_hw *cl_hw) +{ + cl_set_lna_bypass_gpio(cl_hw->chip); + + cl_hw->fem_mode = FEM_MODE_LNA_BYPASS_ONLY; +} + +void cl_fem_iq_restore(struct cl_hw *cl_hw, u8 fem_mode) +{ + cl_fem_conf_gpio(cl_hw->chip); + cl_hw->fem_mode = fem_mode; +} + +int cl_fem_update_conf_params(struct cl_chip *chip) +{ + u32 ricu_fem_conf_0, ricu_fem_conf_1 = 0; + int ret = 0; + + ret = cl_fem_update_lut(chip); + if (ret) + return ret; + + cl_fem_get_conf_params(chip, &ricu_fem_conf_0, &ricu_fem_conf_1); + ricu_fem_conf_0_set(chip, ricu_fem_conf_0); + ricu_fem_conf_1_set(chip, ricu_fem_conf_1); + + ret = cl_fem_conf_gpio(chip); + if (ret) + return ret; + + return 0; +} + +bool cl_fem_wiring_id_is_evb(struct cl_chip *chip) +{ + u8 wiring_id = chip->fem.wiring_id; + + switch (wiring_id) { + case FEM_WIRING_0_TCV0_6_TCV1_6: + case FEM_WIRING_9_TCV0_4_TCV1_4: + case FEM_WIRING_10_TCV0_4_TCV1_4: + case FEM_WIRING_13_SENSING_4RX_2TX: + case FEM_WIRING_14_SENSING_4TX_2RX: + case FEM_WIRING_24_TCV0_6_TCV1_4: + return true; + default: + break; + } + + return false; +} + From patchwork Tue May 24 11:34:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576837 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 15121C433EF for ; Tue, 24 May 2022 11:41:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236954AbiEXLkw (ORCPT ); Tue, 24 May 2022 07:40:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236952AbiEXLkm (ORCPT ); Tue, 24 May 2022 07:40:42 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50045.outbound.protection.outlook.com [40.107.5.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5947391550 for ; Tue, 24 May 2022 04:40:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kNBnZsdPzCfeWTyQYftSt4TjFU+8Wi2X3EuzNc8b0A/1Lia13oCdyhjRzpy96+2WfUn5Zl2sPq3tRBHkeYO2xxRzmcF5f2HQWPCCMnseBY/0Oa+6fxSS0AT7Gc93s1R/g2EdefnaoB9Fn59cbROhow0X6zuUUvWl0sa3RnioiIJfE42TwhtkS/HpPlR++YzMmq7RL9nuMQdOFQvqwwGbQcsdiLOL8YjHuOWNVOwf0a2UKtLTae2HeSt5MAo1QCb9KOsqD5DuxIHjuPf175c5mVjjiBKlqA9vpu/6H+VN/fPpJiJXa9+QiEGHDirJGBefGLE9whOSQCNMY9YLUZMj+g== 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=BCLaKWHcvztBBwCIsD6TtiEDwbl0C4sxuLq/9hj6wus=; b=YKHW0nss90jGTiUSWIQRSRp+9bl4dEJ1QSivzw83nd8SP0ZhxgrbOuTogchvsnPgt9oNGtzIpkyhCdfSI8RaRpZJCs6/4Dqn9yjpIvC/SesGNCCZObj7DxgsSBe+L9vZ01O/M1ZgmHWVZMrEAm8cmsV810lChXM+LTp4zASBhu6Grkn/rel3qFQnRjnq8hJHf6bhCx5s1sSqYFmKAtqFYdNG0yPkxC7XsVKRL91BmCSAZVBaT/RNk8/9fjVNAxS5EC9kvWvbPf5pyZaU9PE/loBimURToiCS5YClRGEtkbQbFPT8Lx3evnoddBkVmO3XejVdlEv9x3o/hPcs5u8c7w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BCLaKWHcvztBBwCIsD6TtiEDwbl0C4sxuLq/9hj6wus=; b=13/GvQpacSsw33WLAmyZ3mEH90cdQVA6Xz/Er+Rt7PW+fmzIgOockTR7WSNwd0Hy9JWukAKx/L8m9/dz/wLgbnB2ZuMmT0pJqqpVXQvaVEVDh9VPbfrPxUuAD9jZtL+gQqRoxSos7RmI/gbRIsnUAeEGUfM96rNtyz1VeiOuTIY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:47 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:47 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 51/96] cl8k: add phy.h Date: Tue, 24 May 2022 14:34:17 +0300 Message-Id: <20220524113502.1094459-52-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e91afe85-d3c5-4b12-41b2-08da3d79ecee X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: MkKX7qagIjxZ57/nhlIlGqYrDzYtl1NK6XXSZ7d9drSR4OLf7gbQbXmgAdMO+zmVZIrX0zL69aWXiQNSCwXIK+Glt7uRuaBySvQAqWmke6FiYRVtdr/CMdWw7CSzOukkQkV1+2W1r7oebgmO6bVT75gdZ4IqAK+BsVUlbg1XkXvBX22gYNHWrEZf4zobtTq/hrIwQxH9x9dZPDalmAeGWWWaQFafbChqaSRbpEa+dQxEMhZHjHmUxsyUU6ATQ1ZpE/gRfwpkmWYXabSp1q3P7aK/x5Vhx01JDe3pWwvkgkpzlE/b+wIZUIhCkc1VlKTQrCkgiXZH1mOVWKcdo0p0rF82zZxJf3QtdLfSWYnsDGBtAgACRxdtgeyGOnYmOlzCH1v4/pZRPzStBVgTfXhvX7xtPjmEgT9uqLNT2SLH6brW/fRB5fdIeF52n0NIvTRJLN7sPDCjKAJgYCsYOeSt1D+U0L7JxPYAM/20SOI1SJ8oVC2GSNI/AjrGN7OVQMMHWoTTFO4Rm1QjhoWAkbWE84VDxv1W8ok4hldhrh1IZrab4eDQfw89Gj19ATu0cngP+don7KLK5Zr6x5SR0bh9yS+TzCi7oMylco8ZZOuYNeOXjrSqT++zQLONFnx3IEeNBok/siItZPV5BP9KEaJOdzLUgitOQJPsMoQwGXQWbtvS/zlRN1zKPLaRmLc6xSxPHlLmmt5A3GIuuNZXSuyGtUGXdZJ9gbJEdS84eI3M0yM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: x8UxTJJ++qoyD4DVlV+OTvZ01I2EDLu69Yv99/+Y3NtrALjaeAB/h6gA9JJnJcsoWbajDbXxB3fjf55s4bh7rwdUMNIbWfVumedhfe3XnhxiL7sIfUqyt9IqctVjvwyEvT8i8N/YGwYtrdU1okH79nQxd3+hAiWiNW9hzXCHfo/+/4GcjwHHNMwbY4QuxoAhAZwtxwj0BnFYfvvDqoKpUsDISNlccxLUDvN3xDmXoGsQOAIxmFe6RQkUQdbjn3JH/rCYB/GxdjqWcWOazKlOVYJFFviXw8kILXGlzG2lwa8gwJX0gmhnqpWiS4wd/lohP5JyzlyfiehBFC6fqEcNAJwKNA1Uygm8Retyz8qoe8rHg83f4ChMU0m6vPHqkiPSwuM+/KarnJFGz3EpIJSLWTAeUJt0YNsLBgddqGVBB4dBXQSa7wCxv/dnEtp6OU4lJLItGc1txesQjaNO5dfbRe4uwZGrxdhGxQK9ZFZ2pSqqifN3Ay9B82Vb2x+efmCSGW/gRNcY/IuhPTQBr/HKviLe3o9qdaEO5f70QrMgc1dHNSHAycztghFENuHyiu2PecT7P/ZatjIA1DDWdJXjaJMvRPWTAUWn/SDCsfVGjO0IUaV/R35pcsz4mYLp/EvhTdjSAXGmpuEm+AJ04lYl58XO95/qOUxNxc0LXDCxuJlcPg6H1rQAYXNehfWXG20W1UA+mXK0aiof0B2QxSMHGawfp0ZYPhoHdWCQui+EvGrsvFiIa54+l7+BTVBFO6rEeqaOR0K1SDvUhtBQGPZ1ugJwWyZEUU7CGFcnVa3BRi3zCCc6aNwQvYPDTcjGydSdkj1wATbEObOq+WPixRegRdf1Mujki/acEVpR86XUghrfcBeW8m3XsUHqQDEHg4WAi0Qx3UFo561udx/on5+/3dp/bqZXAtOxymkfSaMRmEnK11FZyOOrtpLoXgLAO/BFadCkftVolfZYJpYPazPk40nJE86hVaIpBZaUuuJMOsMbdkavJnzrPKCYlXxLq3q9JFgOmnxetwX3MXpFsObNWqDM3vRDcTUdRDUD7N55XhdpOSLLEBgdEWTUXMNIb4LLkPqwevJS7CwaFFUfpBbyjeZeJux5aHr7BwrLDeq0mVQJu8wNNCuDTHXO3fjMUBQIKR3JEALeZ8KV/PAOU14PQmF3CDbTALlCDAe66FyGQnAT+NjuCMiLicl4OileBx12fyRfsQVhx39SEXseoIyhq76AcEzTun4NVFi2C8Na61h0IxyuFs7JK6tlAJj1Dm7j6B6ZnC1TEo+9BFM7CI3sROCdnnfo1gagoCrI9MafaTw7C5uWwjLzhwPM+OTu4k+9wSL6PLqM/RwtRNWagcM39T5iEs/Z+Utvw1J8R2sROixbYGfYHnAmupA8/eqyFtJioL0vJzLIHwa9g0JUkuZTxCwOwoKf5DsE1ieVvR3HQMDeX8mgbdOFum8nhgDHTOFqGhGA0Sxp2vytBgBucUtx99IRzsquDHc7n8DDPyDMmA3a/AlVFMWhj8j8X1EC3PLFe8i1FykI0iWC6CjqEAYk7AonXG2Mik9GJY64fsPQbmigOJHxf8zA08JdrK3vCAbp85srr8nrhICpkNDttbaZkMOoCqBryt1UjGBQkaY65RQSsJScypkgv4jOhDRH6Hi+mQkiR7jHSEmx/lS5+PHriX3GzTkvX9d1Li8DkzI8M/T1b3i2Jlux3I2slrWoLtLs6ftMjKcDFdDD0+YB3QPUgYz3wvob09hRr5D26+2jo/8= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: e91afe85-d3c5-4b12-41b2-08da3d79ecee X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:30.5470 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TO3vSFY6YUm0aYdzrR0qimhhnQ8UcjCazUFIQAPgiGk5ID9jHP1+2lg0B/LFNI5gPUujpRf2UC8TRl9bSR6vnw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/phy.h | 3680 ++++++++++++++++++++++++ 1 file changed, 3680 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/phy.h diff --git a/drivers/net/wireless/celeno/cl8k/phy.h b/drivers/net/wireless/celeno/cl8k/phy.h new file mode 100644 index 000000000000..ed5a2d847d3d --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/phy.h @@ -0,0 +1,3680 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_PHY_H +#define CL_PHY_H + +#include + +#include "power.h" +#include "def.h" + +struct cl_phy_data { + struct cl_pwr_tables pwr_tables; + struct cl_iq_dcoc_info iq_dcoc_db; + struct cl_agc_params agc_params; +}; + +struct cl_phy_data_info { + struct cl_phy_data *data; + u32 dma_addr; +}; + +void cl_phy_reset(struct cl_hw *cl_hw); +void cl_phy_off(struct cl_hw *cl_hw); +int cl_phy_load_recovery(struct cl_hw *cl_hw); +int cl_phy_data_alloc(struct cl_hw *cl_hw); +void cl_phy_data_free(struct cl_hw *cl_hw); +void cl_phy_enable(struct cl_hw *cl_hw); + +struct common_lut_line { + u16 frequency_q2; + u8 vcocalsel; + u8 nint; + u32 nfrac; + u32 freqmeastarg; +}; + +void cl_phy_oly_lut_update(u8 rfic_version, u8 nl_band, u16 freq, + struct mm_mac_api_lut_line *api_lut_line); + +enum athos_lut_idx_6g { + ATHOS_LUT_CHAN_593000_IDX, + ATHOS_LUT_CHAN_593125_IDX, + ATHOS_LUT_CHAN_593250_IDX, + ATHOS_LUT_CHAN_593375_IDX, + ATHOS_LUT_CHAN_593500_IDX, + ATHOS_LUT_CHAN_593625_IDX, + ATHOS_LUT_CHAN_593750_IDX, + ATHOS_LUT_CHAN_593875_IDX, + ATHOS_LUT_CHAN_594000_IDX, + ATHOS_LUT_CHAN_594125_IDX, + ATHOS_LUT_CHAN_594250_IDX, + ATHOS_LUT_CHAN_594375_IDX, + ATHOS_LUT_CHAN_594500_IDX, + ATHOS_LUT_CHAN_594625_IDX, + ATHOS_LUT_CHAN_594750_IDX, + ATHOS_LUT_CHAN_594875_IDX, + ATHOS_LUT_CHAN_595000_IDX, + ATHOS_LUT_CHAN_595125_IDX, + ATHOS_LUT_CHAN_595250_IDX, + ATHOS_LUT_CHAN_595375_IDX, + ATHOS_LUT_CHAN_595500_IDX, + ATHOS_LUT_CHAN_595625_IDX, + ATHOS_LUT_CHAN_595750_IDX, + ATHOS_LUT_CHAN_595875_IDX, + ATHOS_LUT_CHAN_596000_IDX, + ATHOS_LUT_CHAN_596125_IDX, + ATHOS_LUT_CHAN_596250_IDX, + ATHOS_LUT_CHAN_596375_IDX, + ATHOS_LUT_CHAN_596500_IDX, + ATHOS_LUT_CHAN_596625_IDX, + ATHOS_LUT_CHAN_596750_IDX, + ATHOS_LUT_CHAN_596875_IDX, + ATHOS_LUT_CHAN_597000_IDX, + ATHOS_LUT_CHAN_597125_IDX, + ATHOS_LUT_CHAN_597250_IDX, + ATHOS_LUT_CHAN_597375_IDX, + ATHOS_LUT_CHAN_597500_IDX, + ATHOS_LUT_CHAN_597625_IDX, + ATHOS_LUT_CHAN_597750_IDX, + ATHOS_LUT_CHAN_597875_IDX, + ATHOS_LUT_CHAN_598000_IDX, + ATHOS_LUT_CHAN_598125_IDX, + ATHOS_LUT_CHAN_598250_IDX, + ATHOS_LUT_CHAN_598375_IDX, + ATHOS_LUT_CHAN_598500_IDX, + ATHOS_LUT_CHAN_598625_IDX, + ATHOS_LUT_CHAN_598750_IDX, + ATHOS_LUT_CHAN_598875_IDX, + ATHOS_LUT_CHAN_599000_IDX, + ATHOS_LUT_CHAN_599125_IDX, + ATHOS_LUT_CHAN_599250_IDX, + ATHOS_LUT_CHAN_599375_IDX, + ATHOS_LUT_CHAN_599500_IDX, + ATHOS_LUT_CHAN_599625_IDX, + ATHOS_LUT_CHAN_599750_IDX, + ATHOS_LUT_CHAN_599875_IDX, + ATHOS_LUT_CHAN_600000_IDX, + ATHOS_LUT_CHAN_600125_IDX, + ATHOS_LUT_CHAN_600250_IDX, + ATHOS_LUT_CHAN_600375_IDX, + ATHOS_LUT_CHAN_600500_IDX, + ATHOS_LUT_CHAN_600625_IDX, + ATHOS_LUT_CHAN_600750_IDX, + ATHOS_LUT_CHAN_600875_IDX, + ATHOS_LUT_CHAN_601000_IDX, + ATHOS_LUT_CHAN_601125_IDX, + ATHOS_LUT_CHAN_601250_IDX, + ATHOS_LUT_CHAN_601375_IDX, + ATHOS_LUT_CHAN_601500_IDX, + ATHOS_LUT_CHAN_601625_IDX, + ATHOS_LUT_CHAN_601750_IDX, + ATHOS_LUT_CHAN_601875_IDX, + ATHOS_LUT_CHAN_602000_IDX, + ATHOS_LUT_CHAN_602125_IDX, + ATHOS_LUT_CHAN_602250_IDX, + ATHOS_LUT_CHAN_602375_IDX, + ATHOS_LUT_CHAN_602500_IDX, + ATHOS_LUT_CHAN_602625_IDX, + ATHOS_LUT_CHAN_602750_IDX, + ATHOS_LUT_CHAN_602875_IDX, + ATHOS_LUT_CHAN_603000_IDX, + ATHOS_LUT_CHAN_603125_IDX, + ATHOS_LUT_CHAN_603250_IDX, + ATHOS_LUT_CHAN_603375_IDX, + ATHOS_LUT_CHAN_603500_IDX, + ATHOS_LUT_CHAN_603625_IDX, + ATHOS_LUT_CHAN_603750_IDX, + ATHOS_LUT_CHAN_603875_IDX, + ATHOS_LUT_CHAN_604000_IDX, + ATHOS_LUT_CHAN_604125_IDX, + ATHOS_LUT_CHAN_604250_IDX, + ATHOS_LUT_CHAN_604375_IDX, + ATHOS_LUT_CHAN_604500_IDX, + ATHOS_LUT_CHAN_604625_IDX, + ATHOS_LUT_CHAN_604750_IDX, + ATHOS_LUT_CHAN_604875_IDX, + ATHOS_LUT_CHAN_605000_IDX, + ATHOS_LUT_CHAN_605125_IDX, + ATHOS_LUT_CHAN_605250_IDX, + ATHOS_LUT_CHAN_605375_IDX, + ATHOS_LUT_CHAN_605500_IDX, + ATHOS_LUT_CHAN_605625_IDX, + ATHOS_LUT_CHAN_605750_IDX, + ATHOS_LUT_CHAN_605875_IDX, + ATHOS_LUT_CHAN_606000_IDX, + ATHOS_LUT_CHAN_606125_IDX, + ATHOS_LUT_CHAN_606250_IDX, + ATHOS_LUT_CHAN_606375_IDX, + ATHOS_LUT_CHAN_606500_IDX, + ATHOS_LUT_CHAN_606625_IDX, + ATHOS_LUT_CHAN_606750_IDX, + ATHOS_LUT_CHAN_606875_IDX, + ATHOS_LUT_CHAN_607000_IDX, + ATHOS_LUT_CHAN_607125_IDX, + ATHOS_LUT_CHAN_607250_IDX, + ATHOS_LUT_CHAN_607375_IDX, + ATHOS_LUT_CHAN_607500_IDX, + ATHOS_LUT_CHAN_607625_IDX, + ATHOS_LUT_CHAN_607750_IDX, + ATHOS_LUT_CHAN_607875_IDX, + ATHOS_LUT_CHAN_608000_IDX, + ATHOS_LUT_CHAN_608125_IDX, + ATHOS_LUT_CHAN_608250_IDX, + ATHOS_LUT_CHAN_608375_IDX, + ATHOS_LUT_CHAN_608500_IDX, + ATHOS_LUT_CHAN_608625_IDX, + ATHOS_LUT_CHAN_608750_IDX, + ATHOS_LUT_CHAN_608875_IDX, + ATHOS_LUT_CHAN_609000_IDX, + ATHOS_LUT_CHAN_609125_IDX, + ATHOS_LUT_CHAN_609250_IDX, + ATHOS_LUT_CHAN_609375_IDX, + ATHOS_LUT_CHAN_609500_IDX, + ATHOS_LUT_CHAN_609625_IDX, + ATHOS_LUT_CHAN_609750_IDX, + ATHOS_LUT_CHAN_609875_IDX, + ATHOS_LUT_CHAN_610000_IDX, + ATHOS_LUT_CHAN_610125_IDX, + ATHOS_LUT_CHAN_610250_IDX, + ATHOS_LUT_CHAN_610375_IDX, + ATHOS_LUT_CHAN_610500_IDX, + ATHOS_LUT_CHAN_610625_IDX, + ATHOS_LUT_CHAN_610750_IDX, + ATHOS_LUT_CHAN_610875_IDX, + ATHOS_LUT_CHAN_611000_IDX, + ATHOS_LUT_CHAN_611125_IDX, + ATHOS_LUT_CHAN_611250_IDX, + ATHOS_LUT_CHAN_611375_IDX, + ATHOS_LUT_CHAN_611500_IDX, + ATHOS_LUT_CHAN_611625_IDX, + ATHOS_LUT_CHAN_611750_IDX, + ATHOS_LUT_CHAN_611875_IDX, + ATHOS_LUT_CHAN_612000_IDX, + ATHOS_LUT_CHAN_612125_IDX, + ATHOS_LUT_CHAN_612250_IDX, + ATHOS_LUT_CHAN_612375_IDX, + ATHOS_LUT_CHAN_612500_IDX, + ATHOS_LUT_CHAN_612625_IDX, + ATHOS_LUT_CHAN_612750_IDX, + ATHOS_LUT_CHAN_612875_IDX, + ATHOS_LUT_CHAN_613000_IDX, + ATHOS_LUT_CHAN_613125_IDX, + ATHOS_LUT_CHAN_613250_IDX, + ATHOS_LUT_CHAN_613375_IDX, + ATHOS_LUT_CHAN_613500_IDX, + ATHOS_LUT_CHAN_613625_IDX, + ATHOS_LUT_CHAN_613750_IDX, + ATHOS_LUT_CHAN_613875_IDX, + ATHOS_LUT_CHAN_614000_IDX, + ATHOS_LUT_CHAN_614125_IDX, + ATHOS_LUT_CHAN_614250_IDX, + ATHOS_LUT_CHAN_614375_IDX, + ATHOS_LUT_CHAN_614500_IDX, + ATHOS_LUT_CHAN_614625_IDX, + ATHOS_LUT_CHAN_614750_IDX, + ATHOS_LUT_CHAN_614875_IDX, + ATHOS_LUT_CHAN_615000_IDX, + ATHOS_LUT_CHAN_615125_IDX, + ATHOS_LUT_CHAN_615250_IDX, + ATHOS_LUT_CHAN_615375_IDX, + ATHOS_LUT_CHAN_615500_IDX, + ATHOS_LUT_CHAN_615625_IDX, + ATHOS_LUT_CHAN_615750_IDX, + ATHOS_LUT_CHAN_615875_IDX, + ATHOS_LUT_CHAN_616000_IDX, + ATHOS_LUT_CHAN_616125_IDX, + ATHOS_LUT_CHAN_616250_IDX, + ATHOS_LUT_CHAN_616375_IDX, + ATHOS_LUT_CHAN_616500_IDX, + ATHOS_LUT_CHAN_616625_IDX, + ATHOS_LUT_CHAN_616750_IDX, + ATHOS_LUT_CHAN_616875_IDX, + ATHOS_LUT_CHAN_617000_IDX, + ATHOS_LUT_CHAN_617125_IDX, + ATHOS_LUT_CHAN_617250_IDX, + ATHOS_LUT_CHAN_617375_IDX, + ATHOS_LUT_CHAN_617500_IDX, + ATHOS_LUT_CHAN_617625_IDX, + ATHOS_LUT_CHAN_617750_IDX, + ATHOS_LUT_CHAN_617875_IDX, + ATHOS_LUT_CHAN_618000_IDX, + ATHOS_LUT_CHAN_618125_IDX, + ATHOS_LUT_CHAN_618250_IDX, + ATHOS_LUT_CHAN_618375_IDX, + ATHOS_LUT_CHAN_618500_IDX, + ATHOS_LUT_CHAN_618625_IDX, + ATHOS_LUT_CHAN_618750_IDX, + ATHOS_LUT_CHAN_618875_IDX, + ATHOS_LUT_CHAN_619000_IDX, + ATHOS_LUT_CHAN_619125_IDX, + ATHOS_LUT_CHAN_619250_IDX, + ATHOS_LUT_CHAN_619375_IDX, + ATHOS_LUT_CHAN_619500_IDX, + ATHOS_LUT_CHAN_619625_IDX, + ATHOS_LUT_CHAN_619750_IDX, + ATHOS_LUT_CHAN_619875_IDX, + ATHOS_LUT_CHAN_620000_IDX, + ATHOS_LUT_CHAN_620125_IDX, + ATHOS_LUT_CHAN_620250_IDX, + ATHOS_LUT_CHAN_620375_IDX, + ATHOS_LUT_CHAN_620500_IDX, + ATHOS_LUT_CHAN_620625_IDX, + ATHOS_LUT_CHAN_620750_IDX, + ATHOS_LUT_CHAN_620875_IDX, + ATHOS_LUT_CHAN_621000_IDX, + ATHOS_LUT_CHAN_621125_IDX, + ATHOS_LUT_CHAN_621250_IDX, + ATHOS_LUT_CHAN_621375_IDX, + ATHOS_LUT_CHAN_621500_IDX, + ATHOS_LUT_CHAN_621625_IDX, + ATHOS_LUT_CHAN_621750_IDX, + ATHOS_LUT_CHAN_621875_IDX, + ATHOS_LUT_CHAN_622000_IDX, + ATHOS_LUT_CHAN_622125_IDX, + ATHOS_LUT_CHAN_622250_IDX, + ATHOS_LUT_CHAN_622375_IDX, + ATHOS_LUT_CHAN_622500_IDX, + ATHOS_LUT_CHAN_622625_IDX, + ATHOS_LUT_CHAN_622750_IDX, + ATHOS_LUT_CHAN_622875_IDX, + ATHOS_LUT_CHAN_623000_IDX, + ATHOS_LUT_CHAN_623125_IDX, + ATHOS_LUT_CHAN_623250_IDX, + ATHOS_LUT_CHAN_623375_IDX, + ATHOS_LUT_CHAN_623500_IDX, + ATHOS_LUT_CHAN_623625_IDX, + ATHOS_LUT_CHAN_623750_IDX, + ATHOS_LUT_CHAN_623875_IDX, + ATHOS_LUT_CHAN_624000_IDX, + ATHOS_LUT_CHAN_624125_IDX, + ATHOS_LUT_CHAN_624250_IDX, + ATHOS_LUT_CHAN_624375_IDX, + ATHOS_LUT_CHAN_624500_IDX, + ATHOS_LUT_CHAN_624625_IDX, + ATHOS_LUT_CHAN_624750_IDX, + ATHOS_LUT_CHAN_624875_IDX, + ATHOS_LUT_CHAN_625000_IDX, + ATHOS_LUT_CHAN_625125_IDX, + ATHOS_LUT_CHAN_625250_IDX, + ATHOS_LUT_CHAN_625375_IDX, + ATHOS_LUT_CHAN_625500_IDX, + ATHOS_LUT_CHAN_625625_IDX, + ATHOS_LUT_CHAN_625750_IDX, + ATHOS_LUT_CHAN_625875_IDX, + ATHOS_LUT_CHAN_626000_IDX, + ATHOS_LUT_CHAN_626125_IDX, + ATHOS_LUT_CHAN_626250_IDX, + ATHOS_LUT_CHAN_626375_IDX, + ATHOS_LUT_CHAN_626500_IDX, + ATHOS_LUT_CHAN_626625_IDX, + ATHOS_LUT_CHAN_626750_IDX, + ATHOS_LUT_CHAN_626875_IDX, + ATHOS_LUT_CHAN_627000_IDX, + ATHOS_LUT_CHAN_627125_IDX, + ATHOS_LUT_CHAN_627250_IDX, + ATHOS_LUT_CHAN_627375_IDX, + ATHOS_LUT_CHAN_627500_IDX, + ATHOS_LUT_CHAN_627625_IDX, + ATHOS_LUT_CHAN_627750_IDX, + ATHOS_LUT_CHAN_627875_IDX, + ATHOS_LUT_CHAN_628000_IDX, + ATHOS_LUT_CHAN_628125_IDX, + ATHOS_LUT_CHAN_628250_IDX, + ATHOS_LUT_CHAN_628375_IDX, + ATHOS_LUT_CHAN_628500_IDX, + ATHOS_LUT_CHAN_628625_IDX, + ATHOS_LUT_CHAN_628750_IDX, + ATHOS_LUT_CHAN_628875_IDX, + ATHOS_LUT_CHAN_629000_IDX, + ATHOS_LUT_CHAN_629125_IDX, + ATHOS_LUT_CHAN_629250_IDX, + ATHOS_LUT_CHAN_629375_IDX, + ATHOS_LUT_CHAN_629500_IDX, + ATHOS_LUT_CHAN_629625_IDX, + ATHOS_LUT_CHAN_629750_IDX, + ATHOS_LUT_CHAN_629875_IDX, + ATHOS_LUT_CHAN_630000_IDX, + ATHOS_LUT_CHAN_630125_IDX, + ATHOS_LUT_CHAN_630250_IDX, + ATHOS_LUT_CHAN_630375_IDX, + ATHOS_LUT_CHAN_630500_IDX, + ATHOS_LUT_CHAN_630625_IDX, + ATHOS_LUT_CHAN_630750_IDX, + ATHOS_LUT_CHAN_630875_IDX, + ATHOS_LUT_CHAN_631000_IDX, + ATHOS_LUT_CHAN_631125_IDX, + ATHOS_LUT_CHAN_631250_IDX, + ATHOS_LUT_CHAN_631375_IDX, + ATHOS_LUT_CHAN_631500_IDX, + ATHOS_LUT_CHAN_631625_IDX, + ATHOS_LUT_CHAN_631750_IDX, + ATHOS_LUT_CHAN_631875_IDX, + ATHOS_LUT_CHAN_632000_IDX, + ATHOS_LUT_CHAN_632125_IDX, + ATHOS_LUT_CHAN_632250_IDX, + ATHOS_LUT_CHAN_632375_IDX, + ATHOS_LUT_CHAN_632500_IDX, + ATHOS_LUT_CHAN_632625_IDX, + ATHOS_LUT_CHAN_632750_IDX, + ATHOS_LUT_CHAN_632875_IDX, + ATHOS_LUT_CHAN_633000_IDX, + ATHOS_LUT_CHAN_633125_IDX, + ATHOS_LUT_CHAN_633250_IDX, + ATHOS_LUT_CHAN_633375_IDX, + ATHOS_LUT_CHAN_633500_IDX, + ATHOS_LUT_CHAN_633625_IDX, + ATHOS_LUT_CHAN_633750_IDX, + ATHOS_LUT_CHAN_633875_IDX, + ATHOS_LUT_CHAN_634000_IDX, + ATHOS_LUT_CHAN_634125_IDX, + ATHOS_LUT_CHAN_634250_IDX, + ATHOS_LUT_CHAN_634375_IDX, + ATHOS_LUT_CHAN_634500_IDX, + ATHOS_LUT_CHAN_634625_IDX, + ATHOS_LUT_CHAN_634750_IDX, + ATHOS_LUT_CHAN_634875_IDX, + ATHOS_LUT_CHAN_635000_IDX, + ATHOS_LUT_CHAN_635125_IDX, + ATHOS_LUT_CHAN_635250_IDX, + ATHOS_LUT_CHAN_635375_IDX, + ATHOS_LUT_CHAN_635500_IDX, + ATHOS_LUT_CHAN_635625_IDX, + ATHOS_LUT_CHAN_635750_IDX, + ATHOS_LUT_CHAN_635875_IDX, + ATHOS_LUT_CHAN_636000_IDX, + ATHOS_LUT_CHAN_636125_IDX, + ATHOS_LUT_CHAN_636250_IDX, + ATHOS_LUT_CHAN_636375_IDX, + ATHOS_LUT_CHAN_636500_IDX, + ATHOS_LUT_CHAN_636625_IDX, + ATHOS_LUT_CHAN_636750_IDX, + ATHOS_LUT_CHAN_636875_IDX, + ATHOS_LUT_CHAN_637000_IDX, + ATHOS_LUT_CHAN_637125_IDX, + ATHOS_LUT_CHAN_637250_IDX, + ATHOS_LUT_CHAN_637375_IDX, + ATHOS_LUT_CHAN_637500_IDX, + ATHOS_LUT_CHAN_637625_IDX, + ATHOS_LUT_CHAN_637750_IDX, + ATHOS_LUT_CHAN_637875_IDX, + ATHOS_LUT_CHAN_638000_IDX, + ATHOS_LUT_CHAN_638125_IDX, + ATHOS_LUT_CHAN_638250_IDX, + ATHOS_LUT_CHAN_638375_IDX, + ATHOS_LUT_CHAN_638500_IDX, + ATHOS_LUT_CHAN_638625_IDX, + ATHOS_LUT_CHAN_638750_IDX, + ATHOS_LUT_CHAN_638875_IDX, + ATHOS_LUT_CHAN_639000_IDX, + ATHOS_LUT_CHAN_639125_IDX, + ATHOS_LUT_CHAN_639250_IDX, + ATHOS_LUT_CHAN_639375_IDX, + ATHOS_LUT_CHAN_639500_IDX, + ATHOS_LUT_CHAN_639625_IDX, + ATHOS_LUT_CHAN_639750_IDX, + ATHOS_LUT_CHAN_639875_IDX, + ATHOS_LUT_CHAN_640000_IDX, + ATHOS_LUT_CHAN_640125_IDX, + ATHOS_LUT_CHAN_640250_IDX, + ATHOS_LUT_CHAN_640375_IDX, + ATHOS_LUT_CHAN_640500_IDX, + ATHOS_LUT_CHAN_640625_IDX, + ATHOS_LUT_CHAN_640750_IDX, + ATHOS_LUT_CHAN_640875_IDX, + ATHOS_LUT_CHAN_641000_IDX, + ATHOS_LUT_CHAN_641125_IDX, + ATHOS_LUT_CHAN_641250_IDX, + ATHOS_LUT_CHAN_641375_IDX, + ATHOS_LUT_CHAN_641500_IDX, + ATHOS_LUT_CHAN_641625_IDX, + ATHOS_LUT_CHAN_641750_IDX, + ATHOS_LUT_CHAN_641875_IDX, + ATHOS_LUT_CHAN_642000_IDX, + ATHOS_LUT_CHAN_642125_IDX, + ATHOS_LUT_CHAN_642250_IDX, + ATHOS_LUT_CHAN_642375_IDX, + ATHOS_LUT_CHAN_642500_IDX, + ATHOS_LUT_CHAN_642625_IDX, + ATHOS_LUT_CHAN_642750_IDX, + ATHOS_LUT_CHAN_642875_IDX, + ATHOS_LUT_CHAN_643000_IDX, + ATHOS_LUT_CHAN_643125_IDX, + ATHOS_LUT_CHAN_643250_IDX, + ATHOS_LUT_CHAN_643375_IDX, + ATHOS_LUT_CHAN_643500_IDX, + ATHOS_LUT_CHAN_643625_IDX, + ATHOS_LUT_CHAN_643750_IDX, + ATHOS_LUT_CHAN_643875_IDX, + ATHOS_LUT_CHAN_644000_IDX, + ATHOS_LUT_CHAN_644125_IDX, + ATHOS_LUT_CHAN_644250_IDX, + ATHOS_LUT_CHAN_644375_IDX, + ATHOS_LUT_CHAN_644500_IDX, + ATHOS_LUT_CHAN_644625_IDX, + ATHOS_LUT_CHAN_644750_IDX, + ATHOS_LUT_CHAN_644875_IDX, + ATHOS_LUT_CHAN_645000_IDX, + ATHOS_LUT_CHAN_645125_IDX, + ATHOS_LUT_CHAN_645250_IDX, + ATHOS_LUT_CHAN_645375_IDX, + ATHOS_LUT_CHAN_645500_IDX, + ATHOS_LUT_CHAN_645625_IDX, + ATHOS_LUT_CHAN_645750_IDX, + ATHOS_LUT_CHAN_645875_IDX, + ATHOS_LUT_CHAN_646000_IDX, + ATHOS_LUT_CHAN_646125_IDX, + ATHOS_LUT_CHAN_646250_IDX, + ATHOS_LUT_CHAN_646375_IDX, + ATHOS_LUT_CHAN_646500_IDX, + ATHOS_LUT_CHAN_646625_IDX, + ATHOS_LUT_CHAN_646750_IDX, + ATHOS_LUT_CHAN_646875_IDX, + ATHOS_LUT_CHAN_647000_IDX, + ATHOS_LUT_CHAN_647125_IDX, + ATHOS_LUT_CHAN_647250_IDX, + ATHOS_LUT_CHAN_647375_IDX, + ATHOS_LUT_CHAN_647500_IDX, + ATHOS_LUT_CHAN_647625_IDX, + ATHOS_LUT_CHAN_647750_IDX, + ATHOS_LUT_CHAN_647875_IDX, + ATHOS_LUT_CHAN_648000_IDX, + ATHOS_LUT_CHAN_648125_IDX, + ATHOS_LUT_CHAN_648250_IDX, + ATHOS_LUT_CHAN_648375_IDX, + ATHOS_LUT_CHAN_648500_IDX, + ATHOS_LUT_CHAN_648625_IDX, + ATHOS_LUT_CHAN_648750_IDX, + ATHOS_LUT_CHAN_648875_IDX, + ATHOS_LUT_CHAN_649000_IDX, + ATHOS_LUT_CHAN_649125_IDX, + ATHOS_LUT_CHAN_649250_IDX, + ATHOS_LUT_CHAN_649375_IDX, + ATHOS_LUT_CHAN_649500_IDX, + ATHOS_LUT_CHAN_649625_IDX, + ATHOS_LUT_CHAN_649750_IDX, + ATHOS_LUT_CHAN_649875_IDX, + ATHOS_LUT_CHAN_650000_IDX, + ATHOS_LUT_CHAN_650125_IDX, + ATHOS_LUT_CHAN_650250_IDX, + ATHOS_LUT_CHAN_650375_IDX, + ATHOS_LUT_CHAN_650500_IDX, + ATHOS_LUT_CHAN_650625_IDX, + ATHOS_LUT_CHAN_650750_IDX, + ATHOS_LUT_CHAN_650875_IDX, + ATHOS_LUT_CHAN_651000_IDX, + ATHOS_LUT_CHAN_651125_IDX, + ATHOS_LUT_CHAN_651250_IDX, + ATHOS_LUT_CHAN_651375_IDX, + ATHOS_LUT_CHAN_651500_IDX, + ATHOS_LUT_CHAN_651625_IDX, + ATHOS_LUT_CHAN_651750_IDX, + ATHOS_LUT_CHAN_651875_IDX, + ATHOS_LUT_CHAN_652000_IDX, + ATHOS_LUT_CHAN_652125_IDX, + ATHOS_LUT_CHAN_652250_IDX, + ATHOS_LUT_CHAN_652375_IDX, + ATHOS_LUT_CHAN_652500_IDX, + ATHOS_LUT_CHAN_652625_IDX, + ATHOS_LUT_CHAN_652750_IDX, + ATHOS_LUT_CHAN_652875_IDX, + ATHOS_LUT_CHAN_653000_IDX, + ATHOS_LUT_CHAN_653125_IDX, + ATHOS_LUT_CHAN_653250_IDX, + ATHOS_LUT_CHAN_653375_IDX, + ATHOS_LUT_CHAN_653500_IDX, + ATHOS_LUT_CHAN_653625_IDX, + ATHOS_LUT_CHAN_653750_IDX, + ATHOS_LUT_CHAN_653875_IDX, + ATHOS_LUT_CHAN_654000_IDX, + ATHOS_LUT_CHAN_654125_IDX, + ATHOS_LUT_CHAN_654250_IDX, + ATHOS_LUT_CHAN_654375_IDX, + ATHOS_LUT_CHAN_654500_IDX, + ATHOS_LUT_CHAN_654625_IDX, + ATHOS_LUT_CHAN_654750_IDX, + ATHOS_LUT_CHAN_654875_IDX, + ATHOS_LUT_CHAN_655000_IDX, + ATHOS_LUT_CHAN_655125_IDX, + ATHOS_LUT_CHAN_655250_IDX, + ATHOS_LUT_CHAN_655375_IDX, + ATHOS_LUT_CHAN_655500_IDX, + ATHOS_LUT_CHAN_655625_IDX, + ATHOS_LUT_CHAN_655750_IDX, + ATHOS_LUT_CHAN_655875_IDX, + ATHOS_LUT_CHAN_656000_IDX, + ATHOS_LUT_CHAN_656125_IDX, + ATHOS_LUT_CHAN_656250_IDX, + ATHOS_LUT_CHAN_656375_IDX, + ATHOS_LUT_CHAN_656500_IDX, + ATHOS_LUT_CHAN_656625_IDX, + ATHOS_LUT_CHAN_656750_IDX, + ATHOS_LUT_CHAN_656875_IDX, + ATHOS_LUT_CHAN_657000_IDX, + ATHOS_LUT_CHAN_657125_IDX, + ATHOS_LUT_CHAN_657250_IDX, + ATHOS_LUT_CHAN_657375_IDX, + ATHOS_LUT_CHAN_657500_IDX, + ATHOS_LUT_CHAN_657625_IDX, + ATHOS_LUT_CHAN_657750_IDX, + ATHOS_LUT_CHAN_657875_IDX, + ATHOS_LUT_CHAN_658000_IDX, + ATHOS_LUT_CHAN_658125_IDX, + ATHOS_LUT_CHAN_658250_IDX, + ATHOS_LUT_CHAN_658375_IDX, + ATHOS_LUT_CHAN_658500_IDX, + ATHOS_LUT_CHAN_658625_IDX, + ATHOS_LUT_CHAN_658750_IDX, + ATHOS_LUT_CHAN_658875_IDX, + ATHOS_LUT_CHAN_659000_IDX, + ATHOS_LUT_CHAN_659125_IDX, + ATHOS_LUT_CHAN_659250_IDX, + ATHOS_LUT_CHAN_659375_IDX, + ATHOS_LUT_CHAN_659500_IDX, + ATHOS_LUT_CHAN_659625_IDX, + ATHOS_LUT_CHAN_659750_IDX, + ATHOS_LUT_CHAN_659875_IDX, + ATHOS_LUT_CHAN_660000_IDX, + ATHOS_LUT_CHAN_660125_IDX, + ATHOS_LUT_CHAN_660250_IDX, + ATHOS_LUT_CHAN_660375_IDX, + ATHOS_LUT_CHAN_660500_IDX, + ATHOS_LUT_CHAN_660625_IDX, + ATHOS_LUT_CHAN_660750_IDX, + ATHOS_LUT_CHAN_660875_IDX, + ATHOS_LUT_CHAN_661000_IDX, + ATHOS_LUT_CHAN_661125_IDX, + ATHOS_LUT_CHAN_661250_IDX, + ATHOS_LUT_CHAN_661375_IDX, + ATHOS_LUT_CHAN_661500_IDX, + ATHOS_LUT_CHAN_661625_IDX, + ATHOS_LUT_CHAN_661750_IDX, + ATHOS_LUT_CHAN_661875_IDX, + ATHOS_LUT_CHAN_662000_IDX, + ATHOS_LUT_CHAN_662125_IDX, + ATHOS_LUT_CHAN_662250_IDX, + ATHOS_LUT_CHAN_662375_IDX, + ATHOS_LUT_CHAN_662500_IDX, + ATHOS_LUT_CHAN_662625_IDX, + ATHOS_LUT_CHAN_662750_IDX, + ATHOS_LUT_CHAN_662875_IDX, + ATHOS_LUT_CHAN_663000_IDX, + ATHOS_LUT_CHAN_663125_IDX, + ATHOS_LUT_CHAN_663250_IDX, + ATHOS_LUT_CHAN_663375_IDX, + ATHOS_LUT_CHAN_663500_IDX, + ATHOS_LUT_CHAN_663625_IDX, + ATHOS_LUT_CHAN_663750_IDX, + ATHOS_LUT_CHAN_663875_IDX, + ATHOS_LUT_CHAN_664000_IDX, + ATHOS_LUT_CHAN_664125_IDX, + ATHOS_LUT_CHAN_664250_IDX, + ATHOS_LUT_CHAN_664375_IDX, + ATHOS_LUT_CHAN_664500_IDX, + ATHOS_LUT_CHAN_664625_IDX, + ATHOS_LUT_CHAN_664750_IDX, + ATHOS_LUT_CHAN_664875_IDX, + ATHOS_LUT_CHAN_665000_IDX, + ATHOS_LUT_CHAN_665125_IDX, + ATHOS_LUT_CHAN_665250_IDX, + ATHOS_LUT_CHAN_665375_IDX, + ATHOS_LUT_CHAN_665500_IDX, + ATHOS_LUT_CHAN_665625_IDX, + ATHOS_LUT_CHAN_665750_IDX, + ATHOS_LUT_CHAN_665875_IDX, + ATHOS_LUT_CHAN_666000_IDX, + ATHOS_LUT_CHAN_666125_IDX, + ATHOS_LUT_CHAN_666250_IDX, + ATHOS_LUT_CHAN_666375_IDX, + ATHOS_LUT_CHAN_666500_IDX, + ATHOS_LUT_CHAN_666625_IDX, + ATHOS_LUT_CHAN_666750_IDX, + ATHOS_LUT_CHAN_666875_IDX, + ATHOS_LUT_CHAN_667000_IDX, + ATHOS_LUT_CHAN_667125_IDX, + ATHOS_LUT_CHAN_667250_IDX, + ATHOS_LUT_CHAN_667375_IDX, + ATHOS_LUT_CHAN_667500_IDX, + ATHOS_LUT_CHAN_667625_IDX, + ATHOS_LUT_CHAN_667750_IDX, + ATHOS_LUT_CHAN_667875_IDX, + ATHOS_LUT_CHAN_668000_IDX, + ATHOS_LUT_CHAN_668125_IDX, + ATHOS_LUT_CHAN_668250_IDX, + ATHOS_LUT_CHAN_668375_IDX, + ATHOS_LUT_CHAN_668500_IDX, + ATHOS_LUT_CHAN_668625_IDX, + ATHOS_LUT_CHAN_668750_IDX, + ATHOS_LUT_CHAN_668875_IDX, + ATHOS_LUT_CHAN_669000_IDX, + ATHOS_LUT_CHAN_669125_IDX, + ATHOS_LUT_CHAN_669250_IDX, + ATHOS_LUT_CHAN_669375_IDX, + ATHOS_LUT_CHAN_669500_IDX, + ATHOS_LUT_CHAN_669625_IDX, + ATHOS_LUT_CHAN_669750_IDX, + ATHOS_LUT_CHAN_669875_IDX, + ATHOS_LUT_CHAN_670000_IDX, + ATHOS_LUT_CHAN_670125_IDX, + ATHOS_LUT_CHAN_670250_IDX, + ATHOS_LUT_CHAN_670375_IDX, + ATHOS_LUT_CHAN_670500_IDX, + ATHOS_LUT_CHAN_670625_IDX, + ATHOS_LUT_CHAN_670750_IDX, + ATHOS_LUT_CHAN_670875_IDX, + ATHOS_LUT_CHAN_671000_IDX, + ATHOS_LUT_CHAN_671125_IDX, + ATHOS_LUT_CHAN_671250_IDX, + ATHOS_LUT_CHAN_671375_IDX, + ATHOS_LUT_CHAN_671500_IDX, + ATHOS_LUT_CHAN_671625_IDX, + ATHOS_LUT_CHAN_671750_IDX, + ATHOS_LUT_CHAN_671875_IDX, + ATHOS_LUT_CHAN_672000_IDX, + ATHOS_LUT_CHAN_672125_IDX, + ATHOS_LUT_CHAN_672250_IDX, + ATHOS_LUT_CHAN_672375_IDX, + ATHOS_LUT_CHAN_672500_IDX, + ATHOS_LUT_CHAN_672625_IDX, + ATHOS_LUT_CHAN_672750_IDX, + ATHOS_LUT_CHAN_672875_IDX, + ATHOS_LUT_CHAN_673000_IDX, + ATHOS_LUT_CHAN_673125_IDX, + ATHOS_LUT_CHAN_673250_IDX, + ATHOS_LUT_CHAN_673375_IDX, + ATHOS_LUT_CHAN_673500_IDX, + ATHOS_LUT_CHAN_673625_IDX, + ATHOS_LUT_CHAN_673750_IDX, + ATHOS_LUT_CHAN_673875_IDX, + ATHOS_LUT_CHAN_674000_IDX, + ATHOS_LUT_CHAN_674125_IDX, + ATHOS_LUT_CHAN_674250_IDX, + ATHOS_LUT_CHAN_674375_IDX, + ATHOS_LUT_CHAN_674500_IDX, + ATHOS_LUT_CHAN_674625_IDX, + ATHOS_LUT_CHAN_674750_IDX, + ATHOS_LUT_CHAN_674875_IDX, + ATHOS_LUT_CHAN_675000_IDX, + ATHOS_LUT_CHAN_675125_IDX, + ATHOS_LUT_CHAN_675250_IDX, + ATHOS_LUT_CHAN_675375_IDX, + ATHOS_LUT_CHAN_675500_IDX, + ATHOS_LUT_CHAN_675625_IDX, + ATHOS_LUT_CHAN_675750_IDX, + ATHOS_LUT_CHAN_675875_IDX, + ATHOS_LUT_CHAN_676000_IDX, + ATHOS_LUT_CHAN_676125_IDX, + ATHOS_LUT_CHAN_676250_IDX, + ATHOS_LUT_CHAN_676375_IDX, + ATHOS_LUT_CHAN_676500_IDX, + ATHOS_LUT_CHAN_676625_IDX, + ATHOS_LUT_CHAN_676750_IDX, + ATHOS_LUT_CHAN_676875_IDX, + ATHOS_LUT_CHAN_677000_IDX, + ATHOS_LUT_CHAN_677125_IDX, + ATHOS_LUT_CHAN_677250_IDX, + ATHOS_LUT_CHAN_677375_IDX, + ATHOS_LUT_CHAN_677500_IDX, + ATHOS_LUT_CHAN_677625_IDX, + ATHOS_LUT_CHAN_677750_IDX, + ATHOS_LUT_CHAN_677875_IDX, + ATHOS_LUT_CHAN_678000_IDX, + ATHOS_LUT_CHAN_678125_IDX, + ATHOS_LUT_CHAN_678250_IDX, + ATHOS_LUT_CHAN_678375_IDX, + ATHOS_LUT_CHAN_678500_IDX, + ATHOS_LUT_CHAN_678625_IDX, + ATHOS_LUT_CHAN_678750_IDX, + ATHOS_LUT_CHAN_678875_IDX, + ATHOS_LUT_CHAN_679000_IDX, + ATHOS_LUT_CHAN_679125_IDX, + ATHOS_LUT_CHAN_679250_IDX, + ATHOS_LUT_CHAN_679375_IDX, + ATHOS_LUT_CHAN_679500_IDX, + ATHOS_LUT_CHAN_679625_IDX, + ATHOS_LUT_CHAN_679750_IDX, + ATHOS_LUT_CHAN_679875_IDX, + ATHOS_LUT_CHAN_680000_IDX, + ATHOS_LUT_CHAN_680125_IDX, + ATHOS_LUT_CHAN_680250_IDX, + ATHOS_LUT_CHAN_680375_IDX, + ATHOS_LUT_CHAN_680500_IDX, + ATHOS_LUT_CHAN_680625_IDX, + ATHOS_LUT_CHAN_680750_IDX, + ATHOS_LUT_CHAN_680875_IDX, + ATHOS_LUT_CHAN_681000_IDX, + ATHOS_LUT_CHAN_681125_IDX, + ATHOS_LUT_CHAN_681250_IDX, + ATHOS_LUT_CHAN_681375_IDX, + ATHOS_LUT_CHAN_681500_IDX, + ATHOS_LUT_CHAN_681625_IDX, + ATHOS_LUT_CHAN_681750_IDX, + ATHOS_LUT_CHAN_681875_IDX, + ATHOS_LUT_CHAN_682000_IDX, + ATHOS_LUT_CHAN_682125_IDX, + ATHOS_LUT_CHAN_682250_IDX, + ATHOS_LUT_CHAN_682375_IDX, + ATHOS_LUT_CHAN_682500_IDX, + ATHOS_LUT_CHAN_682625_IDX, + ATHOS_LUT_CHAN_682750_IDX, + ATHOS_LUT_CHAN_682875_IDX, + ATHOS_LUT_CHAN_683000_IDX, + ATHOS_LUT_CHAN_683125_IDX, + ATHOS_LUT_CHAN_683250_IDX, + ATHOS_LUT_CHAN_683375_IDX, + ATHOS_LUT_CHAN_683500_IDX, + ATHOS_LUT_CHAN_683625_IDX, + ATHOS_LUT_CHAN_683750_IDX, + ATHOS_LUT_CHAN_683875_IDX, + ATHOS_LUT_CHAN_684000_IDX, + ATHOS_LUT_CHAN_684125_IDX, + ATHOS_LUT_CHAN_684250_IDX, + ATHOS_LUT_CHAN_684375_IDX, + ATHOS_LUT_CHAN_684500_IDX, + ATHOS_LUT_CHAN_684625_IDX, + ATHOS_LUT_CHAN_684750_IDX, + ATHOS_LUT_CHAN_684875_IDX, + ATHOS_LUT_CHAN_685000_IDX, + ATHOS_LUT_CHAN_685125_IDX, + ATHOS_LUT_CHAN_685250_IDX, + ATHOS_LUT_CHAN_685375_IDX, + ATHOS_LUT_CHAN_685500_IDX, + ATHOS_LUT_CHAN_685625_IDX, + ATHOS_LUT_CHAN_685750_IDX, + ATHOS_LUT_CHAN_685875_IDX, + ATHOS_LUT_CHAN_686000_IDX, + ATHOS_LUT_CHAN_686125_IDX, + ATHOS_LUT_CHAN_686250_IDX, + ATHOS_LUT_CHAN_686375_IDX, + ATHOS_LUT_CHAN_686500_IDX, + ATHOS_LUT_CHAN_686625_IDX, + ATHOS_LUT_CHAN_686750_IDX, + ATHOS_LUT_CHAN_686875_IDX, + ATHOS_LUT_CHAN_687000_IDX, + ATHOS_LUT_CHAN_687125_IDX, + ATHOS_LUT_CHAN_687250_IDX, + ATHOS_LUT_CHAN_687375_IDX, + ATHOS_LUT_CHAN_687500_IDX, + ATHOS_LUT_CHAN_687625_IDX, + ATHOS_LUT_CHAN_687750_IDX, + ATHOS_LUT_CHAN_687875_IDX, + ATHOS_LUT_CHAN_688000_IDX, + ATHOS_LUT_CHAN_688125_IDX, + ATHOS_LUT_CHAN_688250_IDX, + ATHOS_LUT_CHAN_688375_IDX, + ATHOS_LUT_CHAN_688500_IDX, + ATHOS_LUT_CHAN_688625_IDX, + ATHOS_LUT_CHAN_688750_IDX, + ATHOS_LUT_CHAN_688875_IDX, + ATHOS_LUT_CHAN_689000_IDX, + ATHOS_LUT_CHAN_689125_IDX, + ATHOS_LUT_CHAN_689250_IDX, + ATHOS_LUT_CHAN_689375_IDX, + ATHOS_LUT_CHAN_689500_IDX, + ATHOS_LUT_CHAN_689625_IDX, + ATHOS_LUT_CHAN_689750_IDX, + ATHOS_LUT_CHAN_689875_IDX, + ATHOS_LUT_CHAN_690000_IDX, + ATHOS_LUT_CHAN_690125_IDX, + ATHOS_LUT_CHAN_690250_IDX, + ATHOS_LUT_CHAN_690375_IDX, + ATHOS_LUT_CHAN_690500_IDX, + ATHOS_LUT_CHAN_690625_IDX, + ATHOS_LUT_CHAN_690750_IDX, + ATHOS_LUT_CHAN_690875_IDX, + ATHOS_LUT_CHAN_691000_IDX, + ATHOS_LUT_CHAN_691125_IDX, + ATHOS_LUT_CHAN_691250_IDX, + ATHOS_LUT_CHAN_691375_IDX, + ATHOS_LUT_CHAN_691500_IDX, + ATHOS_LUT_CHAN_691625_IDX, + ATHOS_LUT_CHAN_691750_IDX, + ATHOS_LUT_CHAN_691875_IDX, + ATHOS_LUT_CHAN_692000_IDX, + ATHOS_LUT_CHAN_692125_IDX, + ATHOS_LUT_CHAN_692250_IDX, + ATHOS_LUT_CHAN_692375_IDX, + ATHOS_LUT_CHAN_692500_IDX, + ATHOS_LUT_CHAN_692625_IDX, + ATHOS_LUT_CHAN_692750_IDX, + ATHOS_LUT_CHAN_692875_IDX, + ATHOS_LUT_CHAN_693000_IDX, + ATHOS_LUT_CHAN_693125_IDX, + ATHOS_LUT_CHAN_693250_IDX, + ATHOS_LUT_CHAN_693375_IDX, + ATHOS_LUT_CHAN_693500_IDX, + ATHOS_LUT_CHAN_693625_IDX, + ATHOS_LUT_CHAN_693750_IDX, + ATHOS_LUT_CHAN_693875_IDX, + ATHOS_LUT_CHAN_694000_IDX, + ATHOS_LUT_CHAN_694125_IDX, + ATHOS_LUT_CHAN_694250_IDX, + ATHOS_LUT_CHAN_694375_IDX, + ATHOS_LUT_CHAN_694500_IDX, + ATHOS_LUT_CHAN_694625_IDX, + ATHOS_LUT_CHAN_694750_IDX, + ATHOS_LUT_CHAN_694875_IDX, + ATHOS_LUT_CHAN_695000_IDX, + ATHOS_LUT_CHAN_695125_IDX, + ATHOS_LUT_CHAN_695250_IDX, + ATHOS_LUT_CHAN_695375_IDX, + ATHOS_LUT_CHAN_695500_IDX, + ATHOS_LUT_CHAN_695625_IDX, + ATHOS_LUT_CHAN_695750_IDX, + ATHOS_LUT_CHAN_695875_IDX, + ATHOS_LUT_CHAN_696000_IDX, + ATHOS_LUT_CHAN_696125_IDX, + ATHOS_LUT_CHAN_696250_IDX, + ATHOS_LUT_CHAN_696375_IDX, + ATHOS_LUT_CHAN_696500_IDX, + ATHOS_LUT_CHAN_696625_IDX, + ATHOS_LUT_CHAN_696750_IDX, + ATHOS_LUT_CHAN_696875_IDX, + ATHOS_LUT_CHAN_697000_IDX, + ATHOS_LUT_CHAN_697125_IDX, + ATHOS_LUT_CHAN_697250_IDX, + ATHOS_LUT_CHAN_697375_IDX, + ATHOS_LUT_CHAN_697500_IDX, + ATHOS_LUT_CHAN_697625_IDX, + ATHOS_LUT_CHAN_697750_IDX, + ATHOS_LUT_CHAN_697875_IDX, + ATHOS_LUT_CHAN_698000_IDX, + ATHOS_LUT_CHAN_698125_IDX, + ATHOS_LUT_CHAN_698250_IDX, + ATHOS_LUT_CHAN_698375_IDX, + ATHOS_LUT_CHAN_698500_IDX, + ATHOS_LUT_CHAN_698625_IDX, + ATHOS_LUT_CHAN_698750_IDX, + ATHOS_LUT_CHAN_698875_IDX, + ATHOS_LUT_CHAN_699000_IDX, + ATHOS_LUT_CHAN_699125_IDX, + ATHOS_LUT_CHAN_699250_IDX, + ATHOS_LUT_CHAN_699375_IDX, + ATHOS_LUT_CHAN_699500_IDX, + ATHOS_LUT_CHAN_699625_IDX, + ATHOS_LUT_CHAN_699750_IDX, + ATHOS_LUT_CHAN_699875_IDX, + ATHOS_LUT_CHAN_700000_IDX, + ATHOS_LUT_CHAN_700125_IDX, + ATHOS_LUT_CHAN_700250_IDX, + ATHOS_LUT_CHAN_700375_IDX, + ATHOS_LUT_CHAN_700500_IDX, + ATHOS_LUT_CHAN_700625_IDX, + ATHOS_LUT_CHAN_700750_IDX, + ATHOS_LUT_CHAN_700875_IDX, + ATHOS_LUT_CHAN_701000_IDX, + ATHOS_LUT_CHAN_701125_IDX, + ATHOS_LUT_CHAN_701250_IDX, + ATHOS_LUT_CHAN_701375_IDX, + ATHOS_LUT_CHAN_701500_IDX, + ATHOS_LUT_CHAN_701625_IDX, + ATHOS_LUT_CHAN_701750_IDX, + ATHOS_LUT_CHAN_701875_IDX, + ATHOS_LUT_CHAN_702000_IDX, + ATHOS_LUT_CHAN_702125_IDX, + ATHOS_LUT_CHAN_702250_IDX, + ATHOS_LUT_CHAN_702375_IDX, + ATHOS_LUT_CHAN_702500_IDX, + ATHOS_LUT_CHAN_702625_IDX, + ATHOS_LUT_CHAN_702750_IDX, + ATHOS_LUT_CHAN_702875_IDX, + ATHOS_LUT_CHAN_703000_IDX, + ATHOS_LUT_CHAN_703125_IDX, + ATHOS_LUT_CHAN_703250_IDX, + ATHOS_LUT_CHAN_703375_IDX, + ATHOS_LUT_CHAN_703500_IDX, + ATHOS_LUT_CHAN_703625_IDX, + ATHOS_LUT_CHAN_703750_IDX, + ATHOS_LUT_CHAN_703875_IDX, + ATHOS_LUT_CHAN_704000_IDX, + ATHOS_LUT_CHAN_704125_IDX, + ATHOS_LUT_CHAN_704250_IDX, + ATHOS_LUT_CHAN_704375_IDX, + ATHOS_LUT_CHAN_704500_IDX, + ATHOS_LUT_CHAN_704625_IDX, + ATHOS_LUT_CHAN_704750_IDX, + ATHOS_LUT_CHAN_704875_IDX, + ATHOS_LUT_CHAN_705000_IDX, + ATHOS_LUT_CHAN_705125_IDX, + ATHOS_LUT_CHAN_705250_IDX, + ATHOS_LUT_CHAN_705375_IDX, + ATHOS_LUT_CHAN_705500_IDX, + ATHOS_LUT_CHAN_705625_IDX, + ATHOS_LUT_CHAN_705750_IDX, + ATHOS_LUT_CHAN_705875_IDX, + ATHOS_LUT_CHAN_706000_IDX, + ATHOS_LUT_CHAN_706125_IDX, + ATHOS_LUT_CHAN_706250_IDX, + ATHOS_LUT_CHAN_706375_IDX, + ATHOS_LUT_CHAN_706500_IDX, + ATHOS_LUT_CHAN_706625_IDX, + ATHOS_LUT_CHAN_706750_IDX, + ATHOS_LUT_CHAN_706875_IDX, + ATHOS_LUT_CHAN_707000_IDX, + ATHOS_LUT_CHAN_707125_IDX, + ATHOS_LUT_CHAN_707250_IDX, + ATHOS_LUT_CHAN_707375_IDX, + ATHOS_LUT_CHAN_707500_IDX, + ATHOS_LUT_CHAN_707625_IDX, + ATHOS_LUT_CHAN_707750_IDX, + ATHOS_LUT_CHAN_707875_IDX, + ATHOS_LUT_CHAN_708000_IDX, + ATHOS_LUT_CHAN_708125_IDX, + ATHOS_LUT_CHAN_708250_IDX, + ATHOS_LUT_CHAN_708375_IDX, + ATHOS_LUT_CHAN_708500_IDX, + ATHOS_LUT_CHAN_708625_IDX, + ATHOS_LUT_CHAN_708750_IDX, + ATHOS_LUT_CHAN_708875_IDX, + ATHOS_LUT_CHAN_709000_IDX, + ATHOS_LUT_CHAN_709125_IDX, + ATHOS_LUT_CHAN_709250_IDX, + ATHOS_LUT_CHAN_709375_IDX, + ATHOS_LUT_CHAN_709500_IDX, + ATHOS_LUT_CHAN_709625_IDX, + ATHOS_LUT_CHAN_709750_IDX, + ATHOS_LUT_CHAN_709875_IDX, + ATHOS_LUT_CHAN_710000_IDX, + ATHOS_LUT_CHAN_710125_IDX, + ATHOS_LUT_CHAN_710250_IDX, + ATHOS_LUT_CHAN_710375_IDX, + ATHOS_LUT_CHAN_710500_IDX, + ATHOS_LUT_CHAN_710625_IDX, + ATHOS_LUT_CHAN_710750_IDX, + ATHOS_LUT_CHAN_710875_IDX, + ATHOS_LUT_CHAN_711000_IDX, + ATHOS_LUT_CHAN_711125_IDX, + ATHOS_LUT_CHAN_711250_IDX, + ATHOS_LUT_CHAN_711375_IDX, + ATHOS_LUT_CHAN_711500_IDX, + ATHOS_LUT_CHAN_711625_IDX, + ATHOS_LUT_CHAN_711750_IDX, + ATHOS_LUT_CHAN_711875_IDX, + ATHOS_LUT_CHAN_712000_IDX, + ATHOS_LUT_CHAN_712125_IDX, + ATHOS_LUT_CHAN_712250_IDX, + ATHOS_LUT_CHAN_712375_IDX, + ATHOS_LUT_CHAN_712500_IDX, + ATHOS_LUT_CHAN_712625_IDX, + ATHOS_LUT_CHAN_712750_IDX, + ATHOS_LUT_CHAN_712875_IDX, + ATHOS_LUT_CHAN_713000_IDX, + ATHOS_LUT_CHAN_713125_IDX, + ATHOS_LUT_CHAN_713250_IDX, + ATHOS_LUT_CHAN_713375_IDX, + ATHOS_LUT_CHAN_713500_IDX, + ATHOS_LUT_CHAN_713625_IDX, + ATHOS_LUT_CHAN_713750_IDX, + ATHOS_LUT_CHAN_713875_IDX, + ATHOS_LUT_CHAN_714000_IDX, + ATHOS_LUT_CHAN_714125_IDX, + ATHOS_LUT_CHAN_714250_IDX, + ATHOS_LUT_CHAN_714375_IDX, + ATHOS_LUT_CHAN_714500_IDX, + ATHOS_LUT_CHAN_714625_IDX, + ATHOS_LUT_CHAN_714750_IDX, + ATHOS_LUT_CHAN_714875_IDX, + ATHOS_LUT_CHAN_715000_IDX, + ATHOS_LUT_CHAN_715125_IDX, + ATHOS_LUT_CHAN_715250_IDX, + ATHOS_LUT_CHAN_715375_IDX, + ATHOS_LUT_CHAN_715500_IDX, + ATHOS_LUT_CHAN_715625_IDX, + ATHOS_LUT_CHAN_715750_IDX, + ATHOS_LUT_CHAN_715875_IDX, + ATHOS_LUT_CHAN_716000_IDX, + ATHOS_LUT_CHAN_716125_IDX, + ATHOS_LUT_CHAN_716250_IDX, + ATHOS_LUT_CHAN_716375_IDX, + ATHOS_LUT_CHAN_716500_IDX, + ATHOS_LUT_CHAN_716625_IDX, + ATHOS_LUT_CHAN_716750_IDX, + ATHOS_LUT_CHAN_716875_IDX, + ATHOS_LUT_CHAN_717000_IDX, + ATHOS_LUT_CHAN_717125_IDX, + ATHOS_LUT_CHAN_717250_IDX, + ATHOS_LUT_CHAN_717375_IDX, + ATHOS_LUT_CHAN_717500_IDX, + ATHOS_LUT_CHAN_717625_IDX, + ATHOS_LUT_CHAN_717750_IDX, + ATHOS_LUT_CHAN_717875_IDX, + ATHOS_LUT_CHAN_718000_IDX, + ATHOS_LUT_CHAN_718125_IDX, + ATHOS_LUT_CHAN_718250_IDX, + ATHOS_LUT_CHAN_718375_IDX, + ATHOS_LUT_CHAN_718500_IDX, + ATHOS_LUT_CHAN_718625_IDX, + ATHOS_LUT_CHAN_718750_IDX, + ATHOS_LUT_CHAN_718875_IDX, + ATHOS_LUT_CHAN_719000_IDX, + ATHOS_LUT_CHAN_719125_IDX, + ATHOS_LUT_CHAN_719250_IDX, + ATHOS_LUT_CHAN_719375_IDX, + ATHOS_LUT_CHAN_719500_IDX, + ATHOS_LUT_CHAN_719625_IDX, + ATHOS_LUT_CHAN_719750_IDX, + ATHOS_LUT_CHAN_719875_IDX, + ATHOS_LUT_CHAN_720000_IDX, + ATHOS_LUT_CHAN_720125_IDX, + ATHOS_LUT_CHAN_720250_IDX, + ATHOS_LUT_CHAN_720375_IDX, + ATHOS_LUT_CHAN_720500_IDX, + ATHOS_LUT_CHAN_720625_IDX, + ATHOS_LUT_CHAN_720750_IDX, + ATHOS_LUT_CHAN_720875_IDX, + ATHOS_LUT_CHAN_721000_IDX, + ATHOS_LUT_CHAN_721125_IDX, + ATHOS_LUT_CHAN_721250_IDX, + ATHOS_LUT_CHAN_721375_IDX, + ATHOS_LUT_CHAN_721500_IDX, + ATHOS_LUT_CHAN_6G_MAX +}; + +enum athos_b_idx_5g { + ATHOS_B_5G_LUT_CHAN_516000_IDX, + ATHOS_B_5G_LUT_CHAN_516125_IDX, + ATHOS_B_5G_LUT_CHAN_516250_IDX, + ATHOS_B_5G_LUT_CHAN_516375_IDX, + ATHOS_B_5G_LUT_CHAN_516500_IDX, + ATHOS_B_5G_LUT_CHAN_516625_IDX, + ATHOS_B_5G_LUT_CHAN_516750_IDX, + ATHOS_B_5G_LUT_CHAN_516875_IDX, + ATHOS_B_5G_LUT_CHAN_517000_IDX, + ATHOS_B_5G_LUT_CHAN_517125_IDX, + ATHOS_B_5G_LUT_CHAN_517250_IDX, + ATHOS_B_5G_LUT_CHAN_517375_IDX, + ATHOS_B_5G_LUT_CHAN_517500_IDX, + ATHOS_B_5G_LUT_CHAN_517625_IDX, + ATHOS_B_5G_LUT_CHAN_517750_IDX, + ATHOS_B_5G_LUT_CHAN_517875_IDX, + ATHOS_B_5G_LUT_CHAN_518000_IDX, + ATHOS_B_5G_LUT_CHAN_518125_IDX, + ATHOS_B_5G_LUT_CHAN_518250_IDX, + ATHOS_B_5G_LUT_CHAN_518375_IDX, + ATHOS_B_5G_LUT_CHAN_518500_IDX, + ATHOS_B_5G_LUT_CHAN_518625_IDX, + ATHOS_B_5G_LUT_CHAN_518750_IDX, + ATHOS_B_5G_LUT_CHAN_518875_IDX, + ATHOS_B_5G_LUT_CHAN_519000_IDX, + ATHOS_B_5G_LUT_CHAN_519125_IDX, + ATHOS_B_5G_LUT_CHAN_519250_IDX, + ATHOS_B_5G_LUT_CHAN_519375_IDX, + ATHOS_B_5G_LUT_CHAN_519500_IDX, + ATHOS_B_5G_LUT_CHAN_519625_IDX, + ATHOS_B_5G_LUT_CHAN_519750_IDX, + ATHOS_B_5G_LUT_CHAN_519875_IDX, + ATHOS_B_5G_LUT_CHAN_520000_IDX, + ATHOS_B_5G_LUT_CHAN_520125_IDX, + ATHOS_B_5G_LUT_CHAN_520250_IDX, + ATHOS_B_5G_LUT_CHAN_520375_IDX, + ATHOS_B_5G_LUT_CHAN_520500_IDX, + ATHOS_B_5G_LUT_CHAN_520625_IDX, + ATHOS_B_5G_LUT_CHAN_520750_IDX, + ATHOS_B_5G_LUT_CHAN_520875_IDX, + ATHOS_B_5G_LUT_CHAN_521000_IDX, + ATHOS_B_5G_LUT_CHAN_521125_IDX, + ATHOS_B_5G_LUT_CHAN_521250_IDX, + ATHOS_B_5G_LUT_CHAN_521375_IDX, + ATHOS_B_5G_LUT_CHAN_521500_IDX, + ATHOS_B_5G_LUT_CHAN_521625_IDX, + ATHOS_B_5G_LUT_CHAN_521750_IDX, + ATHOS_B_5G_LUT_CHAN_521875_IDX, + ATHOS_B_5G_LUT_CHAN_522000_IDX, + ATHOS_B_5G_LUT_CHAN_522125_IDX, + ATHOS_B_5G_LUT_CHAN_522250_IDX, + ATHOS_B_5G_LUT_CHAN_522375_IDX, + ATHOS_B_5G_LUT_CHAN_522500_IDX, + ATHOS_B_5G_LUT_CHAN_522625_IDX, + ATHOS_B_5G_LUT_CHAN_522750_IDX, + ATHOS_B_5G_LUT_CHAN_522875_IDX, + ATHOS_B_5G_LUT_CHAN_523000_IDX, + ATHOS_B_5G_LUT_CHAN_523125_IDX, + ATHOS_B_5G_LUT_CHAN_523250_IDX, + ATHOS_B_5G_LUT_CHAN_523375_IDX, + ATHOS_B_5G_LUT_CHAN_523500_IDX, + ATHOS_B_5G_LUT_CHAN_523625_IDX, + ATHOS_B_5G_LUT_CHAN_523750_IDX, + ATHOS_B_5G_LUT_CHAN_523875_IDX, + ATHOS_B_5G_LUT_CHAN_524000_IDX, + ATHOS_B_5G_LUT_CHAN_524125_IDX, + ATHOS_B_5G_LUT_CHAN_524250_IDX, + ATHOS_B_5G_LUT_CHAN_524375_IDX, + ATHOS_B_5G_LUT_CHAN_524500_IDX, + ATHOS_B_5G_LUT_CHAN_524625_IDX, + ATHOS_B_5G_LUT_CHAN_524750_IDX, + ATHOS_B_5G_LUT_CHAN_524875_IDX, + ATHOS_B_5G_LUT_CHAN_525000_IDX, + ATHOS_B_5G_LUT_CHAN_525125_IDX, + ATHOS_B_5G_LUT_CHAN_525250_IDX, + ATHOS_B_5G_LUT_CHAN_525375_IDX, + ATHOS_B_5G_LUT_CHAN_525500_IDX, + ATHOS_B_5G_LUT_CHAN_525625_IDX, + ATHOS_B_5G_LUT_CHAN_525750_IDX, + ATHOS_B_5G_LUT_CHAN_525875_IDX, + ATHOS_B_5G_LUT_CHAN_526000_IDX, + ATHOS_B_5G_LUT_CHAN_526125_IDX, + ATHOS_B_5G_LUT_CHAN_526250_IDX, + ATHOS_B_5G_LUT_CHAN_526375_IDX, + ATHOS_B_5G_LUT_CHAN_526500_IDX, + ATHOS_B_5G_LUT_CHAN_526625_IDX, + ATHOS_B_5G_LUT_CHAN_526750_IDX, + ATHOS_B_5G_LUT_CHAN_526875_IDX, + ATHOS_B_5G_LUT_CHAN_527000_IDX, + ATHOS_B_5G_LUT_CHAN_527125_IDX, + ATHOS_B_5G_LUT_CHAN_527250_IDX, + ATHOS_B_5G_LUT_CHAN_527375_IDX, + ATHOS_B_5G_LUT_CHAN_527500_IDX, + ATHOS_B_5G_LUT_CHAN_527625_IDX, + ATHOS_B_5G_LUT_CHAN_527750_IDX, + ATHOS_B_5G_LUT_CHAN_527875_IDX, + ATHOS_B_5G_LUT_CHAN_528000_IDX, + ATHOS_B_5G_LUT_CHAN_528125_IDX, + ATHOS_B_5G_LUT_CHAN_528250_IDX, + ATHOS_B_5G_LUT_CHAN_528375_IDX, + ATHOS_B_5G_LUT_CHAN_528500_IDX, + ATHOS_B_5G_LUT_CHAN_528625_IDX, + ATHOS_B_5G_LUT_CHAN_528750_IDX, + ATHOS_B_5G_LUT_CHAN_528875_IDX, + ATHOS_B_5G_LUT_CHAN_529000_IDX, + ATHOS_B_5G_LUT_CHAN_529125_IDX, + ATHOS_B_5G_LUT_CHAN_529250_IDX, + ATHOS_B_5G_LUT_CHAN_529375_IDX, + ATHOS_B_5G_LUT_CHAN_529500_IDX, + ATHOS_B_5G_LUT_CHAN_529625_IDX, + ATHOS_B_5G_LUT_CHAN_529750_IDX, + ATHOS_B_5G_LUT_CHAN_529875_IDX, + ATHOS_B_5G_LUT_CHAN_530000_IDX, + ATHOS_B_5G_LUT_CHAN_530125_IDX, + ATHOS_B_5G_LUT_CHAN_530250_IDX, + ATHOS_B_5G_LUT_CHAN_530375_IDX, + ATHOS_B_5G_LUT_CHAN_530500_IDX, + ATHOS_B_5G_LUT_CHAN_530625_IDX, + ATHOS_B_5G_LUT_CHAN_530750_IDX, + ATHOS_B_5G_LUT_CHAN_530875_IDX, + ATHOS_B_5G_LUT_CHAN_531000_IDX, + ATHOS_B_5G_LUT_CHAN_531125_IDX, + ATHOS_B_5G_LUT_CHAN_531250_IDX, + ATHOS_B_5G_LUT_CHAN_531375_IDX, + ATHOS_B_5G_LUT_CHAN_531500_IDX, + ATHOS_B_5G_LUT_CHAN_531625_IDX, + ATHOS_B_5G_LUT_CHAN_531750_IDX, + ATHOS_B_5G_LUT_CHAN_531875_IDX, + ATHOS_B_5G_LUT_CHAN_532000_IDX, + ATHOS_B_5G_LUT_CHAN_532125_IDX, + ATHOS_B_5G_LUT_CHAN_532250_IDX, + ATHOS_B_5G_LUT_CHAN_532375_IDX, + ATHOS_B_5G_LUT_CHAN_532500_IDX, + ATHOS_B_5G_LUT_CHAN_532625_IDX, + ATHOS_B_5G_LUT_CHAN_532750_IDX, + ATHOS_B_5G_LUT_CHAN_532875_IDX, + ATHOS_B_5G_LUT_CHAN_533000_IDX, + ATHOS_B_5G_LUT_CHAN_533125_IDX, + ATHOS_B_5G_LUT_CHAN_533250_IDX, + ATHOS_B_5G_LUT_CHAN_533375_IDX, + ATHOS_B_5G_LUT_CHAN_533500_IDX, + ATHOS_B_5G_LUT_CHAN_533625_IDX, + ATHOS_B_5G_LUT_CHAN_533750_IDX, + ATHOS_B_5G_LUT_CHAN_533875_IDX, + ATHOS_B_5G_LUT_CHAN_534000_IDX, + ATHOS_B_5G_LUT_CHAN_534125_IDX, + ATHOS_B_5G_LUT_CHAN_534250_IDX, + ATHOS_B_5G_LUT_CHAN_534375_IDX, + ATHOS_B_5G_LUT_CHAN_534500_IDX, + ATHOS_B_5G_LUT_CHAN_534625_IDX, + ATHOS_B_5G_LUT_CHAN_534750_IDX, + ATHOS_B_5G_LUT_CHAN_534875_IDX, + ATHOS_B_5G_LUT_CHAN_535000_IDX, + ATHOS_B_5G_LUT_CHAN_535125_IDX, + ATHOS_B_5G_LUT_CHAN_535250_IDX, + ATHOS_B_5G_LUT_CHAN_535375_IDX, + ATHOS_B_5G_LUT_CHAN_535500_IDX, + ATHOS_B_5G_LUT_CHAN_535625_IDX, + ATHOS_B_5G_LUT_CHAN_535750_IDX, + ATHOS_B_5G_LUT_CHAN_535875_IDX, + ATHOS_B_5G_LUT_CHAN_536000_IDX, + ATHOS_B_5G_LUT_CHAN_536125_IDX, + ATHOS_B_5G_LUT_CHAN_536250_IDX, + ATHOS_B_5G_LUT_CHAN_536375_IDX, + ATHOS_B_5G_LUT_CHAN_536500_IDX, + ATHOS_B_5G_LUT_CHAN_536625_IDX, + ATHOS_B_5G_LUT_CHAN_536750_IDX, + ATHOS_B_5G_LUT_CHAN_536875_IDX, + ATHOS_B_5G_LUT_CHAN_537000_IDX, + ATHOS_B_5G_LUT_CHAN_537125_IDX, + ATHOS_B_5G_LUT_CHAN_537250_IDX, + ATHOS_B_5G_LUT_CHAN_537375_IDX, + ATHOS_B_5G_LUT_CHAN_537500_IDX, + ATHOS_B_5G_LUT_CHAN_537625_IDX, + ATHOS_B_5G_LUT_CHAN_537750_IDX, + ATHOS_B_5G_LUT_CHAN_537875_IDX, + ATHOS_B_5G_LUT_CHAN_538000_IDX, + ATHOS_B_5G_LUT_CHAN_538125_IDX, + ATHOS_B_5G_LUT_CHAN_538250_IDX, + ATHOS_B_5G_LUT_CHAN_538375_IDX, + ATHOS_B_5G_LUT_CHAN_538500_IDX, + ATHOS_B_5G_LUT_CHAN_538625_IDX, + ATHOS_B_5G_LUT_CHAN_538750_IDX, + ATHOS_B_5G_LUT_CHAN_538875_IDX, + ATHOS_B_5G_LUT_CHAN_539000_IDX, + ATHOS_B_5G_LUT_CHAN_539125_IDX, + ATHOS_B_5G_LUT_CHAN_539250_IDX, + ATHOS_B_5G_LUT_CHAN_539375_IDX, + ATHOS_B_5G_LUT_CHAN_539500_IDX, + ATHOS_B_5G_LUT_CHAN_539625_IDX, + ATHOS_B_5G_LUT_CHAN_539750_IDX, + ATHOS_B_5G_LUT_CHAN_539875_IDX, + ATHOS_B_5G_LUT_CHAN_540000_IDX, + ATHOS_B_5G_LUT_CHAN_540125_IDX, + ATHOS_B_5G_LUT_CHAN_540250_IDX, + ATHOS_B_5G_LUT_CHAN_540375_IDX, + ATHOS_B_5G_LUT_CHAN_540500_IDX, + ATHOS_B_5G_LUT_CHAN_540625_IDX, + ATHOS_B_5G_LUT_CHAN_540750_IDX, + ATHOS_B_5G_LUT_CHAN_540875_IDX, + ATHOS_B_5G_LUT_CHAN_541000_IDX, + ATHOS_B_5G_LUT_CHAN_541125_IDX, + ATHOS_B_5G_LUT_CHAN_541250_IDX, + ATHOS_B_5G_LUT_CHAN_541375_IDX, + ATHOS_B_5G_LUT_CHAN_541500_IDX, + ATHOS_B_5G_LUT_CHAN_541625_IDX, + ATHOS_B_5G_LUT_CHAN_541750_IDX, + ATHOS_B_5G_LUT_CHAN_541875_IDX, + ATHOS_B_5G_LUT_CHAN_542000_IDX, + ATHOS_B_5G_LUT_CHAN_542125_IDX, + ATHOS_B_5G_LUT_CHAN_542250_IDX, + ATHOS_B_5G_LUT_CHAN_542375_IDX, + ATHOS_B_5G_LUT_CHAN_542500_IDX, + ATHOS_B_5G_LUT_CHAN_542625_IDX, + ATHOS_B_5G_LUT_CHAN_542750_IDX, + ATHOS_B_5G_LUT_CHAN_542875_IDX, + ATHOS_B_5G_LUT_CHAN_543000_IDX, + ATHOS_B_5G_LUT_CHAN_543125_IDX, + ATHOS_B_5G_LUT_CHAN_543250_IDX, + ATHOS_B_5G_LUT_CHAN_543375_IDX, + ATHOS_B_5G_LUT_CHAN_543500_IDX, + ATHOS_B_5G_LUT_CHAN_543625_IDX, + ATHOS_B_5G_LUT_CHAN_543750_IDX, + ATHOS_B_5G_LUT_CHAN_543875_IDX, + ATHOS_B_5G_LUT_CHAN_544000_IDX, + ATHOS_B_5G_LUT_CHAN_544125_IDX, + ATHOS_B_5G_LUT_CHAN_544250_IDX, + ATHOS_B_5G_LUT_CHAN_544375_IDX, + ATHOS_B_5G_LUT_CHAN_544500_IDX, + ATHOS_B_5G_LUT_CHAN_544625_IDX, + ATHOS_B_5G_LUT_CHAN_544750_IDX, + ATHOS_B_5G_LUT_CHAN_544875_IDX, + ATHOS_B_5G_LUT_CHAN_545000_IDX, + ATHOS_B_5G_LUT_CHAN_545125_IDX, + ATHOS_B_5G_LUT_CHAN_545250_IDX, + ATHOS_B_5G_LUT_CHAN_545375_IDX, + ATHOS_B_5G_LUT_CHAN_545500_IDX, + ATHOS_B_5G_LUT_CHAN_545625_IDX, + ATHOS_B_5G_LUT_CHAN_545750_IDX, + ATHOS_B_5G_LUT_CHAN_545875_IDX, + ATHOS_B_5G_LUT_CHAN_546000_IDX, + ATHOS_B_5G_LUT_CHAN_546125_IDX, + ATHOS_B_5G_LUT_CHAN_546250_IDX, + ATHOS_B_5G_LUT_CHAN_546375_IDX, + ATHOS_B_5G_LUT_CHAN_546500_IDX, + ATHOS_B_5G_LUT_CHAN_546625_IDX, + ATHOS_B_5G_LUT_CHAN_546750_IDX, + ATHOS_B_5G_LUT_CHAN_546875_IDX, + ATHOS_B_5G_LUT_CHAN_547000_IDX, + ATHOS_B_5G_LUT_CHAN_547125_IDX, + ATHOS_B_5G_LUT_CHAN_547250_IDX, + ATHOS_B_5G_LUT_CHAN_547375_IDX, + ATHOS_B_5G_LUT_CHAN_547500_IDX, + ATHOS_B_5G_LUT_CHAN_547625_IDX, + ATHOS_B_5G_LUT_CHAN_547750_IDX, + ATHOS_B_5G_LUT_CHAN_547875_IDX, + ATHOS_B_5G_LUT_CHAN_548000_IDX, + ATHOS_B_5G_LUT_CHAN_548125_IDX, + ATHOS_B_5G_LUT_CHAN_548250_IDX, + ATHOS_B_5G_LUT_CHAN_548375_IDX, + ATHOS_B_5G_LUT_CHAN_548500_IDX, + ATHOS_B_5G_LUT_CHAN_548625_IDX, + ATHOS_B_5G_LUT_CHAN_548750_IDX, + ATHOS_B_5G_LUT_CHAN_548875_IDX, + ATHOS_B_5G_LUT_CHAN_549000_IDX, + ATHOS_B_5G_LUT_CHAN_549125_IDX, + ATHOS_B_5G_LUT_CHAN_549250_IDX, + ATHOS_B_5G_LUT_CHAN_549375_IDX, + ATHOS_B_5G_LUT_CHAN_549500_IDX, + ATHOS_B_5G_LUT_CHAN_549625_IDX, + ATHOS_B_5G_LUT_CHAN_549750_IDX, + ATHOS_B_5G_LUT_CHAN_549875_IDX, + ATHOS_B_5G_LUT_CHAN_550000_IDX, + ATHOS_B_5G_LUT_CHAN_550125_IDX, + ATHOS_B_5G_LUT_CHAN_550250_IDX, + ATHOS_B_5G_LUT_CHAN_550375_IDX, + ATHOS_B_5G_LUT_CHAN_550500_IDX, + ATHOS_B_5G_LUT_CHAN_550625_IDX, + ATHOS_B_5G_LUT_CHAN_550750_IDX, + ATHOS_B_5G_LUT_CHAN_550875_IDX, + ATHOS_B_5G_LUT_CHAN_551000_IDX, + ATHOS_B_5G_LUT_CHAN_551125_IDX, + ATHOS_B_5G_LUT_CHAN_551250_IDX, + ATHOS_B_5G_LUT_CHAN_551375_IDX, + ATHOS_B_5G_LUT_CHAN_551500_IDX, + ATHOS_B_5G_LUT_CHAN_551625_IDX, + ATHOS_B_5G_LUT_CHAN_551750_IDX, + ATHOS_B_5G_LUT_CHAN_551875_IDX, + ATHOS_B_5G_LUT_CHAN_552000_IDX, + ATHOS_B_5G_LUT_CHAN_552125_IDX, + ATHOS_B_5G_LUT_CHAN_552250_IDX, + ATHOS_B_5G_LUT_CHAN_552375_IDX, + ATHOS_B_5G_LUT_CHAN_552500_IDX, + ATHOS_B_5G_LUT_CHAN_552625_IDX, + ATHOS_B_5G_LUT_CHAN_552750_IDX, + ATHOS_B_5G_LUT_CHAN_552875_IDX, + ATHOS_B_5G_LUT_CHAN_553000_IDX, + ATHOS_B_5G_LUT_CHAN_553125_IDX, + ATHOS_B_5G_LUT_CHAN_553250_IDX, + ATHOS_B_5G_LUT_CHAN_553375_IDX, + ATHOS_B_5G_LUT_CHAN_553500_IDX, + ATHOS_B_5G_LUT_CHAN_553625_IDX, + ATHOS_B_5G_LUT_CHAN_553750_IDX, + ATHOS_B_5G_LUT_CHAN_553875_IDX, + ATHOS_B_5G_LUT_CHAN_554000_IDX, + ATHOS_B_5G_LUT_CHAN_554125_IDX, + ATHOS_B_5G_LUT_CHAN_554250_IDX, + ATHOS_B_5G_LUT_CHAN_554375_IDX, + ATHOS_B_5G_LUT_CHAN_554500_IDX, + ATHOS_B_5G_LUT_CHAN_554625_IDX, + ATHOS_B_5G_LUT_CHAN_554750_IDX, + ATHOS_B_5G_LUT_CHAN_554875_IDX, + ATHOS_B_5G_LUT_CHAN_555000_IDX, + ATHOS_B_5G_LUT_CHAN_555125_IDX, + ATHOS_B_5G_LUT_CHAN_555250_IDX, + ATHOS_B_5G_LUT_CHAN_555375_IDX, + ATHOS_B_5G_LUT_CHAN_555500_IDX, + ATHOS_B_5G_LUT_CHAN_555625_IDX, + ATHOS_B_5G_LUT_CHAN_555750_IDX, + ATHOS_B_5G_LUT_CHAN_555875_IDX, + ATHOS_B_5G_LUT_CHAN_556000_IDX, + ATHOS_B_5G_LUT_CHAN_556125_IDX, + ATHOS_B_5G_LUT_CHAN_556250_IDX, + ATHOS_B_5G_LUT_CHAN_556375_IDX, + ATHOS_B_5G_LUT_CHAN_556500_IDX, + ATHOS_B_5G_LUT_CHAN_556625_IDX, + ATHOS_B_5G_LUT_CHAN_556750_IDX, + ATHOS_B_5G_LUT_CHAN_556875_IDX, + ATHOS_B_5G_LUT_CHAN_557000_IDX, + ATHOS_B_5G_LUT_CHAN_557125_IDX, + ATHOS_B_5G_LUT_CHAN_557250_IDX, + ATHOS_B_5G_LUT_CHAN_557375_IDX, + ATHOS_B_5G_LUT_CHAN_557500_IDX, + ATHOS_B_5G_LUT_CHAN_557625_IDX, + ATHOS_B_5G_LUT_CHAN_557750_IDX, + ATHOS_B_5G_LUT_CHAN_557875_IDX, + ATHOS_B_5G_LUT_CHAN_558000_IDX, + ATHOS_B_5G_LUT_CHAN_558125_IDX, + ATHOS_B_5G_LUT_CHAN_558250_IDX, + ATHOS_B_5G_LUT_CHAN_558375_IDX, + ATHOS_B_5G_LUT_CHAN_558500_IDX, + ATHOS_B_5G_LUT_CHAN_558625_IDX, + ATHOS_B_5G_LUT_CHAN_558750_IDX, + ATHOS_B_5G_LUT_CHAN_558875_IDX, + ATHOS_B_5G_LUT_CHAN_559000_IDX, + ATHOS_B_5G_LUT_CHAN_559125_IDX, + ATHOS_B_5G_LUT_CHAN_559250_IDX, + ATHOS_B_5G_LUT_CHAN_559375_IDX, + ATHOS_B_5G_LUT_CHAN_559500_IDX, + ATHOS_B_5G_LUT_CHAN_559625_IDX, + ATHOS_B_5G_LUT_CHAN_559750_IDX, + ATHOS_B_5G_LUT_CHAN_559875_IDX, + ATHOS_B_5G_LUT_CHAN_560000_IDX, + ATHOS_B_5G_LUT_CHAN_560125_IDX, + ATHOS_B_5G_LUT_CHAN_560250_IDX, + ATHOS_B_5G_LUT_CHAN_560375_IDX, + ATHOS_B_5G_LUT_CHAN_560500_IDX, + ATHOS_B_5G_LUT_CHAN_560625_IDX, + ATHOS_B_5G_LUT_CHAN_560750_IDX, + ATHOS_B_5G_LUT_CHAN_560875_IDX, + ATHOS_B_5G_LUT_CHAN_561000_IDX, + ATHOS_B_5G_LUT_CHAN_561125_IDX, + ATHOS_B_5G_LUT_CHAN_561250_IDX, + ATHOS_B_5G_LUT_CHAN_561375_IDX, + ATHOS_B_5G_LUT_CHAN_561500_IDX, + ATHOS_B_5G_LUT_CHAN_561625_IDX, + ATHOS_B_5G_LUT_CHAN_561750_IDX, + ATHOS_B_5G_LUT_CHAN_561875_IDX, + ATHOS_B_5G_LUT_CHAN_562000_IDX, + ATHOS_B_5G_LUT_CHAN_562125_IDX, + ATHOS_B_5G_LUT_CHAN_562250_IDX, + ATHOS_B_5G_LUT_CHAN_562375_IDX, + ATHOS_B_5G_LUT_CHAN_562500_IDX, + ATHOS_B_5G_LUT_CHAN_562625_IDX, + ATHOS_B_5G_LUT_CHAN_562750_IDX, + ATHOS_B_5G_LUT_CHAN_562875_IDX, + ATHOS_B_5G_LUT_CHAN_563000_IDX, + ATHOS_B_5G_LUT_CHAN_563125_IDX, + ATHOS_B_5G_LUT_CHAN_563250_IDX, + ATHOS_B_5G_LUT_CHAN_563375_IDX, + ATHOS_B_5G_LUT_CHAN_563500_IDX, + ATHOS_B_5G_LUT_CHAN_563625_IDX, + ATHOS_B_5G_LUT_CHAN_563750_IDX, + ATHOS_B_5G_LUT_CHAN_563875_IDX, + ATHOS_B_5G_LUT_CHAN_564000_IDX, + ATHOS_B_5G_LUT_CHAN_564125_IDX, + ATHOS_B_5G_LUT_CHAN_564250_IDX, + ATHOS_B_5G_LUT_CHAN_564375_IDX, + ATHOS_B_5G_LUT_CHAN_564500_IDX, + ATHOS_B_5G_LUT_CHAN_564625_IDX, + ATHOS_B_5G_LUT_CHAN_564750_IDX, + ATHOS_B_5G_LUT_CHAN_564875_IDX, + ATHOS_B_5G_LUT_CHAN_565000_IDX, + ATHOS_B_5G_LUT_CHAN_565125_IDX, + ATHOS_B_5G_LUT_CHAN_565250_IDX, + ATHOS_B_5G_LUT_CHAN_565375_IDX, + ATHOS_B_5G_LUT_CHAN_565500_IDX, + ATHOS_B_5G_LUT_CHAN_565625_IDX, + ATHOS_B_5G_LUT_CHAN_565750_IDX, + ATHOS_B_5G_LUT_CHAN_565875_IDX, + ATHOS_B_5G_LUT_CHAN_566000_IDX, + ATHOS_B_5G_LUT_CHAN_566125_IDX, + ATHOS_B_5G_LUT_CHAN_566250_IDX, + ATHOS_B_5G_LUT_CHAN_566375_IDX, + ATHOS_B_5G_LUT_CHAN_566500_IDX, + ATHOS_B_5G_LUT_CHAN_566625_IDX, + ATHOS_B_5G_LUT_CHAN_566750_IDX, + ATHOS_B_5G_LUT_CHAN_566875_IDX, + ATHOS_B_5G_LUT_CHAN_567000_IDX, + ATHOS_B_5G_LUT_CHAN_567125_IDX, + ATHOS_B_5G_LUT_CHAN_567250_IDX, + ATHOS_B_5G_LUT_CHAN_567375_IDX, + ATHOS_B_5G_LUT_CHAN_567500_IDX, + ATHOS_B_5G_LUT_CHAN_567625_IDX, + ATHOS_B_5G_LUT_CHAN_567750_IDX, + ATHOS_B_5G_LUT_CHAN_567875_IDX, + ATHOS_B_5G_LUT_CHAN_568000_IDX, + ATHOS_B_5G_LUT_CHAN_568125_IDX, + ATHOS_B_5G_LUT_CHAN_568250_IDX, + ATHOS_B_5G_LUT_CHAN_568375_IDX, + ATHOS_B_5G_LUT_CHAN_568500_IDX, + ATHOS_B_5G_LUT_CHAN_568625_IDX, + ATHOS_B_5G_LUT_CHAN_568750_IDX, + ATHOS_B_5G_LUT_CHAN_568875_IDX, + ATHOS_B_5G_LUT_CHAN_569000_IDX, + ATHOS_B_5G_LUT_CHAN_569125_IDX, + ATHOS_B_5G_LUT_CHAN_569250_IDX, + ATHOS_B_5G_LUT_CHAN_569375_IDX, + ATHOS_B_5G_LUT_CHAN_569500_IDX, + ATHOS_B_5G_LUT_CHAN_569625_IDX, + ATHOS_B_5G_LUT_CHAN_569750_IDX, + ATHOS_B_5G_LUT_CHAN_569875_IDX, + ATHOS_B_5G_LUT_CHAN_570000_IDX, + ATHOS_B_5G_LUT_CHAN_570125_IDX, + ATHOS_B_5G_LUT_CHAN_570250_IDX, + ATHOS_B_5G_LUT_CHAN_570375_IDX, + ATHOS_B_5G_LUT_CHAN_570500_IDX, + ATHOS_B_5G_LUT_CHAN_570625_IDX, + ATHOS_B_5G_LUT_CHAN_570750_IDX, + ATHOS_B_5G_LUT_CHAN_570875_IDX, + ATHOS_B_5G_LUT_CHAN_571000_IDX, + ATHOS_B_5G_LUT_CHAN_571125_IDX, + ATHOS_B_5G_LUT_CHAN_571250_IDX, + ATHOS_B_5G_LUT_CHAN_571375_IDX, + ATHOS_B_5G_LUT_CHAN_571500_IDX, + ATHOS_B_5G_LUT_CHAN_571625_IDX, + ATHOS_B_5G_LUT_CHAN_571750_IDX, + ATHOS_B_5G_LUT_CHAN_571875_IDX, + ATHOS_B_5G_LUT_CHAN_572000_IDX, + ATHOS_B_5G_LUT_CHAN_572125_IDX, + ATHOS_B_5G_LUT_CHAN_572250_IDX, + ATHOS_B_5G_LUT_CHAN_572375_IDX, + ATHOS_B_5G_LUT_CHAN_572500_IDX, + ATHOS_B_5G_LUT_CHAN_572625_IDX, + ATHOS_B_5G_LUT_CHAN_572750_IDX, + ATHOS_B_5G_LUT_CHAN_572875_IDX, + ATHOS_B_5G_LUT_CHAN_573000_IDX, + ATHOS_B_5G_LUT_CHAN_573125_IDX, + ATHOS_B_5G_LUT_CHAN_573250_IDX, + ATHOS_B_5G_LUT_CHAN_573375_IDX, + ATHOS_B_5G_LUT_CHAN_573500_IDX, + ATHOS_B_5G_LUT_CHAN_573625_IDX, + ATHOS_B_5G_LUT_CHAN_573750_IDX, + ATHOS_B_5G_LUT_CHAN_573875_IDX, + ATHOS_B_5G_LUT_CHAN_574000_IDX, + ATHOS_B_5G_LUT_CHAN_574125_IDX, + ATHOS_B_5G_LUT_CHAN_574250_IDX, + ATHOS_B_5G_LUT_CHAN_574375_IDX, + ATHOS_B_5G_LUT_CHAN_574500_IDX, + ATHOS_B_5G_LUT_CHAN_574625_IDX, + ATHOS_B_5G_LUT_CHAN_574750_IDX, + ATHOS_B_5G_LUT_CHAN_574875_IDX, + ATHOS_B_5G_LUT_CHAN_575000_IDX, + ATHOS_B_5G_LUT_CHAN_575125_IDX, + ATHOS_B_5G_LUT_CHAN_575250_IDX, + ATHOS_B_5G_LUT_CHAN_575375_IDX, + ATHOS_B_5G_LUT_CHAN_575500_IDX, + ATHOS_B_5G_LUT_CHAN_575625_IDX, + ATHOS_B_5G_LUT_CHAN_575750_IDX, + ATHOS_B_5G_LUT_CHAN_575875_IDX, + ATHOS_B_5G_LUT_CHAN_576000_IDX, + ATHOS_B_5G_LUT_CHAN_576125_IDX, + ATHOS_B_5G_LUT_CHAN_576250_IDX, + ATHOS_B_5G_LUT_CHAN_576375_IDX, + ATHOS_B_5G_LUT_CHAN_576500_IDX, + ATHOS_B_5G_LUT_CHAN_576625_IDX, + ATHOS_B_5G_LUT_CHAN_576750_IDX, + ATHOS_B_5G_LUT_CHAN_576875_IDX, + ATHOS_B_5G_LUT_CHAN_577000_IDX, + ATHOS_B_5G_LUT_CHAN_577125_IDX, + ATHOS_B_5G_LUT_CHAN_577250_IDX, + ATHOS_B_5G_LUT_CHAN_577375_IDX, + ATHOS_B_5G_LUT_CHAN_577500_IDX, + ATHOS_B_5G_LUT_CHAN_577625_IDX, + ATHOS_B_5G_LUT_CHAN_577750_IDX, + ATHOS_B_5G_LUT_CHAN_577875_IDX, + ATHOS_B_5G_LUT_CHAN_578000_IDX, + ATHOS_B_5G_LUT_CHAN_578125_IDX, + ATHOS_B_5G_LUT_CHAN_578250_IDX, + ATHOS_B_5G_LUT_CHAN_578375_IDX, + ATHOS_B_5G_LUT_CHAN_578500_IDX, + ATHOS_B_5G_LUT_CHAN_578625_IDX, + ATHOS_B_5G_LUT_CHAN_578750_IDX, + ATHOS_B_5G_LUT_CHAN_578875_IDX, + ATHOS_B_5G_LUT_CHAN_579000_IDX, + ATHOS_B_5G_LUT_CHAN_579125_IDX, + ATHOS_B_5G_LUT_CHAN_579250_IDX, + ATHOS_B_5G_LUT_CHAN_579375_IDX, + ATHOS_B_5G_LUT_CHAN_579500_IDX, + ATHOS_B_5G_LUT_CHAN_579625_IDX, + ATHOS_B_5G_LUT_CHAN_579750_IDX, + ATHOS_B_5G_LUT_CHAN_579875_IDX, + ATHOS_B_5G_LUT_CHAN_580000_IDX, + ATHOS_B_5G_LUT_CHAN_580125_IDX, + ATHOS_B_5G_LUT_CHAN_580250_IDX, + ATHOS_B_5G_LUT_CHAN_580375_IDX, + ATHOS_B_5G_LUT_CHAN_580500_IDX, + ATHOS_B_5G_LUT_CHAN_580625_IDX, + ATHOS_B_5G_LUT_CHAN_580750_IDX, + ATHOS_B_5G_LUT_CHAN_580875_IDX, + ATHOS_B_5G_LUT_CHAN_581000_IDX, + ATHOS_B_5G_LUT_CHAN_581125_IDX, + ATHOS_B_5G_LUT_CHAN_581250_IDX, + ATHOS_B_5G_LUT_CHAN_581375_IDX, + ATHOS_B_5G_LUT_CHAN_581500_IDX, + ATHOS_B_5G_LUT_CHAN_581625_IDX, + ATHOS_B_5G_LUT_CHAN_581750_IDX, + ATHOS_B_5G_LUT_CHAN_581875_IDX, + ATHOS_B_5G_LUT_CHAN_582000_IDX, + ATHOS_B_5G_LUT_CHAN_582125_IDX, + ATHOS_B_5G_LUT_CHAN_582250_IDX, + ATHOS_B_5G_LUT_CHAN_582375_IDX, + ATHOS_B_5G_LUT_CHAN_582500_IDX, + ATHOS_B_5G_LUT_CHAN_582625_IDX, + ATHOS_B_5G_LUT_CHAN_582750_IDX, + ATHOS_B_5G_LUT_CHAN_582875_IDX, + ATHOS_B_5G_LUT_CHAN_583000_IDX, + ATHOS_B_5G_LUT_CHAN_583125_IDX, + ATHOS_B_5G_LUT_CHAN_583250_IDX, + ATHOS_B_5G_LUT_CHAN_583375_IDX, + ATHOS_B_5G_LUT_CHAN_583500_IDX, + ATHOS_B_5G_LUT_CHAN_583625_IDX, + ATHOS_B_5G_LUT_CHAN_583750_IDX, + ATHOS_B_5G_LUT_CHAN_583875_IDX, + ATHOS_B_5G_LUT_CHAN_584000_IDX, + ATHOS_B_5G_LUT_CHAN_584125_IDX, + ATHOS_B_5G_LUT_CHAN_584250_IDX, + ATHOS_B_5G_LUT_CHAN_584375_IDX, + ATHOS_B_5G_LUT_CHAN_584500_IDX, + ATHOS_B_5G_LUT_CHAN_584625_IDX, + ATHOS_B_5G_LUT_CHAN_584750_IDX, + ATHOS_B_5G_LUT_CHAN_584875_IDX, + ATHOS_B_5G_LUT_CHAN_585000_IDX, + ATHOS_B_5G_LUT_CHAN_585125_IDX, + ATHOS_B_5G_LUT_CHAN_585250_IDX, + ATHOS_B_5G_LUT_CHAN_585375_IDX, + ATHOS_B_5G_LUT_CHAN_585500_IDX, + ATHOS_B_5G_LUT_CHAN_585625_IDX, + ATHOS_B_5G_LUT_CHAN_585750_IDX, + ATHOS_B_5G_LUT_CHAN_585875_IDX, + ATHOS_B_5G_LUT_CHAN_586000_IDX, + ATHOS_B_5G_LUT_CHAN_586125_IDX, + ATHOS_B_5G_LUT_CHAN_586250_IDX, + ATHOS_B_5G_LUT_CHAN_586375_IDX, + ATHOS_B_5G_LUT_CHAN_586500_IDX, + ATHOS_B_5G_LUT_CHAN_586625_IDX, + ATHOS_B_5G_LUT_CHAN_586750_IDX, + ATHOS_B_5G_LUT_CHAN_586875_IDX, + ATHOS_B_5G_LUT_CHAN_587000_IDX, + ATHOS_B_5G_LUT_CHAN_587125_IDX, + ATHOS_B_5G_LUT_CHAN_587250_IDX, + ATHOS_B_5G_LUT_CHAN_587375_IDX, + ATHOS_B_5G_LUT_CHAN_587500_IDX, + ATHOS_B_5G_LUT_CHAN_587625_IDX, + ATHOS_B_5G_LUT_CHAN_587750_IDX, + ATHOS_B_5G_LUT_CHAN_587875_IDX, + ATHOS_B_5G_LUT_CHAN_588000_IDX, + ATHOS_B_5G_LUT_CHAN_588125_IDX, + ATHOS_B_5G_LUT_CHAN_588250_IDX, + ATHOS_B_5G_LUT_CHAN_588375_IDX, + ATHOS_B_5G_LUT_CHAN_588500_IDX, + ATHOS_B_5G_LUT_CHAN_588625_IDX, + ATHOS_B_5G_LUT_CHAN_588750_IDX, + ATHOS_B_5G_LUT_CHAN_588875_IDX, + ATHOS_B_5G_LUT_CHAN_589000_IDX, + ATHOS_B_5G_LUT_CHAN_589125_IDX, + ATHOS_B_5G_LUT_CHAN_589250_IDX, + ATHOS_B_5G_LUT_CHAN_589375_IDX, + ATHOS_B_5G_LUT_CHAN_589500_IDX, + ATHOS_B_5G_LUT_CHAN_589625_IDX, + ATHOS_B_5G_LUT_CHAN_589750_IDX, + ATHOS_B_5G_LUT_CHAN_589875_IDX, + ATHOS_B_5G_LUT_CHAN_590000_IDX, + ATHOS_B_5G_LUT_CHAN_590125_IDX, + ATHOS_B_5G_LUT_CHAN_590250_IDX, + ATHOS_B_5G_LUT_CHAN_590375_IDX, + ATHOS_B_5G_LUT_CHAN_590500_IDX, + ATHOS_B_5G_LUT_CHAN_590625_IDX, + ATHOS_B_5G_LUT_CHAN_590750_IDX, + ATHOS_B_5G_LUT_CHAN_590875_IDX, + ATHOS_B_5G_LUT_CHAN_591000_IDX, + ATHOS_B_5G_LUT_CHAN_591125_IDX, + ATHOS_B_5G_LUT_CHAN_591250_IDX, + ATHOS_B_5G_LUT_CHAN_591375_IDX, + ATHOS_B_5G_LUT_CHAN_591500_IDX, + ATHOS_B_5G_LUT_CHAN_591625_IDX, + ATHOS_B_5G_LUT_CHAN_591750_IDX, + ATHOS_B_5G_LUT_CHAN_591875_IDX, + ATHOS_B_5G_LUT_CHAN_592000_IDX, + ATHOS_B_5G_LUT_CHAN_592125_IDX, + ATHOS_B_5G_LUT_CHAN_592250_IDX, + ATHOS_B_5G_LUT_CHAN_592375_IDX, + ATHOS_B_5G_LUT_CHAN_592500_IDX, + ATHOS_B_5G_LUT_CHAN_592625_IDX, + ATHOS_B_5G_LUT_CHAN_592750_IDX, + ATHOS_B_5G_LUT_CHAN_592875_IDX, + ATHOS_B_5G_LUT_CHAN_593000_IDX, + ATHOS_B_5G_LUT_CHAN_593125_IDX, + ATHOS_B_5G_LUT_CHAN_593250_IDX, + ATHOS_B_5G_LUT_CHAN_593375_IDX, + ATHOS_B_5G_LUT_CHAN_593500_IDX, + ATHOS_B_5G_LUT_CHAN_593625_IDX, + ATHOS_B_5G_LUT_CHAN_593750_IDX, + ATHOS_B_5G_LUT_CHAN_593875_IDX, + ATHOS_B_5G_LUT_CHAN_594000_IDX, + ATHOS_B_5G_LUT_CHAN_594125_IDX, + ATHOS_B_5G_LUT_CHAN_594250_IDX, + ATHOS_B_5G_LUT_CHAN_594375_IDX, + ATHOS_B_5G_LUT_CHAN_594500_IDX, + ATHOS_B_5G_LUT_CHAN_594625_IDX, + ATHOS_B_5G_LUT_CHAN_594750_IDX, + ATHOS_B_5G_LUT_CHAN_594875_IDX, + ATHOS_B_5G_LUT_CHAN_595000_IDX, + ATHOS_B_5G_LUT_CHAN_595125_IDX, + ATHOS_B_5G_LUT_CHAN_595250_IDX, + ATHOS_B_5G_LUT_CHAN_595375_IDX, + ATHOS_B_5G_LUT_CHAN_595500_IDX, + ATHOS_B_5G_LUT_CHAN_595625_IDX, + ATHOS_B_5G_LUT_CHAN_595750_IDX, + ATHOS_B_5G_LUT_CHAN_595875_IDX, + ATHOS_B_5G_LUT_CHAN_596000_IDX, + ATHOS_B_5G_LUT_CHAN_596125_IDX, + ATHOS_B_5G_LUT_CHAN_596250_IDX, + ATHOS_B_5G_LUT_CHAN_596375_IDX, + ATHOS_B_5G_LUT_CHAN_596500_IDX, + ATHOS_B_5G_LUT_CHAN_596625_IDX, + ATHOS_B_5G_LUT_CHAN_596750_IDX, + ATHOS_B_5G_LUT_CHAN_596875_IDX, + ATHOS_B_5G_LUT_CHAN_597000_IDX, + ATHOS_B_5G_LUT_CHAN_597125_IDX, + ATHOS_B_5G_LUT_CHAN_597250_IDX, + ATHOS_B_5G_LUT_CHAN_597375_IDX, + ATHOS_B_5G_LUT_CHAN_597500_IDX, + ATHOS_B_5G_LUT_CHAN_597625_IDX, + ATHOS_B_5G_LUT_CHAN_597750_IDX, + ATHOS_B_5G_LUT_CHAN_597875_IDX, + ATHOS_B_5G_LUT_CHAN_598000_IDX, + ATHOS_B_5G_LUT_CHAN_598125_IDX, + ATHOS_B_5G_LUT_CHAN_598250_IDX, + ATHOS_B_5G_LUT_CHAN_598375_IDX, + ATHOS_B_5G_LUT_CHAN_598500_IDX, + ATHOS_B_5G_LUT_CHAN_598625_IDX, + ATHOS_B_5G_LUT_CHAN_598750_IDX, + ATHOS_B_5G_LUT_CHAN_598875_IDX, + ATHOS_B_5G_LUT_CHAN_599000_IDX, + ATHOS_B_5G_LUT_CHAN_599125_IDX, + ATHOS_B_5G_LUT_CHAN_599250_IDX, + ATHOS_B_5G_LUT_CHAN_599375_IDX, + ATHOS_B_5G_LUT_CHAN_599500_IDX, + ATHOS_B_5G_LUT_CHAN_599625_IDX, + ATHOS_B_5G_LUT_CHAN_599750_IDX, + ATHOS_B_5G_LUT_CHAN_599875_IDX, + ATHOS_B_5G_LUT_CHAN_600000_IDX, + ATHOS_B_5G_LUT_CHAN_5G_MAX +}; + +enum athos_b_idx_6g { + ATHOS_B_6G_LUT_CHAN_593000_IDX, + ATHOS_B_6G_LUT_CHAN_593125_IDX, + ATHOS_B_6G_LUT_CHAN_593250_IDX, + ATHOS_B_6G_LUT_CHAN_593375_IDX, + ATHOS_B_6G_LUT_CHAN_593500_IDX, + ATHOS_B_6G_LUT_CHAN_593625_IDX, + ATHOS_B_6G_LUT_CHAN_593750_IDX, + ATHOS_B_6G_LUT_CHAN_593875_IDX, + ATHOS_B_6G_LUT_CHAN_594000_IDX, + ATHOS_B_6G_LUT_CHAN_594125_IDX, + ATHOS_B_6G_LUT_CHAN_594250_IDX, + ATHOS_B_6G_LUT_CHAN_594375_IDX, + ATHOS_B_6G_LUT_CHAN_594500_IDX, + ATHOS_B_6G_LUT_CHAN_594625_IDX, + ATHOS_B_6G_LUT_CHAN_594750_IDX, + ATHOS_B_6G_LUT_CHAN_594875_IDX, + ATHOS_B_6G_LUT_CHAN_595000_IDX, + ATHOS_B_6G_LUT_CHAN_595125_IDX, + ATHOS_B_6G_LUT_CHAN_595250_IDX, + ATHOS_B_6G_LUT_CHAN_595375_IDX, + ATHOS_B_6G_LUT_CHAN_595500_IDX, + ATHOS_B_6G_LUT_CHAN_595625_IDX, + ATHOS_B_6G_LUT_CHAN_595750_IDX, + ATHOS_B_6G_LUT_CHAN_595875_IDX, + ATHOS_B_6G_LUT_CHAN_596000_IDX, + ATHOS_B_6G_LUT_CHAN_596125_IDX, + ATHOS_B_6G_LUT_CHAN_596250_IDX, + ATHOS_B_6G_LUT_CHAN_596375_IDX, + ATHOS_B_6G_LUT_CHAN_596500_IDX, + ATHOS_B_6G_LUT_CHAN_596625_IDX, + ATHOS_B_6G_LUT_CHAN_596750_IDX, + ATHOS_B_6G_LUT_CHAN_596875_IDX, + ATHOS_B_6G_LUT_CHAN_597000_IDX, + ATHOS_B_6G_LUT_CHAN_597125_IDX, + ATHOS_B_6G_LUT_CHAN_597250_IDX, + ATHOS_B_6G_LUT_CHAN_597375_IDX, + ATHOS_B_6G_LUT_CHAN_597500_IDX, + ATHOS_B_6G_LUT_CHAN_597625_IDX, + ATHOS_B_6G_LUT_CHAN_597750_IDX, + ATHOS_B_6G_LUT_CHAN_597875_IDX, + ATHOS_B_6G_LUT_CHAN_598000_IDX, + ATHOS_B_6G_LUT_CHAN_598125_IDX, + ATHOS_B_6G_LUT_CHAN_598250_IDX, + ATHOS_B_6G_LUT_CHAN_598375_IDX, + ATHOS_B_6G_LUT_CHAN_598500_IDX, + ATHOS_B_6G_LUT_CHAN_598625_IDX, + ATHOS_B_6G_LUT_CHAN_598750_IDX, + ATHOS_B_6G_LUT_CHAN_598875_IDX, + ATHOS_B_6G_LUT_CHAN_599000_IDX, + ATHOS_B_6G_LUT_CHAN_599125_IDX, + ATHOS_B_6G_LUT_CHAN_599250_IDX, + ATHOS_B_6G_LUT_CHAN_599375_IDX, + ATHOS_B_6G_LUT_CHAN_599500_IDX, + ATHOS_B_6G_LUT_CHAN_599625_IDX, + ATHOS_B_6G_LUT_CHAN_599750_IDX, + ATHOS_B_6G_LUT_CHAN_599875_IDX, + ATHOS_B_6G_LUT_CHAN_600000_IDX, + ATHOS_B_6G_LUT_CHAN_600125_IDX, + ATHOS_B_6G_LUT_CHAN_600250_IDX, + ATHOS_B_6G_LUT_CHAN_600375_IDX, + ATHOS_B_6G_LUT_CHAN_600500_IDX, + ATHOS_B_6G_LUT_CHAN_600625_IDX, + ATHOS_B_6G_LUT_CHAN_600750_IDX, + ATHOS_B_6G_LUT_CHAN_600875_IDX, + ATHOS_B_6G_LUT_CHAN_601000_IDX, + ATHOS_B_6G_LUT_CHAN_601125_IDX, + ATHOS_B_6G_LUT_CHAN_601250_IDX, + ATHOS_B_6G_LUT_CHAN_601375_IDX, + ATHOS_B_6G_LUT_CHAN_601500_IDX, + ATHOS_B_6G_LUT_CHAN_601625_IDX, + ATHOS_B_6G_LUT_CHAN_601750_IDX, + ATHOS_B_6G_LUT_CHAN_601875_IDX, + ATHOS_B_6G_LUT_CHAN_602000_IDX, + ATHOS_B_6G_LUT_CHAN_602125_IDX, + ATHOS_B_6G_LUT_CHAN_602250_IDX, + ATHOS_B_6G_LUT_CHAN_602375_IDX, + ATHOS_B_6G_LUT_CHAN_602500_IDX, + ATHOS_B_6G_LUT_CHAN_602625_IDX, + ATHOS_B_6G_LUT_CHAN_602750_IDX, + ATHOS_B_6G_LUT_CHAN_602875_IDX, + ATHOS_B_6G_LUT_CHAN_603000_IDX, + ATHOS_B_6G_LUT_CHAN_603125_IDX, + ATHOS_B_6G_LUT_CHAN_603250_IDX, + ATHOS_B_6G_LUT_CHAN_603375_IDX, + ATHOS_B_6G_LUT_CHAN_603500_IDX, + ATHOS_B_6G_LUT_CHAN_603625_IDX, + ATHOS_B_6G_LUT_CHAN_603750_IDX, + ATHOS_B_6G_LUT_CHAN_603875_IDX, + ATHOS_B_6G_LUT_CHAN_604000_IDX, + ATHOS_B_6G_LUT_CHAN_604125_IDX, + ATHOS_B_6G_LUT_CHAN_604250_IDX, + ATHOS_B_6G_LUT_CHAN_604375_IDX, + ATHOS_B_6G_LUT_CHAN_604500_IDX, + ATHOS_B_6G_LUT_CHAN_604625_IDX, + ATHOS_B_6G_LUT_CHAN_604750_IDX, + ATHOS_B_6G_LUT_CHAN_604875_IDX, + ATHOS_B_6G_LUT_CHAN_605000_IDX, + ATHOS_B_6G_LUT_CHAN_605125_IDX, + ATHOS_B_6G_LUT_CHAN_605250_IDX, + ATHOS_B_6G_LUT_CHAN_605375_IDX, + ATHOS_B_6G_LUT_CHAN_605500_IDX, + ATHOS_B_6G_LUT_CHAN_605625_IDX, + ATHOS_B_6G_LUT_CHAN_605750_IDX, + ATHOS_B_6G_LUT_CHAN_605875_IDX, + ATHOS_B_6G_LUT_CHAN_606000_IDX, + ATHOS_B_6G_LUT_CHAN_606125_IDX, + ATHOS_B_6G_LUT_CHAN_606250_IDX, + ATHOS_B_6G_LUT_CHAN_606375_IDX, + ATHOS_B_6G_LUT_CHAN_606500_IDX, + ATHOS_B_6G_LUT_CHAN_606625_IDX, + ATHOS_B_6G_LUT_CHAN_606750_IDX, + ATHOS_B_6G_LUT_CHAN_606875_IDX, + ATHOS_B_6G_LUT_CHAN_607000_IDX, + ATHOS_B_6G_LUT_CHAN_607125_IDX, + ATHOS_B_6G_LUT_CHAN_607250_IDX, + ATHOS_B_6G_LUT_CHAN_607375_IDX, + ATHOS_B_6G_LUT_CHAN_607500_IDX, + ATHOS_B_6G_LUT_CHAN_607625_IDX, + ATHOS_B_6G_LUT_CHAN_607750_IDX, + ATHOS_B_6G_LUT_CHAN_607875_IDX, + ATHOS_B_6G_LUT_CHAN_608000_IDX, + ATHOS_B_6G_LUT_CHAN_608125_IDX, + ATHOS_B_6G_LUT_CHAN_608250_IDX, + ATHOS_B_6G_LUT_CHAN_608375_IDX, + ATHOS_B_6G_LUT_CHAN_608500_IDX, + ATHOS_B_6G_LUT_CHAN_608625_IDX, + ATHOS_B_6G_LUT_CHAN_608750_IDX, + ATHOS_B_6G_LUT_CHAN_608875_IDX, + ATHOS_B_6G_LUT_CHAN_609000_IDX, + ATHOS_B_6G_LUT_CHAN_609125_IDX, + ATHOS_B_6G_LUT_CHAN_609250_IDX, + ATHOS_B_6G_LUT_CHAN_609375_IDX, + ATHOS_B_6G_LUT_CHAN_609500_IDX, + ATHOS_B_6G_LUT_CHAN_609625_IDX, + ATHOS_B_6G_LUT_CHAN_609750_IDX, + ATHOS_B_6G_LUT_CHAN_609875_IDX, + ATHOS_B_6G_LUT_CHAN_610000_IDX, + ATHOS_B_6G_LUT_CHAN_610125_IDX, + ATHOS_B_6G_LUT_CHAN_610250_IDX, + ATHOS_B_6G_LUT_CHAN_610375_IDX, + ATHOS_B_6G_LUT_CHAN_610500_IDX, + ATHOS_B_6G_LUT_CHAN_610625_IDX, + ATHOS_B_6G_LUT_CHAN_610750_IDX, + ATHOS_B_6G_LUT_CHAN_610875_IDX, + ATHOS_B_6G_LUT_CHAN_611000_IDX, + ATHOS_B_6G_LUT_CHAN_611125_IDX, + ATHOS_B_6G_LUT_CHAN_611250_IDX, + ATHOS_B_6G_LUT_CHAN_611375_IDX, + ATHOS_B_6G_LUT_CHAN_611500_IDX, + ATHOS_B_6G_LUT_CHAN_611625_IDX, + ATHOS_B_6G_LUT_CHAN_611750_IDX, + ATHOS_B_6G_LUT_CHAN_611875_IDX, + ATHOS_B_6G_LUT_CHAN_612000_IDX, + ATHOS_B_6G_LUT_CHAN_612125_IDX, + ATHOS_B_6G_LUT_CHAN_612250_IDX, + ATHOS_B_6G_LUT_CHAN_612375_IDX, + ATHOS_B_6G_LUT_CHAN_612500_IDX, + ATHOS_B_6G_LUT_CHAN_612625_IDX, + ATHOS_B_6G_LUT_CHAN_612750_IDX, + ATHOS_B_6G_LUT_CHAN_612875_IDX, + ATHOS_B_6G_LUT_CHAN_613000_IDX, + ATHOS_B_6G_LUT_CHAN_613125_IDX, + ATHOS_B_6G_LUT_CHAN_613250_IDX, + ATHOS_B_6G_LUT_CHAN_613375_IDX, + ATHOS_B_6G_LUT_CHAN_613500_IDX, + ATHOS_B_6G_LUT_CHAN_613625_IDX, + ATHOS_B_6G_LUT_CHAN_613750_IDX, + ATHOS_B_6G_LUT_CHAN_613875_IDX, + ATHOS_B_6G_LUT_CHAN_614000_IDX, + ATHOS_B_6G_LUT_CHAN_614125_IDX, + ATHOS_B_6G_LUT_CHAN_614250_IDX, + ATHOS_B_6G_LUT_CHAN_614375_IDX, + ATHOS_B_6G_LUT_CHAN_614500_IDX, + ATHOS_B_6G_LUT_CHAN_614625_IDX, + ATHOS_B_6G_LUT_CHAN_614750_IDX, + ATHOS_B_6G_LUT_CHAN_614875_IDX, + ATHOS_B_6G_LUT_CHAN_615000_IDX, + ATHOS_B_6G_LUT_CHAN_615125_IDX, + ATHOS_B_6G_LUT_CHAN_615250_IDX, + ATHOS_B_6G_LUT_CHAN_615375_IDX, + ATHOS_B_6G_LUT_CHAN_615500_IDX, + ATHOS_B_6G_LUT_CHAN_615625_IDX, + ATHOS_B_6G_LUT_CHAN_615750_IDX, + ATHOS_B_6G_LUT_CHAN_615875_IDX, + ATHOS_B_6G_LUT_CHAN_616000_IDX, + ATHOS_B_6G_LUT_CHAN_616125_IDX, + ATHOS_B_6G_LUT_CHAN_616250_IDX, + ATHOS_B_6G_LUT_CHAN_616375_IDX, + ATHOS_B_6G_LUT_CHAN_616500_IDX, + ATHOS_B_6G_LUT_CHAN_616625_IDX, + ATHOS_B_6G_LUT_CHAN_616750_IDX, + ATHOS_B_6G_LUT_CHAN_616875_IDX, + ATHOS_B_6G_LUT_CHAN_617000_IDX, + ATHOS_B_6G_LUT_CHAN_617125_IDX, + ATHOS_B_6G_LUT_CHAN_617250_IDX, + ATHOS_B_6G_LUT_CHAN_617375_IDX, + ATHOS_B_6G_LUT_CHAN_617500_IDX, + ATHOS_B_6G_LUT_CHAN_617625_IDX, + ATHOS_B_6G_LUT_CHAN_617750_IDX, + ATHOS_B_6G_LUT_CHAN_617875_IDX, + ATHOS_B_6G_LUT_CHAN_618000_IDX, + ATHOS_B_6G_LUT_CHAN_618125_IDX, + ATHOS_B_6G_LUT_CHAN_618250_IDX, + ATHOS_B_6G_LUT_CHAN_618375_IDX, + ATHOS_B_6G_LUT_CHAN_618500_IDX, + ATHOS_B_6G_LUT_CHAN_618625_IDX, + ATHOS_B_6G_LUT_CHAN_618750_IDX, + ATHOS_B_6G_LUT_CHAN_618875_IDX, + ATHOS_B_6G_LUT_CHAN_619000_IDX, + ATHOS_B_6G_LUT_CHAN_619125_IDX, + ATHOS_B_6G_LUT_CHAN_619250_IDX, + ATHOS_B_6G_LUT_CHAN_619375_IDX, + ATHOS_B_6G_LUT_CHAN_619500_IDX, + ATHOS_B_6G_LUT_CHAN_619625_IDX, + ATHOS_B_6G_LUT_CHAN_619750_IDX, + ATHOS_B_6G_LUT_CHAN_619875_IDX, + ATHOS_B_6G_LUT_CHAN_620000_IDX, + ATHOS_B_6G_LUT_CHAN_620125_IDX, + ATHOS_B_6G_LUT_CHAN_620250_IDX, + ATHOS_B_6G_LUT_CHAN_620375_IDX, + ATHOS_B_6G_LUT_CHAN_620500_IDX, + ATHOS_B_6G_LUT_CHAN_620625_IDX, + ATHOS_B_6G_LUT_CHAN_620750_IDX, + ATHOS_B_6G_LUT_CHAN_620875_IDX, + ATHOS_B_6G_LUT_CHAN_621000_IDX, + ATHOS_B_6G_LUT_CHAN_621125_IDX, + ATHOS_B_6G_LUT_CHAN_621250_IDX, + ATHOS_B_6G_LUT_CHAN_621375_IDX, + ATHOS_B_6G_LUT_CHAN_621500_IDX, + ATHOS_B_6G_LUT_CHAN_621625_IDX, + ATHOS_B_6G_LUT_CHAN_621750_IDX, + ATHOS_B_6G_LUT_CHAN_621875_IDX, + ATHOS_B_6G_LUT_CHAN_622000_IDX, + ATHOS_B_6G_LUT_CHAN_622125_IDX, + ATHOS_B_6G_LUT_CHAN_622250_IDX, + ATHOS_B_6G_LUT_CHAN_622375_IDX, + ATHOS_B_6G_LUT_CHAN_622500_IDX, + ATHOS_B_6G_LUT_CHAN_622625_IDX, + ATHOS_B_6G_LUT_CHAN_622750_IDX, + ATHOS_B_6G_LUT_CHAN_622875_IDX, + ATHOS_B_6G_LUT_CHAN_623000_IDX, + ATHOS_B_6G_LUT_CHAN_623125_IDX, + ATHOS_B_6G_LUT_CHAN_623250_IDX, + ATHOS_B_6G_LUT_CHAN_623375_IDX, + ATHOS_B_6G_LUT_CHAN_623500_IDX, + ATHOS_B_6G_LUT_CHAN_623625_IDX, + ATHOS_B_6G_LUT_CHAN_623750_IDX, + ATHOS_B_6G_LUT_CHAN_623875_IDX, + ATHOS_B_6G_LUT_CHAN_624000_IDX, + ATHOS_B_6G_LUT_CHAN_624125_IDX, + ATHOS_B_6G_LUT_CHAN_624250_IDX, + ATHOS_B_6G_LUT_CHAN_624375_IDX, + ATHOS_B_6G_LUT_CHAN_624500_IDX, + ATHOS_B_6G_LUT_CHAN_624625_IDX, + ATHOS_B_6G_LUT_CHAN_624750_IDX, + ATHOS_B_6G_LUT_CHAN_624875_IDX, + ATHOS_B_6G_LUT_CHAN_625000_IDX, + ATHOS_B_6G_LUT_CHAN_625125_IDX, + ATHOS_B_6G_LUT_CHAN_625250_IDX, + ATHOS_B_6G_LUT_CHAN_625375_IDX, + ATHOS_B_6G_LUT_CHAN_625500_IDX, + ATHOS_B_6G_LUT_CHAN_625625_IDX, + ATHOS_B_6G_LUT_CHAN_625750_IDX, + ATHOS_B_6G_LUT_CHAN_625875_IDX, + ATHOS_B_6G_LUT_CHAN_626000_IDX, + ATHOS_B_6G_LUT_CHAN_626125_IDX, + ATHOS_B_6G_LUT_CHAN_626250_IDX, + ATHOS_B_6G_LUT_CHAN_626375_IDX, + ATHOS_B_6G_LUT_CHAN_626500_IDX, + ATHOS_B_6G_LUT_CHAN_626625_IDX, + ATHOS_B_6G_LUT_CHAN_626750_IDX, + ATHOS_B_6G_LUT_CHAN_626875_IDX, + ATHOS_B_6G_LUT_CHAN_627000_IDX, + ATHOS_B_6G_LUT_CHAN_627125_IDX, + ATHOS_B_6G_LUT_CHAN_627250_IDX, + ATHOS_B_6G_LUT_CHAN_627375_IDX, + ATHOS_B_6G_LUT_CHAN_627500_IDX, + ATHOS_B_6G_LUT_CHAN_627625_IDX, + ATHOS_B_6G_LUT_CHAN_627750_IDX, + ATHOS_B_6G_LUT_CHAN_627875_IDX, + ATHOS_B_6G_LUT_CHAN_628000_IDX, + ATHOS_B_6G_LUT_CHAN_628125_IDX, + ATHOS_B_6G_LUT_CHAN_628250_IDX, + ATHOS_B_6G_LUT_CHAN_628375_IDX, + ATHOS_B_6G_LUT_CHAN_628500_IDX, + ATHOS_B_6G_LUT_CHAN_628625_IDX, + ATHOS_B_6G_LUT_CHAN_628750_IDX, + ATHOS_B_6G_LUT_CHAN_628875_IDX, + ATHOS_B_6G_LUT_CHAN_629000_IDX, + ATHOS_B_6G_LUT_CHAN_629125_IDX, + ATHOS_B_6G_LUT_CHAN_629250_IDX, + ATHOS_B_6G_LUT_CHAN_629375_IDX, + ATHOS_B_6G_LUT_CHAN_629500_IDX, + ATHOS_B_6G_LUT_CHAN_629625_IDX, + ATHOS_B_6G_LUT_CHAN_629750_IDX, + ATHOS_B_6G_LUT_CHAN_629875_IDX, + ATHOS_B_6G_LUT_CHAN_630000_IDX, + ATHOS_B_6G_LUT_CHAN_630125_IDX, + ATHOS_B_6G_LUT_CHAN_630250_IDX, + ATHOS_B_6G_LUT_CHAN_630375_IDX, + ATHOS_B_6G_LUT_CHAN_630500_IDX, + ATHOS_B_6G_LUT_CHAN_630625_IDX, + ATHOS_B_6G_LUT_CHAN_630750_IDX, + ATHOS_B_6G_LUT_CHAN_630875_IDX, + ATHOS_B_6G_LUT_CHAN_631000_IDX, + ATHOS_B_6G_LUT_CHAN_631125_IDX, + ATHOS_B_6G_LUT_CHAN_631250_IDX, + ATHOS_B_6G_LUT_CHAN_631375_IDX, + ATHOS_B_6G_LUT_CHAN_631500_IDX, + ATHOS_B_6G_LUT_CHAN_631625_IDX, + ATHOS_B_6G_LUT_CHAN_631750_IDX, + ATHOS_B_6G_LUT_CHAN_631875_IDX, + ATHOS_B_6G_LUT_CHAN_632000_IDX, + ATHOS_B_6G_LUT_CHAN_632125_IDX, + ATHOS_B_6G_LUT_CHAN_632250_IDX, + ATHOS_B_6G_LUT_CHAN_632375_IDX, + ATHOS_B_6G_LUT_CHAN_632500_IDX, + ATHOS_B_6G_LUT_CHAN_632625_IDX, + ATHOS_B_6G_LUT_CHAN_632750_IDX, + ATHOS_B_6G_LUT_CHAN_632875_IDX, + ATHOS_B_6G_LUT_CHAN_633000_IDX, + ATHOS_B_6G_LUT_CHAN_633125_IDX, + ATHOS_B_6G_LUT_CHAN_633250_IDX, + ATHOS_B_6G_LUT_CHAN_633375_IDX, + ATHOS_B_6G_LUT_CHAN_633500_IDX, + ATHOS_B_6G_LUT_CHAN_633625_IDX, + ATHOS_B_6G_LUT_CHAN_633750_IDX, + ATHOS_B_6G_LUT_CHAN_633875_IDX, + ATHOS_B_6G_LUT_CHAN_634000_IDX, + ATHOS_B_6G_LUT_CHAN_634125_IDX, + ATHOS_B_6G_LUT_CHAN_634250_IDX, + ATHOS_B_6G_LUT_CHAN_634375_IDX, + ATHOS_B_6G_LUT_CHAN_634500_IDX, + ATHOS_B_6G_LUT_CHAN_634625_IDX, + ATHOS_B_6G_LUT_CHAN_634750_IDX, + ATHOS_B_6G_LUT_CHAN_634875_IDX, + ATHOS_B_6G_LUT_CHAN_635000_IDX, + ATHOS_B_6G_LUT_CHAN_635125_IDX, + ATHOS_B_6G_LUT_CHAN_635250_IDX, + ATHOS_B_6G_LUT_CHAN_635375_IDX, + ATHOS_B_6G_LUT_CHAN_635500_IDX, + ATHOS_B_6G_LUT_CHAN_635625_IDX, + ATHOS_B_6G_LUT_CHAN_635750_IDX, + ATHOS_B_6G_LUT_CHAN_635875_IDX, + ATHOS_B_6G_LUT_CHAN_636000_IDX, + ATHOS_B_6G_LUT_CHAN_636125_IDX, + ATHOS_B_6G_LUT_CHAN_636250_IDX, + ATHOS_B_6G_LUT_CHAN_636375_IDX, + ATHOS_B_6G_LUT_CHAN_636500_IDX, + ATHOS_B_6G_LUT_CHAN_636625_IDX, + ATHOS_B_6G_LUT_CHAN_636750_IDX, + ATHOS_B_6G_LUT_CHAN_636875_IDX, + ATHOS_B_6G_LUT_CHAN_637000_IDX, + ATHOS_B_6G_LUT_CHAN_637125_IDX, + ATHOS_B_6G_LUT_CHAN_637250_IDX, + ATHOS_B_6G_LUT_CHAN_637375_IDX, + ATHOS_B_6G_LUT_CHAN_637500_IDX, + ATHOS_B_6G_LUT_CHAN_637625_IDX, + ATHOS_B_6G_LUT_CHAN_637750_IDX, + ATHOS_B_6G_LUT_CHAN_637875_IDX, + ATHOS_B_6G_LUT_CHAN_638000_IDX, + ATHOS_B_6G_LUT_CHAN_638125_IDX, + ATHOS_B_6G_LUT_CHAN_638250_IDX, + ATHOS_B_6G_LUT_CHAN_638375_IDX, + ATHOS_B_6G_LUT_CHAN_638500_IDX, + ATHOS_B_6G_LUT_CHAN_638625_IDX, + ATHOS_B_6G_LUT_CHAN_638750_IDX, + ATHOS_B_6G_LUT_CHAN_638875_IDX, + ATHOS_B_6G_LUT_CHAN_639000_IDX, + ATHOS_B_6G_LUT_CHAN_639125_IDX, + ATHOS_B_6G_LUT_CHAN_639250_IDX, + ATHOS_B_6G_LUT_CHAN_639375_IDX, + ATHOS_B_6G_LUT_CHAN_639500_IDX, + ATHOS_B_6G_LUT_CHAN_639625_IDX, + ATHOS_B_6G_LUT_CHAN_639750_IDX, + ATHOS_B_6G_LUT_CHAN_639875_IDX, + ATHOS_B_6G_LUT_CHAN_640000_IDX, + ATHOS_B_6G_LUT_CHAN_640125_IDX, + ATHOS_B_6G_LUT_CHAN_640250_IDX, + ATHOS_B_6G_LUT_CHAN_640375_IDX, + ATHOS_B_6G_LUT_CHAN_640500_IDX, + ATHOS_B_6G_LUT_CHAN_640625_IDX, + ATHOS_B_6G_LUT_CHAN_640750_IDX, + ATHOS_B_6G_LUT_CHAN_640875_IDX, + ATHOS_B_6G_LUT_CHAN_641000_IDX, + ATHOS_B_6G_LUT_CHAN_641125_IDX, + ATHOS_B_6G_LUT_CHAN_641250_IDX, + ATHOS_B_6G_LUT_CHAN_641375_IDX, + ATHOS_B_6G_LUT_CHAN_641500_IDX, + ATHOS_B_6G_LUT_CHAN_641625_IDX, + ATHOS_B_6G_LUT_CHAN_641750_IDX, + ATHOS_B_6G_LUT_CHAN_641875_IDX, + ATHOS_B_6G_LUT_CHAN_642000_IDX, + ATHOS_B_6G_LUT_CHAN_642125_IDX, + ATHOS_B_6G_LUT_CHAN_642250_IDX, + ATHOS_B_6G_LUT_CHAN_642375_IDX, + ATHOS_B_6G_LUT_CHAN_642500_IDX, + ATHOS_B_6G_LUT_CHAN_642625_IDX, + ATHOS_B_6G_LUT_CHAN_642750_IDX, + ATHOS_B_6G_LUT_CHAN_642875_IDX, + ATHOS_B_6G_LUT_CHAN_643000_IDX, + ATHOS_B_6G_LUT_CHAN_643125_IDX, + ATHOS_B_6G_LUT_CHAN_643250_IDX, + ATHOS_B_6G_LUT_CHAN_643375_IDX, + ATHOS_B_6G_LUT_CHAN_643500_IDX, + ATHOS_B_6G_LUT_CHAN_643625_IDX, + ATHOS_B_6G_LUT_CHAN_643750_IDX, + ATHOS_B_6G_LUT_CHAN_643875_IDX, + ATHOS_B_6G_LUT_CHAN_644000_IDX, + ATHOS_B_6G_LUT_CHAN_644125_IDX, + ATHOS_B_6G_LUT_CHAN_644250_IDX, + ATHOS_B_6G_LUT_CHAN_644375_IDX, + ATHOS_B_6G_LUT_CHAN_644500_IDX, + ATHOS_B_6G_LUT_CHAN_644625_IDX, + ATHOS_B_6G_LUT_CHAN_644750_IDX, + ATHOS_B_6G_LUT_CHAN_644875_IDX, + ATHOS_B_6G_LUT_CHAN_645000_IDX, + ATHOS_B_6G_LUT_CHAN_645125_IDX, + ATHOS_B_6G_LUT_CHAN_645250_IDX, + ATHOS_B_6G_LUT_CHAN_645375_IDX, + ATHOS_B_6G_LUT_CHAN_645500_IDX, + ATHOS_B_6G_LUT_CHAN_645625_IDX, + ATHOS_B_6G_LUT_CHAN_645750_IDX, + ATHOS_B_6G_LUT_CHAN_645875_IDX, + ATHOS_B_6G_LUT_CHAN_646000_IDX, + ATHOS_B_6G_LUT_CHAN_646125_IDX, + ATHOS_B_6G_LUT_CHAN_646250_IDX, + ATHOS_B_6G_LUT_CHAN_646375_IDX, + ATHOS_B_6G_LUT_CHAN_646500_IDX, + ATHOS_B_6G_LUT_CHAN_646625_IDX, + ATHOS_B_6G_LUT_CHAN_646750_IDX, + ATHOS_B_6G_LUT_CHAN_646875_IDX, + ATHOS_B_6G_LUT_CHAN_647000_IDX, + ATHOS_B_6G_LUT_CHAN_647125_IDX, + ATHOS_B_6G_LUT_CHAN_647250_IDX, + ATHOS_B_6G_LUT_CHAN_647375_IDX, + ATHOS_B_6G_LUT_CHAN_647500_IDX, + ATHOS_B_6G_LUT_CHAN_647625_IDX, + ATHOS_B_6G_LUT_CHAN_647750_IDX, + ATHOS_B_6G_LUT_CHAN_647875_IDX, + ATHOS_B_6G_LUT_CHAN_648000_IDX, + ATHOS_B_6G_LUT_CHAN_648125_IDX, + ATHOS_B_6G_LUT_CHAN_648250_IDX, + ATHOS_B_6G_LUT_CHAN_648375_IDX, + ATHOS_B_6G_LUT_CHAN_648500_IDX, + ATHOS_B_6G_LUT_CHAN_648625_IDX, + ATHOS_B_6G_LUT_CHAN_648750_IDX, + ATHOS_B_6G_LUT_CHAN_648875_IDX, + ATHOS_B_6G_LUT_CHAN_649000_IDX, + ATHOS_B_6G_LUT_CHAN_649125_IDX, + ATHOS_B_6G_LUT_CHAN_649250_IDX, + ATHOS_B_6G_LUT_CHAN_649375_IDX, + ATHOS_B_6G_LUT_CHAN_649500_IDX, + ATHOS_B_6G_LUT_CHAN_649625_IDX, + ATHOS_B_6G_LUT_CHAN_649750_IDX, + ATHOS_B_6G_LUT_CHAN_649875_IDX, + ATHOS_B_6G_LUT_CHAN_650000_IDX, + ATHOS_B_6G_LUT_CHAN_650125_IDX, + ATHOS_B_6G_LUT_CHAN_650250_IDX, + ATHOS_B_6G_LUT_CHAN_650375_IDX, + ATHOS_B_6G_LUT_CHAN_650500_IDX, + ATHOS_B_6G_LUT_CHAN_650625_IDX, + ATHOS_B_6G_LUT_CHAN_650750_IDX, + ATHOS_B_6G_LUT_CHAN_650875_IDX, + ATHOS_B_6G_LUT_CHAN_651000_IDX, + ATHOS_B_6G_LUT_CHAN_651125_IDX, + ATHOS_B_6G_LUT_CHAN_651250_IDX, + ATHOS_B_6G_LUT_CHAN_651375_IDX, + ATHOS_B_6G_LUT_CHAN_651500_IDX, + ATHOS_B_6G_LUT_CHAN_651625_IDX, + ATHOS_B_6G_LUT_CHAN_651750_IDX, + ATHOS_B_6G_LUT_CHAN_651875_IDX, + ATHOS_B_6G_LUT_CHAN_652000_IDX, + ATHOS_B_6G_LUT_CHAN_652125_IDX, + ATHOS_B_6G_LUT_CHAN_652250_IDX, + ATHOS_B_6G_LUT_CHAN_652375_IDX, + ATHOS_B_6G_LUT_CHAN_652500_IDX, + ATHOS_B_6G_LUT_CHAN_652625_IDX, + ATHOS_B_6G_LUT_CHAN_652750_IDX, + ATHOS_B_6G_LUT_CHAN_652875_IDX, + ATHOS_B_6G_LUT_CHAN_653000_IDX, + ATHOS_B_6G_LUT_CHAN_653125_IDX, + ATHOS_B_6G_LUT_CHAN_653250_IDX, + ATHOS_B_6G_LUT_CHAN_653375_IDX, + ATHOS_B_6G_LUT_CHAN_653500_IDX, + ATHOS_B_6G_LUT_CHAN_653625_IDX, + ATHOS_B_6G_LUT_CHAN_653750_IDX, + ATHOS_B_6G_LUT_CHAN_653875_IDX, + ATHOS_B_6G_LUT_CHAN_654000_IDX, + ATHOS_B_6G_LUT_CHAN_654125_IDX, + ATHOS_B_6G_LUT_CHAN_654250_IDX, + ATHOS_B_6G_LUT_CHAN_654375_IDX, + ATHOS_B_6G_LUT_CHAN_654500_IDX, + ATHOS_B_6G_LUT_CHAN_654625_IDX, + ATHOS_B_6G_LUT_CHAN_654750_IDX, + ATHOS_B_6G_LUT_CHAN_654875_IDX, + ATHOS_B_6G_LUT_CHAN_655000_IDX, + ATHOS_B_6G_LUT_CHAN_655125_IDX, + ATHOS_B_6G_LUT_CHAN_655250_IDX, + ATHOS_B_6G_LUT_CHAN_655375_IDX, + ATHOS_B_6G_LUT_CHAN_655500_IDX, + ATHOS_B_6G_LUT_CHAN_655625_IDX, + ATHOS_B_6G_LUT_CHAN_655750_IDX, + ATHOS_B_6G_LUT_CHAN_655875_IDX, + ATHOS_B_6G_LUT_CHAN_656000_IDX, + ATHOS_B_6G_LUT_CHAN_656125_IDX, + ATHOS_B_6G_LUT_CHAN_656250_IDX, + ATHOS_B_6G_LUT_CHAN_656375_IDX, + ATHOS_B_6G_LUT_CHAN_656500_IDX, + ATHOS_B_6G_LUT_CHAN_656625_IDX, + ATHOS_B_6G_LUT_CHAN_656750_IDX, + ATHOS_B_6G_LUT_CHAN_656875_IDX, + ATHOS_B_6G_LUT_CHAN_657000_IDX, + ATHOS_B_6G_LUT_CHAN_657125_IDX, + ATHOS_B_6G_LUT_CHAN_657250_IDX, + ATHOS_B_6G_LUT_CHAN_657375_IDX, + ATHOS_B_6G_LUT_CHAN_657500_IDX, + ATHOS_B_6G_LUT_CHAN_657625_IDX, + ATHOS_B_6G_LUT_CHAN_657750_IDX, + ATHOS_B_6G_LUT_CHAN_657875_IDX, + ATHOS_B_6G_LUT_CHAN_658000_IDX, + ATHOS_B_6G_LUT_CHAN_658125_IDX, + ATHOS_B_6G_LUT_CHAN_658250_IDX, + ATHOS_B_6G_LUT_CHAN_658375_IDX, + ATHOS_B_6G_LUT_CHAN_658500_IDX, + ATHOS_B_6G_LUT_CHAN_658625_IDX, + ATHOS_B_6G_LUT_CHAN_658750_IDX, + ATHOS_B_6G_LUT_CHAN_658875_IDX, + ATHOS_B_6G_LUT_CHAN_659000_IDX, + ATHOS_B_6G_LUT_CHAN_659125_IDX, + ATHOS_B_6G_LUT_CHAN_659250_IDX, + ATHOS_B_6G_LUT_CHAN_659375_IDX, + ATHOS_B_6G_LUT_CHAN_659500_IDX, + ATHOS_B_6G_LUT_CHAN_659625_IDX, + ATHOS_B_6G_LUT_CHAN_659750_IDX, + ATHOS_B_6G_LUT_CHAN_659875_IDX, + ATHOS_B_6G_LUT_CHAN_660000_IDX, + ATHOS_B_6G_LUT_CHAN_660125_IDX, + ATHOS_B_6G_LUT_CHAN_660250_IDX, + ATHOS_B_6G_LUT_CHAN_660375_IDX, + ATHOS_B_6G_LUT_CHAN_660500_IDX, + ATHOS_B_6G_LUT_CHAN_660625_IDX, + ATHOS_B_6G_LUT_CHAN_660750_IDX, + ATHOS_B_6G_LUT_CHAN_660875_IDX, + ATHOS_B_6G_LUT_CHAN_661000_IDX, + ATHOS_B_6G_LUT_CHAN_661125_IDX, + ATHOS_B_6G_LUT_CHAN_661250_IDX, + ATHOS_B_6G_LUT_CHAN_661375_IDX, + ATHOS_B_6G_LUT_CHAN_661500_IDX, + ATHOS_B_6G_LUT_CHAN_661625_IDX, + ATHOS_B_6G_LUT_CHAN_661750_IDX, + ATHOS_B_6G_LUT_CHAN_661875_IDX, + ATHOS_B_6G_LUT_CHAN_662000_IDX, + ATHOS_B_6G_LUT_CHAN_662125_IDX, + ATHOS_B_6G_LUT_CHAN_662250_IDX, + ATHOS_B_6G_LUT_CHAN_662375_IDX, + ATHOS_B_6G_LUT_CHAN_662500_IDX, + ATHOS_B_6G_LUT_CHAN_662625_IDX, + ATHOS_B_6G_LUT_CHAN_662750_IDX, + ATHOS_B_6G_LUT_CHAN_662875_IDX, + ATHOS_B_6G_LUT_CHAN_663000_IDX, + ATHOS_B_6G_LUT_CHAN_663125_IDX, + ATHOS_B_6G_LUT_CHAN_663250_IDX, + ATHOS_B_6G_LUT_CHAN_663375_IDX, + ATHOS_B_6G_LUT_CHAN_663500_IDX, + ATHOS_B_6G_LUT_CHAN_663625_IDX, + ATHOS_B_6G_LUT_CHAN_663750_IDX, + ATHOS_B_6G_LUT_CHAN_663875_IDX, + ATHOS_B_6G_LUT_CHAN_664000_IDX, + ATHOS_B_6G_LUT_CHAN_664125_IDX, + ATHOS_B_6G_LUT_CHAN_664250_IDX, + ATHOS_B_6G_LUT_CHAN_664375_IDX, + ATHOS_B_6G_LUT_CHAN_664500_IDX, + ATHOS_B_6G_LUT_CHAN_664625_IDX, + ATHOS_B_6G_LUT_CHAN_664750_IDX, + ATHOS_B_6G_LUT_CHAN_664875_IDX, + ATHOS_B_6G_LUT_CHAN_665000_IDX, + ATHOS_B_6G_LUT_CHAN_665125_IDX, + ATHOS_B_6G_LUT_CHAN_665250_IDX, + ATHOS_B_6G_LUT_CHAN_665375_IDX, + ATHOS_B_6G_LUT_CHAN_665500_IDX, + ATHOS_B_6G_LUT_CHAN_665625_IDX, + ATHOS_B_6G_LUT_CHAN_665750_IDX, + ATHOS_B_6G_LUT_CHAN_665875_IDX, + ATHOS_B_6G_LUT_CHAN_666000_IDX, + ATHOS_B_6G_LUT_CHAN_666125_IDX, + ATHOS_B_6G_LUT_CHAN_666250_IDX, + ATHOS_B_6G_LUT_CHAN_666375_IDX, + ATHOS_B_6G_LUT_CHAN_666500_IDX, + ATHOS_B_6G_LUT_CHAN_666625_IDX, + ATHOS_B_6G_LUT_CHAN_666750_IDX, + ATHOS_B_6G_LUT_CHAN_666875_IDX, + ATHOS_B_6G_LUT_CHAN_667000_IDX, + ATHOS_B_6G_LUT_CHAN_667125_IDX, + ATHOS_B_6G_LUT_CHAN_667250_IDX, + ATHOS_B_6G_LUT_CHAN_667375_IDX, + ATHOS_B_6G_LUT_CHAN_667500_IDX, + ATHOS_B_6G_LUT_CHAN_667625_IDX, + ATHOS_B_6G_LUT_CHAN_667750_IDX, + ATHOS_B_6G_LUT_CHAN_667875_IDX, + ATHOS_B_6G_LUT_CHAN_668000_IDX, + ATHOS_B_6G_LUT_CHAN_668125_IDX, + ATHOS_B_6G_LUT_CHAN_668250_IDX, + ATHOS_B_6G_LUT_CHAN_668375_IDX, + ATHOS_B_6G_LUT_CHAN_668500_IDX, + ATHOS_B_6G_LUT_CHAN_668625_IDX, + ATHOS_B_6G_LUT_CHAN_668750_IDX, + ATHOS_B_6G_LUT_CHAN_668875_IDX, + ATHOS_B_6G_LUT_CHAN_669000_IDX, + ATHOS_B_6G_LUT_CHAN_669125_IDX, + ATHOS_B_6G_LUT_CHAN_669250_IDX, + ATHOS_B_6G_LUT_CHAN_669375_IDX, + ATHOS_B_6G_LUT_CHAN_669500_IDX, + ATHOS_B_6G_LUT_CHAN_669625_IDX, + ATHOS_B_6G_LUT_CHAN_669750_IDX, + ATHOS_B_6G_LUT_CHAN_669875_IDX, + ATHOS_B_6G_LUT_CHAN_670000_IDX, + ATHOS_B_6G_LUT_CHAN_670125_IDX, + ATHOS_B_6G_LUT_CHAN_670250_IDX, + ATHOS_B_6G_LUT_CHAN_670375_IDX, + ATHOS_B_6G_LUT_CHAN_670500_IDX, + ATHOS_B_6G_LUT_CHAN_670625_IDX, + ATHOS_B_6G_LUT_CHAN_670750_IDX, + ATHOS_B_6G_LUT_CHAN_670875_IDX, + ATHOS_B_6G_LUT_CHAN_671000_IDX, + ATHOS_B_6G_LUT_CHAN_671125_IDX, + ATHOS_B_6G_LUT_CHAN_671250_IDX, + ATHOS_B_6G_LUT_CHAN_671375_IDX, + ATHOS_B_6G_LUT_CHAN_671500_IDX, + ATHOS_B_6G_LUT_CHAN_671625_IDX, + ATHOS_B_6G_LUT_CHAN_671750_IDX, + ATHOS_B_6G_LUT_CHAN_671875_IDX, + ATHOS_B_6G_LUT_CHAN_672000_IDX, + ATHOS_B_6G_LUT_CHAN_672125_IDX, + ATHOS_B_6G_LUT_CHAN_672250_IDX, + ATHOS_B_6G_LUT_CHAN_672375_IDX, + ATHOS_B_6G_LUT_CHAN_672500_IDX, + ATHOS_B_6G_LUT_CHAN_672625_IDX, + ATHOS_B_6G_LUT_CHAN_672750_IDX, + ATHOS_B_6G_LUT_CHAN_672875_IDX, + ATHOS_B_6G_LUT_CHAN_673000_IDX, + ATHOS_B_6G_LUT_CHAN_673125_IDX, + ATHOS_B_6G_LUT_CHAN_673250_IDX, + ATHOS_B_6G_LUT_CHAN_673375_IDX, + ATHOS_B_6G_LUT_CHAN_673500_IDX, + ATHOS_B_6G_LUT_CHAN_673625_IDX, + ATHOS_B_6G_LUT_CHAN_673750_IDX, + ATHOS_B_6G_LUT_CHAN_673875_IDX, + ATHOS_B_6G_LUT_CHAN_674000_IDX, + ATHOS_B_6G_LUT_CHAN_674125_IDX, + ATHOS_B_6G_LUT_CHAN_674250_IDX, + ATHOS_B_6G_LUT_CHAN_674375_IDX, + ATHOS_B_6G_LUT_CHAN_674500_IDX, + ATHOS_B_6G_LUT_CHAN_674625_IDX, + ATHOS_B_6G_LUT_CHAN_674750_IDX, + ATHOS_B_6G_LUT_CHAN_674875_IDX, + ATHOS_B_6G_LUT_CHAN_675000_IDX, + ATHOS_B_6G_LUT_CHAN_675125_IDX, + ATHOS_B_6G_LUT_CHAN_675250_IDX, + ATHOS_B_6G_LUT_CHAN_675375_IDX, + ATHOS_B_6G_LUT_CHAN_675500_IDX, + ATHOS_B_6G_LUT_CHAN_675625_IDX, + ATHOS_B_6G_LUT_CHAN_675750_IDX, + ATHOS_B_6G_LUT_CHAN_675875_IDX, + ATHOS_B_6G_LUT_CHAN_676000_IDX, + ATHOS_B_6G_LUT_CHAN_676125_IDX, + ATHOS_B_6G_LUT_CHAN_676250_IDX, + ATHOS_B_6G_LUT_CHAN_676375_IDX, + ATHOS_B_6G_LUT_CHAN_676500_IDX, + ATHOS_B_6G_LUT_CHAN_676625_IDX, + ATHOS_B_6G_LUT_CHAN_676750_IDX, + ATHOS_B_6G_LUT_CHAN_676875_IDX, + ATHOS_B_6G_LUT_CHAN_677000_IDX, + ATHOS_B_6G_LUT_CHAN_677125_IDX, + ATHOS_B_6G_LUT_CHAN_677250_IDX, + ATHOS_B_6G_LUT_CHAN_677375_IDX, + ATHOS_B_6G_LUT_CHAN_677500_IDX, + ATHOS_B_6G_LUT_CHAN_677625_IDX, + ATHOS_B_6G_LUT_CHAN_677750_IDX, + ATHOS_B_6G_LUT_CHAN_677875_IDX, + ATHOS_B_6G_LUT_CHAN_678000_IDX, + ATHOS_B_6G_LUT_CHAN_678125_IDX, + ATHOS_B_6G_LUT_CHAN_678250_IDX, + ATHOS_B_6G_LUT_CHAN_678375_IDX, + ATHOS_B_6G_LUT_CHAN_678500_IDX, + ATHOS_B_6G_LUT_CHAN_678625_IDX, + ATHOS_B_6G_LUT_CHAN_678750_IDX, + ATHOS_B_6G_LUT_CHAN_678875_IDX, + ATHOS_B_6G_LUT_CHAN_679000_IDX, + ATHOS_B_6G_LUT_CHAN_679125_IDX, + ATHOS_B_6G_LUT_CHAN_679250_IDX, + ATHOS_B_6G_LUT_CHAN_679375_IDX, + ATHOS_B_6G_LUT_CHAN_679500_IDX, + ATHOS_B_6G_LUT_CHAN_679625_IDX, + ATHOS_B_6G_LUT_CHAN_679750_IDX, + ATHOS_B_6G_LUT_CHAN_679875_IDX, + ATHOS_B_6G_LUT_CHAN_680000_IDX, + ATHOS_B_6G_LUT_CHAN_680125_IDX, + ATHOS_B_6G_LUT_CHAN_680250_IDX, + ATHOS_B_6G_LUT_CHAN_680375_IDX, + ATHOS_B_6G_LUT_CHAN_680500_IDX, + ATHOS_B_6G_LUT_CHAN_680625_IDX, + ATHOS_B_6G_LUT_CHAN_680750_IDX, + ATHOS_B_6G_LUT_CHAN_680875_IDX, + ATHOS_B_6G_LUT_CHAN_681000_IDX, + ATHOS_B_6G_LUT_CHAN_681125_IDX, + ATHOS_B_6G_LUT_CHAN_681250_IDX, + ATHOS_B_6G_LUT_CHAN_681375_IDX, + ATHOS_B_6G_LUT_CHAN_681500_IDX, + ATHOS_B_6G_LUT_CHAN_681625_IDX, + ATHOS_B_6G_LUT_CHAN_681750_IDX, + ATHOS_B_6G_LUT_CHAN_681875_IDX, + ATHOS_B_6G_LUT_CHAN_682000_IDX, + ATHOS_B_6G_LUT_CHAN_682125_IDX, + ATHOS_B_6G_LUT_CHAN_682250_IDX, + ATHOS_B_6G_LUT_CHAN_682375_IDX, + ATHOS_B_6G_LUT_CHAN_682500_IDX, + ATHOS_B_6G_LUT_CHAN_682625_IDX, + ATHOS_B_6G_LUT_CHAN_682750_IDX, + ATHOS_B_6G_LUT_CHAN_682875_IDX, + ATHOS_B_6G_LUT_CHAN_683000_IDX, + ATHOS_B_6G_LUT_CHAN_683125_IDX, + ATHOS_B_6G_LUT_CHAN_683250_IDX, + ATHOS_B_6G_LUT_CHAN_683375_IDX, + ATHOS_B_6G_LUT_CHAN_683500_IDX, + ATHOS_B_6G_LUT_CHAN_683625_IDX, + ATHOS_B_6G_LUT_CHAN_683750_IDX, + ATHOS_B_6G_LUT_CHAN_683875_IDX, + ATHOS_B_6G_LUT_CHAN_684000_IDX, + ATHOS_B_6G_LUT_CHAN_684125_IDX, + ATHOS_B_6G_LUT_CHAN_684250_IDX, + ATHOS_B_6G_LUT_CHAN_684375_IDX, + ATHOS_B_6G_LUT_CHAN_684500_IDX, + ATHOS_B_6G_LUT_CHAN_684625_IDX, + ATHOS_B_6G_LUT_CHAN_684750_IDX, + ATHOS_B_6G_LUT_CHAN_684875_IDX, + ATHOS_B_6G_LUT_CHAN_685000_IDX, + ATHOS_B_6G_LUT_CHAN_685125_IDX, + ATHOS_B_6G_LUT_CHAN_685250_IDX, + ATHOS_B_6G_LUT_CHAN_685375_IDX, + ATHOS_B_6G_LUT_CHAN_685500_IDX, + ATHOS_B_6G_LUT_CHAN_685625_IDX, + ATHOS_B_6G_LUT_CHAN_685750_IDX, + ATHOS_B_6G_LUT_CHAN_685875_IDX, + ATHOS_B_6G_LUT_CHAN_686000_IDX, + ATHOS_B_6G_LUT_CHAN_686125_IDX, + ATHOS_B_6G_LUT_CHAN_686250_IDX, + ATHOS_B_6G_LUT_CHAN_686375_IDX, + ATHOS_B_6G_LUT_CHAN_686500_IDX, + ATHOS_B_6G_LUT_CHAN_686625_IDX, + ATHOS_B_6G_LUT_CHAN_686750_IDX, + ATHOS_B_6G_LUT_CHAN_686875_IDX, + ATHOS_B_6G_LUT_CHAN_687000_IDX, + ATHOS_B_6G_LUT_CHAN_687125_IDX, + ATHOS_B_6G_LUT_CHAN_687250_IDX, + ATHOS_B_6G_LUT_CHAN_687375_IDX, + ATHOS_B_6G_LUT_CHAN_687500_IDX, + ATHOS_B_6G_LUT_CHAN_687625_IDX, + ATHOS_B_6G_LUT_CHAN_687750_IDX, + ATHOS_B_6G_LUT_CHAN_687875_IDX, + ATHOS_B_6G_LUT_CHAN_688000_IDX, + ATHOS_B_6G_LUT_CHAN_688125_IDX, + ATHOS_B_6G_LUT_CHAN_688250_IDX, + ATHOS_B_6G_LUT_CHAN_688375_IDX, + ATHOS_B_6G_LUT_CHAN_688500_IDX, + ATHOS_B_6G_LUT_CHAN_688625_IDX, + ATHOS_B_6G_LUT_CHAN_688750_IDX, + ATHOS_B_6G_LUT_CHAN_688875_IDX, + ATHOS_B_6G_LUT_CHAN_689000_IDX, + ATHOS_B_6G_LUT_CHAN_689125_IDX, + ATHOS_B_6G_LUT_CHAN_689250_IDX, + ATHOS_B_6G_LUT_CHAN_689375_IDX, + ATHOS_B_6G_LUT_CHAN_689500_IDX, + ATHOS_B_6G_LUT_CHAN_689625_IDX, + ATHOS_B_6G_LUT_CHAN_689750_IDX, + ATHOS_B_6G_LUT_CHAN_689875_IDX, + ATHOS_B_6G_LUT_CHAN_690000_IDX, + ATHOS_B_6G_LUT_CHAN_690125_IDX, + ATHOS_B_6G_LUT_CHAN_690250_IDX, + ATHOS_B_6G_LUT_CHAN_690375_IDX, + ATHOS_B_6G_LUT_CHAN_690500_IDX, + ATHOS_B_6G_LUT_CHAN_690625_IDX, + ATHOS_B_6G_LUT_CHAN_690750_IDX, + ATHOS_B_6G_LUT_CHAN_690875_IDX, + ATHOS_B_6G_LUT_CHAN_691000_IDX, + ATHOS_B_6G_LUT_CHAN_691125_IDX, + ATHOS_B_6G_LUT_CHAN_691250_IDX, + ATHOS_B_6G_LUT_CHAN_691375_IDX, + ATHOS_B_6G_LUT_CHAN_691500_IDX, + ATHOS_B_6G_LUT_CHAN_691625_IDX, + ATHOS_B_6G_LUT_CHAN_691750_IDX, + ATHOS_B_6G_LUT_CHAN_691875_IDX, + ATHOS_B_6G_LUT_CHAN_692000_IDX, + ATHOS_B_6G_LUT_CHAN_692125_IDX, + ATHOS_B_6G_LUT_CHAN_692250_IDX, + ATHOS_B_6G_LUT_CHAN_692375_IDX, + ATHOS_B_6G_LUT_CHAN_692500_IDX, + ATHOS_B_6G_LUT_CHAN_692625_IDX, + ATHOS_B_6G_LUT_CHAN_692750_IDX, + ATHOS_B_6G_LUT_CHAN_692875_IDX, + ATHOS_B_6G_LUT_CHAN_693000_IDX, + ATHOS_B_6G_LUT_CHAN_693125_IDX, + ATHOS_B_6G_LUT_CHAN_693250_IDX, + ATHOS_B_6G_LUT_CHAN_693375_IDX, + ATHOS_B_6G_LUT_CHAN_693500_IDX, + ATHOS_B_6G_LUT_CHAN_693625_IDX, + ATHOS_B_6G_LUT_CHAN_693750_IDX, + ATHOS_B_6G_LUT_CHAN_693875_IDX, + ATHOS_B_6G_LUT_CHAN_694000_IDX, + ATHOS_B_6G_LUT_CHAN_694125_IDX, + ATHOS_B_6G_LUT_CHAN_694250_IDX, + ATHOS_B_6G_LUT_CHAN_694375_IDX, + ATHOS_B_6G_LUT_CHAN_694500_IDX, + ATHOS_B_6G_LUT_CHAN_694625_IDX, + ATHOS_B_6G_LUT_CHAN_694750_IDX, + ATHOS_B_6G_LUT_CHAN_694875_IDX, + ATHOS_B_6G_LUT_CHAN_695000_IDX, + ATHOS_B_6G_LUT_CHAN_695125_IDX, + ATHOS_B_6G_LUT_CHAN_695250_IDX, + ATHOS_B_6G_LUT_CHAN_695375_IDX, + ATHOS_B_6G_LUT_CHAN_695500_IDX, + ATHOS_B_6G_LUT_CHAN_695625_IDX, + ATHOS_B_6G_LUT_CHAN_695750_IDX, + ATHOS_B_6G_LUT_CHAN_695875_IDX, + ATHOS_B_6G_LUT_CHAN_696000_IDX, + ATHOS_B_6G_LUT_CHAN_696125_IDX, + ATHOS_B_6G_LUT_CHAN_696250_IDX, + ATHOS_B_6G_LUT_CHAN_696375_IDX, + ATHOS_B_6G_LUT_CHAN_696500_IDX, + ATHOS_B_6G_LUT_CHAN_696625_IDX, + ATHOS_B_6G_LUT_CHAN_696750_IDX, + ATHOS_B_6G_LUT_CHAN_696875_IDX, + ATHOS_B_6G_LUT_CHAN_697000_IDX, + ATHOS_B_6G_LUT_CHAN_697125_IDX, + ATHOS_B_6G_LUT_CHAN_697250_IDX, + ATHOS_B_6G_LUT_CHAN_697375_IDX, + ATHOS_B_6G_LUT_CHAN_697500_IDX, + ATHOS_B_6G_LUT_CHAN_697625_IDX, + ATHOS_B_6G_LUT_CHAN_697750_IDX, + ATHOS_B_6G_LUT_CHAN_697875_IDX, + ATHOS_B_6G_LUT_CHAN_698000_IDX, + ATHOS_B_6G_LUT_CHAN_698125_IDX, + ATHOS_B_6G_LUT_CHAN_698250_IDX, + ATHOS_B_6G_LUT_CHAN_698375_IDX, + ATHOS_B_6G_LUT_CHAN_698500_IDX, + ATHOS_B_6G_LUT_CHAN_698625_IDX, + ATHOS_B_6G_LUT_CHAN_698750_IDX, + ATHOS_B_6G_LUT_CHAN_698875_IDX, + ATHOS_B_6G_LUT_CHAN_699000_IDX, + ATHOS_B_6G_LUT_CHAN_699125_IDX, + ATHOS_B_6G_LUT_CHAN_699250_IDX, + ATHOS_B_6G_LUT_CHAN_699375_IDX, + ATHOS_B_6G_LUT_CHAN_699500_IDX, + ATHOS_B_6G_LUT_CHAN_699625_IDX, + ATHOS_B_6G_LUT_CHAN_699750_IDX, + ATHOS_B_6G_LUT_CHAN_699875_IDX, + ATHOS_B_6G_LUT_CHAN_700000_IDX, + ATHOS_B_6G_LUT_CHAN_700125_IDX, + ATHOS_B_6G_LUT_CHAN_700250_IDX, + ATHOS_B_6G_LUT_CHAN_700375_IDX, + ATHOS_B_6G_LUT_CHAN_700500_IDX, + ATHOS_B_6G_LUT_CHAN_700625_IDX, + ATHOS_B_6G_LUT_CHAN_700750_IDX, + ATHOS_B_6G_LUT_CHAN_700875_IDX, + ATHOS_B_6G_LUT_CHAN_701000_IDX, + ATHOS_B_6G_LUT_CHAN_701125_IDX, + ATHOS_B_6G_LUT_CHAN_701250_IDX, + ATHOS_B_6G_LUT_CHAN_701375_IDX, + ATHOS_B_6G_LUT_CHAN_701500_IDX, + ATHOS_B_6G_LUT_CHAN_701625_IDX, + ATHOS_B_6G_LUT_CHAN_701750_IDX, + ATHOS_B_6G_LUT_CHAN_701875_IDX, + ATHOS_B_6G_LUT_CHAN_702000_IDX, + ATHOS_B_6G_LUT_CHAN_702125_IDX, + ATHOS_B_6G_LUT_CHAN_702250_IDX, + ATHOS_B_6G_LUT_CHAN_702375_IDX, + ATHOS_B_6G_LUT_CHAN_702500_IDX, + ATHOS_B_6G_LUT_CHAN_702625_IDX, + ATHOS_B_6G_LUT_CHAN_702750_IDX, + ATHOS_B_6G_LUT_CHAN_702875_IDX, + ATHOS_B_6G_LUT_CHAN_703000_IDX, + ATHOS_B_6G_LUT_CHAN_703125_IDX, + ATHOS_B_6G_LUT_CHAN_703250_IDX, + ATHOS_B_6G_LUT_CHAN_703375_IDX, + ATHOS_B_6G_LUT_CHAN_703500_IDX, + ATHOS_B_6G_LUT_CHAN_703625_IDX, + ATHOS_B_6G_LUT_CHAN_703750_IDX, + ATHOS_B_6G_LUT_CHAN_703875_IDX, + ATHOS_B_6G_LUT_CHAN_704000_IDX, + ATHOS_B_6G_LUT_CHAN_704125_IDX, + ATHOS_B_6G_LUT_CHAN_704250_IDX, + ATHOS_B_6G_LUT_CHAN_704375_IDX, + ATHOS_B_6G_LUT_CHAN_704500_IDX, + ATHOS_B_6G_LUT_CHAN_704625_IDX, + ATHOS_B_6G_LUT_CHAN_704750_IDX, + ATHOS_B_6G_LUT_CHAN_704875_IDX, + ATHOS_B_6G_LUT_CHAN_705000_IDX, + ATHOS_B_6G_LUT_CHAN_705125_IDX, + ATHOS_B_6G_LUT_CHAN_705250_IDX, + ATHOS_B_6G_LUT_CHAN_705375_IDX, + ATHOS_B_6G_LUT_CHAN_705500_IDX, + ATHOS_B_6G_LUT_CHAN_705625_IDX, + ATHOS_B_6G_LUT_CHAN_705750_IDX, + ATHOS_B_6G_LUT_CHAN_705875_IDX, + ATHOS_B_6G_LUT_CHAN_706000_IDX, + ATHOS_B_6G_LUT_CHAN_706125_IDX, + ATHOS_B_6G_LUT_CHAN_706250_IDX, + ATHOS_B_6G_LUT_CHAN_706375_IDX, + ATHOS_B_6G_LUT_CHAN_706500_IDX, + ATHOS_B_6G_LUT_CHAN_706625_IDX, + ATHOS_B_6G_LUT_CHAN_706750_IDX, + ATHOS_B_6G_LUT_CHAN_706875_IDX, + ATHOS_B_6G_LUT_CHAN_707000_IDX, + ATHOS_B_6G_LUT_CHAN_707125_IDX, + ATHOS_B_6G_LUT_CHAN_707250_IDX, + ATHOS_B_6G_LUT_CHAN_707375_IDX, + ATHOS_B_6G_LUT_CHAN_707500_IDX, + ATHOS_B_6G_LUT_CHAN_707625_IDX, + ATHOS_B_6G_LUT_CHAN_707750_IDX, + ATHOS_B_6G_LUT_CHAN_707875_IDX, + ATHOS_B_6G_LUT_CHAN_708000_IDX, + ATHOS_B_6G_LUT_CHAN_708125_IDX, + ATHOS_B_6G_LUT_CHAN_708250_IDX, + ATHOS_B_6G_LUT_CHAN_708375_IDX, + ATHOS_B_6G_LUT_CHAN_708500_IDX, + ATHOS_B_6G_LUT_CHAN_708625_IDX, + ATHOS_B_6G_LUT_CHAN_708750_IDX, + ATHOS_B_6G_LUT_CHAN_708875_IDX, + ATHOS_B_6G_LUT_CHAN_709000_IDX, + ATHOS_B_6G_LUT_CHAN_709125_IDX, + ATHOS_B_6G_LUT_CHAN_709250_IDX, + ATHOS_B_6G_LUT_CHAN_709375_IDX, + ATHOS_B_6G_LUT_CHAN_709500_IDX, + ATHOS_B_6G_LUT_CHAN_709625_IDX, + ATHOS_B_6G_LUT_CHAN_709750_IDX, + ATHOS_B_6G_LUT_CHAN_709875_IDX, + ATHOS_B_6G_LUT_CHAN_710000_IDX, + ATHOS_B_6G_LUT_CHAN_710125_IDX, + ATHOS_B_6G_LUT_CHAN_710250_IDX, + ATHOS_B_6G_LUT_CHAN_710375_IDX, + ATHOS_B_6G_LUT_CHAN_710500_IDX, + ATHOS_B_6G_LUT_CHAN_710625_IDX, + ATHOS_B_6G_LUT_CHAN_710750_IDX, + ATHOS_B_6G_LUT_CHAN_710875_IDX, + ATHOS_B_6G_LUT_CHAN_711000_IDX, + ATHOS_B_6G_LUT_CHAN_711125_IDX, + ATHOS_B_6G_LUT_CHAN_711250_IDX, + ATHOS_B_6G_LUT_CHAN_711375_IDX, + ATHOS_B_6G_LUT_CHAN_711500_IDX, + ATHOS_B_6G_LUT_CHAN_711625_IDX, + ATHOS_B_6G_LUT_CHAN_711750_IDX, + ATHOS_B_6G_LUT_CHAN_711875_IDX, + ATHOS_B_6G_LUT_CHAN_712000_IDX, + ATHOS_B_6G_LUT_CHAN_712125_IDX, + ATHOS_B_6G_LUT_CHAN_712250_IDX, + ATHOS_B_6G_LUT_CHAN_712375_IDX, + ATHOS_B_6G_LUT_CHAN_712500_IDX, + ATHOS_B_6G_LUT_CHAN_712625_IDX, + ATHOS_B_6G_LUT_CHAN_712750_IDX, + ATHOS_B_6G_LUT_CHAN_712875_IDX, + ATHOS_B_6G_LUT_CHAN_713000_IDX, + ATHOS_B_6G_LUT_CHAN_713125_IDX, + ATHOS_B_6G_LUT_CHAN_713250_IDX, + ATHOS_B_6G_LUT_CHAN_713375_IDX, + ATHOS_B_6G_LUT_CHAN_713500_IDX, + ATHOS_B_6G_LUT_CHAN_713625_IDX, + ATHOS_B_6G_LUT_CHAN_713750_IDX, + ATHOS_B_6G_LUT_CHAN_713875_IDX, + ATHOS_B_6G_LUT_CHAN_714000_IDX, + ATHOS_B_6G_LUT_CHAN_714125_IDX, + ATHOS_B_6G_LUT_CHAN_714250_IDX, + ATHOS_B_6G_LUT_CHAN_714375_IDX, + ATHOS_B_6G_LUT_CHAN_714500_IDX, + ATHOS_B_6G_LUT_CHAN_714625_IDX, + ATHOS_B_6G_LUT_CHAN_714750_IDX, + ATHOS_B_6G_LUT_CHAN_714875_IDX, + ATHOS_B_6G_LUT_CHAN_715000_IDX, + ATHOS_B_6G_LUT_CHAN_715125_IDX, + ATHOS_B_6G_LUT_CHAN_715250_IDX, + ATHOS_B_6G_LUT_CHAN_715375_IDX, + ATHOS_B_6G_LUT_CHAN_715500_IDX, + ATHOS_B_6G_LUT_CHAN_715625_IDX, + ATHOS_B_6G_LUT_CHAN_715750_IDX, + ATHOS_B_6G_LUT_CHAN_715875_IDX, + ATHOS_B_6G_LUT_CHAN_716000_IDX, + ATHOS_B_6G_LUT_CHAN_716125_IDX, + ATHOS_B_6G_LUT_CHAN_716250_IDX, + ATHOS_B_6G_LUT_CHAN_716375_IDX, + ATHOS_B_6G_LUT_CHAN_716500_IDX, + ATHOS_B_6G_LUT_CHAN_716625_IDX, + ATHOS_B_6G_LUT_CHAN_716750_IDX, + ATHOS_B_6G_LUT_CHAN_716875_IDX, + ATHOS_B_6G_LUT_CHAN_717000_IDX, + ATHOS_B_6G_LUT_CHAN_717125_IDX, + ATHOS_B_6G_LUT_CHAN_717250_IDX, + ATHOS_B_6G_LUT_CHAN_717375_IDX, + ATHOS_B_6G_LUT_CHAN_717500_IDX, + ATHOS_B_6G_LUT_CHAN_717625_IDX, + ATHOS_B_6G_LUT_CHAN_717750_IDX, + ATHOS_B_6G_LUT_CHAN_717875_IDX, + ATHOS_B_6G_LUT_CHAN_718000_IDX, + ATHOS_B_6G_LUT_CHAN_718125_IDX, + ATHOS_B_6G_LUT_CHAN_718250_IDX, + ATHOS_B_6G_LUT_CHAN_718375_IDX, + ATHOS_B_6G_LUT_CHAN_718500_IDX, + ATHOS_B_6G_LUT_CHAN_718625_IDX, + ATHOS_B_6G_LUT_CHAN_718750_IDX, + ATHOS_B_6G_LUT_CHAN_718875_IDX, + ATHOS_B_6G_LUT_CHAN_719000_IDX, + ATHOS_B_6G_LUT_CHAN_719125_IDX, + ATHOS_B_6G_LUT_CHAN_719250_IDX, + ATHOS_B_6G_LUT_CHAN_719375_IDX, + ATHOS_B_6G_LUT_CHAN_719500_IDX, + ATHOS_B_6G_LUT_CHAN_719625_IDX, + ATHOS_B_6G_LUT_CHAN_719750_IDX, + ATHOS_B_6G_LUT_CHAN_719875_IDX, + ATHOS_B_6G_LUT_CHAN_720000_IDX, + ATHOS_B_6G_LUT_CHAN_720125_IDX, + ATHOS_B_6G_LUT_CHAN_720250_IDX, + ATHOS_B_6G_LUT_CHAN_720375_IDX, + ATHOS_B_6G_LUT_CHAN_720500_IDX, + ATHOS_B_6G_LUT_CHAN_720625_IDX, + ATHOS_B_6G_LUT_CHAN_720750_IDX, + ATHOS_B_6G_LUT_CHAN_720875_IDX, + ATHOS_B_6G_LUT_CHAN_721000_IDX, + ATHOS_B_6G_LUT_CHAN_721125_IDX, + ATHOS_B_6G_LUT_CHAN_721250_IDX, + ATHOS_B_6G_LUT_CHAN_721375_IDX, + ATHOS_B_6G_LUT_CHAN_721500_IDX, + ATHOS_B_6G_LUT_CHAN_6G_MAX +}; + +enum olympus_lut_idx_5g { + OLYMPUS_LUT_CHAN_516000_IDX, + OLYMPUS_LUT_CHAN_516125_IDX, + OLYMPUS_LUT_CHAN_516250_IDX, + OLYMPUS_LUT_CHAN_516375_IDX, + OLYMPUS_LUT_CHAN_516500_IDX, + OLYMPUS_LUT_CHAN_516625_IDX, + OLYMPUS_LUT_CHAN_516750_IDX, + OLYMPUS_LUT_CHAN_516875_IDX, + OLYMPUS_LUT_CHAN_517000_IDX, + OLYMPUS_LUT_CHAN_517125_IDX, + OLYMPUS_LUT_CHAN_517250_IDX, + OLYMPUS_LUT_CHAN_517375_IDX, + OLYMPUS_LUT_CHAN_517500_IDX, + OLYMPUS_LUT_CHAN_517625_IDX, + OLYMPUS_LUT_CHAN_517750_IDX, + OLYMPUS_LUT_CHAN_517875_IDX, + OLYMPUS_LUT_CHAN_518000_IDX, + OLYMPUS_LUT_CHAN_518125_IDX, + OLYMPUS_LUT_CHAN_518250_IDX, + OLYMPUS_LUT_CHAN_518375_IDX, + OLYMPUS_LUT_CHAN_518500_IDX, + OLYMPUS_LUT_CHAN_518625_IDX, + OLYMPUS_LUT_CHAN_518750_IDX, + OLYMPUS_LUT_CHAN_518875_IDX, + OLYMPUS_LUT_CHAN_519000_IDX, + OLYMPUS_LUT_CHAN_519125_IDX, + OLYMPUS_LUT_CHAN_519250_IDX, + OLYMPUS_LUT_CHAN_519375_IDX, + OLYMPUS_LUT_CHAN_519500_IDX, + OLYMPUS_LUT_CHAN_519625_IDX, + OLYMPUS_LUT_CHAN_519750_IDX, + OLYMPUS_LUT_CHAN_519875_IDX, + OLYMPUS_LUT_CHAN_520000_IDX, + OLYMPUS_LUT_CHAN_520125_IDX, + OLYMPUS_LUT_CHAN_520250_IDX, + OLYMPUS_LUT_CHAN_520375_IDX, + OLYMPUS_LUT_CHAN_520500_IDX, + OLYMPUS_LUT_CHAN_520625_IDX, + OLYMPUS_LUT_CHAN_520750_IDX, + OLYMPUS_LUT_CHAN_520875_IDX, + OLYMPUS_LUT_CHAN_521000_IDX, + OLYMPUS_LUT_CHAN_521125_IDX, + OLYMPUS_LUT_CHAN_521250_IDX, + OLYMPUS_LUT_CHAN_521375_IDX, + OLYMPUS_LUT_CHAN_521500_IDX, + OLYMPUS_LUT_CHAN_521625_IDX, + OLYMPUS_LUT_CHAN_521750_IDX, + OLYMPUS_LUT_CHAN_521875_IDX, + OLYMPUS_LUT_CHAN_522000_IDX, + OLYMPUS_LUT_CHAN_522125_IDX, + OLYMPUS_LUT_CHAN_522250_IDX, + OLYMPUS_LUT_CHAN_522375_IDX, + OLYMPUS_LUT_CHAN_522500_IDX, + OLYMPUS_LUT_CHAN_522625_IDX, + OLYMPUS_LUT_CHAN_522750_IDX, + OLYMPUS_LUT_CHAN_522875_IDX, + OLYMPUS_LUT_CHAN_523000_IDX, + OLYMPUS_LUT_CHAN_523125_IDX, + OLYMPUS_LUT_CHAN_523250_IDX, + OLYMPUS_LUT_CHAN_523375_IDX, + OLYMPUS_LUT_CHAN_523500_IDX, + OLYMPUS_LUT_CHAN_523625_IDX, + OLYMPUS_LUT_CHAN_523750_IDX, + OLYMPUS_LUT_CHAN_523875_IDX, + OLYMPUS_LUT_CHAN_524000_IDX, + OLYMPUS_LUT_CHAN_524125_IDX, + OLYMPUS_LUT_CHAN_524250_IDX, + OLYMPUS_LUT_CHAN_524375_IDX, + OLYMPUS_LUT_CHAN_524500_IDX, + OLYMPUS_LUT_CHAN_524625_IDX, + OLYMPUS_LUT_CHAN_524750_IDX, + OLYMPUS_LUT_CHAN_524875_IDX, + OLYMPUS_LUT_CHAN_525000_IDX, + OLYMPUS_LUT_CHAN_525125_IDX, + OLYMPUS_LUT_CHAN_525250_IDX, + OLYMPUS_LUT_CHAN_525375_IDX, + OLYMPUS_LUT_CHAN_525500_IDX, + OLYMPUS_LUT_CHAN_525625_IDX, + OLYMPUS_LUT_CHAN_525750_IDX, + OLYMPUS_LUT_CHAN_525875_IDX, + OLYMPUS_LUT_CHAN_526000_IDX, + OLYMPUS_LUT_CHAN_526125_IDX, + OLYMPUS_LUT_CHAN_526250_IDX, + OLYMPUS_LUT_CHAN_526375_IDX, + OLYMPUS_LUT_CHAN_526500_IDX, + OLYMPUS_LUT_CHAN_526625_IDX, + OLYMPUS_LUT_CHAN_526750_IDX, + OLYMPUS_LUT_CHAN_526875_IDX, + OLYMPUS_LUT_CHAN_527000_IDX, + OLYMPUS_LUT_CHAN_527125_IDX, + OLYMPUS_LUT_CHAN_527250_IDX, + OLYMPUS_LUT_CHAN_527375_IDX, + OLYMPUS_LUT_CHAN_527500_IDX, + OLYMPUS_LUT_CHAN_527625_IDX, + OLYMPUS_LUT_CHAN_527750_IDX, + OLYMPUS_LUT_CHAN_527875_IDX, + OLYMPUS_LUT_CHAN_528000_IDX, + OLYMPUS_LUT_CHAN_528125_IDX, + OLYMPUS_LUT_CHAN_528250_IDX, + OLYMPUS_LUT_CHAN_528375_IDX, + OLYMPUS_LUT_CHAN_528500_IDX, + OLYMPUS_LUT_CHAN_528625_IDX, + OLYMPUS_LUT_CHAN_528750_IDX, + OLYMPUS_LUT_CHAN_528875_IDX, + OLYMPUS_LUT_CHAN_529000_IDX, + OLYMPUS_LUT_CHAN_529125_IDX, + OLYMPUS_LUT_CHAN_529250_IDX, + OLYMPUS_LUT_CHAN_529375_IDX, + OLYMPUS_LUT_CHAN_529500_IDX, + OLYMPUS_LUT_CHAN_529625_IDX, + OLYMPUS_LUT_CHAN_529750_IDX, + OLYMPUS_LUT_CHAN_529875_IDX, + OLYMPUS_LUT_CHAN_530000_IDX, + OLYMPUS_LUT_CHAN_530125_IDX, + OLYMPUS_LUT_CHAN_530250_IDX, + OLYMPUS_LUT_CHAN_530375_IDX, + OLYMPUS_LUT_CHAN_530500_IDX, + OLYMPUS_LUT_CHAN_530625_IDX, + OLYMPUS_LUT_CHAN_530750_IDX, + OLYMPUS_LUT_CHAN_530875_IDX, + OLYMPUS_LUT_CHAN_531000_IDX, + OLYMPUS_LUT_CHAN_531125_IDX, + OLYMPUS_LUT_CHAN_531250_IDX, + OLYMPUS_LUT_CHAN_531375_IDX, + OLYMPUS_LUT_CHAN_531500_IDX, + OLYMPUS_LUT_CHAN_531625_IDX, + OLYMPUS_LUT_CHAN_531750_IDX, + OLYMPUS_LUT_CHAN_531875_IDX, + OLYMPUS_LUT_CHAN_532000_IDX, + OLYMPUS_LUT_CHAN_532125_IDX, + OLYMPUS_LUT_CHAN_532250_IDX, + OLYMPUS_LUT_CHAN_532375_IDX, + OLYMPUS_LUT_CHAN_532500_IDX, + OLYMPUS_LUT_CHAN_532625_IDX, + OLYMPUS_LUT_CHAN_532750_IDX, + OLYMPUS_LUT_CHAN_532875_IDX, + OLYMPUS_LUT_CHAN_533000_IDX, + OLYMPUS_LUT_CHAN_533125_IDX, + OLYMPUS_LUT_CHAN_533250_IDX, + OLYMPUS_LUT_CHAN_533375_IDX, + OLYMPUS_LUT_CHAN_533500_IDX, + OLYMPUS_LUT_CHAN_533625_IDX, + OLYMPUS_LUT_CHAN_533750_IDX, + OLYMPUS_LUT_CHAN_533875_IDX, + OLYMPUS_LUT_CHAN_534000_IDX, + OLYMPUS_LUT_CHAN_534125_IDX, + OLYMPUS_LUT_CHAN_534250_IDX, + OLYMPUS_LUT_CHAN_534375_IDX, + OLYMPUS_LUT_CHAN_534500_IDX, + OLYMPUS_LUT_CHAN_534625_IDX, + OLYMPUS_LUT_CHAN_534750_IDX, + OLYMPUS_LUT_CHAN_534875_IDX, + OLYMPUS_LUT_CHAN_535000_IDX, + OLYMPUS_LUT_CHAN_535125_IDX, + OLYMPUS_LUT_CHAN_535250_IDX, + OLYMPUS_LUT_CHAN_535375_IDX, + OLYMPUS_LUT_CHAN_535500_IDX, + OLYMPUS_LUT_CHAN_535625_IDX, + OLYMPUS_LUT_CHAN_535750_IDX, + OLYMPUS_LUT_CHAN_535875_IDX, + OLYMPUS_LUT_CHAN_536000_IDX, + OLYMPUS_LUT_CHAN_536125_IDX, + OLYMPUS_LUT_CHAN_536250_IDX, + OLYMPUS_LUT_CHAN_536375_IDX, + OLYMPUS_LUT_CHAN_536500_IDX, + OLYMPUS_LUT_CHAN_536625_IDX, + OLYMPUS_LUT_CHAN_536750_IDX, + OLYMPUS_LUT_CHAN_536875_IDX, + OLYMPUS_LUT_CHAN_537000_IDX, + OLYMPUS_LUT_CHAN_537125_IDX, + OLYMPUS_LUT_CHAN_537250_IDX, + OLYMPUS_LUT_CHAN_537375_IDX, + OLYMPUS_LUT_CHAN_537500_IDX, + OLYMPUS_LUT_CHAN_537625_IDX, + OLYMPUS_LUT_CHAN_537750_IDX, + OLYMPUS_LUT_CHAN_537875_IDX, + OLYMPUS_LUT_CHAN_538000_IDX, + OLYMPUS_LUT_CHAN_538125_IDX, + OLYMPUS_LUT_CHAN_538250_IDX, + OLYMPUS_LUT_CHAN_538375_IDX, + OLYMPUS_LUT_CHAN_538500_IDX, + OLYMPUS_LUT_CHAN_538625_IDX, + OLYMPUS_LUT_CHAN_538750_IDX, + OLYMPUS_LUT_CHAN_538875_IDX, + OLYMPUS_LUT_CHAN_539000_IDX, + OLYMPUS_LUT_CHAN_539125_IDX, + OLYMPUS_LUT_CHAN_539250_IDX, + OLYMPUS_LUT_CHAN_539375_IDX, + OLYMPUS_LUT_CHAN_539500_IDX, + OLYMPUS_LUT_CHAN_539625_IDX, + OLYMPUS_LUT_CHAN_539750_IDX, + OLYMPUS_LUT_CHAN_539875_IDX, + OLYMPUS_LUT_CHAN_540000_IDX, + OLYMPUS_LUT_CHAN_540125_IDX, + OLYMPUS_LUT_CHAN_540250_IDX, + OLYMPUS_LUT_CHAN_540375_IDX, + OLYMPUS_LUT_CHAN_540500_IDX, + OLYMPUS_LUT_CHAN_540625_IDX, + OLYMPUS_LUT_CHAN_540750_IDX, + OLYMPUS_LUT_CHAN_540875_IDX, + OLYMPUS_LUT_CHAN_541000_IDX, + OLYMPUS_LUT_CHAN_541125_IDX, + OLYMPUS_LUT_CHAN_541250_IDX, + OLYMPUS_LUT_CHAN_541375_IDX, + OLYMPUS_LUT_CHAN_541500_IDX, + OLYMPUS_LUT_CHAN_541625_IDX, + OLYMPUS_LUT_CHAN_541750_IDX, + OLYMPUS_LUT_CHAN_541875_IDX, + OLYMPUS_LUT_CHAN_542000_IDX, + OLYMPUS_LUT_CHAN_542125_IDX, + OLYMPUS_LUT_CHAN_542250_IDX, + OLYMPUS_LUT_CHAN_542375_IDX, + OLYMPUS_LUT_CHAN_542500_IDX, + OLYMPUS_LUT_CHAN_542625_IDX, + OLYMPUS_LUT_CHAN_542750_IDX, + OLYMPUS_LUT_CHAN_542875_IDX, + OLYMPUS_LUT_CHAN_543000_IDX, + OLYMPUS_LUT_CHAN_543125_IDX, + OLYMPUS_LUT_CHAN_543250_IDX, + OLYMPUS_LUT_CHAN_543375_IDX, + OLYMPUS_LUT_CHAN_543500_IDX, + OLYMPUS_LUT_CHAN_543625_IDX, + OLYMPUS_LUT_CHAN_543750_IDX, + OLYMPUS_LUT_CHAN_543875_IDX, + OLYMPUS_LUT_CHAN_544000_IDX, + OLYMPUS_LUT_CHAN_544125_IDX, + OLYMPUS_LUT_CHAN_544250_IDX, + OLYMPUS_LUT_CHAN_544375_IDX, + OLYMPUS_LUT_CHAN_544500_IDX, + OLYMPUS_LUT_CHAN_544625_IDX, + OLYMPUS_LUT_CHAN_544750_IDX, + OLYMPUS_LUT_CHAN_544875_IDX, + OLYMPUS_LUT_CHAN_545000_IDX, + OLYMPUS_LUT_CHAN_545125_IDX, + OLYMPUS_LUT_CHAN_545250_IDX, + OLYMPUS_LUT_CHAN_545375_IDX, + OLYMPUS_LUT_CHAN_545500_IDX, + OLYMPUS_LUT_CHAN_545625_IDX, + OLYMPUS_LUT_CHAN_545750_IDX, + OLYMPUS_LUT_CHAN_545875_IDX, + OLYMPUS_LUT_CHAN_546000_IDX, + OLYMPUS_LUT_CHAN_546125_IDX, + OLYMPUS_LUT_CHAN_546250_IDX, + OLYMPUS_LUT_CHAN_546375_IDX, + OLYMPUS_LUT_CHAN_546500_IDX, + OLYMPUS_LUT_CHAN_546625_IDX, + OLYMPUS_LUT_CHAN_546750_IDX, + OLYMPUS_LUT_CHAN_546875_IDX, + OLYMPUS_LUT_CHAN_547000_IDX, + OLYMPUS_LUT_CHAN_547125_IDX, + OLYMPUS_LUT_CHAN_547250_IDX, + OLYMPUS_LUT_CHAN_547375_IDX, + OLYMPUS_LUT_CHAN_547500_IDX, + OLYMPUS_LUT_CHAN_547625_IDX, + OLYMPUS_LUT_CHAN_547750_IDX, + OLYMPUS_LUT_CHAN_547875_IDX, + OLYMPUS_LUT_CHAN_548000_IDX, + OLYMPUS_LUT_CHAN_548125_IDX, + OLYMPUS_LUT_CHAN_548250_IDX, + OLYMPUS_LUT_CHAN_548375_IDX, + OLYMPUS_LUT_CHAN_548500_IDX, + OLYMPUS_LUT_CHAN_548625_IDX, + OLYMPUS_LUT_CHAN_548750_IDX, + OLYMPUS_LUT_CHAN_548875_IDX, + OLYMPUS_LUT_CHAN_549000_IDX, + OLYMPUS_LUT_CHAN_549125_IDX, + OLYMPUS_LUT_CHAN_549250_IDX, + OLYMPUS_LUT_CHAN_549375_IDX, + OLYMPUS_LUT_CHAN_549500_IDX, + OLYMPUS_LUT_CHAN_549625_IDX, + OLYMPUS_LUT_CHAN_549750_IDX, + OLYMPUS_LUT_CHAN_549875_IDX, + OLYMPUS_LUT_CHAN_550000_IDX, + OLYMPUS_LUT_CHAN_550125_IDX, + OLYMPUS_LUT_CHAN_550250_IDX, + OLYMPUS_LUT_CHAN_550375_IDX, + OLYMPUS_LUT_CHAN_550500_IDX, + OLYMPUS_LUT_CHAN_550625_IDX, + OLYMPUS_LUT_CHAN_550750_IDX, + OLYMPUS_LUT_CHAN_550875_IDX, + OLYMPUS_LUT_CHAN_551000_IDX, + OLYMPUS_LUT_CHAN_551125_IDX, + OLYMPUS_LUT_CHAN_551250_IDX, + OLYMPUS_LUT_CHAN_551375_IDX, + OLYMPUS_LUT_CHAN_551500_IDX, + OLYMPUS_LUT_CHAN_551625_IDX, + OLYMPUS_LUT_CHAN_551750_IDX, + OLYMPUS_LUT_CHAN_551875_IDX, + OLYMPUS_LUT_CHAN_552000_IDX, + OLYMPUS_LUT_CHAN_552125_IDX, + OLYMPUS_LUT_CHAN_552250_IDX, + OLYMPUS_LUT_CHAN_552375_IDX, + OLYMPUS_LUT_CHAN_552500_IDX, + OLYMPUS_LUT_CHAN_552625_IDX, + OLYMPUS_LUT_CHAN_552750_IDX, + OLYMPUS_LUT_CHAN_552875_IDX, + OLYMPUS_LUT_CHAN_553000_IDX, + OLYMPUS_LUT_CHAN_553125_IDX, + OLYMPUS_LUT_CHAN_553250_IDX, + OLYMPUS_LUT_CHAN_553375_IDX, + OLYMPUS_LUT_CHAN_553500_IDX, + OLYMPUS_LUT_CHAN_553625_IDX, + OLYMPUS_LUT_CHAN_553750_IDX, + OLYMPUS_LUT_CHAN_553875_IDX, + OLYMPUS_LUT_CHAN_554000_IDX, + OLYMPUS_LUT_CHAN_554125_IDX, + OLYMPUS_LUT_CHAN_554250_IDX, + OLYMPUS_LUT_CHAN_554375_IDX, + OLYMPUS_LUT_CHAN_554500_IDX, + OLYMPUS_LUT_CHAN_554625_IDX, + OLYMPUS_LUT_CHAN_554750_IDX, + OLYMPUS_LUT_CHAN_554875_IDX, + OLYMPUS_LUT_CHAN_555000_IDX, + OLYMPUS_LUT_CHAN_555125_IDX, + OLYMPUS_LUT_CHAN_555250_IDX, + OLYMPUS_LUT_CHAN_555375_IDX, + OLYMPUS_LUT_CHAN_555500_IDX, + OLYMPUS_LUT_CHAN_555625_IDX, + OLYMPUS_LUT_CHAN_555750_IDX, + OLYMPUS_LUT_CHAN_555875_IDX, + OLYMPUS_LUT_CHAN_556000_IDX, + OLYMPUS_LUT_CHAN_556125_IDX, + OLYMPUS_LUT_CHAN_556250_IDX, + OLYMPUS_LUT_CHAN_556375_IDX, + OLYMPUS_LUT_CHAN_556500_IDX, + OLYMPUS_LUT_CHAN_556625_IDX, + OLYMPUS_LUT_CHAN_556750_IDX, + OLYMPUS_LUT_CHAN_556875_IDX, + OLYMPUS_LUT_CHAN_557000_IDX, + OLYMPUS_LUT_CHAN_557125_IDX, + OLYMPUS_LUT_CHAN_557250_IDX, + OLYMPUS_LUT_CHAN_557375_IDX, + OLYMPUS_LUT_CHAN_557500_IDX, + OLYMPUS_LUT_CHAN_557625_IDX, + OLYMPUS_LUT_CHAN_557750_IDX, + OLYMPUS_LUT_CHAN_557875_IDX, + OLYMPUS_LUT_CHAN_558000_IDX, + OLYMPUS_LUT_CHAN_558125_IDX, + OLYMPUS_LUT_CHAN_558250_IDX, + OLYMPUS_LUT_CHAN_558375_IDX, + OLYMPUS_LUT_CHAN_558500_IDX, + OLYMPUS_LUT_CHAN_558625_IDX, + OLYMPUS_LUT_CHAN_558750_IDX, + OLYMPUS_LUT_CHAN_558875_IDX, + OLYMPUS_LUT_CHAN_559000_IDX, + OLYMPUS_LUT_CHAN_559125_IDX, + OLYMPUS_LUT_CHAN_559250_IDX, + OLYMPUS_LUT_CHAN_559375_IDX, + OLYMPUS_LUT_CHAN_559500_IDX, + OLYMPUS_LUT_CHAN_559625_IDX, + OLYMPUS_LUT_CHAN_559750_IDX, + OLYMPUS_LUT_CHAN_559875_IDX, + OLYMPUS_LUT_CHAN_560000_IDX, + OLYMPUS_LUT_CHAN_560125_IDX, + OLYMPUS_LUT_CHAN_560250_IDX, + OLYMPUS_LUT_CHAN_560375_IDX, + OLYMPUS_LUT_CHAN_560500_IDX, + OLYMPUS_LUT_CHAN_560625_IDX, + OLYMPUS_LUT_CHAN_560750_IDX, + OLYMPUS_LUT_CHAN_560875_IDX, + OLYMPUS_LUT_CHAN_561000_IDX, + OLYMPUS_LUT_CHAN_561125_IDX, + OLYMPUS_LUT_CHAN_561250_IDX, + OLYMPUS_LUT_CHAN_561375_IDX, + OLYMPUS_LUT_CHAN_561500_IDX, + OLYMPUS_LUT_CHAN_561625_IDX, + OLYMPUS_LUT_CHAN_561750_IDX, + OLYMPUS_LUT_CHAN_561875_IDX, + OLYMPUS_LUT_CHAN_562000_IDX, + OLYMPUS_LUT_CHAN_562125_IDX, + OLYMPUS_LUT_CHAN_562250_IDX, + OLYMPUS_LUT_CHAN_562375_IDX, + OLYMPUS_LUT_CHAN_562500_IDX, + OLYMPUS_LUT_CHAN_562625_IDX, + OLYMPUS_LUT_CHAN_562750_IDX, + OLYMPUS_LUT_CHAN_562875_IDX, + OLYMPUS_LUT_CHAN_563000_IDX, + OLYMPUS_LUT_CHAN_563125_IDX, + OLYMPUS_LUT_CHAN_563250_IDX, + OLYMPUS_LUT_CHAN_563375_IDX, + OLYMPUS_LUT_CHAN_563500_IDX, + OLYMPUS_LUT_CHAN_563625_IDX, + OLYMPUS_LUT_CHAN_563750_IDX, + OLYMPUS_LUT_CHAN_563875_IDX, + OLYMPUS_LUT_CHAN_564000_IDX, + OLYMPUS_LUT_CHAN_564125_IDX, + OLYMPUS_LUT_CHAN_564250_IDX, + OLYMPUS_LUT_CHAN_564375_IDX, + OLYMPUS_LUT_CHAN_564500_IDX, + OLYMPUS_LUT_CHAN_564625_IDX, + OLYMPUS_LUT_CHAN_564750_IDX, + OLYMPUS_LUT_CHAN_564875_IDX, + OLYMPUS_LUT_CHAN_565000_IDX, + OLYMPUS_LUT_CHAN_565125_IDX, + OLYMPUS_LUT_CHAN_565250_IDX, + OLYMPUS_LUT_CHAN_565375_IDX, + OLYMPUS_LUT_CHAN_565500_IDX, + OLYMPUS_LUT_CHAN_565625_IDX, + OLYMPUS_LUT_CHAN_565750_IDX, + OLYMPUS_LUT_CHAN_565875_IDX, + OLYMPUS_LUT_CHAN_566000_IDX, + OLYMPUS_LUT_CHAN_566125_IDX, + OLYMPUS_LUT_CHAN_566250_IDX, + OLYMPUS_LUT_CHAN_566375_IDX, + OLYMPUS_LUT_CHAN_566500_IDX, + OLYMPUS_LUT_CHAN_566625_IDX, + OLYMPUS_LUT_CHAN_566750_IDX, + OLYMPUS_LUT_CHAN_566875_IDX, + OLYMPUS_LUT_CHAN_567000_IDX, + OLYMPUS_LUT_CHAN_567125_IDX, + OLYMPUS_LUT_CHAN_567250_IDX, + OLYMPUS_LUT_CHAN_567375_IDX, + OLYMPUS_LUT_CHAN_567500_IDX, + OLYMPUS_LUT_CHAN_567625_IDX, + OLYMPUS_LUT_CHAN_567750_IDX, + OLYMPUS_LUT_CHAN_567875_IDX, + OLYMPUS_LUT_CHAN_568000_IDX, + OLYMPUS_LUT_CHAN_568125_IDX, + OLYMPUS_LUT_CHAN_568250_IDX, + OLYMPUS_LUT_CHAN_568375_IDX, + OLYMPUS_LUT_CHAN_568500_IDX, + OLYMPUS_LUT_CHAN_568625_IDX, + OLYMPUS_LUT_CHAN_568750_IDX, + OLYMPUS_LUT_CHAN_568875_IDX, + OLYMPUS_LUT_CHAN_569000_IDX, + OLYMPUS_LUT_CHAN_569125_IDX, + OLYMPUS_LUT_CHAN_569250_IDX, + OLYMPUS_LUT_CHAN_569375_IDX, + OLYMPUS_LUT_CHAN_569500_IDX, + OLYMPUS_LUT_CHAN_569625_IDX, + OLYMPUS_LUT_CHAN_569750_IDX, + OLYMPUS_LUT_CHAN_569875_IDX, + OLYMPUS_LUT_CHAN_570000_IDX, + OLYMPUS_LUT_CHAN_570125_IDX, + OLYMPUS_LUT_CHAN_570250_IDX, + OLYMPUS_LUT_CHAN_570375_IDX, + OLYMPUS_LUT_CHAN_570500_IDX, + OLYMPUS_LUT_CHAN_570625_IDX, + OLYMPUS_LUT_CHAN_570750_IDX, + OLYMPUS_LUT_CHAN_570875_IDX, + OLYMPUS_LUT_CHAN_571000_IDX, + OLYMPUS_LUT_CHAN_571125_IDX, + OLYMPUS_LUT_CHAN_571250_IDX, + OLYMPUS_LUT_CHAN_571375_IDX, + OLYMPUS_LUT_CHAN_571500_IDX, + OLYMPUS_LUT_CHAN_571625_IDX, + OLYMPUS_LUT_CHAN_571750_IDX, + OLYMPUS_LUT_CHAN_571875_IDX, + OLYMPUS_LUT_CHAN_572000_IDX, + OLYMPUS_LUT_CHAN_572125_IDX, + OLYMPUS_LUT_CHAN_572250_IDX, + OLYMPUS_LUT_CHAN_572375_IDX, + OLYMPUS_LUT_CHAN_572500_IDX, + OLYMPUS_LUT_CHAN_572625_IDX, + OLYMPUS_LUT_CHAN_572750_IDX, + OLYMPUS_LUT_CHAN_572875_IDX, + OLYMPUS_LUT_CHAN_573000_IDX, + OLYMPUS_LUT_CHAN_573125_IDX, + OLYMPUS_LUT_CHAN_573250_IDX, + OLYMPUS_LUT_CHAN_573375_IDX, + OLYMPUS_LUT_CHAN_573500_IDX, + OLYMPUS_LUT_CHAN_573625_IDX, + OLYMPUS_LUT_CHAN_573750_IDX, + OLYMPUS_LUT_CHAN_573875_IDX, + OLYMPUS_LUT_CHAN_574000_IDX, + OLYMPUS_LUT_CHAN_574125_IDX, + OLYMPUS_LUT_CHAN_574250_IDX, + OLYMPUS_LUT_CHAN_574375_IDX, + OLYMPUS_LUT_CHAN_574500_IDX, + OLYMPUS_LUT_CHAN_574625_IDX, + OLYMPUS_LUT_CHAN_574750_IDX, + OLYMPUS_LUT_CHAN_574875_IDX, + OLYMPUS_LUT_CHAN_575000_IDX, + OLYMPUS_LUT_CHAN_575125_IDX, + OLYMPUS_LUT_CHAN_575250_IDX, + OLYMPUS_LUT_CHAN_575375_IDX, + OLYMPUS_LUT_CHAN_575500_IDX, + OLYMPUS_LUT_CHAN_575625_IDX, + OLYMPUS_LUT_CHAN_575750_IDX, + OLYMPUS_LUT_CHAN_575875_IDX, + OLYMPUS_LUT_CHAN_576000_IDX, + OLYMPUS_LUT_CHAN_576125_IDX, + OLYMPUS_LUT_CHAN_576250_IDX, + OLYMPUS_LUT_CHAN_576375_IDX, + OLYMPUS_LUT_CHAN_576500_IDX, + OLYMPUS_LUT_CHAN_576625_IDX, + OLYMPUS_LUT_CHAN_576750_IDX, + OLYMPUS_LUT_CHAN_576875_IDX, + OLYMPUS_LUT_CHAN_577000_IDX, + OLYMPUS_LUT_CHAN_577125_IDX, + OLYMPUS_LUT_CHAN_577250_IDX, + OLYMPUS_LUT_CHAN_577375_IDX, + OLYMPUS_LUT_CHAN_577500_IDX, + OLYMPUS_LUT_CHAN_577625_IDX, + OLYMPUS_LUT_CHAN_577750_IDX, + OLYMPUS_LUT_CHAN_577875_IDX, + OLYMPUS_LUT_CHAN_578000_IDX, + OLYMPUS_LUT_CHAN_578125_IDX, + OLYMPUS_LUT_CHAN_578250_IDX, + OLYMPUS_LUT_CHAN_578375_IDX, + OLYMPUS_LUT_CHAN_578500_IDX, + OLYMPUS_LUT_CHAN_578625_IDX, + OLYMPUS_LUT_CHAN_578750_IDX, + OLYMPUS_LUT_CHAN_578875_IDX, + OLYMPUS_LUT_CHAN_579000_IDX, + OLYMPUS_LUT_CHAN_579125_IDX, + OLYMPUS_LUT_CHAN_579250_IDX, + OLYMPUS_LUT_CHAN_579375_IDX, + OLYMPUS_LUT_CHAN_579500_IDX, + OLYMPUS_LUT_CHAN_579625_IDX, + OLYMPUS_LUT_CHAN_579750_IDX, + OLYMPUS_LUT_CHAN_579875_IDX, + OLYMPUS_LUT_CHAN_580000_IDX, + OLYMPUS_LUT_CHAN_580125_IDX, + OLYMPUS_LUT_CHAN_580250_IDX, + OLYMPUS_LUT_CHAN_580375_IDX, + OLYMPUS_LUT_CHAN_580500_IDX, + OLYMPUS_LUT_CHAN_580625_IDX, + OLYMPUS_LUT_CHAN_580750_IDX, + OLYMPUS_LUT_CHAN_580875_IDX, + OLYMPUS_LUT_CHAN_581000_IDX, + OLYMPUS_LUT_CHAN_581125_IDX, + OLYMPUS_LUT_CHAN_581250_IDX, + OLYMPUS_LUT_CHAN_581375_IDX, + OLYMPUS_LUT_CHAN_581500_IDX, + OLYMPUS_LUT_CHAN_581625_IDX, + OLYMPUS_LUT_CHAN_581750_IDX, + OLYMPUS_LUT_CHAN_581875_IDX, + OLYMPUS_LUT_CHAN_582000_IDX, + OLYMPUS_LUT_CHAN_582125_IDX, + OLYMPUS_LUT_CHAN_582250_IDX, + OLYMPUS_LUT_CHAN_582375_IDX, + OLYMPUS_LUT_CHAN_582500_IDX, + OLYMPUS_LUT_CHAN_582625_IDX, + OLYMPUS_LUT_CHAN_582750_IDX, + OLYMPUS_LUT_CHAN_582875_IDX, + OLYMPUS_LUT_CHAN_583000_IDX, + OLYMPUS_LUT_CHAN_583125_IDX, + OLYMPUS_LUT_CHAN_583250_IDX, + OLYMPUS_LUT_CHAN_583375_IDX, + OLYMPUS_LUT_CHAN_583500_IDX, + OLYMPUS_LUT_CHAN_583625_IDX, + OLYMPUS_LUT_CHAN_583750_IDX, + OLYMPUS_LUT_CHAN_583875_IDX, + OLYMPUS_LUT_CHAN_584000_IDX, + OLYMPUS_LUT_CHAN_584125_IDX, + OLYMPUS_LUT_CHAN_584250_IDX, + OLYMPUS_LUT_CHAN_584375_IDX, + OLYMPUS_LUT_CHAN_584500_IDX, + OLYMPUS_LUT_CHAN_584625_IDX, + OLYMPUS_LUT_CHAN_584750_IDX, + OLYMPUS_LUT_CHAN_584875_IDX, + OLYMPUS_LUT_CHAN_585000_IDX, + OLYMPUS_LUT_CHAN_585125_IDX, + OLYMPUS_LUT_CHAN_585250_IDX, + OLYMPUS_LUT_CHAN_585375_IDX, + OLYMPUS_LUT_CHAN_585500_IDX, + OLYMPUS_LUT_CHAN_585625_IDX, + OLYMPUS_LUT_CHAN_585750_IDX, + OLYMPUS_LUT_CHAN_585875_IDX, + OLYMPUS_LUT_CHAN_586000_IDX, + OLYMPUS_LUT_CHAN_586125_IDX, + OLYMPUS_LUT_CHAN_586250_IDX, + OLYMPUS_LUT_CHAN_586375_IDX, + OLYMPUS_LUT_CHAN_586500_IDX, + OLYMPUS_LUT_CHAN_586625_IDX, + OLYMPUS_LUT_CHAN_586750_IDX, + OLYMPUS_LUT_CHAN_586875_IDX, + OLYMPUS_LUT_CHAN_587000_IDX, + OLYMPUS_LUT_CHAN_587125_IDX, + OLYMPUS_LUT_CHAN_587250_IDX, + OLYMPUS_LUT_CHAN_587375_IDX, + OLYMPUS_LUT_CHAN_587500_IDX, + OLYMPUS_LUT_CHAN_587625_IDX, + OLYMPUS_LUT_CHAN_587750_IDX, + OLYMPUS_LUT_CHAN_587875_IDX, + OLYMPUS_LUT_CHAN_588000_IDX, + OLYMPUS_LUT_CHAN_588125_IDX, + OLYMPUS_LUT_CHAN_588250_IDX, + OLYMPUS_LUT_CHAN_588375_IDX, + OLYMPUS_LUT_CHAN_588500_IDX, + OLYMPUS_LUT_CHAN_588625_IDX, + OLYMPUS_LUT_CHAN_588750_IDX, + OLYMPUS_LUT_CHAN_588875_IDX, + OLYMPUS_LUT_CHAN_589000_IDX, + OLYMPUS_LUT_CHAN_589125_IDX, + OLYMPUS_LUT_CHAN_589250_IDX, + OLYMPUS_LUT_CHAN_589375_IDX, + OLYMPUS_LUT_CHAN_589500_IDX, + OLYMPUS_LUT_CHAN_589625_IDX, + OLYMPUS_LUT_CHAN_589750_IDX, + OLYMPUS_LUT_CHAN_589875_IDX, + OLYMPUS_LUT_CHAN_590000_IDX, + OLYMPUS_LUT_CHAN_590125_IDX, + OLYMPUS_LUT_CHAN_590250_IDX, + OLYMPUS_LUT_CHAN_590375_IDX, + OLYMPUS_LUT_CHAN_590500_IDX, + OLYMPUS_LUT_CHAN_590625_IDX, + OLYMPUS_LUT_CHAN_590750_IDX, + OLYMPUS_LUT_CHAN_590875_IDX, + OLYMPUS_LUT_CHAN_591000_IDX, + OLYMPUS_LUT_CHAN_591125_IDX, + OLYMPUS_LUT_CHAN_591250_IDX, + OLYMPUS_LUT_CHAN_591375_IDX, + OLYMPUS_LUT_CHAN_591500_IDX, + OLYMPUS_LUT_CHAN_591625_IDX, + OLYMPUS_LUT_CHAN_591750_IDX, + OLYMPUS_LUT_CHAN_591875_IDX, + OLYMPUS_LUT_CHAN_592000_IDX, + OLYMPUS_LUT_CHAN_592125_IDX, + OLYMPUS_LUT_CHAN_592250_IDX, + OLYMPUS_LUT_CHAN_592375_IDX, + OLYMPUS_LUT_CHAN_592500_IDX, + OLYMPUS_LUT_CHAN_592625_IDX, + OLYMPUS_LUT_CHAN_592750_IDX, + OLYMPUS_LUT_CHAN_592875_IDX, + OLYMPUS_LUT_CHAN_593000_IDX, + OLYMPUS_LUT_CHAN_593125_IDX, + OLYMPUS_LUT_CHAN_593250_IDX, + OLYMPUS_LUT_CHAN_593375_IDX, + OLYMPUS_LUT_CHAN_593500_IDX, + OLYMPUS_LUT_CHAN_593625_IDX, + OLYMPUS_LUT_CHAN_593750_IDX, + OLYMPUS_LUT_CHAN_593875_IDX, + OLYMPUS_LUT_CHAN_594000_IDX, + OLYMPUS_LUT_CHAN_594125_IDX, + OLYMPUS_LUT_CHAN_594250_IDX, + OLYMPUS_LUT_CHAN_594375_IDX, + OLYMPUS_LUT_CHAN_594500_IDX, + OLYMPUS_LUT_CHAN_594625_IDX, + OLYMPUS_LUT_CHAN_594750_IDX, + OLYMPUS_LUT_CHAN_594875_IDX, + OLYMPUS_LUT_CHAN_595000_IDX, + OLYMPUS_LUT_CHAN_595125_IDX, + OLYMPUS_LUT_CHAN_595250_IDX, + OLYMPUS_LUT_CHAN_595375_IDX, + OLYMPUS_LUT_CHAN_595500_IDX, + OLYMPUS_LUT_CHAN_595625_IDX, + OLYMPUS_LUT_CHAN_595750_IDX, + OLYMPUS_LUT_CHAN_595875_IDX, + OLYMPUS_LUT_CHAN_596000_IDX, + OLYMPUS_LUT_CHAN_596125_IDX, + OLYMPUS_LUT_CHAN_596250_IDX, + OLYMPUS_LUT_CHAN_596375_IDX, + OLYMPUS_LUT_CHAN_596500_IDX, + OLYMPUS_LUT_CHAN_596625_IDX, + OLYMPUS_LUT_CHAN_596750_IDX, + OLYMPUS_LUT_CHAN_596875_IDX, + OLYMPUS_LUT_CHAN_597000_IDX, + OLYMPUS_LUT_CHAN_597125_IDX, + OLYMPUS_LUT_CHAN_597250_IDX, + OLYMPUS_LUT_CHAN_597375_IDX, + OLYMPUS_LUT_CHAN_597500_IDX, + OLYMPUS_LUT_CHAN_597625_IDX, + OLYMPUS_LUT_CHAN_597750_IDX, + OLYMPUS_LUT_CHAN_597875_IDX, + OLYMPUS_LUT_CHAN_598000_IDX, + OLYMPUS_LUT_CHAN_598125_IDX, + OLYMPUS_LUT_CHAN_598250_IDX, + OLYMPUS_LUT_CHAN_598375_IDX, + OLYMPUS_LUT_CHAN_598500_IDX, + OLYMPUS_LUT_CHAN_598625_IDX, + OLYMPUS_LUT_CHAN_598750_IDX, + OLYMPUS_LUT_CHAN_598875_IDX, + OLYMPUS_LUT_CHAN_599000_IDX, + OLYMPUS_LUT_CHAN_599125_IDX, + OLYMPUS_LUT_CHAN_599250_IDX, + OLYMPUS_LUT_CHAN_599375_IDX, + OLYMPUS_LUT_CHAN_599500_IDX, + OLYMPUS_LUT_CHAN_599625_IDX, + OLYMPUS_LUT_CHAN_599750_IDX, + OLYMPUS_LUT_CHAN_599875_IDX, + OLYMPUS_LUT_CHAN_600000_IDX, + OLYMPUS_LUT_CHAN_5G_MAX +}; + +enum olympus_lut_idx_24g { + OLYMPUS_LUT_CHAN_240700_IDX, + OLYMPUS_LUT_CHAN_240825_IDX, + OLYMPUS_LUT_CHAN_240950_IDX, + OLYMPUS_LUT_CHAN_241075_IDX, + OLYMPUS_LUT_CHAN_241200_IDX, + OLYMPUS_LUT_CHAN_241325_IDX, + OLYMPUS_LUT_CHAN_241450_IDX, + OLYMPUS_LUT_CHAN_241575_IDX, + OLYMPUS_LUT_CHAN_241700_IDX, + OLYMPUS_LUT_CHAN_241825_IDX, + OLYMPUS_LUT_CHAN_241950_IDX, + OLYMPUS_LUT_CHAN_242075_IDX, + OLYMPUS_LUT_CHAN_242200_IDX, + OLYMPUS_LUT_CHAN_242325_IDX, + OLYMPUS_LUT_CHAN_242450_IDX, + OLYMPUS_LUT_CHAN_242575_IDX, + OLYMPUS_LUT_CHAN_242700_IDX, + OLYMPUS_LUT_CHAN_242825_IDX, + OLYMPUS_LUT_CHAN_242950_IDX, + OLYMPUS_LUT_CHAN_243075_IDX, + OLYMPUS_LUT_CHAN_243200_IDX, + OLYMPUS_LUT_CHAN_243325_IDX, + OLYMPUS_LUT_CHAN_243450_IDX, + OLYMPUS_LUT_CHAN_243575_IDX, + OLYMPUS_LUT_CHAN_243700_IDX, + OLYMPUS_LUT_CHAN_243825_IDX, + OLYMPUS_LUT_CHAN_243950_IDX, + OLYMPUS_LUT_CHAN_244075_IDX, + OLYMPUS_LUT_CHAN_244200_IDX, + OLYMPUS_LUT_CHAN_244325_IDX, + OLYMPUS_LUT_CHAN_244450_IDX, + OLYMPUS_LUT_CHAN_244575_IDX, + OLYMPUS_LUT_CHAN_244700_IDX, + OLYMPUS_LUT_CHAN_244825_IDX, + OLYMPUS_LUT_CHAN_244950_IDX, + OLYMPUS_LUT_CHAN_245075_IDX, + OLYMPUS_LUT_CHAN_245200_IDX, + OLYMPUS_LUT_CHAN_245325_IDX, + OLYMPUS_LUT_CHAN_245450_IDX, + OLYMPUS_LUT_CHAN_245575_IDX, + OLYMPUS_LUT_CHAN_245700_IDX, + OLYMPUS_LUT_CHAN_245825_IDX, + OLYMPUS_LUT_CHAN_245950_IDX, + OLYMPUS_LUT_CHAN_246075_IDX, + OLYMPUS_LUT_CHAN_246200_IDX, + OLYMPUS_LUT_CHAN_246325_IDX, + OLYMPUS_LUT_CHAN_246450_IDX, + OLYMPUS_LUT_CHAN_246575_IDX, + OLYMPUS_LUT_CHAN_246700_IDX, + OLYMPUS_LUT_CHAN_246825_IDX, + OLYMPUS_LUT_CHAN_246950_IDX, + OLYMPUS_LUT_CHAN_247075_IDX, + OLYMPUS_LUT_CHAN_247200_IDX, + OLYMPUS_LUT_CHAN_247325_IDX, + OLYMPUS_LUT_CHAN_247450_IDX, + OLYMPUS_LUT_CHAN_247575_IDX, + OLYMPUS_LUT_CHAN_247700_IDX, + OLYMPUS_LUT_CHAN_247825_IDX, + OLYMPUS_LUT_CHAN_247950_IDX, + OLYMPUS_LUT_CHAN_248075_IDX, + OLYMPUS_LUT_CHAN_248200_IDX, + OLYMPUS_LUT_CHAN_248325_IDX, + OLYMPUS_LUT_CHAN_248450_IDX, + OLYMPUS_LUT_CHAN_248575_IDX, + OLYMPUS_LUT_CHAN_248700_IDX, + OLYMPUS_LUT_CHAN_248825_IDX, + OLYMPUS_LUT_CHAN_248950_IDX, + OLYMPUS_LUT_CHAN_249075_IDX, + OLYMPUS_LUT_CHAN_249200_IDX, + OLYMPUS_LUT_CHAN_249325_IDX, + OLYMPUS_LUT_CHAN_249450_IDX, + OLYMPUS_LUT_CHAN_249575_IDX, + OLYMPUS_LUT_CHAN_249700_IDX, + OLYMPUS_LUT_CHAN_249825_IDX, + OLYMPUS_LUT_CHAN_249950_IDX, + OLYMPUS_LUT_CHAN_250075_IDX, + OLYMPUS_LUT_CHAN_24G_MAX +}; + +/** + * DOC: AFE (=Analog Front End) + * + * Configuration layer for the HW component, most of the defined operations + * happen when we start the driver. + * + * The configuration supports: + * CL8080: 4 + 4 (chains 0-3 @ TCV0 and chains 0-3 @ TCV1) + * CL8060: 4 + 2 (chains 0-3 @ TCV0 and chains 2-3 @ TCV1) + * CL8064: 4 + 2 (chains 0-3 @ TCV0 and chains 2-3 @ TCV1) + * CL8040: 2 + 2 (chains 1-2 @ TCV0 and chains 1-2 @ TCV1) + * CL8046: 4 + 0 (chains 0-3 @ TCV0) + */ + +struct cl_afe_reg { + u32 ctrl8; + u32 ctrl9; + u32 ctrl36_phy0; + u32 ctrl36_phy1; + u32 ctrl37_phy0; + u32 ctrl37_phy1; + u8 adc_ch_alloc; +}; + +int cl_afe_cfg(struct cl_chip *chip); +void cl_afe_cfg_calib(struct cl_chip *chip); +void cl_afe_cfg_restore(struct cl_chip *chip); + +/** + * FEM (=Front End Module) + */ + +enum fem_wiring_id { + /* TCV0 - 6 FEMs 3 wires, TCV1 - 6 FEMs 2 wires */ + FEM_WIRING_0_TCV0_6_TCV1_6 = 0, + /* TCV0 - 6 FEMs 2 wires, TCV1 - 6 FEMs 2 wires */ + FEM_WIRING_1_OBSOLETE_TCV0_6_TCV1_6 = 1, + /* TCV0 - 6 FEMs 2 wires, TCV1 - 6 FEMs 3 wires */ + FEM_WIRING_2_OBSOLETE_TCV0_6_TCV1_6 = 2, + /* TCV0 - 2 FEMs 3 wires, Elastic - 4 FEMs 3 wires, TCV1 - 2 FEMs 2 wires */ + FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2 = 3, + /* TCV0 - 2 FEMs 2 wires, Elastic - 4 FEMs 3 wires, TCV1 - 2 FEMs 2 wires */ + FEM_WIRING_4_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 = 4, + /* TCV0 - 2 FEMs 3 wires, Elastic - 4 FEMs 3 wires, TCV1 - 2 FEMs 3 wires */ + FEM_WIRING_5_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 = 5, + /* TCV0 - 2 FEMs 2 wires, Elastic - 4 FEMs 3 wires, TCV1 - 2 FEMs 3 wires */ + FEM_WIRING_6_OBSOLETE_TCV0_2_ELASTIC_4_TCV1_2 = 6, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 FEMs 2 wires */ + FEM_WIRING_7_TCV0_4_TCV1_4 = 7, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 FEMs 3 wires */ + FEM_WIRING_8_OBSOLETE_TCV0_4_TCV1_4 = 8, + /* TCV0 - 4 FEMs 2 wires, TCV1 - 4 FEMs 2 wires */ + FEM_WIRING_9_TCV0_4_TCV1_4 = 9, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 FEMs 3 wires */ + FEM_WIRING_10_TCV0_4_TCV1_4 = 10, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 LNAs (RX only) */ + FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY = 11, + /* TCV0 - 4 FEMs 2 wires, TCV1 - 4 LNAs (RX only) */ + FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY = 12, + /* TCV0 - 6 FEMs 3 wires, TCV1 - 6 FEMs 2 wires (not active), 2 LNAs 1 wire (not active) */ + FEM_WIRING_13_SENSING_4RX_2TX = 13, + /* TCV0 - 6 FEMs 3 wires (4 active), TCV1 - 6 FEMs 2 wires (not active), 2 LNAs 1 wire */ + FEM_WIRING_14_SENSING_4TX_2RX = 14, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 FEMs (RX only) */ + FEM_WIRING_15_CHAMELEON_4TX_4RX = 15, + /* TCV0 - 2 FEMs 3 wires, TCV1 - 2 FEMs 2 wires (CL8040) */ + FEM_WIRING_16_TCV0_2_TCV1_2 = 16, + /* TCV0 - 4 FEMs 2 wires, TCV1 - 0 FEMs (CL8046) */ + FEM_WIRING_17_TCV0_4_TCV1_0 = 17, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 4 FEMs 3 wires */ + FEM_WIRING_18_TCV0_4_TCV1_4 = 18, + /* TCV0 - 2 FEMs 3 wires, TCV1 - 2 FEMs 3 wires (EVB swapped) */ + FEM_WIRING_19_OBSOLETE_TCV0_2_TCV1_2_SWAPPED = 19, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 2 FEMs 2 wires (CL8060 4+2) */ + FEM_WIRING_20_TCV0_2_TCV1_2 = 20, + /* TCV0 - 4 FEMs 3 wires, TCV1 - 2 LNAs (RX only) (CL8066 4+2) */ + FEM_WIRING_21_OBSOLETE_TCV0_4_TCV1_2 = 21, + FEM_WIRING_22_OBSOLETE = 22, + FEM_WIRING_23_TCV0_4_TCV1_4 = 23, + FEM_WIRING_24_TCV0_6_TCV1_4 = 24, + FEM_WIRING_25_TCV0_4_TCV1_2_MODE_0 = 25, + FEM_WIRING_26_TCV0_4_TCV1_2_MODE_1 = 26, + FEM_WIRING_27_TCV0_2_TCV1_1 = 27, + FEM_WIRING_28_TCV0_4_TCV1_2 = 28, + FEM_WIRING_29_TCV0_4_TCV1_2 = 29, + FEM_WIRING_30_TCV0_4_TCV1_2 = 30, + FEM_WIRING_31_TCV0_2_TCV1_1 = 31, + FEM_WIRING_32_TCV0_4_TCV1_0 = 32, + FEM_WIRING_33_TCV0_4_TCV1_4 = 33, + + FEM_WIRING_MAX, + FEM_WIRING_DEFAULT = 255 +}; + +enum fem_type { + FEM_TYPE_TCV0 = 0, + FEM_TYPE_TCV1 = 1, + FEM_TYPE_ELASTIC = 2, + FEM_TYPE_SENSING = 3, + + FEM_TYPE_MAX, +}; + +#define FEM_TYPE_STR(type) \ + ((type == FEM_TYPE_TCV0) ? "TCV0" : \ + ((type == FEM_TYPE_TCV1) ? "TCV1" : \ + ((type == FEM_TYPE_ELASTIC) ? "ELASTIC" : \ + ((type == FEM_TYPE_SENSING) ? "SENSING" : "ERROR")))) + +enum fem_mode { + FEM_MODE_LNA_BYPASS_ONLY = 0, + FEM_MODE_TX_ONLY = 1, + FEM_MODE_RX_ONLY = 2, + + FEM_MODE_MAX, + FEM_MODE_OPERETIONAL = 255 +}; + +struct cl_fem_params { + u8 wiring_id; + u16 lut[FEM_TYPE_MAX]; + u16 lut_registers[TCV_MAX][FEM_LUT_AMOUNT_PER_MAC]; + u16 lut_off_register[TCV_MAX]; + u16 lut_off_register_list[FEM_TYPE_MAX]; +}; + +struct cl_chip; +struct cl_hw; + +int cl_fem_init(struct cl_chip *chip); +int cl_fem_read_wiring_id(struct cl_chip *chip); +int cl_fem_get_registers(struct cl_hw *cl_hw, u32 fem_data[FEM_REGISTERS_AMOUNT]); +void cl_fem_set_dcoc_bypass(struct cl_hw *cl_hw); +void cl_fem_dcoc_restore(struct cl_hw *cl_hw, u8 fem_mode); +void cl_fem_set_iq_bypass(struct cl_hw *cl_hw); +void cl_fem_iq_restore(struct cl_hw *cl_hw, u8 fem_mode); +int cl_fem_update_conf_params(struct cl_chip *chip); +bool cl_fem_wiring_id_is_evb(struct cl_chip *chip); + +#endif /* CL_PHY_H */ From patchwork Tue May 24 11:34:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575968 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 7CDA9C433F5 for ; Tue, 24 May 2022 11:39:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236843AbiEXLjh (ORCPT ); Tue, 24 May 2022 07:39:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236860AbiEXLjf (ORCPT ); Tue, 24 May 2022 07:39:35 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50088.outbound.protection.outlook.com [40.107.5.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB25E8CCEA for ; Tue, 24 May 2022 04:39:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RngjiYnJJrvTL/Cd1kRYHTBIZLm4H6OJCtVMuaOxQvfw9BW15ZX1ds1ih1xjEd4fM5O2j8cCXbs18YwqIRbpwjgPUkGD77SnPuhdSabP8wl7suCqGrCMbcbyrWtODayo4qCnR36SHTMDJGv+T9+WcF1txOQbFXVxY2gn1x25lVzCXniQ2A2AFgr8pgYUmXr/schi7n3aI/wT5skIOFzshYdgWJFEINP8H8Njiv7j3atoGfPtDMUemVeRFt0/fTrPnXQfPbJJd8P2s5HwaN56Y+KXbwuKeIAQmZHB3rReXfcuHs68WYPOQOiHqcp68xQU9JctbFzVgmF95ryleNz1lQ== 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=zMKvWTleB9iG/UOWfQmbR9WPHfo2LA9D9BYTg+SEASs=; b=aI4haBqzysYA00efM05pfISOb0//htfU/zAFa7+M+vMdmtv7NzGigi0BySTeu/gdvi25R9ypdCY90e0RCOuEi6/gUWmASVminlSBZU0mZ41kiog0azMrBFqKB+jtpbyPmVg1fgs8uHkVtzvBT5UAVmHeY+W47Oc/ClSzOFVGDiCjNghYhS3xY01ACAcI9wBFSwMA3RlvfGpr7uY9p9AiIuxDWN47J5ki44l2/J7Zn7316vCjzE+wwE0UluIXr0S3LvueGVqokGpouy7PH31mBvlNUeg2PBuNYt0KeSWTOg+asGPpLQufr+g0d11w+VDeaLpE+NWKsamJcTPGnfIXkg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zMKvWTleB9iG/UOWfQmbR9WPHfo2LA9D9BYTg+SEASs=; b=q8zsStpGvpy7wUTSLxBAFyhbfwDSxen87YdD9vwynlTZoCJcMsv06xauZzrgNZJwpwT/0DVfV3AUKR3dpOAFzfE6KGhPddsGVwRbn1bvDtpNfWoprJEo4SDuScJ52YxvKs+v1ySFFj366PqXyJbIIKadAmMREhtyVGbk+YxzktE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:48 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:48 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 52/96] cl8k: add platform.c Date: Tue, 24 May 2022 14:34:18 +0300 Message-Id: <20220524113502.1094459-53-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 99a7fd48-4964-4171-0c27-08da3d79ed80 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: KMiw8H6Hfu05mK0K+8ssQ6a4HVFXS6DadEUqdL1R3feEP7CN8gG+sjh3Gh721AZlqF0tTHF/j4AQJES0Po6OnyXVLzw7L+a2zSHdMBWDI3U4n/PINrWycG1RxWMoE7BXWUbwodee8KXNKyi/EnU3kIeWYRIBCXuxd8tVsUnrMjMKH9AseGpHOB0A33Lio8L7/6Y8HP5Kpc4t1zsLkrSkd2b08B5zWpiDwQM+zAIGK01+X6TZxNySUj20JEtREbXa9CrQujxBl+WHC1d7qZJ6NiLKIBRZxt2PeVfgkdAPpmebmMlQzsn+mT/DdMNzejm8OaUy8monsDS215HKGdScXWYzQSF613Hy5iTBA5pXQ8QInmsa8lvm8nX5plERICBP6FUlB4JH9mk6Q/EGml3QxWh7FBne3r8x2ujIMtbbJivMhwiDgd2ujLFLD0Q/SRluQweEUPwwt5q756UMJeblhFDBG0izPESlATxdSxunMNAj06b+IxbHGRE0V7BHcIz0Yxx2PZE8gzzHzhlG6kcHnZII+7WRQsKVihfRSEEZX2p/n0fwe+HsEixx/PVedgak8qIHiGTkCO9rmWYySTJ/A/MOpuOgqA8znBzwS6zIB4ouzEQUKfaYJ+hwAYZ+wQRajZkicr8YbLRLnGAn7ImTPX0Pk9KJB3+vd6U+0BI52dfwGCbccqJAhFVCtvYrX0CZQnT49raI4xdHN3R+Ob86Mto0y6sF8pLq8xdzKQkIVmw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: zmoPGFwuDOA1kHPC6zhqdWc/T1TDF3CA1Qwq01dvuUWtqn+6Fu21ImcOYMZFe+tdu9Xo2W416eN0nRyFl8U+Oj8mKD5Oc3TI4YCU2er/f72EMcvwoYSWnDSnnVjdtx2GMmwiuk1dSp4Bx4v3BNd0oEUOCuaOe9lyptpw0ALEgfnh6TgN9+S2ezWIKbVpigJi4soYVOAsK+1wDRjaYPIifrN9kmxDRXAvuAwiPUc2tH9m4rZfZgoKp6w+ivtzc3dpvxbmajIoSg98zmF4mgPgRzFOUf2ng3tkMP4wo4ZZqQ3zYsAIa59UqeNeSz3eePoh7W6ePoTddYzsjSZehvSBHnGMx5K9FLF9Up0J9uIC0Gfazmse7ljSIRYXtpOBx9kM3CtVh53Thh/0s5RUQFYSYUw84X/SJNanaaDknf/8DOGx9ZzRpUYNHsUaqsAo5wJ5PnYxE0K1pWVZSz1+2GIhC6vegAsOJ9zD/4EmLJPVbKUZOuimW+18b7wiU9/uTMdJZ7uPit/x4Z0ylLv4w1lPNmqba/eaGB6viHYeXvKacrqnYH6YANkRl91jJyKCRcwEpuiZa+HNnX1pLHY97dOMxt8UV1UtfpL+gFNlwK4BveJyw2eyGvpKCJKq6uRXWmc/sMGZt20ktAsl53XAfxleGc21U9Flv+yWHtAtE8DFwvGGfCxcDqsKWpe56QkXQ7p3WEhYFrHH0wm6ToOxEV+TopOao7TuL6hSdZ0dJvFREtILoTqv6CYePHSWXykt+yEtYNBSlS5OuPhKM7/k5PqbeDcF7rcWU3njRRkCZ0TAQJqWswX8wXXh3jU8EkgdMFE4/Qy3SIB89g1DGJEwX0ws1nA2gKhfEj8BKbBogSPlK9z8TG19T7sZFMKgYY98O9bAWeNeFUYni6VGWSV2ozF5X/Lryk7TSOb+orZIVRBf3Aoo7XB+KghNoLW332lJlIJM/gRBZny83jVkx5ttwnKKuw9GttEqhcSnNa6ZYmSflPliEpZCIDWK3CXos71vBqbhvHPj5XZcMNZDCI5SLI25oyXe753lnpGajAaddnDAMvo/XuX4tWNw0Zp0WIBDeDw3Xj2f3mGQdMPwf6l30eCohMj/LPlxEB5kxzuOzjfDz0cm47tssu6wllTaZHxxpJ5Z8QyhqVVzuoKdWxWNMll6xNtUhKlEYCQ9qd7R7W1gGCC34jJpBubxJt4PDRL+rXXx0puMnm9S5VDsMxspWK/2TuMw6ZkQDFssAaOsFo0uEz0oEAVO0RFEE7torTyT6pf/qE+KGznkgznjhCFa6GRBsz9Q7c+cpByffvl5VD2qTub/VS6X0dWWgR6PURYZQ5Si+IwFGaG/YKFdxXA6E/VioiXuDrn+PNhT9vOBKmuZlbn65EjTrmTjJsKDwTLbzoXYl+UN8/y/h+MjkJZsTuGIQGbgI5MEMPM3Tkx/+1pAlmVS758SX5iLdt6sod0dYIJBDtxizkf4Yaiv/NPArQyf71a0S6Nl6o2rLM/uoV9w3CVdqZ+vs7LyxD2eB1TTTByrwRjS5XTFxOgpxuXRNIcSqlLpQ8JqU8pAd7vD8sGJJQchNC6fJvxrCNga8xYinxebE8Vl9D76krdhpCG7cmDZSQdgIRJS1X/agqH7/LGkRxYm10HIkN1NXd/K78Bru5Z5MJn4ABHne+CQJiu5fv1jYtMF/3xNejKgaqiGuJjdiR6OjcJyv1u5CN+xxK8QnFWQCl3Bed2y/jTNVj6kzXTAzVawhO+y9Dy3h9f8jRVaHq4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 99a7fd48-4964-4171-0c27-08da3d79ed80 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:31.2837 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: kaub5LcSblWjWJjB0OXkATXqcN0kS+MzmsGqmTKQnHRICWDg64KIoVfBlbWjxwWk910UvZVFYn/zcehaEpaiCg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/platform.c | 392 ++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/platform.c diff --git a/drivers/net/wireless/celeno/cl8k/platform.c b/drivers/net/wireless/celeno/cl8k/platform.c new file mode 100644 index 000000000000..140505523fb2 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/platform.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "e2p.h" +#include "debug.h" +#include "utils.h" +#include "hw.h" +#include "platform.h" + +static int cl_platform_update_idx_v1(struct cl_chip *chip) +{ + u8 i = 0; + u32 platform_id = 0; + struct cl_agc_platform_pack *app = chip->platform.app; + ssize_t buf_len = chip->platform.app_size; + ssize_t data_len = buf_len - sizeof(*app); + ssize_t offset = 0; + struct cl_platform_binding *platform = NULL; + + if (cl_e2p_read(chip, (u8 *)&platform_id, SIZE_FEM_PLATFORM_ID, ADDR_FEM_PLATFORM_ID)) + return -1; + + cl_dbg_chip_verbose(chip, + "platform_id: 0x%08x, " + "customer_id: 0x%04x, board_id: 0x%02x, chip_id: 0x%x\n", + platform_id, + PLATFORM_CUSTOMER(platform_id), + PLATFORM_BOARD(platform_id), + PLATFORM_CHIP(platform_id)); + + while (offset <= data_len) { + struct cl_agc_tilv *tilv = (struct cl_agc_tilv *)((u8 *)app->data + offset); + + if (tilv->t == CL_AGC_PACK_EOF || tilv->t == CL_AGC_PACK_UNDEFINED) + break; + + if (tilv->t != CL_AGC_PACK_PLATFORM_BINDING) + goto next_tilv; + + platform = (void *)tilv->v; + if (platform_id != platform->platform_id) + goto next_tilv; + + cl_dbg_chip_verbose(chip, "%s\n", platform->platform_description); + chip->platform.idx = i; + return 0; +next_tilv: + i += 1; + offset += sizeof(*tilv) + tilv->l; + } + + if (IS_REAL_PHY(chip)) { + CL_DBG_ERROR_CHIP(chip, "Invalid platform_id 0x%08x\n", platform_id); + + if (!chip->conf->ce_production_mode) + return -1; + } + + return 0; +} + +struct cl_platform_table *cl_platform_get_active_table(struct cl_chip *chip, u8 idx) +{ + bool is_active = (idx == chip->platform.idx); + + if (idx >= cl_platform_get_tables_cnt(chip)) + return NULL; + + if (is_active && chip->platform.app) + return &chip->platform.table; + + return NULL; +} + +static int cl_calc_platforms_number(struct cl_agc_platform_pack *app, ssize_t buf_len) +{ + ssize_t data_len = buf_len - sizeof(*app); + ssize_t offset = 0; + int ret = 0; + + while (offset <= data_len) { + struct cl_agc_tilv *tilv = (struct cl_agc_tilv *)((u8 *)app->data + offset); + + if (tilv->t == CL_AGC_PACK_EOF || tilv->t == CL_AGC_PACK_UNDEFINED) + break; + + if (tilv->t != CL_AGC_PACK_PLATFORM_BINDING) + goto next_tilv; + + ret += 1; +next_tilv: + offset += sizeof(*tilv) + tilv->l; + } + + return ret; +} + +static void *cl_find_tilv_data(struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 seeking_id, u8 seeking_type) +{ + ssize_t data_len = buf_len - sizeof(*app); + ssize_t offset = 0; + void *ret = NULL; + + if (seeking_type >= CL_AGC_PACK_MAX) + return NULL; + + while (offset <= data_len) { + struct cl_agc_tilv *tilv = (struct cl_agc_tilv *)((u8 *)app->data + offset); + + if (tilv->t == CL_AGC_PACK_EOF || tilv->t == CL_AGC_PACK_UNDEFINED) + break; + + if (tilv->t != seeking_type) + goto next_tilv; + + if (tilv->i == seeking_id) { + ret = (void *)&tilv->v; + break; + } + +next_tilv: + offset += sizeof(*tilv) + tilv->l; + } + + return ret; +} + +static struct cl_platform_binding *cl_find_binding(struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 seeking_id) +{ + return cl_find_tilv_data(app, buf_len, seeking_id, CL_AGC_PACK_PLATFORM_BINDING); +} + +static struct cl_agc_profile_per_bw *cl_find_agc_profile(struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 seeking_id) +{ + return cl_find_tilv_data(app, buf_len, seeking_id, CL_AGC_PACK_PROFILE); +} + +static const u8 *cl_find_power_table(struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 seeking_id) +{ + return cl_find_tilv_data(app, buf_len, seeking_id, CL_AGC_PACK_POWER_TABLE); +} + +static bool cl_is_valid_agc_profile(u8 profile_id) +{ + return (profile_id >= CL_AGC_PROFILE_FIRST) && + (profile_id < CL_AGC_PROFILE_MAX); +} + +static bool cl_is_valid_power_table(u8 table_id) +{ + return (table_id >= CL_POWER_TO_POWERWORD_CONV_TABLE_FIRST) && + (table_id < CL_POWER_TO_POWERWORD_CONV_TABLE_MAX); +} + +int cl_platform_get_tables_cnt(struct cl_chip *chip) +{ + return cl_calc_platforms_number(chip->platform.app, chip->platform.app_size); +} + +int cl_platform_unpack_v1(struct cl_platform_table *table, + struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 platform_idx) +{ + struct cl_platform_binding *binding = NULL; + u8 profile_id = CL_AGC_PROFILE_UNDEFINED; + + binding = cl_find_binding(app, buf_len, platform_idx); + if (!binding) + return -ENODATA; + + /* Find corresponding binding */ + table->platform_id = binding->platform_id; + memcpy(table->platform_description, binding->platform_description, + sizeof(table->platform_description)); + + /* Bind AGC profiles */ + profile_id = binding->agc_profile[TCV0]; + if (cl_is_valid_agc_profile(profile_id)) + table->agc_profile[TCV0] = cl_find_agc_profile(app, buf_len, profile_id); + + profile_id = binding->agc_profile[TCV1]; + if (cl_is_valid_agc_profile(profile_id)) + table->agc_profile[TCV1] = cl_find_agc_profile(app, buf_len, profile_id); + + profile_id = binding->agc_profile_elastic[TCV0]; + if (cl_is_valid_agc_profile(profile_id)) + table->agc_profile_elastic[TCV0] = cl_find_agc_profile(app, buf_len, profile_id); + + profile_id = binding->agc_profile_elastic[TCV1]; + if (cl_is_valid_agc_profile(profile_id)) + table->agc_profile_elastic[TCV1] = cl_find_agc_profile(app, buf_len, profile_id); + + profile_id = binding->agc_profile_sensing; + if (cl_is_valid_agc_profile(profile_id)) + table->agc_profile_sensing = cl_find_agc_profile(app, buf_len, profile_id); + + /* Bind power tables */ + if (cl_is_valid_power_table(binding->power_conv_table_2)) + table->power_conv_table_2 = cl_find_power_table(app, buf_len, + binding->power_conv_table_2); + + if (cl_is_valid_power_table(binding->power_conv_table_5)) + table->power_conv_table_5 = cl_find_power_table(app, buf_len, + binding->power_conv_table_5); + + if (cl_is_valid_power_table(binding->power_conv_table_6)) + table->power_conv_table_6 = cl_find_power_table(app, buf_len, + binding->power_conv_table_6); + + return 0; +} + +static int cl_platform_unpack(struct cl_chip *chip) +{ + int ret = 0; + struct cl_agc_platform_pack *app = chip->platform.app; + ssize_t buf_len = chip->platform.app_size; + + if (strncmp(app->magic, PLATFORM_PACK_MAGIC_V1, sizeof(app->magic)) != 0) { + cl_dbg_chip_err(chip, + "Magic differs, got %s, expected %s\n", + app->magic, PLATFORM_PACK_MAGIC_V1); + return -EINVAL; + } + if (le32_to_cpu(app->version) != PLATFORM_PACK_VERSION_V1) { + cl_dbg_chip_err(chip, + "Invalid pack version: %u\n", + le32_to_cpu(app->version)); + return -EINVAL; + } + + ret = cl_platform_update_idx_v1(chip); + if (ret) + return ret; + + ret = cl_platform_unpack_v1(&chip->platform.table, app, buf_len, + chip->platform.idx); + return ret; +} + +int cl_platform_alloc(struct cl_chip *chip) +{ + char filename[CL_FILENAME_MAX]; + size_t size = 0; + char *buf = NULL; + int ret = 0; + + snprintf(filename, sizeof(filename), PLATFORM_PACK_FILENAME_V1); + size = cl_file_open_and_read(chip, filename, (char **)&buf); + if (!buf) { + cl_dbg_chip_err(chip, "AGC platform pack data buffer is empty\n"); + + ret = -ENODATA; + goto err; + } + + chip->platform.app_size = size; + chip->platform.app = (struct cl_agc_platform_pack *)buf; + + ret = cl_platform_unpack(chip); +err: + return ret; +} + +void cl_platform_dealloc(struct cl_chip *chip) +{ + if (chip->platform.app) { + kvfree(chip->platform.app); + chip->platform.app = NULL; + chip->platform.app_size = 0; + } +} + +/* AGC PROFILE */ +#define AGC_PROFILE_BAND_MASK 0xff000000 +#define AGC_PROFILE_BRANCH_MASK 0x00ff0000 +#define AGC_PROFILE_VERSION_MASK 0x0000ff00 + +#define AGC_PROFILE_BAND(profile) \ + u32_get_bits(profile, AGC_PROFILE_BAND_MASK) +#define AGC_PROFILE_BRANCH(profile) \ + u32_get_bits(profile, AGC_PROFILE_BRANCH_MASK) +#define AGC_PROFILE_VERSION(profile) \ + u32_get_bits(profile, AGC_PROFILE_VERSION_MASK) + +#ifdef __BIG_ENDIAN_BITFIELD +static void cl_agc_profile_to_le32(struct cl_agc_profile *profile) +{ + u32 i; + u32 size = sizeof(struct cl_agc_profile); + u32 *ptr = (u32 *)profile; + + /* Make sure that size divides by 4 */ + WARN_ON((size & 0x3) != 0); + + for (i = 0; i < size / 4; i++) + ptr[i] = cpu_to_le32(ptr[i]); +} +#endif + +int cl_agc_params_fill(struct cl_hw *cl_hw, struct cl_agc_params *agc_params) +{ + u8 tcv_idx = cl_hw->tcv_idx; + u8 platform_idx = cl_hw->chip->platform.idx; + u8 bw = cl_hw->bw; + struct cl_platform_table *table = NULL; + + memset(agc_params, 0, sizeof(struct cl_agc_params)); + + if (platform_idx == U8_MAX) + return 0; + + table = cl_platform_get_active_table(cl_hw->chip, platform_idx); + if (!table) + return -EINVAL; + + if (!table->agc_profile_elastic[tcv_idx] || cl_hw->num_antennas <= 2) { + u8 ant_shift = cl_hw_ant_shift(cl_hw); + + if (table->agc_profile[tcv_idx]) { + agc_params->profile1.id = table->agc_profile[tcv_idx]->id; + agc_params->profile1.regs = table->agc_profile[tcv_idx]->regs[bw]; + } else if (tcv_idx == TCV1 && table->agc_profile_sensing) { + agc_params->profile1.id = table->agc_profile_sensing->id; + agc_params->profile1.regs = table->agc_profile_sensing->regs[bw]; + } else { + CL_DBG_ERROR(cl_hw, "Invalid tcv/sensing profile"); + return -1; + } + + agc_params->num_profiles = 1; + agc_params->ant_mask1 = ANT_MASK(cl_hw->num_antennas) << ant_shift; + agc_params->ant_mask2 = 0; + +#ifdef __BIG_ENDIAN_BITFIELD + cl_agc_profile_to_le32(&agc_params->profile1); +#endif + } else { + if (table->agc_profile[tcv_idx]) { + memcpy(&agc_params->profile1, + table->agc_profile[tcv_idx], + sizeof(struct cl_agc_profile)); + } else { + CL_DBG_ERROR(cl_hw, "Invalid tcv profile"); + return -1; + } + + if (table->agc_profile_elastic[tcv_idx]) { + memcpy(&agc_params->profile2, + table->agc_profile_elastic[tcv_idx], + sizeof(struct cl_agc_profile)); + } else { + CL_DBG_ERROR(cl_hw, "Invalid elastic profile"); + return -1; + } + + agc_params->num_profiles = 2; + agc_params->ant_mask1 = ANT_MASK(2); + agc_params->ant_mask2 = ANT_MASK(cl_hw->num_antennas - 2) << 2; + +#ifdef __BIG_ENDIAN_BITFIELD + cl_agc_profile_to_le32(&agc_params->profile1); + cl_agc_profile_to_le32(&agc_params->profile2); +#endif + } + + return 0; +} + +void cl_agc_params_dump_profile_id(char *buf, ssize_t buf_size, ssize_t *len, + u32 id, const char *str) +{ + u8 band, branch, version; + + band = AGC_PROFILE_BAND(id); + branch = AGC_PROFILE_BRANCH(id); + version = AGC_PROFILE_VERSION(id); + + if (*buf) { + *len += scnprintf(buf + *len, buf_size - *len, + "%s %u.%u.%u\n", str, band, branch, version); + } else { + pr_debug("%s %u.%u.%u\n", str, band, branch, version); + } +} + From patchwork Tue May 24 11:34:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576849 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 D8B23C433F5 for ; Tue, 24 May 2022 11:39:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236866AbiEXLjm (ORCPT ); Tue, 24 May 2022 07:39:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236855AbiEXLjk (ORCPT ); Tue, 24 May 2022 07:39:40 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50045.outbound.protection.outlook.com [40.107.5.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 788A38CCC5 for ; Tue, 24 May 2022 04:39:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=djUfPvq+9xlbgCsk1RP47SdOARhe7ll3yHVCjKmbY0Mxfh1pt6QeJ/sU112jT1FtD6rlmWVBiXLrCDBpVATYAKgheuzKVLhpNVB4LKDt0tJqsHz0fdh9IiVPi5XEoVwg8mgeRUKzUSnnc6zVNcvRk5deL3Pq274FGHLJwJOKCBuGW5JfBsimDrGdbESThe7rVT+ll/mPuEn6bL3lOJ+4UGEeZ286mEHbfHVRyscr6paoAFN8/ZRhDMqGUigzIjI41RNI3AimLb/1AGDNx8gSLkXCg+ROi78uFu9PCS0wVDNgaZ0bEYvHIvHCphYnxu9BAc2CmiFE/RvFlRt0AOZpXA== 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=dbFwNoLDetNRL9pSM2yqP7f+QPSmXwL9C0yQrYD8EuI=; b=e2UzBbgJpbq3lDXBvr1O4HWa7dqSnRdHlVI06UjLzS6ckl4AZ0UQ4ULT0/6aV2rAZBG6k9QmSkTnuTLQjDapK/Dh6pDQP4QVKS4jUp266MtaM4thdpQOp3waS+Pom9VI2w25wil/vzNIIWVwdh8t+vSnoLbBhlNgYYjWKAmKx/XrjWyjdl2NJpF2tx7QdFOJYUodjXbyCwMWGMq5gZoOJmcccki4cur15bKhsfL0AGx2LsNXmcTGWnzIacQQcFyA2npd0nePppSnqo5XU2j1df0YvYR4Ua/6SONpdxFEidtSGOQKbvagPFkwCeOgon5RnP4DD+i6peYN3HKJ+xnfpg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=dbFwNoLDetNRL9pSM2yqP7f+QPSmXwL9C0yQrYD8EuI=; b=d9ynHD4z3Ht7MIVZC7cwcyoOiPRnROIzjdAPPf6fbOc/lj1FT0juP7tiuCDrfW9PSAYbDotml4jiMRvS8PjppaASGllTWe0jUrZ9AB8woMWUwivbTZpgj4pWl1EGFNgSK07dEFjV/V6Fh1c5883Cfg/BHNY3VjOHxDfN10UUS2g= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:50 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:48 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 53/96] cl8k: add platform.h Date: Tue, 24 May 2022 14:34:19 +0300 Message-Id: <20220524113502.1094459-54-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ba8ce742-5e9e-4497-b2c4-08da3d79eded X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fi9sZ2qbVUA7AL6wqIK7YAKaf09HyIhrRu6mcSBjIooigMhv4WuWJ9dAaeBD/RNFmfZaRkl4L6US+9U8rMiw46YVZD0Yr7VS5kOySYf4Eacy1QDnCXOK9/AYpJ+I1wsDXfpbif7Uhag6zjTiUsuGACpNsU5/w5suDYMBJctDfTaIYnuEIYSgqnGpXMM3Qzqf3LqHcR7gzvD6+TibNMm3RsggCYM6v7uuLC5vdMC2XNcu2LhBLohc23IFkpisvc/cILQjeHURbae/0aYLzTW0XCEeddJk7potFP0umnfOBPpHciLNRLZjpQsYx97TtSA23fGuSRl0XGN/zCRqG98xFpzk3UYLrOrBCPX8rggf/LEJ1BtQvBOaYDws4tu6wtK69AEOzc21xBM/Xbvu7SmfcUwTIn3WpFJQcOyowdpjb0QjVKhPKBS8e4Zl1z3PWi9fhffWY2uE/A6Y2nf7838gOkAYcWt2XgS8a5++M7EQPTFL1T1Nucz0JSQCNiKKDDIwt67rP+939iPRTLtGYc5MROCpAk5iV0CiM0rfL/wS/4UFM6z2x6rrAkyV0wKlgrUUfrYDnkkgE8ZCREKDW4nTjoVfRo0EdsDtxozW/l40IYQ2zKUhImqycrYZ5/EqkpsdabMQMtUAywskDRV0KN7/TzRLCxY7knH6jCCIOzQdmsZDcbEYmK2A8SZdQMpyDL8W2XhcKqvwY/qWbUhdxOvMs9P3f0vY+a37HMwXW78Rkl8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: qYt3caMzyyfFOMjHyq1394htLyyZ2Lj+tdsToZMVzYtplMyO4dBrqSMGOlnzrgMIrePNQbdXM64Rzz4TGSRtjzGIUcNAp0CsYVioY955joduJRljyPqVEc9jpH8TBQFhqH159OnJsptHJQB1Ds1GiNRVkApvr6B2Hr6QWsIWBkelIMZMg7JAxd9enq2ngiHMX2r9PdZ+B2br+unrHiI6yoGAjlji8kU2QksK9Uuf6+Z5vzKKaSf48mMwQoE11luXu37gmc3Q8e1Qe/Iue8sOttPZ2uN8jgaNJJibVpcpULkD1pfx30fr87Ro4s7Zutbmcp1x3Q9mBcw834xbDomZRqsdxGlXl40cr6ooscNhPPmmH5FAFi04uejYhQdAXapknu8swtfaqQWM8m9za4Fvv5OWhDbsCX1VppV1lAbwHWxPbg3A7t/25jEcAvOr+Lmb1NHL841H8tVxX4k/j1RHxO03mnDMhkDsGROfcv6tHfEWZ2oELDU/xuio8tHoloVqrNKSgsqohAuOucEV5gxwm+mQNqE5KaFA1sIsfKJ6a6aNLcILKM1ZrBU7EpnhpQEVUMJYWWnlywrqYp5ddtA6wTKhRuxH5PXXsyEqfR2IlxPqE8BCHWoiLLV6Vv5RjhEsrLkTh3tOBVfzWcTDHnr8pFUpVynPtFrR5EBfYar2QQUZOn18x96+3EVRsELupcN9g5i9djowimlTm1xWhvtOSBXGD41UoeSsShUJJ2N/x7hu5rFxiKotlHaQz68WkwiJtUosUvC0p/slWO+/DbvqhunDZP83nI6WH/y6wzpau0/cpUdBKaC0L2lxVwqLPyLWjIHiShtq1P1E4nBKDYMmKaenxIvLj009tIWpXW8WaotqI0qaH6oD/iVYdx6P5XO00uIR98rQsT/mfMIxPaOh+quefspAnX/1AdkotiYONgZT2fzTw05k1TOJPThJlFHIf8X3InkLMj5XKGTk6CRYC8pN8odcVEvW8rOcal0BbEiM/sHTGUbilZCr9f8IeSTNbNXolmHq0+Kb2b3zcLgkvXP6yp9K+hV5M3iRF2gUgSgT5rcZi2IWoKZ5dE86YBBQd33KNjAttIyfnya0OiMFI+ayr+Az92kFXyDD0R4lkPLG6hkjx+aYvvbSZWLHhI7RstAI5AMv93zh5sG5CCwvo5R7bqKOx2bkw3wQaj40q79YkWl/56hm4hlut7vt5ZbxPYEdZiUMoGQnB0oFWvQz92wHcG1TW+yS5Jar/T51Vdtj0RksH3XAka8qFvOTyzHVAwBYz73Vn3mkWUHxRAxktofW7vadSSzS4Ir6UNm0TxRo2qFFVK9dQyq1da+QG3rQv07KZGvfilkhr7LHWLwUxsi/t1KXRhMVUeZuqjKUVP2D6bmsn7/lhMQYE7iRrH1/7y2h36/uA9sDrRRRwbSfesK2BTa9IjlvYsRtkGwSADZ30Qm5gG6SGjTeLASIFvSe05eceh0gH5UVc50rOh4EN0L0Hke38JRKVNyi+LDHH2NLMwxyfKfzsitjZN7TbEQw9COrTAN+d6Vxb1Pc0qAOeQ11ztnTt0aa6pjmYTh7v4o1pp55JBCVvXlvxxx9kYbfYg6SikR84hFMP8pVEgx2WeFgWLuKHYVxZM5nw+1OUw3qJUj289cbIyENpHedIduyVODD72ChViB3CaG4Flp2Ax1nEadA4E2B/bn4eXbguIHB1Rva/e+47WTN0VQ6yfqiAunXpce3QgEqZZobkyIPGMBjGrTne4LStMc8+2P/oeA= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ba8ce742-5e9e-4497-b2c4-08da3d79eded X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:32.0023 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 3sV9OiNumvEIuZf8sjyaX0QnQT6mO/VyAfvnKoovKEUrp0Gsodj0Xz4DxPmk01jJgn1Bj8Lk+o52xin7GTnhqg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/platform.h | 196 ++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/platform.h diff --git a/drivers/net/wireless/celeno/cl8k/platform.h b/drivers/net/wireless/celeno/cl8k/platform.h new file mode 100644 index 000000000000..d0268eded0c3 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/platform.h @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_PLATFORM_H +#define CL_PLATFORM_H + +#define PLATFORM_DESCRIPTION_LENGTH 100 +#define PLATFORM_CUSTOMER_MASK 0xffff0000 +#define PLATFORM_BOARD_MASK 0x0000ff00 +#define PLATFORM_CHIP_MASK 0x000000f0 + +#define PLATFORM_CUSTOMER(platform) \ + u32_get_bits(platform, PLATFORM_CUSTOMER_MASK) +#define PLATFORM_BOARD(platform) \ + u32_get_bits(platform, PLATFORM_BOARD_MASK) +#define PLATFORM_CHIP(platform) \ + u32_get_bits(platform, PLATFORM_CHIP_MASK) + +#define PLATFORM_PACK_VERSION_V1 1 +#define PLATFORM_PACK_MAGIC_V1 "CL8K-AGC-PPCK" +#define PLATFORM_PACK_FILENAME_V1 "agcppk.bin" +#define PLATFORM_PACK_MAGIC_LEN 16 + +struct cl_platform_table { + u32 platform_id; + u8 platform_description[PLATFORM_DESCRIPTION_LENGTH]; + struct cl_agc_profile_per_bw *agc_profile[TCV_MAX]; + struct cl_agc_profile_per_bw *agc_profile_elastic[TCV_MAX]; + struct cl_agc_profile_per_bw *agc_profile_sensing; + const u8 *power_conv_table_2; + const u8 *power_conv_table_5; + const u8 *power_conv_table_6; +}; + +enum cl_agc_pack_type { + CL_AGC_PACK_UNDEFINED, + CL_AGC_PACK_PLATFORM_BINDING, + CL_AGC_PACK_PROFILE, + CL_AGC_PACK_POWER_TABLE, + CL_AGC_PACK_EOF, + + CL_AGC_PACK_MAX +}; + +enum cl_agc_profile_type { + CL_AGC_PROFILE_UNDEFINED, + CL_AGC_PROFILE_FIRST, + CL_AGC_PROFILE_2_1_9 = CL_AGC_PROFILE_FIRST, + CL_AGC_PROFILE_5_1_9, + CL_AGC_PROFILE_6_1_3, + CL_AGC_PROFILE_50_0_1, + CL_AGC_PROFILE_60_1_3, + + CL_AGC_PROFILE_MAX +}; + +enum cl_power_table_type { + CL_POWER_TO_POWERWORD_CONV_TABLE_UNDEFINED, + CL_POWER_TO_POWERWORD_CONV_TABLE_FIRST, + CL_POWER_TO_POWERWORD_CONV_TABLE_COMMON_ID_0 = CL_POWER_TO_POWERWORD_CONV_TABLE_FIRST, + CL_POWER_TO_POWERWORD_CONV_TABLE_COMMON_ID_1, + CL_POWER_TO_POWERWORD_CONV_TABLE_COMMON_ID_2, + CL_POWER_TO_POWERWORD_CONV_TABLE_ATHOS_B_ID_0, + CL_POWER_TO_POWERWORD_CONV_TABLE_ATHOS_B_ID_1, + + CL_POWER_TO_POWERWORD_CONV_TABLE_MAX +}; + +struct cl_agc_platform_pack { + char magic[PLATFORM_PACK_MAGIC_LEN]; + __le32 version; + u8 reserved[249]; + u8 data[]; +} __packed; + +struct cl_agc_tilv { + u8 t; + u8 i; + u32 l; + u8 v[]; +} __packed; + +struct cl_platform_binding { + u32 platform_id; + u8 platform_description[PLATFORM_DESCRIPTION_LENGTH]; + u8 agc_profile[TCV_MAX]; + u8 agc_profile_elastic[TCV_MAX]; + u8 agc_profile_sensing; + u8 power_conv_table_2; + u8 power_conv_table_5; + u8 power_conv_table_6; +} __packed; + +struct cl_platform { + struct cl_agc_platform_pack *app; + ssize_t app_size; + struct cl_platform_table table; + u8 idx; +}; + +struct cl_platform_table *cl_platform_get_active_table(struct cl_chip *chip, + u8 idx); +int cl_platform_get_tables_cnt(struct cl_chip *chip); +int cl_platform_unpack_v1(struct cl_platform_table *table, + struct cl_agc_platform_pack *app, + ssize_t buf_len, u8 platform_idx); +int cl_platform_alloc(struct cl_chip *chip); +void cl_platform_dealloc(struct cl_chip *chip); + +/** + * AGC (=Automatic Gain Control) + */ + +struct cl_agc_reg { + u32 val; + u32 mask; +}; + +struct cl_agc_regs { + struct cl_agc_reg fsm_preset_p2; /* 0x244 */ + struct cl_agc_reg lna_thr_set0_ref2; /* 0x25C */ + struct cl_agc_reg lna_thr_set0_ref3; /* 0x260 */ + struct cl_agc_reg lna_thr_set1_ref2; /* 0x264 */ + struct cl_agc_reg lna_thr_set1_ref3; /* 0x268 */ + struct cl_agc_reg lna_thr_set2_ref2; /* 0x26C */ + struct cl_agc_reg lna_thr_set2_ref3; /* 0x270 */ + struct cl_agc_reg lna_gain_set0_ref2; /* 0x274 */ + struct cl_agc_reg lna_gain_set0_ref3; /* 0x278 */ + struct cl_agc_reg lna_nf_set0_ref2; /* 0x27C */ + struct cl_agc_reg lna_nf_set0_ref3; /* 0x280 */ + struct cl_agc_reg lna_icp1_set0_ref2; /* 0x284 */ + struct cl_agc_reg lna_icp1_set0_ref3; /* 0x288 */ + struct cl_agc_reg fsm_preset_p10; /* 0x2A8 */ + struct cl_agc_reg fsm_preset_p11; /* 0x2AC */ + struct cl_agc_reg fsm_preset_p12; /* 0x2B0 */ + struct cl_agc_reg ant_loss; /* 0x300 */ + struct cl_agc_reg gain_range; /* 0x304 */ + struct cl_agc_reg vga_ref0; /* 0x308 */ + struct cl_agc_reg lna_gain_set0_ref0; /* 0x30C */ + struct cl_agc_reg lna_gain_set0_ref1; /* 0x310 */ + struct cl_agc_reg lna_thr_set0_ref0; /* 0x314 */ + struct cl_agc_reg lna_thr_set0_ref1; /* 0x318 */ + struct cl_agc_reg lna_thr_set1_ref0; /* 0x31C */ + struct cl_agc_reg lna_thr_set1_ref1; /* 0x320 */ + struct cl_agc_reg lna_thr_set2_ref0; /* 0x324 */ + struct cl_agc_reg lna_thr_set2_ref1; /* 0x328 */ + struct cl_agc_reg lna_nf_set0_ref0; /* 0x32C */ + struct cl_agc_reg lna_nf_set0_ref1; /* 0x330 */ + struct cl_agc_reg lna_icp1_set0_ref0; /* 0x334 */ + struct cl_agc_reg lna_icp1_set0_ref1; /* 0x338 */ + struct cl_agc_reg saturation; /* 0x364 */ + struct cl_agc_reg ramp; /* 0x36C */ + struct cl_agc_reg dsp0; /* 0x394 */ + struct cl_agc_reg dsp1; /* 0x398 */ + struct cl_agc_reg dsp2; /* 0x39C */ + struct cl_agc_reg dsp3; /* 0x3A0 */ + struct cl_agc_reg lna_gain_set1_ref0; /* 0x590 */ + struct cl_agc_reg lna_gain_set1_ref1; /* 0x594 */ + struct cl_agc_reg lna_gain_set1_ref2; /* 0x598 */ + struct cl_agc_reg lna_gain_set1_ref3; /* 0x59c */ + struct cl_agc_reg lna_nf_set1_ref0; /* 0x5A0 */ + struct cl_agc_reg lna_nf_set1_ref1; /* 0x5A4 */ + struct cl_agc_reg lna_nf_set1_ref2; /* 0x5A8 */ + struct cl_agc_reg lna_nf_set1_ref3 ; /* 0x5AC */ + struct cl_agc_reg lna_icp1_set1_ref0; /* 0x5B0 */ + struct cl_agc_reg lna_icp1_set1_ref1; /* 0x5B4 */ + struct cl_agc_reg lna_icp1_set1_ref2; /* 0x5B8 */ + struct cl_agc_reg lna_icp1_set1_ref3 ;/* 0x5BC */ +}; + +struct cl_agc_profile_per_bw { + u32 id; + struct cl_agc_regs regs[CHNL_BW_MAX]; +}; + +struct cl_agc_profile { + u32 id; + struct cl_agc_regs regs; +}; + +struct cl_agc_params { + u8 num_profiles; + u8 ant_mask1; + u8 ant_mask2; + struct cl_agc_profile profile1; + struct cl_agc_profile profile2; +}; + +struct cl_chip; + +int cl_agc_params_read_platform_id(struct cl_chip *chip); +int cl_agc_params_fill(struct cl_hw *cl_hw, struct cl_agc_params *agc_params); +void cl_agc_params_dump_profile_id(char *buf, ssize_t buf_size, ssize_t *len, + u32 id, const char *str); + +#endif /* CL_PLATFORM_H */ From patchwork Tue May 24 11:34:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576844 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 ECAE2C433EF for ; Tue, 24 May 2022 11:40:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236887AbiEXLkF (ORCPT ); Tue, 24 May 2022 07:40:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236352AbiEXLj7 (ORCPT ); Tue, 24 May 2022 07:39:59 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50088.outbound.protection.outlook.com [40.107.5.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 682CC84A19 for ; Tue, 24 May 2022 04:39:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QvqZ1xXTNzZaiXnRLrs0LTAp8zADMj76U9yVCRv8GlNWEGZv6AQTBnNb1zDrz0+3Pu2Le80gVcH+Wuy0279SE5Bz0dh7ARLVHN03LK1THWeVbUtV94Wt8xHXlWzirgCGj8YEJqmaqun7+VutI1+kfT+pE1d60MYbZYCUT3DrcymC4nOi5d+OPk2sRzb1C/sARin+C298grM277Uj6muSBxxGl/BvDH20jV13m7JdUTWfh61OCo9kjYDiePyLyFNERXRfxh/UGJe+ZKw528wBQBmJde1RK3XTe6/v60IU40r8T40YaH47fKikRoZ/p0CSR1KrJk8GYj0YxxtT2WSbNA== 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=hVF/eLK5F0zynKTKaRr0M8gz7HAmsb11dMH/03d49gA=; b=MMnZhBzYHnaiCiy3Lm6QKIKX6qkoh6abINZdhD4gdpPRgCghDDBIZ4yYyrTUElrjz15DKCDOz0s70hTO2wCqjILsJR7yBZHlCvT+si1stxGHitCMx0kx4sV23NdDnXvbwi3HwNizSt6az+cKU6TiF3fSr1/e8QSvM42XVFGElxnoSkEHuHsk0IcAdMtyMQEIpPqMZyrmcLb9LHP1V/SfD0ttSb52S8SJcjn6ICOfewE8w5Kswq74PA4L6PR+mOY9DVTRDku+0VXQyO4F8RZtVwrqow0Hx3pIDerLnZPDKYq//6d7B9GPkyMIJjBngkIxelXZq1koioS5HQBdaviS+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hVF/eLK5F0zynKTKaRr0M8gz7HAmsb11dMH/03d49gA=; b=mtJ0Ug+fXOz9+BEPVZl86UyaCSg3+Bvn5I/+x9B4Cbqub9AMl4F5rNe/chpbqKz6xEykjYwHDqkmxASQ20RkoayJFMZjBXChJrJcTaD/AJEosBP7T6UogbFUUX1578dA9z2b9fGYgv6CGu0yMYEBZ1zGbhpxG/03orVOe1/uG+Q= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:50 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:50 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 54/96] cl8k: add power.c Date: Tue, 24 May 2022 14:34:20 +0300 Message-Id: <20220524113502.1094459-55-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b9b2b9f4-446c-49ae-599c-08da3d79ee5b X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +egcCvViSMd7Endnutu+yOKKN7tWFXduu4A21qHal/RHWw/sc1IMIhaPIlVcZ0ODoIAwdLxo1bkoCcipqw5k7xX2CqS6rAUb/GzgG4vkjNufQLinfTDiJVzaBQMaR9F6lAWetYAh1mE9fHYpVMd+yj0EOf3bcvqvuvCEFBPdNusByy16CYukiD7wd6IGRggRkc7gSnTmkRg0vO+YhEBjVG3SIsWbvBTqkAQD1H+jcOFmVvYQcrNzZjZIApnPkST9En245e2sUEqo2GpmSTsLvbaQ/xkbreXwtvqGEgSyeJHLxDQTkN4pITC3tYH42/OQ7SnCEIuePvCEURbB9FxqghtnVQiRF6SuPPMBT7jg8HdjRKI7dAP4yLV+g9hMfQ7ZkweP9fqCPvsQDQ10EU4eC7Ub8ZnMKKYol5G/TAbyek8gLI5zcd0XxUaR/HSc2Fnew3yxx2FxuvhG8HU6FWrDYRe+Ty24lmhyJvnktvW+Ch+3wRv9ryHagmIeUlp2plCoV1tQsmSu24eSqE1fU+962f0L8FV4Quza4BtcOmGy3TLTH3W/jfG/JHlfpo61cDvPHAwIN9oHCXFNq4bNJI2JGRGqyjpWxTkm5F9/lED2e1D49w2JIYpCnncmbyIYu3hjUG17oA9stf9f/ykgBnMtVTB3EQzWn0Rj9DR2SZ8SXo1V2C/U0J95zFHZ6LN13Gmmc9Xy9lH6KHekAUkPO8DivK7rZKosVonq8X4f8IEuceo= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: K0+gLve4m0zVBbgMqfkoBrJftqROBRZVYZToBNcblI7B8aVQvoDx4+9vDtpfzh7IWQ0X71Xxw7d1DKyVSHLVl5Oh86KQaRVHt5ZmvDJfweqjfrAH0LCDCaOyKTzpTnWLJWHRDbC/NIfrcwJv7Ej4kcx7d60aEI9UbWHKZv07wRBScXSQzT8a3xKWIdneQv7Cgwnex7+5BbKkFkV1w+WFLv/HLq0QTUw5ddWIF5/fZhR/upQbXvhJrcYZVtdsoTLsjPKbzV/cYvDJpzb9n2AWAF7Plt/p5YtgNckVWSp3vyOeZ57GvperIW0yPuBuD/okLCcIysmZZ/yz5ghvQ000/hGzXbKv1qv3p1tIZGK6WqlXzO9xSMljzK+qafsnWKk0oiaUAizwBfD57zgkYFFNHa/02yhR4uPegnGn/NM0o14hA8GxQ7zxrnfIOvjzv3ucpE6MzgaSN29jxvAzhW0N/rg4aoMZgaN0GuM4zV/OBsfYYMImstOfX/LOHQnhKAGhxYRaMs3Tnf05xjQHWzFctethnd2RFrw2jD43S+OE3KJYEOT+R+Pus4VtovXWnAP9jSHUgIrnpS+qrEzRzj17+MbJNdc5CVyKmcMdUJ+3iU3hLxEnsSj1yMgLsI3MNyf0XZu9VAOakxcizq0vXDZcAbUO58/Yq/7Nr/JCBfVkZEEgleMfL1SsE1ERrPN47LhhrXK1pkPJPzZXL9LeHmpw9h2mGA5ZPPlwMgErptP+HqqXiMwdCec0KX5TOj9Qa+c48NGz8E01k84nbu7SS6NquFxKCYitG7QIsgqdoA/IhF1FiU1BCTwiwsb6MhLhP8YutPngpj6ODWGU3x1Iir/L4d0nVDNx5jwzTjlAyAJDPVSnBLlvKlIq/oQWI8LAaluF/OFKgVpodqUCPOio5MBQ1jOEsQMp2YeUpUlhNW69bXXCGh8PtbmBMZILhN4iKqDWeUuOmebt2HfW05hAyoDwphBtco9PZnS8rtY/pZ0JH34TrnO/T3Xixr/zm6aXKRtPwspJIRE37NJkkx1FC/Dt9x96ELHeBZzGa7e7gHn0E5XiM+SvXvAAJQFpNaalVeDbkJWoR4z+VWYRPIjSmx9pN5WoEjWiwqtyO3FHkQA6MnnBVSFtjKU5u2l0+K2Lpf6gNgQ7U9XCuahSnfONerE/i+8Ub5OXnU14HmW3r7j8eEqRZ0Auis/ZzsiUia63XnnQ1kqBxnyxbTkkJoK4wb3Ww0+S0L6TaVOtVxLbjyjmaDvg6G5Lj4L2DGga2nqbwQXbgTgW3Z7xPZF9GYxHZLiXCzVDzffe86LO0vsvqWPUxIMEMbAjkPa7avvE0ecjtQel/xeItGXgseuIx9JzN+rNjukLvswfM9TGeO7jG25u2tTijnH0DmZUlbbLzYn4Q6UPIWY8HyIRL7APzNCczMu0kclzU1Xvrfn6MG7KtKrumm2wg4SNADYO5szJy388FbNRDue7ZAsbqIye8KRAfxBe2hY2XErAcPHqopSdIpemszv8wK/J2T+mkneVOIPtB7Fa9qr5LMF+zae+pej439kClQNQ/9dX1RBJzaK7WglisKDKE3Sj1/jG/ycLz+m5FwBbq9Oobm5Af+ECfcFabQ+tt2pu6dIuTgoQ45vspxNXv8p7j2grAuqKRWi/Da8F/x/D+47AQiOyeIxw+k7TU+1xzqUjmr5YopjqVe5N9E2NRFlP4VN6xGAlhb2/PtJyMH32relS9C7CNfFlaLy8sJWsphEHxMXPIFWhpvnBHtz1IOw= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9b2b9f4-446c-49ae-599c-08da3d79ee5b X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:32.7522 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: +72NWNSvdU4/9hC+Ldm+htdv7weCo1ozAz+WbYE4FLzLQAww/HYC4dd32jUzG5x6duVGlmd8Mpe19Y2A0w4AHg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/power.c | 1123 ++++++++++++++++++++++ 1 file changed, 1123 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/power.c diff --git a/drivers/net/wireless/celeno/cl8k/power.c b/drivers/net/wireless/celeno/cl8k/power.c new file mode 100644 index 000000000000..ef62c4b7a332 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/power.c @@ -0,0 +1,1123 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_access.h" +#include "channel.h" +#include "debug.h" +#include "utils.h" +#include "e2p.h" +#include "power.h" + +static u8 cl_power_table_read(struct cl_hw *cl_hw) +{ + u8 pwr_table_id = 0; + + if (cl_e2p_read(cl_hw->chip, &pwr_table_id, 1, ADDR_GEN_PWR_TABLE_ID + cl_hw->tcv_idx)) + return U8_MAX; + + return pwr_table_id; +} + +static int cl_power_table_fill(struct cl_hw *cl_hw) +{ + u8 pwr_table_id = cl_power_table_read(cl_hw); + u8 platform_idx = cl_hw->chip->platform.idx; + struct cl_platform_table *table = NULL; + + table = cl_platform_get_active_table(cl_hw->chip, platform_idx); + if (!table) + return cl_hw->chip->conf->ce_production_mode ? 0 : -1; + + switch (pwr_table_id) { + case 0: + if (cl_band_is_5g(cl_hw)) { + memcpy(cl_hw->power_table_info.data->conv_table, + table->power_conv_table_5, + NUM_POWER_WORDS); + cl_hw->tx_power_version = 5; + } else if (IS_REAL_PHY(cl_hw->chip)) { + CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 5g only\n", + pwr_table_id); + + if (!cl_hw_is_prod_or_listener(cl_hw)) + return -EINVAL; + } + break; + case 1: + if (cl_band_is_24g(cl_hw)) { + memcpy(cl_hw->power_table_info.data->conv_table, + table->power_conv_table_2, + NUM_POWER_WORDS); + cl_hw->tx_power_version = 25; + } else if (IS_REAL_PHY(cl_hw->chip)) { + CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 2.4g only\n", + pwr_table_id); + + if (!cl_hw_is_prod_or_listener(cl_hw)) + return -1; + } + break; + case 2: + if (cl_band_is_6g(cl_hw)) { + memcpy(cl_hw->power_table_info.data->conv_table, + table->power_conv_table_6, + NUM_POWER_WORDS); + cl_hw->tx_power_version = 1; + } else if (IS_REAL_PHY(cl_hw->chip)) { + CL_DBG_ERROR(cl_hw, "Power table ID (%u) is valid for 6g only\n", + pwr_table_id); + + if (!cl_hw_is_prod_or_listener(cl_hw)) + return -1; + } + break; + default: + if (IS_REAL_PHY(cl_hw->chip)) { + CL_DBG_ERROR(cl_hw, "Power table ID is not configured in EEPROM\n"); + + if (!cl_hw_is_prod_or_listener(cl_hw)) + return -1; + } + } + + cl_dbg_verbose(cl_hw, "Power table ID %u (V%u)\n", pwr_table_id, cl_hw->tx_power_version); + + return 0; +} + +int cl_power_table_alloc(struct cl_hw *cl_hw) +{ + struct cl_power_table_data *buf = NULL; + u32 len = sizeof(struct cl_power_table_data); + dma_addr_t phys_dma_addr; + + buf = dma_alloc_coherent(cl_hw->chip->dev, len, &phys_dma_addr, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + cl_hw->power_table_info.data = buf; + cl_hw->power_table_info.dma_addr = phys_dma_addr; + + return cl_power_table_fill(cl_hw); +} + +void cl_power_table_free(struct cl_hw *cl_hw) +{ + struct cl_power_table_info *power_table_info = &cl_hw->power_table_info; + u32 len = sizeof(struct cl_power_table_data); + dma_addr_t phys_dma_addr = power_table_info->dma_addr; + + if (!power_table_info->data) + return; + + dma_free_coherent(cl_hw->chip->dev, len, (void *)power_table_info->data, phys_dma_addr); + power_table_info->data = NULL; +} + +static s32 convert_str_int_q8(s8 *str) +{ + s32 x, y; + + if (!str) + return 0; + if (sscanf(str, "%d.%2d", &x, &y) == 0) + return 0; + if (!strstr(str, ".")) + return x << 8; + if (y < 10 && (*(strstr(str, ".") + 1) != '0')) + y *= 10; + return ((x * 100 + y) << 8) / 100; +} + +u8 cl_power_tx_ant(struct cl_hw *cl_hw, enum cl_wrs_mode mode) +{ + if (mode == WRS_MODE_CCK) + return hweight8(cl_hw->conf->ce_cck_tx_ant_mask); + + if (mode <= WRS_MODE_VHT) + return min_t(u8, cl_hw->num_antennas, MAX_ANTENNAS_OFDM_HT_VHT); + + return cl_hw->num_antennas; +} + +s32 cl_power_antenna_gain_q8(struct cl_hw *cl_hw) +{ + u8 channel = cl_hw->channel; + + if (channel >= 36 && channel <= 64) + return convert_str_int_q8(cl_hw->conf->ce_ant_gain_36_64); + else if (channel >= 100 && channel <= 140) + return convert_str_int_q8(cl_hw->conf->ce_ant_gain_100_140); + else if (channel >= 149 && channel < 165) + return convert_str_int_q8(cl_hw->conf->ce_ant_gain_149_165); + else + return convert_str_int_q8(cl_hw->conf->ce_ant_gain); /* 2.4g and 6g */ +} + +s32 cl_power_antenna_gain_q1(struct cl_hw *cl_hw) +{ + return cl_power_antenna_gain_q8(cl_hw) >> 7; +} + +s32 cl_power_array_gain_q8(struct cl_hw *cl_hw, u8 tx_ant) +{ + /* + * Format in NVRAM of ce_arr_gain=A,B,C,D,E,F + * A is the array gain with 1 tx_ant, B is with 2 tx_ant and so on... + */ + int arr_gain_val = 0; + int arr_gain_len = 0; + int idx = 0; + char *arr_gain_cpy = NULL; + char *arr_gain_cpy_p = NULL; + char *arr_gain_str = NULL; + + arr_gain_len = strlen(cl_hw->conf->ce_arr_gain) + 1; + arr_gain_cpy_p = kzalloc(arr_gain_len, GFP_ATOMIC); + arr_gain_cpy = arr_gain_cpy_p; + + if (!arr_gain_cpy) + return 0; + + /* Copy cl_hw->conf->ce_arr_gain so its value won't be changed by strsep() */ + memcpy(arr_gain_cpy, cl_hw->conf->ce_arr_gain, arr_gain_len); + + /* Arr_gain_str points to the array gain of 1 tx_ant */ + arr_gain_str = strsep(&arr_gain_cpy, ","); + + /* Only a single value in ce_arr_gain - same value will be applied for all tx_ant */ + if (!arr_gain_cpy) { + arr_gain_val = convert_str_int_q8(arr_gain_str); + } else { + /* Keep iterating until getting to the correct ant idx */ + for (idx = 1; arr_gain_str && (idx < tx_ant); idx++) + arr_gain_str = strsep(&arr_gain_cpy, ","); + + arr_gain_val = arr_gain_str ? convert_str_int_q8(arr_gain_str) : 0; + } + + kfree(arr_gain_cpy_p); + + return arr_gain_val; +} + +s8 cl_power_array_gain_q2(struct cl_hw *cl_hw, u8 tx_ant) +{ + return (s8)(cl_power_array_gain_q8(cl_hw, tx_ant) >> 6); +} + +s32 cl_power_array_gain_q1(struct cl_hw *cl_hw, u8 tx_ant) +{ + return cl_power_array_gain_q8(cl_hw, tx_ant) >> 7; +} + +static s32 cl_power_bf_gain_q8(struct cl_hw *cl_hw, u8 tx_ant, u8 nss) +{ + /* + * Format in NVRAM of ce_bf_gain=A,B,C,D + * A is the bf gain with 1 NSS, B is with 2 NSS and so on... + */ + int bf_gain_val = 0; + int bf_gain_len = 0; + int idx = 0; + char *bf_gain_cpy = NULL; + char *bf_gain_cpy_p = NULL; + char *bf_gain_str = NULL; + s8 *bf_gain_ptr = NULL; + + if (tx_ant == 6) { + bf_gain_ptr = cl_hw->conf->ce_bf_gain_6_ant; + } else if (tx_ant == 5) { + bf_gain_ptr = cl_hw->conf->ce_bf_gain_5_ant; + } else if (tx_ant == 4) { + bf_gain_ptr = cl_hw->conf->ce_bf_gain_4_ant; + } else if (tx_ant == 3) { + bf_gain_ptr = cl_hw->conf->ce_bf_gain_3_ant; + } else if (tx_ant == 2) { + bf_gain_ptr = cl_hw->conf->ce_bf_gain_2_ant; + } else if (tx_ant == 1) { + goto out; + } else { + pr_err("[%s]: invalid tx_ant %u\n", __func__, tx_ant); + goto out; + } + + bf_gain_len = strlen(bf_gain_ptr) + 1; + bf_gain_cpy_p = kzalloc(bf_gain_len, GFP_ATOMIC); + bf_gain_cpy = bf_gain_cpy_p; + + if (!bf_gain_cpy) + return 0; + + /* Copy cl_hw->conf->ce_bf_gain_*_ant so its value won't be changed by strsep() */ + memcpy(bf_gain_cpy, bf_gain_ptr, bf_gain_len); + + /* Bf_gain_str points to the bf gain of 1 SS */ + bf_gain_str = strsep(&bf_gain_cpy, ","); + + /* Keep iterating until getting to the correct ss index */ + for (idx = 0; bf_gain_str && (idx < nss); idx++) + bf_gain_str = strsep(&bf_gain_cpy, ","); + + bf_gain_val = bf_gain_str ? convert_str_int_q8(bf_gain_str) : 0; + + kfree(bf_gain_cpy_p); + out: + return bf_gain_val; +} + +s32 cl_power_bf_gain_q1(struct cl_hw *cl_hw, u8 tx_ant, u8 nss) +{ + return cl_power_bf_gain_q8(cl_hw, tx_ant, nss) >> 7; +} + +static s32 cl_power_min_ant_q8(struct cl_hw *cl_hw) +{ + return convert_str_int_q8(cl_hw->conf->ci_min_ant_pwr); +} + +s32 cl_power_min_ant_q1(struct cl_hw *cl_hw) +{ + return cl_power_min_ant_q8(cl_hw) >> 7; +}; + +s8 cl_power_bw_factor_q2(struct cl_hw *cl_hw, u8 bw) +{ + /* + * Format in NVRAM of ci_bw_factor=A,B,C,D + * A is the bw factor for bw 20MHz, B is for 40MHz and so on.. + */ + int bw_factor_val = 0; + int bw_factor_len = 0; + int idx = 0; + char *bw_factor_cpy = NULL; + char *bw_factor_cpy_p = NULL; + char *bw_factor_str = NULL; + + bw_factor_len = strlen(cl_hw->conf->ci_bw_factor) + 1; + bw_factor_cpy = kzalloc(bw_factor_len, GFP_ATOMIC); + bw_factor_cpy = bw_factor_cpy_p; + + if (!bw_factor_cpy) + return 0; + + /* Copy cl_hw->conf->ci_bw_factor so its value won't be changed by strsep() */ + memcpy(bw_factor_cpy, cl_hw->conf->ci_bw_factor, bw_factor_len); + + /* Bw_factor_str points to the bw factor of 20MHz */ + bw_factor_str = strsep(&bw_factor_cpy, ","); + + /* Only a single value in ci_bw_factor - same value will be applied for all bandwidths */ + if (!bw_factor_cpy) { + bw_factor_val = convert_str_int_q8(bw_factor_str); + } else { + /* Keep iterating until getting to the correct bw index */ + for (idx = 0; bw_factor_str && (idx < bw); idx++) + bw_factor_str = strsep(&bw_factor_cpy, ","); + + bw_factor_val = bw_factor_str ? convert_str_int_q8(bw_factor_str) : 0; + } + + kfree(bw_factor_cpy_p); + + return (s8)(bw_factor_val >> 6); +} + +static s32 cl_power_average_calib_q8(struct cl_hw *cl_hw, u8 ant_num) +{ + u8 ant = 0, ant_cnt = 0; + u8 chan_idx = cl_channel_to_index(cl_hw, cl_hw->channel); + s32 total_calib_pow = 0; + + if (chan_idx == INVALID_CHAN_IDX) + return 0; + + for (ant = 0; ant < MAX_ANTENNAS && ant_cnt < ant_num; ant++) { + if (!(cl_hw->mask_num_antennas & BIT(ant))) + continue; + + total_calib_pow += cl_hw->tx_pow_info[chan_idx][ant].power; + ant_cnt++; + } + + return ((total_calib_pow << 8) / ant_num); +} + +s32 cl_power_average_calib_q1(struct cl_hw *cl_hw, u8 ant_num) +{ + return cl_power_average_calib_q8(cl_hw, ant_num) >> 7; +} + +static s32 cl_power_total_q8(struct cl_hw *cl_hw, s8 pwr_offset_q1, u8 tx_ant, u8 nss, + enum cl_wrs_mode mode, bool is_auto_resp) +{ + s32 bf_gain_q8 = 0; + s32 antenna_gain_q8 = cl_power_antenna_gain_q8(cl_hw); + s32 array_gain_q8 = cl_power_array_gain_q8(cl_hw, tx_ant); + s32 pwr_offset_q8 = (s32)pwr_offset_q1 << 7; + s32 calib_power_q8 = cl_power_average_calib_q8(cl_hw, tx_ant); + s32 total_power_q8 = 0; + + if (!is_auto_resp) + bf_gain_q8 = (mode > WRS_MODE_OFDM) ? cl_power_bf_gain_q8(cl_hw, tx_ant, nss) : 0; + + total_power_q8 = calib_power_q8 + bf_gain_q8 + array_gain_q8 + + antenna_gain_q8 + pwr_offset_q8; + + /* FCC calculation */ + if (cl_hw->channel_info.standard == NL80211_DFS_FCC) + total_power_q8 -= min(bf_gain_q8 + antenna_gain_q8, 6 << 8); + + return total_power_q8; +} + +static s32 cl_power_eirp_delta_q1(struct cl_hw *cl_hw, u8 bw, s8 pwr_offset_q1, u8 tx_ant, + u8 nss, enum cl_wrs_mode mode, bool is_auto_resp) +{ + /* Calculate total TX power */ + s32 total_power_q8 = cl_power_total_q8(cl_hw, pwr_offset_q1, tx_ant, nss, + mode, is_auto_resp); + + /* EIRP power limit */ + s32 eirp_power_limit_q8 = cl_chan_info_get_eirp_limit_q8(cl_hw, bw); + + /* Delta between total TX power and EIRP limit */ + return (total_power_q8 - eirp_power_limit_q8) >> 7; +} + +static s8 cl_power_calc_q1(struct cl_hw *cl_hw, s8 mcs_offset_q1, u8 bw, u8 nss, + enum cl_wrs_mode mode, bool is_auto_resp, u8 *trunc_pwr_q1) +{ + /* Result is in 0.5dBm resolution */ + u8 tx_ant = cl_power_tx_ant(cl_hw, mode); + s32 calib_power_q1 = cl_power_average_calib_q1(cl_hw, tx_ant); + s32 res_q1 = calib_power_q1 + mcs_offset_q1; + s32 min_pwr_q1 = POWER_MIN_DB_Q1; + u32 trunc_pwr_val_q1 = 0; + bool eirp_regulatory_en = cl_hw->chip->conf->ce_production_mode ? + cl_hw->conf->ce_eirp_regulatory_prod_en : cl_hw->conf->ce_eirp_regulatory_op_en; + + if (cl_hw->channel_info.use_channel_info && eirp_regulatory_en) { + s32 delta_power_q1 = cl_power_eirp_delta_q1(cl_hw, bw, mcs_offset_q1, + tx_ant, nss, mode, is_auto_resp); + + if (delta_power_q1 > 0) { + /* + * If tx power is greater than the limitation + * subtract delta power from the result + */ + res_q1 -= delta_power_q1; + trunc_pwr_val_q1 = delta_power_q1; + } + } + + if (is_auto_resp) + min_pwr_q1 += cl_power_min_ant_q1(cl_hw); + + if (res_q1 < min_pwr_q1) { + trunc_pwr_val_q1 = max((s32)trunc_pwr_val_q1 - min_pwr_q1 - res_q1, 0); + res_q1 = min_pwr_q1; + } + + if (is_auto_resp) + res_q1 += cl_power_array_gain_q1(cl_hw, tx_ant); + + if (trunc_pwr_q1) + *trunc_pwr_q1 = (u8)trunc_pwr_val_q1; + + return (s8)res_q1; +} + +static s8 cl_power_offset_he(struct cl_hw *cl_hw, u8 bw, u8 mcs) +{ + u8 channel = cl_hw->channel; + s8 *ppmcs = NULL; + + switch (cl_hw->conf->ci_band_num) { + case BAND_5G: + if (channel >= 36 && channel <= 64) + ppmcs = cl_hw->conf->ce_ppmcs_offset_he_36_64; + else if (channel >= 100 && channel <= 140) + ppmcs = cl_hw->conf->ce_ppmcs_offset_he_100_140; + else + ppmcs = cl_hw->conf->ce_ppmcs_offset_he_149_165; + break; + case BAND_24G: + ppmcs = cl_hw->conf->ce_ppmcs_offset_he; + break; + case BAND_6G: + ppmcs = cl_hw->conf->ce_ppmcs_offset_he_6g; + break; + default: + return 0; + } + + return ppmcs[mcs] + cl_hw->conf->ce_ppbw_offset[bw]; +} + +static s8 cl_power_offset_ht_vht(struct cl_hw *cl_hw, u8 bw, u8 mcs) +{ + u8 channel = cl_hw->channel; + s8 *ppmcs = NULL; + + switch (cl_hw->conf->ci_band_num) { + case BAND_5G: + if (channel >= 36 && channel <= 64) + ppmcs = cl_hw->conf->ce_ppmcs_offset_ht_vht_36_64; + else if (channel >= 100 && channel <= 140) + ppmcs = cl_hw->conf->ce_ppmcs_offset_ht_vht_100_140; + else + ppmcs = cl_hw->conf->ce_ppmcs_offset_ht_vht_149_165; + break; + case BAND_24G: + ppmcs = cl_hw->conf->ce_ppmcs_offset_ht; + break; + case BAND_6G: + default: + return 0; + } + + return ppmcs[mcs] + cl_hw->conf->ce_ppbw_offset[bw]; +} + +static s8 cl_power_offset_ofdm(struct cl_hw *cl_hw, u8 mcs) +{ + u8 channel = cl_hw->channel; + s8 *ppmcs = NULL; + + switch (cl_hw->conf->ci_band_num) { + case BAND_5G: + if (channel >= 36 && channel <= 64) + ppmcs = cl_hw->conf->ce_ppmcs_offset_ofdm_36_64; + else if (channel >= 100 && channel <= 140) + ppmcs = cl_hw->conf->ce_ppmcs_offset_ofdm_100_140; + else + ppmcs = cl_hw->conf->ce_ppmcs_offset_ofdm_149_165; + break; + case BAND_24G: + ppmcs = cl_hw->conf->ce_ppmcs_offset_ofdm; + break; + case BAND_6G: + default: + return 0; + } + + return ppmcs[mcs] + cl_hw->conf->ce_ppbw_offset[CHNL_BW_20]; +} + +static s8 cl_power_offset_cck(struct cl_hw *cl_hw, u8 mcs) +{ + s8 *ppmcs = cl_hw->conf->ce_ppmcs_offset_cck; + + if (cl_band_is_24g(cl_hw)) + return ppmcs[mcs] + cl_hw->conf->ce_ppbw_offset[CHNL_BW_20]; + + return 0; +} + +s8 cl_power_offset_q1(struct cl_hw *cl_hw, u8 mode, u8 bw, u8 mcs) +{ + if (mode == WRS_MODE_HE) + return cl_power_offset_he(cl_hw, bw, mcs); + else if (mode == WRS_MODE_HT || mode == WRS_MODE_VHT) + return cl_power_offset_ht_vht(cl_hw, bw, mcs); + else if (mode == WRS_MODE_OFDM) + return cl_power_offset_ofdm(cl_hw, mcs); + else if (mode == WRS_MODE_CCK) + return cl_power_offset_cck(cl_hw, mcs); + + return 0; +} + +#define UPPER_POWER_MARGIN_Q2 (38 << 2) +#define LOWER_POWER_MARGIN_Q2 (50 << 2) + +s8 cl_power_offset_check_margin(struct cl_hw *cl_hw, u8 bw, u8 ant_idx, s8 offset_q2) +{ + s8 new_offset_q2 = 0; + s8 bw_factor_q2 = cl_hw->power_db.bw_factor_q2[bw]; + s8 ant_factor_q2 = cl_hw->power_db.ant_factor_q2[ant_idx]; + s8 total_offset_upper_q2 = bw_factor_q2 + offset_q2; + s8 total_offset_lower_q2 = bw_factor_q2 + ant_factor_q2 + offset_q2; + bool upper_limit_valid = (total_offset_upper_q2 <= UPPER_POWER_MARGIN_Q2); + bool lower_limit_valid = (total_offset_lower_q2 <= LOWER_POWER_MARGIN_Q2); + + if (upper_limit_valid && lower_limit_valid) { + return offset_q2; + } else if (!upper_limit_valid && lower_limit_valid) { + new_offset_q2 = UPPER_POWER_MARGIN_Q2 - bw_factor_q2; + + return new_offset_q2; + } else if (upper_limit_valid && !lower_limit_valid) { + new_offset_q2 = LOWER_POWER_MARGIN_Q2 - bw_factor_q2 - ant_factor_q2; + + return new_offset_q2; + } + + new_offset_q2 = min(UPPER_POWER_MARGIN_Q2 - bw_factor_q2, + LOWER_POWER_MARGIN_Q2 - bw_factor_q2 - ant_factor_q2); + + return new_offset_q2; +} + +static s32 cl_power_calc_total_from_eirp_q1(struct cl_hw *cl_hw, s32 tx_power, u8 nss, + enum cl_wrs_mode mode, u8 *trunc_pwr_q1) +{ + s32 pwr_q1, total_pwr_q1, delta_pwr_q1 = 0; + u8 tx_ant; + s32 antenna_gain_q1; + s32 array_gain_q1; + s32 bf_gain_q1; + bool eirp_regulatory_en = cl_hw->chip->conf->ce_production_mode ? + cl_hw->conf->ce_eirp_regulatory_prod_en : cl_hw->conf->ce_eirp_regulatory_op_en; + + pwr_q1 = tx_power << 1; + + tx_ant = cl_power_tx_ant(cl_hw, mode); + array_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + antenna_gain_q1 = cl_power_antenna_gain_q1(cl_hw); + /* bf gain is not used for CCK or OFDM */ + bf_gain_q1 = (mode > WRS_MODE_OFDM) ? cl_power_bf_gain_q1(cl_hw, tx_ant, nss) : 0; + + /* FCC calculation */ + if (cl_hw->channel_info.standard == NL80211_DFS_FCC) + pwr_q1 -= min(bf_gain_q1 + antenna_gain_q1, 6 << 1); + + if (cl_hw->channel_info.use_channel_info && eirp_regulatory_en) { + s32 eirp_pwr_limit_q1; + + eirp_pwr_limit_q1 = cl_chan_info_get_eirp_limit_q8(cl_hw, 0) >> 7; + if (pwr_q1 > eirp_pwr_limit_q1) { + delta_pwr_q1 = pwr_q1 - eirp_pwr_limit_q1; + pwr_q1 = eirp_pwr_limit_q1; + } + } + + total_pwr_q1 = pwr_q1 - antenna_gain_q1 - array_gain_q1 - bf_gain_q1; + if (total_pwr_q1 < POWER_MIN_DB_Q1) { + delta_pwr_q1 = max(delta_pwr_q1 - (POWER_MIN_DB_Q1 - total_pwr_q1), 0); + total_pwr_q1 = POWER_MIN_DB_Q1; + } + + if (trunc_pwr_q1) + *trunc_pwr_q1 = (u8)delta_pwr_q1; + + return total_pwr_q1; +} + +static s32 cl_power_calc_auto_resp_from_eirp_q1(struct cl_hw *cl_hw, s32 tx_power, u8 nss, + enum cl_wrs_mode mode) +{ + s32 auto_resp_total_pwr_q1, auto_resp_min_pwr_q1; + u8 tx_ant; + s32 array_gain_q1; + s32 total_pwr_q1; + + auto_resp_min_pwr_q1 = POWER_MIN_DB_Q1 + cl_power_min_ant_q1(cl_hw); + tx_ant = cl_power_tx_ant(cl_hw, mode); + array_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + total_pwr_q1 = cl_power_calc_total_from_eirp_q1(cl_hw, tx_power, nss, mode, NULL); + + auto_resp_total_pwr_q1 = array_gain_q1 + total_pwr_q1; + if (auto_resp_total_pwr_q1 < auto_resp_min_pwr_q1) + auto_resp_total_pwr_q1 = auto_resp_min_pwr_q1; + + return auto_resp_total_pwr_q1; +} + +static s8 cl_calc_ant_pwr_q1(struct cl_hw *cl_hw, u8 bw, u8 nss, u8 mcs, + enum cl_wrs_mode mode, u8 *trunc_val) +{ + s32 eirp_pwr = 0; + s8 ant_pwr_q1; + + eirp_pwr = cl_hw->new_tx_power; + if (eirp_pwr) { + ant_pwr_q1 = cl_power_calc_total_from_eirp_q1(cl_hw, eirp_pwr, nss, + mode, trunc_val); + } else { + s8 pwr_offset_q1; + + pwr_offset_q1 = cl_power_offset_q1(cl_hw, mode, bw, mcs); + ant_pwr_q1 = cl_power_calc_q1(cl_hw, pwr_offset_q1, bw, nss, + mode, false, trunc_val); + } + return ant_pwr_q1; +} + +static s8 cl_calc_auto_resp_pwr_q1(struct cl_hw *cl_hw, u8 bw, u8 nss, u8 mcs, + enum cl_wrs_mode mode) +{ + s32 eirp_pwr = 0; + s8 auto_resp_pwr_q1; + + eirp_pwr = cl_hw->new_tx_power; + if (eirp_pwr) { + auto_resp_pwr_q1 = cl_power_calc_auto_resp_from_eirp_q1(cl_hw, eirp_pwr, + nss, mode); + } else { + s8 pwr_offset_q1; + + pwr_offset_q1 = cl_power_offset_q1(cl_hw, mode, bw, mcs); + auto_resp_pwr_q1 = cl_power_calc_q1(cl_hw, pwr_offset_q1, bw, nss, + mode, true, NULL); + } + return auto_resp_pwr_q1; +} + +static void cl_power_tables_update_cck(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables) +{ + u8 mcs; + u8 trunc_value = 0; + + /* CCK - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_CCK; mcs++) { + pwr_tables->ant_pwr_cck[mcs] = cl_calc_ant_pwr_q1(cl_hw, 0, 0, mcs, WRS_MODE_CCK, + &trunc_value); + + cl_hw->pwr_trunc.cck[mcs] = trunc_value; + + /* Auto response */ + pwr_tables->pwr_auto_resp_cck[mcs] = cl_calc_auto_resp_pwr_q1(cl_hw, 0, 0, mcs, + WRS_MODE_CCK); + } +} + +static void cl_power_tables_update_ofdm(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables) +{ + u8 mcs; + u8 trunc_value = 0; + + /* OFDM - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_OFDM; mcs++) { + pwr_tables->ant_pwr_ofdm[mcs] = cl_calc_ant_pwr_q1(cl_hw, 0, 0, mcs, WRS_MODE_OFDM, + &trunc_value); + cl_hw->pwr_trunc.ofdm[mcs] = trunc_value; + + /* Auto response */ + pwr_tables->pwr_auto_resp_ofdm[mcs] = cl_calc_auto_resp_pwr_q1(cl_hw, 0, 0, mcs, + WRS_MODE_OFDM); + } +} + +static u8 cl_power_tables_update_ht_vht(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables) +{ + bool is_24g = cl_band_is_24g(cl_hw); + bool is_5g = cl_band_is_5g(cl_hw); + u8 bw; + u8 nss; + u8 mcs; + u8 trunc_value = 0; + u8 min_bw_idx_limit_vht = 0; + u8 max_mcs_ht_vht = (is_5g || (is_24g && cl_hw->conf->ci_vht_cap_24g)) ? + WRS_MCS_MAX_VHT : WRS_MCS_MAX_HT; + s16 min_bw_limit = 0; + s32 eirp_power_limit_q8; + + for (bw = 0, min_bw_limit = 0xFFFF; bw < cl_max_bw_idx(WRS_MODE_VHT, is_24g); bw++) { + if (!cl_hw_is_prod_or_listener(cl_hw) && + !cl_chan_info_get(cl_hw, cl_hw->channel, bw)) + continue; + + /* Find lowest EIRP power limitation among all bw for auto resp calculations */ + eirp_power_limit_q8 = cl_chan_info_get_eirp_limit_q8(cl_hw, bw); + if (eirp_power_limit_q8 < min_bw_limit) { + min_bw_limit = eirp_power_limit_q8; + min_bw_idx_limit_vht = bw; + } + + /* HT/VHT - Enforce EIRP limitations */ + for (mcs = 0; mcs < max_mcs_ht_vht; mcs++) { + for (nss = 0; nss < PWR_TBL_VHT_BF_SIZE; nss++) { + pwr_tables->ant_pwr_ht_vht[bw][mcs][nss] = + cl_calc_ant_pwr_q1(cl_hw, bw, nss, mcs, WRS_MODE_VHT, + &trunc_value); + cl_hw->pwr_trunc.ht_vht[bw][mcs][nss] = trunc_value; + } + } + } + + /* Auto resp HT/VHT - Enforce EIRP limitations */ + for (mcs = 0; mcs < max_mcs_ht_vht; mcs++) + pwr_tables->pwr_auto_resp_ht_vht[mcs] = + cl_calc_auto_resp_pwr_q1(cl_hw, min_bw_idx_limit_vht, 0, mcs, + WRS_MODE_VHT); + + return min_bw_idx_limit_vht; +} + +static u8 cl_power_tables_update_he(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables) +{ + bool is_24g = cl_band_is_24g(cl_hw); + u8 bw; + u8 nss; + u8 mcs; + u8 trunc_value = 0; + u8 min_bw_idx_limit_he = 0; + s16 min_bw_limit = 0; + s32 eirp_power_limit_q8; + + for (bw = 0, min_bw_limit = 0xFFFF; bw < cl_max_bw_idx(WRS_MODE_HE, is_24g); bw++) { + if (!cl_hw_is_prod_or_listener(cl_hw) && + !cl_chan_info_get(cl_hw, cl_hw->channel, bw)) + continue; + + /* Find lowest EIRP power limitation among all bw for auto resp calculations */ + eirp_power_limit_q8 = cl_chan_info_get_eirp_limit_q8(cl_hw, bw); + if (eirp_power_limit_q8 < min_bw_limit) { + min_bw_limit = eirp_power_limit_q8; + min_bw_idx_limit_he = bw; + } + + /* HE - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) { + for (nss = 0; nss < PWR_TBL_HE_BF_SIZE; nss++) { + pwr_tables->ant_pwr_he[bw][mcs][nss] = + cl_calc_ant_pwr_q1(cl_hw, bw, nss, mcs, WRS_MODE_HE, + &trunc_value); + cl_hw->pwr_trunc.he[bw][mcs][nss] = trunc_value; + } + } + } + + /* Auto resp HE - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) + pwr_tables->pwr_auto_resp_he[mcs] = + cl_calc_auto_resp_pwr_q1(cl_hw, min_bw_idx_limit_he, 0, mcs, WRS_MODE_HE); + + return min_bw_idx_limit_he; +} + +static u8 cl_power_calc_max(struct cl_hw *cl_hw, u8 bw, enum cl_wrs_mode mode) +{ + u8 tx_ant = cl_power_tx_ant(cl_hw, mode); + /* Total TX power - pass is_auto_resp = true in order to ignore bf gain */ + s32 total_power_q8 = cl_power_total_q8(cl_hw, 0, tx_ant, 0, mode, true); + /* EIRP power limit */ + s32 eirp_power_limit_q8 = cl_chan_info_get_eirp_limit_q8(cl_hw, bw); + + return (min(total_power_q8, eirp_power_limit_q8) >> 8); +} + +static s8 cl_power_vns_calc_q1(struct cl_hw *cl_hw, u8 bw, + enum cl_wrs_mode mode, bool is_auto_resp) +{ + u8 max_tx_pwr = cl_power_calc_max(cl_hw, bw, mode); + u8 tx_ant = cl_power_tx_ant(cl_hw, mode); + s32 vns_pwr_limit_q8 = min_t(u8, cl_hw->conf->ci_vns_pwr_limit, max_tx_pwr) << 8; + s32 antenna_gain_q8 = cl_power_antenna_gain_q8(cl_hw); + s32 array_gain_q8 = (is_auto_resp ? 0 : cl_power_array_gain_q8(cl_hw, tx_ant)); + s32 min_ant_pwr_q8 = cl_power_min_ant_q8(cl_hw); + s32 min_pwr_q8 = is_auto_resp ? (POWER_MIN_DB_Q8 + min_ant_pwr_q8) : POWER_MIN_DB_Q8; + s32 res_q8 = vns_pwr_limit_q8 - antenna_gain_q8 - array_gain_q8; + + if (res_q8 < min_pwr_q8) + res_q8 = min_pwr_q8; + + /* Result should be in 0.5dBm resolution */ + return (s8)(res_q8 >> 7); +} + +static void cl_power_tables_update_vns(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables, + u8 min_bw_idx_limit_vht, + u8 min_bw_idx_limit_he) +{ + /* VNS */ + pwr_tables->ant_pwr_vns_he = + cl_power_vns_calc_q1(cl_hw, min_bw_idx_limit_he, WRS_MODE_HE, false); + pwr_tables->ant_pwr_vns_ht_vht = + cl_power_vns_calc_q1(cl_hw, min_bw_idx_limit_vht, WRS_MODE_VHT, false); + pwr_tables->ant_pwr_vns_ofdm = + cl_power_vns_calc_q1(cl_hw, 0, WRS_MODE_OFDM, false); + pwr_tables->ant_pwr_vns_cck = + cl_power_vns_calc_q1(cl_hw, 0, WRS_MODE_CCK, false); + + /* Auto response VNS */ + pwr_tables->pwr_auto_resp_vns_he = + cl_power_vns_calc_q1(cl_hw, min_bw_idx_limit_he, WRS_MODE_HE, true); + pwr_tables->pwr_auto_resp_vns_ht_vht = + cl_power_vns_calc_q1(cl_hw, min_bw_idx_limit_vht, WRS_MODE_VHT, true); + pwr_tables->pwr_auto_resp_vns_ofdm = + cl_power_vns_calc_q1(cl_hw, 0, WRS_MODE_OFDM, true); + pwr_tables->pwr_auto_resp_vns_cck = + cl_power_vns_calc_q1(cl_hw, 0, WRS_MODE_CCK, true); +} + +static void cl_power_tables_update_by_offset(struct cl_hw *cl_hw, + struct cl_pwr_tables *pwr_tables, + s8 offset) +{ + u8 mcs = 0; + u8 bw = 0; + u8 nss = 0; + + /* CCK - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_CCK; mcs++) { + pwr_tables->ant_pwr_cck[mcs] += offset; + + /* Auto response */ + pwr_tables->pwr_auto_resp_cck[mcs] += offset; + } + + /* OFDM - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_OFDM; mcs++) { + pwr_tables->ant_pwr_ofdm[mcs] += offset; + + /* Auto response */ + pwr_tables->pwr_auto_resp_ofdm[mcs] += offset; + } + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + /* HT/VHT - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_VHT; mcs++) { + for (nss = 0; nss < PWR_TBL_VHT_BF_SIZE; nss++) + pwr_tables->ant_pwr_ht_vht[bw][mcs][nss] += offset; + + /* + * Auto response: + * always with disabled BF so the offset of the last nss is used + */ + pwr_tables->pwr_auto_resp_ht_vht[mcs] += offset; + } + + /* HE - Enforce EIRP limitations */ + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) { + for (nss = 0; nss < PWR_TBL_HE_BF_SIZE; nss++) + pwr_tables->ant_pwr_he[bw][mcs][nss] += offset; + + /* + * Auto response: + * always with disabled BF so the offset of the last nss is used + */ + pwr_tables->pwr_auto_resp_he[mcs] += offset; + } + } +} + +static s8 cl_power_get_offset(u16 percentage) +{ + if (percentage >= 94) + return 0; + else if (percentage >= 84) + return -1; /* -0.5dBm */ + else if (percentage >= 75) + return -2; /* -1dBm */ + else if (percentage >= 67) + return -3; /* -1.5dBm */ + else if (percentage >= 59) + return -4; /* -2dBm */ + else if (percentage >= 54) + return -5; /* -2.5dBm */ + else if (percentage >= 48) + return -6; /* -3dBm */ + else if (percentage >= 43) + return -7; /* -3.5dBm */ + else if (percentage >= 38) + return -8; /* -4dBm */ + else if (percentage >= 34) + return -9; /* -4.5dBm */ + else if (percentage >= 30) + return -10; /* -5dBm */ + else if (percentage >= 27) + return -11; /* -5.5dBm */ + else if (percentage >= 24) + return -12; /* -6dBm */ + else if (percentage >= 22) + return -13; /* -6.5dBm */ + else if (percentage >= 19) + return -14; /* -7dBm */ + else if (percentage >= 17) + return -15; /* -7.5dBm */ + else if (percentage >= 15) + return -16; /* -8dBm */ + else if (percentage >= 14) + return -17; /* -8.5dBm */ + else if (percentage >= 12) + return -18; /* -9dBm */ + else if (percentage >= 11) + return -19; /* -9.5dBm */ + else if (percentage >= 10) + return -20; /* -10dBm */ + else if (percentage >= 9) + return -21; /* -10.5dBm */ + else if (percentage >= 8) + return -22; /* -11dBm */ + else if (percentage >= 7) + return -23; /* -11.5dBm */ + else if (percentage >= 6) + return -24; /* -12dBm */ + else if (percentage >= 5) + return -26; /* -13dBm */ + else if (percentage >= 4) + return -28; /* -14dBm */ + else if (percentage >= 3) + return -30; /* -15dBm */ + else if (percentage >= 2) + return -34; /* -17dBm */ + else if (percentage >= 1) + return -40; /* -20dBm */ + + /* Should not get here */ + return 0; +} + +static void cl_power_control_apply_percentage(struct cl_hw *cl_hw) +{ + struct cl_power_db *power_db = &cl_hw->power_db; + u8 percentage = cl_hw->conf->ce_tx_power_control; + + power_db->curr_percentage = percentage; + + if (percentage != 100) { + power_db->curr_offset = cl_power_get_offset(percentage); + cl_power_tables_update_by_offset(cl_hw, + &cl_hw->phy_data_info.data->pwr_tables, + power_db->curr_offset); + } +} + +void cl_power_tables_update(struct cl_hw *cl_hw, struct cl_pwr_tables *pwr_tables) +{ + bool is_24g = cl_band_is_24g(cl_hw); + bool is_6g = cl_band_is_6g(cl_hw); + u8 min_bw_idx_limit_he = 0; + u8 min_bw_idx_limit_vht = 0; + + memset(pwr_tables, 0, sizeof(struct cl_pwr_tables)); + + if (is_24g) + cl_power_tables_update_cck(cl_hw, pwr_tables); + + cl_power_tables_update_ofdm(cl_hw, pwr_tables); + + if (!is_6g) + min_bw_idx_limit_vht = cl_power_tables_update_ht_vht(cl_hw, pwr_tables); + + min_bw_idx_limit_he = cl_power_tables_update_he(cl_hw, pwr_tables); + + cl_hw->new_tx_power = 0; + + cl_power_tables_update_vns(cl_hw, pwr_tables, min_bw_idx_limit_vht, min_bw_idx_limit_he); + + cl_power_control_apply_percentage(cl_hw); +} + +static s32 cl_power_get_max_cck(struct cl_hw *cl_hw) +{ + struct cl_pwr_tables *pwr_tables = &cl_hw->phy_data_info.data->pwr_tables; + u8 mcs = 0; + u8 tx_ant = cl_power_tx_ant(cl_hw, WRS_MODE_CCK); + s32 ant_gain_q1 = cl_power_antenna_gain_q1(cl_hw); + s32 arr_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + s32 total_pwr_q1 = 0; + s32 max_pwr_q1 = 0; + + for (mcs = 0; mcs < WRS_MCS_MAX_CCK; mcs++) { + total_pwr_q1 = pwr_tables->ant_pwr_cck[mcs] + ant_gain_q1 + arr_gain_q1; + + if (total_pwr_q1 > max_pwr_q1) + max_pwr_q1 = total_pwr_q1; + } + + return max_pwr_q1; +} + +static s32 cl_power_get_max_ofdm(struct cl_hw *cl_hw) +{ + struct cl_pwr_tables *pwr_tables = &cl_hw->phy_data_info.data->pwr_tables; + u8 mcs = 0; + u8 tx_ant = cl_power_tx_ant(cl_hw, WRS_MODE_OFDM); + s32 ant_gain_q1 = cl_power_antenna_gain_q1(cl_hw); + s32 arr_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + s32 total_pwr_q1 = 0; + s32 max_pwr_q1 = 0; + + for (mcs = 0; mcs < WRS_MCS_MAX_OFDM; mcs++) { + total_pwr_q1 = pwr_tables->ant_pwr_ofdm[mcs] + ant_gain_q1 + arr_gain_q1; + + if (total_pwr_q1 > max_pwr_q1) + max_pwr_q1 = total_pwr_q1; + } + + return max_pwr_q1; +} + +static s32 cl_power_get_max_ht_vht(struct cl_hw *cl_hw) +{ + struct cl_pwr_tables *pwr_tables = &cl_hw->phy_data_info.data->pwr_tables; + u8 tx_ant = cl_power_tx_ant(cl_hw, WRS_MODE_VHT); + u8 mcs = 0; + u8 bw = 0; + u8 bf = 0; + s32 ant_gain_q1 = cl_power_antenna_gain_q1(cl_hw); + s32 arr_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + s32 total_pwr_q1 = 0; + s32 max_pwr_q1 = 0; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + for (mcs = 0; mcs < WRS_MCS_MAX_VHT; mcs++) { + for (bf = 0; bf < PWR_TBL_VHT_BF_SIZE; bf++) { + total_pwr_q1 = pwr_tables->ant_pwr_ht_vht[bw][mcs][bf] + + ant_gain_q1 + arr_gain_q1; + + if (total_pwr_q1 > max_pwr_q1) + max_pwr_q1 = total_pwr_q1; + } + } + } + + return max_pwr_q1; +} + +static s32 cl_power_get_max_he(struct cl_hw *cl_hw) +{ + struct cl_pwr_tables *pwr_tables = &cl_hw->phy_data_info.data->pwr_tables; + u8 tx_ant = cl_power_tx_ant(cl_hw, WRS_MODE_HE); + u8 mcs = 0; + u8 bw = 0; + u8 bf = 0; + s32 ant_gain_q1 = cl_power_antenna_gain_q1(cl_hw); + s32 arr_gain_q1 = cl_power_array_gain_q1(cl_hw, tx_ant); + s32 total_pwr_q1 = 0; + s32 max_pwr_q1 = 0; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) { + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) { + for (bf = 0; bf < PWR_TBL_HE_BF_SIZE; bf++) { + total_pwr_q1 = pwr_tables->ant_pwr_he[bw][mcs][bf] + + ant_gain_q1 + arr_gain_q1; + + if (total_pwr_q1 > max_pwr_q1) + max_pwr_q1 = total_pwr_q1; + } + } + } + + return max_pwr_q1; +} + +s32 cl_power_get_max(struct cl_hw *cl_hw) +{ + bool is_24g = cl_band_is_24g(cl_hw); + bool is_6g = cl_band_is_6g(cl_hw); + s32 max_pwr_cck_q1 = is_24g ? cl_power_get_max_cck(cl_hw) : S32_MIN; + s32 max_pwr_ofdm_q1 = cl_power_get_max_ofdm(cl_hw); + s32 max_pwr_ht_vht_q1 = !is_6g ? cl_power_get_max_ht_vht(cl_hw) : S32_MIN; + s32 max_pwr_he_q1 = cl_power_get_max_he(cl_hw); + s32 max_pwr_q1 = 0; + + max_pwr_q1 = max(max_pwr_q1, max_pwr_cck_q1); + max_pwr_q1 = max(max_pwr_q1, max_pwr_ofdm_q1); + max_pwr_q1 = max(max_pwr_q1, max_pwr_ht_vht_q1); + max_pwr_q1 = max(max_pwr_q1, max_pwr_he_q1); + + return (max_pwr_q1 >> 1); +} + From patchwork Tue May 24 11:34:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575966 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 AD6D0C433F5 for ; Tue, 24 May 2022 11:39:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236860AbiEXLjv (ORCPT ); Tue, 24 May 2022 07:39:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236868AbiEXLjs (ORCPT ); Tue, 24 May 2022 07:39:48 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACA188D6AE for ; Tue, 24 May 2022 04:39:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nY6bea0EVB6BKbCMsePOf+48UAHHUyKDyClPyxlwGk4BPVnWzAmaZSAVxOonCm9ntsGdDTSSTkmX/5EcQ4aUpqOBbfRP+VyRKvn5gFZODBqlonJxwZVJp4VnGPWoTfqxIJjrkXAO2u2vsMWF7RQ51XBd+fR/TWFstESmPyL38OOryDTkg1tGG+Qe8k8i5mPo7kcK+EaF0NYqdtremX9y/tnDnBQo5Kl/gnqqP0ZU20YOM9WPU3XVuv0vbh53rxJ5GwraO8ohFf5I4aJso1f1UqZ8xtRCpQihBwJqJth3sCsZeTNK5TZjJqMzgCpEf6cpxiqf6oQQHpsczkiG+j9PJQ== 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=oafhv9s5MwtR6ncqhHajnROUMJPJRs6kCLjamomQxpA=; b=NiKZiP3RtGnxQjMAETNCCIFQZxgCPODkkDht714pDRWrT40ewKGJ0KXBUu/IfoM60zBuum+0tcg5zRBkOCkMOdrx6W5awtIKgFvQXzOXsk3D59CZqg+zWyCwAnsrKRIjKkNWsUWpmAY3kdzBgZ+gxM26FIr2WsEpgQ3qs5ZfaBZS8siJ5gPmffcgwbZb+8B8U8kSeaAYoXE/um/noJxPwQgSl2Nt/MbgXG3tTJ83DpgQS2IDPimSsFLFyTlF0KwtaqS1v9GkPT84yNEqiWkHhjybxoFCyEjvYuHVYC5pzg1LM1Vi7zEeqTjGNrZUTAAWLS7GhCGwVvsthstcBNi48A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=oafhv9s5MwtR6ncqhHajnROUMJPJRs6kCLjamomQxpA=; b=e+Qc51/EZDBRGOFuL2uXymdWNDkbtIOK4yEfV/98In3lSStfYgu+LT7CMqJkx0VvmjHlPUb8erfjg7g3j97kZw5JypawyKZSoSvisF5TMy63c9x7b9YKlm+voBKziEf/zVWdeU6LgUig9XXfAGGmyypBNXUhYA4ATKkgRD/e1I8= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:51 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:51 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 55/96] cl8k: add power.h Date: Tue, 24 May 2022 14:34:21 +0300 Message-Id: <20220524113502.1094459-56-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d102efec-6672-4362-58d7-08da3d79eed0 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: MqGBTPeR/JFe5HIjM1PeM3uyN0TldgjzDprSmYIWpfEXN96ZbjFZN4B42+SpHwDvNUMokDVerRwrTpUSCrDXfdsleMaRan/aLLOxi/fxlZ9UWDBffeLb5skqsdSQlOVZ+DKbZ+V8S836704BHsuZo9WArDxMRABmigjU043+Tdxi56YZ3i/d6HnSNEv3ITpQ1d51lUtivRR7I08aWwCcLPde8xTE8mIZtV3cpL54Zr2CW/4epg5ed7gSd1UKJO6Rd5eMBLD/lMPLjt9RfC1rzg1T2Oesuvzd7NxOME+HOTG/1PtjdjHfUQ0jDCI9DAKJM8hiXIDufG28ygKFcuZC+DqporPdcXyzx02McfQifsUTT6Ru0J28/PjVCV+NJ3m0V3jUEBaV17dhD86EP3WzUnPEsE81moCQFN7CqKIOMRQbH3/JnQTKFTPO6HmB17/t66nftZCdlo2IKj7ckI0UfgoWigx6oGvjSSlmc15loxczmriH2zMJ2VT6/pLJMXY+G+THjZdN8IIXkD/iAzrMhS9qa0xcy1VY8YaN7qsnClKk6aYhw0NvdQhGplzJR7bHVX1o33Z/S3rNqA118DDazN5zNwVIrl44U+7RMLB0jurYqjLg3QMTJyZ502Xv25hJrELX6t/wlySuxnOCRsSj4yzoRWskfaJNekGi9nKGOdV5QOr629UKXo1TwpeasZBYLo+9GjUvC3S1CnMTDyUvGs9qxXlpvbgORiT82mP7s5E= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: nyBvilXCDat/WhsnpgwgypN1D+oiwJOM8nOFvqU44WL7gOE+JDKInQjE1jNW7OkBIIdX9QhnD6zd1R2Dqtg+33lOGa8q6stJ/w0gEQZW3Diq0eCg3/8YE/nUrd667jrqWEYyPhDXbTk67YmY6Suy6mt8DHcUAOV3DP7erBr+V0QoJxkBUGwOWpUPFrjheZNnlmVdpgUOtY4U1LxKsh3vKJ7VteLdIk5eFGtWrjDWLDNCZDHjWkkvLXzI03mvuWn6104IIHfPOq8qGMIDn/uZ9mi7n4P57sL1OWnZU+hBJbAvBMUcnYM2uvRdwsackqqBI00Ak2J26Pvh0sdaB/+U67Mf910IwTyFxBM8JxzxhNizw50JtBLAaSSyj85dCPKU/rOZIdw6kpPc7SHKIxH2f1ZTW/E+QclLxYW7XD9W/EQY1078L9psUeHsvkvapBuE+VArs47l+WKUzvtIzjZzDEU4WMxCmH6JOWQR7/h239/n1wFjJLXErzBM0kSN9xDk4OsUL2XMzI45PSnJg8Ljp9QICzYR4ZaEO1h/dJcqNIVLt608RGVZ6oEmuiHkVWLR56doRXKhajFlNgIP53kHTw81PXvx/hFAoft9Ff0wZegqM1Ch6jra1TWh5DKOJfO+xffjbnwB0B1/ZyUwjdfT9WqvUdqwX7m/JgWRWo95eyM0g3gyHBtpOmVVuf/ANJVCutFxmsuZiaVsxWmdqnluUWTS7zzKFlWzdfNXllzct2LKDyoeRDBEGCZyXrdWQYzYgv+wsW5LE1WcW2FlyqHJtZUsBeDrIU/NTEe/NY13P8hTvmqvC29oEOk2xWNWlyar4zOxn+0+aA79S0xf8eh25XW8hTNmhj2+vQpyKstD6PFYTDX/FDwr4Tmh+4MszTYr29dQZvU7wOFustSB/dR+p8oh+h+l0y7sm7+60VZ2npB6gs8wQc2F+E3rPjHwqA1QRgPH0QYtcbTt0edpRIWN3C6yFZSUPct4Nv2BtSR0yyhpfrmFMMq1l6rEhpNbjPPWNq0uy1vhWwm+x6+zAxXHThCO6GJZTSJqFAY2he13RzEnmY2OT03HxDxICOXkyw1O9PmuzVP7uK0GbE/wybB9C5tZyv6vccSZ5qJaNjd5RAaSsHbA4bXDudjveTv0ha7SyGpvKkX61V5khB5zHLTYf32L5jtGqARfovvxKbitqGRctwAY9HdLm6ap/OCNI1M/uAcVpic43+6I2Oo2mBDJxuB9NnkMRXeDe0x7sap9SYk7HaX+rBLOnhD1ah/CP6Qs4WcnsfuJd61Y6bjZoUd8CzxTHgGRVviuzA0vIX3VzFGKfqZfteLk34KBjM4OcKYUjQF0IPNQzwwfkIQoPDb9P9ZRRBd2qs30fDZ01sYeRZw0/pW/yZdinUbS48GWYQ7Vp38pPy3u8/IaNPoci8sk7XUgBa6j+ETybXks08M991c4VpVXGbuPvXLg97uRxLyzDJn1/+sXd4KQ8a3Zdzq2BCBjY7Qi+W90KUd6FdPh0OfvIEBqvV/hxEBLz3zcJGPumVZCW91M5R6lMz5xHSu4ohJsG4iv+T4NsnPOdFhDQKGt7EaOpnb3fAUDBANHHxWCrAAUFLmltNc1+j5hQsC5O1UtYTb2qRr2Nd++zEFlbYSw/1kArO7vnVKVg/P6+HxtPc5mnL6F+OCgpBzpfdowtL1a5qJC+DYASFy00u7vTcxp+Ln31hNpRcug4bKHDMhdGGekAeuCsoFrtWXebckVldrlI7GXgiZZioZrfNkKHoQ= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d102efec-6672-4362-58d7-08da3d79eed0 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:33.5346 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: vXQllP0dCSBNL1NGhx5ddw5C48F7I0+PMzQpPZwAb7Kf2cPBGeVudPGUJ6fN56M8TB8MFskMeEmaPMUcJnqpcg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/power.h | 90 ++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/power.h diff --git a/drivers/net/wireless/celeno/cl8k/power.h b/drivers/net/wireless/celeno/cl8k/power.h new file mode 100644 index 000000000000..cd1d36492317 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/power.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_POWER_H +#define CL_POWER_H + +#define NUM_POWER_WORDS 256 +#define POWER_MIN_DB -10 +#define POWER_MIN_DB_Q1 (POWER_MIN_DB << 1) +#define POWER_MIN_DB_Q8 (POWER_MIN_DB << 8) +#define POWER_OFFSET_RES 4 + +struct cl_power_table_data { + u8 conv_table[NUM_POWER_WORDS]; +}; + +struct cl_power_table_info { + struct cl_power_table_data *data; + u32 dma_addr; +}; + +#define PWR_TBL_HE_BF_SIZE (WRS_SS_MAX + 1) +#define PWR_TBL_VHT_BF_SIZE WRS_SS_MAX + +/* + * Structure containing the power tables + * All values are in resolution of 0.5dBm + */ +struct cl_pwr_tables { + /* Regular Tx */ + s8 ant_pwr_he[CHNL_BW_MAX][WRS_MCS_MAX_HE][PWR_TBL_HE_BF_SIZE]; + s8 ant_pwr_ht_vht[CHNL_BW_MAX][WRS_MCS_MAX_VHT][PWR_TBL_VHT_BF_SIZE]; + s8 ant_pwr_ofdm[WRS_MCS_MAX_OFDM]; + s8 ant_pwr_cck[WRS_MCS_MAX_CCK]; + /* VNS */ + s8 ant_pwr_vns_he; + s8 ant_pwr_vns_ht_vht; + s8 ant_pwr_vns_ofdm; + s8 ant_pwr_vns_cck; + /* Auto response */ + s8 pwr_auto_resp_he[WRS_MCS_MAX_HE]; + s8 pwr_auto_resp_ht_vht[WRS_MCS_MAX_VHT]; + s8 pwr_auto_resp_ofdm[WRS_MCS_MAX_OFDM]; + s8 pwr_auto_resp_cck[WRS_MCS_MAX_CCK]; + /* Auto response VNS */ + s8 pwr_auto_resp_vns_he; + s8 pwr_auto_resp_vns_ht_vht; + s8 pwr_auto_resp_vns_ofdm; + s8 pwr_auto_resp_vns_cck; +}; + +struct cl_power_db { + u8 curr_percentage; + s8 curr_offset; + /* Used to validate margins of MAC power */ + s8 bw_factor_q2[CHNL_BW_MAX]; + s8 ant_factor_q2[MAX_ANTENNAS]; +}; + +struct cl_tx_power_info { + s8 power; + s8 offset; + s8 temperature; +}; + +struct cl_power_truncate { + u8 he[CHNL_BW_MAX][WRS_MCS_MAX_HE][PWR_TBL_HE_BF_SIZE]; + u8 ht_vht[CHNL_BW_MAX][WRS_MCS_MAX_VHT][PWR_TBL_VHT_BF_SIZE]; + u8 ofdm[WRS_MCS_MAX_OFDM]; + u8 cck[WRS_MCS_MAX_CCK]; +}; + +int cl_power_table_alloc(struct cl_hw *cl_hw); +void cl_power_table_free(struct cl_hw *cl_hw); +u8 cl_power_tx_ant(struct cl_hw *cl_hw, enum cl_wrs_mode mode); +s32 cl_power_antenna_gain_q8(struct cl_hw *cl_hw); +s32 cl_power_antenna_gain_q1(struct cl_hw *cl_hw); +s32 cl_power_array_gain_q8(struct cl_hw *cl_hw, u8 tx_ant); +s8 cl_power_array_gain_q2(struct cl_hw *cl_hw, u8 tx_ant); +s32 cl_power_array_gain_q1(struct cl_hw *cl_hw, u8 tx_ant); +s32 cl_power_bf_gain_q1(struct cl_hw *cl_hw, u8 tx_ant, u8 nss); +s32 cl_power_min_ant_q1(struct cl_hw *cl_hw); +s8 cl_power_bw_factor_q2(struct cl_hw *cl_hw, u8 bw); +s32 cl_power_average_calib_q1(struct cl_hw *cl_hw, u8 ant_num); +s8 cl_power_offset_q1(struct cl_hw *cl_hw, u8 mode, u8 bw, u8 mcs); +s8 cl_power_offset_check_margin(struct cl_hw *cl_hw, u8 bw, u8 ant_idx, s8 offset_q2); +void cl_power_tables_update(struct cl_hw *cl_hw, struct cl_pwr_tables *pwr_tables); +s32 cl_power_get_max(struct cl_hw *cl_hw); + +#endif /* CL_POWER_H */ From patchwork Tue May 24 11:34:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575960 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 0472DC433EF for ; Tue, 24 May 2022 11:40:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236904AbiEXLkZ (ORCPT ); Tue, 24 May 2022 07:40:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234877AbiEXLkX (ORCPT ); Tue, 24 May 2022 07:40:23 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9292939A0 for ; Tue, 24 May 2022 04:39:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gfR53efHGsH4KeFi8lGz17ROGckgs1fwueV6Y7whIXvbGCjqKRV/SnkT1Hj2+ioPv27ihSkG6IHz3n92jgrTTyrJYoOsiOtP2PD2OPA8k8GQIKcGatqmQp33Y79J40xrQSybmvrcCgjur+Peg1RO2EzGgIn7wrERfRey/L1Z2clh5fekS4L3o/5D7vikju0VXHfcRZoysxMTGys6m8ssXwNPc0+ybtPVvjgBqaK0mjuTzocHgJidU5/46mfWC8PByitTmW1uS5d/XwPzv4+oKvD1QuJO65gy2gbW18lplajyfaSxO7yA9t+QQ1whpdSH3pKpB9GBCaZIaH1txNj3/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=IlPJQilWTY5hoW6q8ZBlpd0qoBHS2YakFmK5RuugP6g=; b=OStvHi//1TcDjP51TK9W0vBepI+TMLbiJ4gXS/rnf1ylmMQnwo4NtEDkLtDfFr37zkNtBnOjelDcGMslpAJk+zxPr4Bc4qjOA9psffWxiVa54y9rjdm1VENJdfOtqAtVMkdSocTSXFxjuIGNzAGOSFsH/uPI39NL1DKutJHWKCkFIz3BuzgsdO1zBTUYr9/v3cvQkra0GWXkFCs395Shh69Z+SSXOKfT5fbwbfURj5UqxzftpwknNJYaQ+J5ZIl35Z8BDid86nUaJHGH+Vuv8EDGaTqqS9rXyanntPTpTCnW6jD8WiLiFozp/eay9IMLANUhln2qMt8p5a1fd3JZrw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IlPJQilWTY5hoW6q8ZBlpd0qoBHS2YakFmK5RuugP6g=; b=W4NOIAcmzwJap4NnWp0mSK8UWM6ns+7vSoO6xMkr0klbblh6UCMifeZkfMPmiAYXsMI2Cu+isZBR+8FFkAZPENXER7OQ3WshOdYMK5b180wcJtuAQBrMI73HqwQjQfvDOUl3gi0n1pYU++04IX2R8Amk5L8VH3iBWT+cVBtwWcw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:51 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:51 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 56/96] cl8k: add radio.c Date: Tue, 24 May 2022 14:34:22 +0300 Message-Id: <20220524113502.1094459-57-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6e4f6aea-e6a4-436d-83f2-08da3d79ef4e X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Vhy0Gjq1kX+UBc4+YDOhNZayMybSo/4Af+3Oxmn1r2Q/6tI4xSNPl0K7McpdPiHjsKakqOqBP4zLBUQyfHYeDXuLYYQOh4lU8cZfCkEp0LYhAt4iMxT4LkX/6CbKwphqi/L7ljjkg4hA/UvSv+l8x90PEvb6lXcwmTNGUz7U1TcXHdFELLcLEyAcV0Sw9tW5riYyNC4nbzWZp54mFoEnE2SU7B86RSQOKpdh6z9GMY+0Arr9MaVzXoe9r+z4DO3ZwB+b7hXZaIMX5wtqzqb4YEnAvfzwC2TPRHd3qvOSN6TEpWuMWSCrbeLHCAFPaNqZGPgTRFlaoLx/fJd/CPYzxKq9fKDuFH5d3bGv7GRpcExMVay69kq3zI7V7aWM309uejBW+1wweUurGTWSg+c9rMW2wPOg+s2I0ggp+C3rKK9adneFQ9mpTCTywKHbI5my9FoE38tOVNcEQJBWrd3XIIjCqVZYyFKWtUNurWGsrmbpnoJb6XI3gTGL7wUM09ql0GZiv+BEV29TPcc7Cak0hO1K6xyMcOahlyjyB9DKect+il/ak7IOYvkIzqINbTamcXPWuObWTkFQMNPH74UBCFvCAACWEcXn28qchsGAUQ0VLQlu6i9JgEEky+WoDpnkm0Y7/vGD+nvJI4QugLfIVof4SypfzGo5lkBEEXjhIwvlcPDT4UJ70H8+EZ5G9P3ca3G/1yDeI45HH7yF2hlIGl110Hi3158Q+3Pi+yEppRU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: mCfhcjoRwaMpY/KN4T6fsdianThEekw+7tlIraV3gQ0bZYqR/BT7XFgDVuWEKNgAvciVRa746tVAES6Lx0Y6sVieZ1CJLRL558jrchDi65JyUBf+TGHmaq9izOfv7fNIIP4jYW3w3tcI3iNDruGTfzOcoXunqet1fhx9ItEIltsdJyWVHhp6+c1rPfKGcy2M36owG6GZLhb4Lp3u5r0UdmWjQtg5fJWm99GXikd2thUyS8w0+fdu6rgfJMiwlpbfLKwOsCeWQVHwr8ZPkGNoY3jTHp+Q7pVeM9s3RRO+1YTfakIFiySwnR+bGYLkAKOYH1eP8Q4aoXsq6ZWxJF8jTNKkjCP6qYx3ecgA6/CjI8ycENZLBcjRzsrg9pDTUJvEeZka2C/z7WLxxYzeZGeLwszKdAadf9TZxC+HjnKEurpnpN8pQc7/5KyeDS4zc5bpq5VKGktIlUYFMavP7Lyuoy6QInEm5SrxloxFrbSabJGdRlw6QU85AtLhrzXps30jcvM4U78kSdKCXttdUqFkoINGeeT+U3EyImxN1vgDGJZj60YTOv0aSNVFZAyZdJNEmIKqM450lpffT4sk0zDY5JYd3uMzovXezVMK5GmKGLygmcvKnvdfj/kiNGq7kvyPVQ4rFGxv86A+Ea6JodwB0I06jJIhiNfwpHpjJoAO/UYnXbb0pMOD9kfKoKgol1tXeC1A5kZYsjUhzzuV45NdvVBNw2Z15hnWostEtKXf6okTsprgEkFML+4yjG1cTBtmx3GXCG4Tz7+H9WLb/Fkk6zv7GV9W8F2ok39KCUDe+MPYLqG1leIwWLNTuTc4lN8Du3WDnAkQpmLBDiAS5JdXqS4sW2qmxYYleINNfqm1iGWClrhuZhd7rHtWlSCj+qIsHBE49dSv5ilvo20xItwaHt7erLzvPYV0hZtBJBtI+LXq2hJ/Ya/DmtgxDXsPXGZVx4vlANnmtv0eoSZioOK7WEz0QlHJ/7wieY+EdGSFVMfKEkwMrNjHdwT/kjexAwSJLJcYNxKUpupEgv45sY88S6xDiOjJwd7p3gyRm9a9AhD0oQ+SqLwMSKxzeW/T2x3Q/xxDUTKXATHoJW3/DHxN+xtAYVofLL5o52ucx6XhjGJqhUFcaQyhHmYVVQpBB8acNfU142IKxm9FDhpijyvp3FddYJJtygF7k72+28tvnVoCcywXedZG4uJkgpqrapnxgA+j7GmK1tyO8ssCUfBgTRReVLr4uTdXYfVIp+kDQ9i+m9DnY7u0ivzzM7+slT56mFiTlgOt5u0R8paUV0p9833Ot2ST8RXG//kSt1TUBynKfOihXuQCBSa+jjOBOmS76VvlSfmZgBV+aU3rvhvQKviSXcSrB2gZrxJbPjVhOEg24Gm+thGsDrqTMqfSddopNhB6SPgu9/HDbs8Pc2fSrRSLEqIdHkEpd3rps+EHmYMQ8+RgjLY672uAwa7Bluvisp8c2F0ws6AywloFlWN1sRqw8scafKoQlf6uj4KrUFFpjGBtZ+bkX66NvgJIYTZVTwOSn5AOZSH+xIk9GauyoIiPjeL3JNtJqb8q60Kti3/gCBgfKEGshEAiwcWpFt4TqlPaJZvrVvjzfCiCr85GY2/W8OP0+5ML6EbuRLCayKxaRw6+uIGk8VnbXnYrh2yWG951C3QwE0y2Rcak91FfC3+GDIeOLAmAsmHP8E2wQdFBdk+n7jALuifrMaqMHE6BTrevRcBrrfK2iFSO+n1kgqsZWXo2SdpN/IVPSQ9hI2k= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6e4f6aea-e6a4-436d-83f2-08da3d79ef4e X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:34.4239 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: A/Mh2YNESwrK799AnQhBPrGXXqStH4hDZa/IjFnvJmMxOhOqpaILon+Qqvogo0GO1wMggJwaQv/pCKeTvB/T2g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/radio.c | 1113 ++++++++++++++++++++++ 1 file changed, 1113 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/radio.c diff --git a/drivers/net/wireless/celeno/cl8k/radio.c b/drivers/net/wireless/celeno/cl8k/radio.c new file mode 100644 index 000000000000..416c2bdff07e --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/radio.c @@ -0,0 +1,1113 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include +#include + +#include "vif.h" +#include "sta.h" +#include "chip.h" +#include "debug.h" +#include "hw.h" +#include "phy.h" +#include "utils.h" +#include "reg/reg_access.h" +#include "reg/reg_defs.h" +#include "mac_addr.h" +#include "stats.h" +#include "radio.h" + +static int cl_radio_off_kthread(void *arg) +{ + struct cl_hw *cl_hw = (struct cl_hw *)arg; + struct cl_vif *cl_vif; + + cl_dbg_verbose(cl_hw, "Waiting for stations to disconnect\n"); + + if (wait_event_timeout(cl_hw->radio_wait_queue, + cl_sta_num_bh(cl_hw) == 0, + msecs_to_jiffies(5000)) == 0) { + cl_dbg_verbose(cl_hw, + "Failed to disconnect stations. %u stations still remaining\n", + cl_sta_num_bh(cl_hw)); + } + + cl_dbg_trace(cl_hw, "Stopping queues ...\n"); + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + cl_vif->tx_en = false; + cl_dbg_verbose(cl_hw, "Radio OFF vif_index = %u\n", + cl_vif->vif_index); + } + read_unlock_bh(&cl_hw->vif_db.lock); + + cl_msg_tx_set_idle(cl_hw, MAC_IDLE_SYNC, true); + + cl_dbg_trace(cl_hw, "Radio shut down successfully\n"); + + cl_hw->radio_status = RADIO_STATUS_OFF; + atomic_set(&cl_hw->radio_lock, 0); + + return 0; +} + +static int cl_radio_off(struct cl_hw *cl_hw) +{ + struct task_struct *k; + + if (cl_hw->radio_status != RADIO_STATUS_ON || + atomic_xchg(&cl_hw->radio_lock, 1)) + return 1; + + cl_hw->radio_status = RADIO_STATUS_GOING_DOWN; + + /* Relegate the job to a kthread to free the system call. */ + k = kthread_run(cl_radio_off_kthread, cl_hw, "cl_radio_off_kthread"); + if (IS_ERR(k)) + cl_dbg_verbose(cl_hw, + "Error: failed to run cl_radio_off_kthread\n"); + return 0; +} + +void cl_radio_on_start(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif; + + if (cl_calib_common_check_errors(cl_hw) != 0 || !cl_hw->conf->ce_num_antennas) + return; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + if (cl_vif->vif->type == NL80211_IFTYPE_AP) { + if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_REPEATER && + !test_bit(CL_DEV_REPEATER, &cl_hw->drv_flags)) + continue; + if (cl_hw_get_iface_conf(cl_hw) == CL_IFCONF_MESH_AP && + !test_bit(CL_DEV_MESH_AP, &cl_hw->drv_flags)) + continue; + } + + if (!cl_hw->conf->ce_listener_en) + cl_vif->tx_en = true; + + cl_dbg_verbose(cl_hw, "Radio ON vif=%u\n", cl_vif->vif_index); + } + read_unlock_bh(&cl_hw->vif_db.lock); + + cl_msg_tx_set_idle(cl_hw, MAC_ACTIVE, true); + + cl_dbg_verbose(cl_hw, "Radio has been started\n"); + + cl_hw->radio_status = RADIO_STATUS_ON; + atomic_set(&cl_hw->radio_lock, 0); +} + +int cl_radio_on(struct cl_hw *cl_hw) +{ + struct cl_hw *cl_hw_other = cl_hw_other_tcv(cl_hw); + bool both_enabled = cl_chip_is_both_enabled(cl_hw->chip); + + if (cl_hw->radio_status != RADIO_STATUS_OFF || + atomic_xchg(&cl_hw->radio_lock, 1)) + return 1; + + if (!both_enabled || + (both_enabled && cl_hw_other && !cl_hw_other->conf->ce_radio_on) || + (cl_hw_is_tcv1(cl_hw) && cl_hw->chip->conf->ci_tcv1_chains_sx0)) { + if (cl_calib_iq_calibration_needed(cl_hw)) { + cl_calib_common_start_work(cl_hw); + + return 0; + } + } else if (cl_hw_other) { + if (cl_hw_other->iq_cal_ready) { + cl_hw_other->iq_cal_ready = false; + cl_calib_common_start_work(cl_hw); + + return 0; + } else if (cl_calib_iq_calibration_needed(cl_hw)) { + cl_hw->iq_cal_ready = true; + cl_dbg_verbose(cl_hw, "IQ Calibration needed. Wait for both TCVs " + "to get to radio-on before turning both on.\n"); + return 1; + } + } + + cl_radio_on_start(cl_hw); + + return 0; +} + +void cl_radio_off_chip(struct cl_chip *chip) +{ + if (cl_chip_is_tcv0_enabled(chip)) + cl_radio_off(chip->cl_hw_tcv0); + + if (cl_chip_is_tcv1_enabled(chip)) + cl_radio_off(chip->cl_hw_tcv1); +} + +void cl_radio_on_chip(struct cl_chip *chip) +{ + if (cl_chip_is_tcv0_enabled(chip)) + cl_radio_on(chip->cl_hw_tcv0); + + if (cl_chip_is_tcv1_enabled(chip)) + cl_radio_on(chip->cl_hw_tcv1); +} + +bool cl_radio_is_off(struct cl_hw *cl_hw) +{ + return cl_hw->radio_status == RADIO_STATUS_OFF; +} + +bool cl_radio_is_on(struct cl_hw *cl_hw) +{ + return cl_hw->radio_status == RADIO_STATUS_ON; +} + +bool cl_radio_is_going_down(struct cl_hw *cl_hw) +{ + return cl_hw->radio_status == RADIO_STATUS_GOING_DOWN; +} + +void cl_radio_off_wake_up(struct cl_hw *cl_hw) +{ + wake_up(&cl_hw->radio_wait_queue); +} + +static void cl_clk_init(struct cl_chip *chip) +{ + cmu_clk_en_set(chip, CMU_MAC_ALL_CLK_EN); + + if (cl_chip_is_both_enabled(chip)) { + cmu_phy_0_clk_en_set(chip, CMU_PHY_0_APB_CLK_EN_BIT | CMU_PHY_0_MAIN_CLK_EN_BIT); + cmu_phy_1_clk_en_set(chip, CMU_PHY_1_APB_CLK_EN_BIT | CMU_PHY_1_MAIN_CLK_EN_BIT); + + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 0); + modem_gcu_ceva_ctrl_external_wait_setf(chip->cl_hw_tcv0, 1); + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 1); + + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 0); + modem_gcu_ceva_ctrl_external_wait_setf(chip->cl_hw_tcv1, 1); + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 1); + + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 1); + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 1); + } else if (cl_chip_is_tcv0_enabled(chip)) { + /* Even if only PHY0 is enabled we need to set CMU_PHY_1_MAIN_CLK_EN_BIT */ + cmu_phy_0_clk_en_set(chip, CMU_PHY_0_APB_CLK_EN_BIT | CMU_PHY_0_MAIN_CLK_EN_BIT); + cmu_phy_1_clk_en_set(chip, CMU_PHY_1_MAIN_CLK_EN_BIT); + + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 0); + modem_gcu_ceva_ctrl_external_wait_setf(chip->cl_hw_tcv0, 1); + cmu_phy_0_rst_ceva_0_global_rst_n_setf(chip, 1); + + cmu_phy_0_clk_en_ceva_0_clk_en_setf(chip, 1); + } else { + /* Even if only PHY1 is enabled we need to set CMU_PHY_0_MAIN_CLK_EN_BIT */ + cmu_phy_0_clk_en_set(chip, CMU_PHY_0_MAIN_CLK_EN_BIT); + cmu_phy_1_clk_en_set(chip, CMU_PHY_1_APB_CLK_EN_BIT | CMU_PHY_1_MAIN_CLK_EN_BIT); + + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 0); + modem_gcu_ceva_ctrl_external_wait_setf(chip->cl_hw_tcv1, 1); + cmu_phy_1_rst_ceva_1_global_rst_n_setf(chip, 1); + + cmu_phy_1_clk_en_ceva_1_clk_en_setf(chip, 1); + } +} + +static int cl_pll1_init(struct cl_chip *chip) +{ + int retry = 0; + + /* Verify pll is locked */ + while (!cmu_pll_1_stat_pll_lock_getf(chip) && (++retry < 10)) { + cl_dbg_chip_verbose(chip, "retry=%d\n", retry); + usleep_range(100, 200); + } + + /* Pll is not locked - fatal error */ + if (retry == 10) { + cl_dbg_chip_err(chip, "retry limit reached - pll1 is not locked !!!\n"); + return -1; + } + + return 0; +} + +static int cl_cmu_init(struct cl_chip *chip) +{ + int ret = 0; + + if (IS_REAL_PHY(chip)) { + ret = cl_pll1_init(chip); + if (ret) + return ret; + } + + /* Set gl_mux_sel bit to work with pll1 instead of crystal */ + cmu_control_gl_mux_sel_setf(chip, 1); + + if (cl_chip_is_both_enabled(chip)) { + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_0_rst_set(chip, CMU_PHY0_RST_EN); + cmu_phy_1_rst_set(chip, CMU_PHY1_RST_EN); + cmu_phy_0_rst_set(chip, 0x0); + cmu_phy_1_rst_set(chip, 0x0); + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_0_rst_set(chip, CMU_PHY0_RST_EN); + cmu_phy_1_rst_set(chip, CMU_PHY1_RST_EN); + } else if (cl_chip_is_tcv0_enabled(chip)) { + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_0_rst_set(chip, CMU_PHY0_RST_EN); + cmu_phy_0_rst_set(chip, 0x0); + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_0_rst_set(chip, CMU_PHY0_RST_EN); + } else { + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_1_rst_set(chip, CMU_PHY1_RST_EN); + cmu_phy_1_rst_set(chip, 0x0); + cmu_rst_n_ricurst_setf(chip, 1); + cmu_phy_1_rst_set(chip, CMU_PHY1_RST_EN); + } + + return ret; +} + +static void cl_riu_clk_bw_init(struct cl_hw *cl_hw) +{ + u32 regval; + + if (!cl_hw) + return; + + switch (cl_hw->conf->ci_cap_bandwidth) { + case CHNL_BW_20: + regval = 0x00000100; + break; + case CHNL_BW_40: + regval = 0x00000555; + break; + case CHNL_BW_160: + regval = 0x00000dff; + break; + case CHNL_BW_80: + default: + regval = 0x000009aa; + break; + } + + /* Set RIU modules clock BW */ + modem_gcu_riu_clk_bw_set(cl_hw, regval); +} + +static int cl_load_riu_rsf_memory(struct cl_chip *chip, const char *filename) +{ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + char *buf = NULL; + loff_t size, i = 0; + int ret = 0; + + size = cl_file_open_and_read(chip, filename, &buf); + + if (!buf) + return -ENOMEM; + + if (size > RIU_RSF_FILE_SIZE) { + ret = -EFBIG; + goto out; + } + + /* Enable re-sampling filter init. */ + riu_rsf_control_rsf_init_en_setf(cl_hw_tcv0, 0x1); + if (cl_hw_tcv1) + riu_rsf_control_rsf_init_en_setf(cl_hw_tcv1, 0x1); + + while (i < size) { + riu_rsf_init_set(cl_hw_tcv0, *(u32 *)&buf[i]); + if (cl_hw_tcv1) + riu_rsf_init_set(cl_hw_tcv1, *(u32 *)&buf[i]); + i += 4; + } + +out: + kfree(buf); + return ret; +} + +static int cl_load_riu_rsf_memory_recovery(struct cl_hw *cl_hw, const char *filename) +{ + struct cl_chip *chip = cl_hw->chip; + char *buf = NULL; + loff_t size, i = 0; + int ret = 0; + + size = cl_file_open_and_read(chip, filename, &buf); + + if (!buf) + return -ENOMEM; + + if (size > RIU_RSF_FILE_SIZE) { + ret = -EFBIG; + goto out; + } + + /* Enable re-sampling filter init. */ + riu_rsf_control_rsf_init_en_setf(cl_hw, 0x1); + + while (i < size) { + riu_rsf_init_set(cl_hw, *(u32 *)&buf[i]); + i += 4; + } + +out: + kfree(buf); + return ret; +} + +static int cl_load_agc_data(struct cl_hw *cl_hw, const char *filename) +{ + struct cl_chip *chip = cl_hw->chip; + char *buf = NULL; + loff_t size, i = 0; + + size = cl_file_open_and_read(chip, filename, &buf); + + if (!buf) + return -ENOMEM; + + /* Enable AGC FSM ram init state */ + riu_agcfsm_ram_init_1_agc_fsm_ram_init_en_setf(cl_hw, 0x1); + /* Start writing the firmware from WPTR=0 */ + riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_setf(cl_hw, 0x0); + /* Allow WPTR register to be writable */ + riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_set_setf(cl_hw, 0x1); + /* Enable auto increment WPTR by 1 upon any write */ + riu_agcfsm_ram_init_1_agc_fsm_ram_init_ainc_1_setf(cl_hw, 0x1); + + while (i < size) { + riu_agcfsm_ram_init_2_set(cl_hw, *(u32 *)&buf[i]); + i += 4; + } + + /* Disable AGC FSM ram init state */ + riu_agcfsm_ram_init_1_agc_fsm_ram_init_en_setf(cl_hw, 0x0); + + kfree(buf); + + return 0; +} + +static int cl_load_agc_fw(struct cl_hw *cl_hw, const char *filename) +{ + int ret = 0; + + if (!cl_hw) + goto out; + + /* Switch AGC to programming mode */ + + /* Disable RIU Modules clocks (RC,LB,ModemB,FE,ADC,Regs,AGC,Radar) */ + modem_gcu_riu_clk_set(cl_hw, 0); + + /* Switch AGC MEM clock to 480MHz */ + modem_gcu_riu_clk_bw_agc_mem_clk_bw_setf(cl_hw, 3); + + /* Enable RIU Modules clocks (RC,LB,ModemB,FE,ADC,Regs,AGC,Radar) */ + modem_gcu_riu_clk_set(cl_hw, 0xFFFFFFFF); + + /* Assert AGC FSM reset */ + riu_rwnxagccntl_agcfsmreset_setf(cl_hw, 1); + + /* Load AGC RAM data */ + ret = cl_load_agc_data(cl_hw, filename); + if (ret) + goto out; + + /* Switch AGC back to operational mode */ + + /* Disable RIU Modules clocks (RC, LB, ModemB, FE, ADC, Regs, AGC, Radar) */ + modem_gcu_riu_clk_set(cl_hw, 0); + /* Switch AGC MEM clock back to 80M */ + modem_gcu_riu_clk_bw_agc_mem_clk_bw_setf(cl_hw, 1); + /* Enable RIU Modules clocks (RC, LB, ModemB, FE, ADC, Regs, AGC, Radar) */ + modem_gcu_riu_clk_set(cl_hw, 0xFFFFFFFF); + + /* Release AGC FSM reset */ + riu_rwnxagccntl_agcfsmreset_setf(cl_hw, 0); + +out: + return ret; +} + +int cl_radio_boot(struct cl_chip *chip) +{ + int ret = 0; + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + struct cl_hw *cl_hw_tcv1 = chip->cl_hw_tcv1; + bool tcv0_enabled = cl_chip_is_tcv0_enabled(chip); + bool tcv1_enabled = cl_chip_is_tcv1_enabled(chip); + + /* Call only once per chip after ASIC reset - configure both phys */ + ret = cl_cmu_init(chip); + if (ret != 0) + goto out; + + cl_clk_init(chip); + cmu_phase_sel_set(chip, (CMU_GP_CLK_PHASE_SEL_BIT | + CMU_DAC_CDB_CLK_PHASE_SEL_BIT | + CMU_DAC_CLK_PHASE_SEL_BIT) & + ~(CMU_ADC_CDB_CLK_PHASE_SEL_BIT | + CMU_ADC_CLK_PHASE_SEL_BIT)); + + if (tcv0_enabled) { + mac_hw_mac_cntrl_1_active_clk_gating_setf(cl_hw_tcv0, 1); /* Disable MPIF clock */ + mac_hw_state_cntrl_next_state_setf(cl_hw_tcv0, 2); /* Move to doze */ + } + + if (tcv1_enabled) { + mac_hw_mac_cntrl_1_active_clk_gating_setf(cl_hw_tcv1, 1); /* Disable MPIF clock */ + mac_hw_state_cntrl_next_state_setf(cl_hw_tcv1, 2); /* Move to doze */ + } + + /* Enable all PHY modules */ + cl_phy_enable(cl_hw_tcv0); + cl_phy_enable(cl_hw_tcv1); + + if (tcv0_enabled) { + mac_hw_doze_cntrl_2_wake_up_sw_setf(cl_hw_tcv0, 1); /* Exit from doze */ + mac_hw_state_cntrl_next_state_setf(cl_hw_tcv0, 0); /* Move to idle */ + } + + if (tcv1_enabled) { + mac_hw_doze_cntrl_2_wake_up_sw_setf(cl_hw_tcv1, 1); /* Exit from doze */ + mac_hw_state_cntrl_next_state_setf(cl_hw_tcv1, 0); /* Move to idle */ + } + + cl_riu_clk_bw_init(cl_hw_tcv0); + cl_riu_clk_bw_init(cl_hw_tcv1); + + /* Load RIU re-sampling filter memory with coefficients */ + ret = cl_load_riu_rsf_memory(chip, "riu_rsf.bin"); + if (ret != 0) { + pr_err("cl_load_riu_rsf_memory failed with error code %d.\n", ret); + goto out; + } + + /* Load AGC FW */ + ret = cl_load_agc_fw(cl_hw_tcv0, "agcram.bin"); + if (ret) { + pr_err("cl_load_agc_fw failed for tcv0 with error code %d.\n", ret); + goto out; + } + + ret = cl_load_agc_fw(cl_hw_tcv1, "agcram.bin"); + if (ret) { + pr_err("cl_load_agc_fw failed for tcv1 with error code %d.\n", ret); + goto out; + } + + /* AFE Registers configuration */ + ret = cl_afe_cfg(chip); + +out: + return ret; +} + +static void cl_restore_ela_state(struct cl_hw *cl_hw) +{ + struct cl_recovery_db *recovery_db = &cl_hw->recovery_db; + + /* Restore eLA state after MAC-HW reset */ + if (recovery_db->ela_en) { + mac_hw_debug_port_sel_a_set(cl_hw, recovery_db->ela_sel_a); + mac_hw_debug_port_sel_b_set(cl_hw, recovery_db->ela_sel_b); + mac_hw_debug_port_sel_c_set(cl_hw, recovery_db->ela_sel_c); + } + + mac_hw_debug_port_en_set(cl_hw, recovery_db->ela_en); +} + +int cl_radio_boot_recovery(struct cl_hw *cl_hw) +{ + int ret = 0; + + mac_hw_mac_cntrl_1_active_clk_gating_setf(cl_hw, 1); /* Disable MPIF clock */ + mac_hw_state_cntrl_next_state_setf(cl_hw, 2); /* Move to doze */ + + /* Enable all PHY modules */ + cl_phy_enable(cl_hw); + + /* Restart LCU recording */ + if (cl_hw_is_tcv0(cl_hw)) + lcu_phy_lcu_ch_0_stop_set(cl_hw, 0); + else + lcu_phy_lcu_ch_1_stop_set(cl_hw, 0); + + cl_restore_ela_state(cl_hw); + + mac_hw_doze_cntrl_2_wake_up_sw_setf(cl_hw, 1); /* Exit from doze */ + mac_hw_state_cntrl_next_state_setf(cl_hw, 0); /* Move to idle */ + + cl_riu_clk_bw_init(cl_hw); + + /* Load RIU re-sampling filter memory with coefficients */ + ret = cl_load_riu_rsf_memory_recovery(cl_hw, "riu_rsf.bin"); + if (ret != 0) { + pr_err("cl_load_riu_rsf_memory failed with error code %d.\n", ret); + goto out; + } + + /* Load AGC FW */ + ret = cl_load_agc_fw(cl_hw, "agcram.bin"); + if (ret) { + pr_err("cl_load_agc_fw failed for with error code %d.\n", ret); + goto out; + } + +out: + return ret; +} + +#define NOISE_MAX_ANT_PER_REG 4 + +void cl_noise_init(struct cl_hw *cl_hw) +{ + struct cl_noise_db *noise_db = &cl_hw->noise_db; + + INIT_LIST_HEAD(&noise_db->reg_list); +} + +void cl_noise_close(struct cl_hw *cl_hw) +{ + struct cl_noise_db *noise_db = &cl_hw->noise_db; + struct cl_noise_reg *elem = NULL; + struct cl_noise_reg *tmp = NULL; + + list_for_each_entry_safe(elem, tmp, &noise_db->reg_list, list) { + list_del(&elem->list); + kfree(elem); + } +} + +void cl_noise_maintenance(struct cl_hw *cl_hw) +{ + struct cl_noise_db *noise_db = &cl_hw->noise_db; + struct cl_noise_reg *reg = NULL; + u8 ch_bw = cl_hw->bw; + + if (noise_db->sample_cnt == 0) + return; + + reg = kzalloc(sizeof(*reg), GFP_ATOMIC); + + if (!reg) + return; + + /*collect statistics */ + reg->np_prim20_per_ant = riu_agcinbdpow_20_pnoisestat_get(cl_hw); + reg->np_sub20_per_chn = riu_agcinbdpownoiseper_20_stat_0_get(cl_hw); + reg->np_sec20_dens_per_ant = riu_agcinbdpowsecnoisestat_get(cl_hw); + reg->nasp_prim20_per_ant = riu_inbdpowformac_0_get(cl_hw); + reg->nasp_sub20_per_chn = riu_inbdpowformac_3_get(cl_hw); + reg->nasp_sec20_dens_per_ant = riu_inbdpowformac_2_get(cl_hw); + + if (ch_bw == CHNL_BW_160) { + reg->np_sub20_per_chn2 = riu_agcinbdpownoiseper_20_stat_1_get(cl_hw); + reg->nasp_sub20_per_chn2 = riu_inbdpowformac_4_get(cl_hw); + } + + if (cl_hw->num_antennas > NOISE_MAX_ANT_PER_REG) { + reg->np_prim20_per_ant2 = riu_agcinbdpow_20_pnoisestat_2_get(cl_hw); + reg->nasp_prim20_per_ant2 = riu_inbdpowformac_1_get(cl_hw); + } + + list_add(®->list, &noise_db->reg_list); + + noise_db->sample_cnt--; + + if (noise_db->sample_cnt == 0) + pr_debug("record done\n"); +} + +/** DOC: RSSI tracking + * + * RSSI values of association packets (request in AP mode and respone in STA mode) + * are not added to rssi pool sample, because at this stage station is not added + * to driver database. + * RSSI of association is important for WRS in order to select its initial rate. + * The goal of this code is to save MAC address and RSSI values of all association + * packets, and after station fully connects, search for the correct RSSI and add + * it to the rssi pool sample. + */ +struct assoc_queue_elem { + struct list_head list; + u8 addr[ETH_ALEN]; + s8 rssi[MAX_ANTENNAS]; + unsigned long timestamp; +}; + +#define CL_RSSI_LIFETIME_MS 5000 + +static void cl_rssi_add_to_wrs(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]) +{ + struct cl_wrs_rssi *wrs_rssi = &cl_sta->wrs_rssi; + int i = 0; + + for (i = 0; i < cl_hw->num_antennas; i++) + wrs_rssi->sum[i] += rssi[i]; + + wrs_rssi->cnt++; +} + +void cl_rssi_assoc_init(struct cl_hw *cl_hw) +{ + INIT_LIST_HEAD(&cl_hw->assoc_queue.list); + spin_lock_init(&cl_hw->assoc_queue.lock); +} + +void cl_rssi_assoc_exit(struct cl_hw *cl_hw) +{ + /* Delete all remaining elements in list */ + spin_lock_bh(&cl_hw->assoc_queue.lock); + + if (!list_empty(&cl_hw->assoc_queue.list)) { + struct assoc_queue_elem *elem = NULL; + struct assoc_queue_elem *tmp = NULL; + + list_for_each_entry_safe(elem, tmp, &cl_hw->assoc_queue.list, list) { + list_del(&elem->list); + kfree(elem); + } + } + + spin_unlock_bh(&cl_hw->assoc_queue.lock); +} + +void cl_rssi_assoc_handle(struct cl_hw *cl_hw, u8 *mac_addr, struct hw_rxhdr *rxhdr) +{ + /* Allocate new element and add to list */ + struct assoc_queue_elem *elem = kmalloc(sizeof(*elem), GFP_ATOMIC); + + if (elem) { + INIT_LIST_HEAD(&elem->list); + cl_mac_addr_copy(elem->addr, mac_addr); + + elem->rssi[0] = (s8)rxhdr->rssi1; + elem->rssi[1] = (s8)rxhdr->rssi2; + elem->rssi[2] = (s8)rxhdr->rssi3; + elem->rssi[3] = (s8)rxhdr->rssi4; + elem->rssi[4] = (s8)rxhdr->rssi5; + elem->rssi[5] = (s8)rxhdr->rssi6; + + elem->timestamp = jiffies; + + spin_lock(&cl_hw->assoc_queue.lock); + list_add(&elem->list, &cl_hw->assoc_queue.list); + spin_unlock(&cl_hw->assoc_queue.lock); + } +} + +void cl_rssi_assoc_find(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 num_sta) +{ + /* Search for rssi of association according to mac address */ + spin_lock_bh(&cl_hw->assoc_queue.lock); + + if (!list_empty(&cl_hw->assoc_queue.list)) { + unsigned long lifetime = 0; + struct assoc_queue_elem *elem = NULL; + struct assoc_queue_elem *tmp = NULL; + + list_for_each_entry_safe(elem, tmp, &cl_hw->assoc_queue.list, list) { + lifetime = jiffies_to_msecs(jiffies - elem->timestamp); + + /* Check lifetime of rssi before using it */ + if (lifetime > CL_RSSI_LIFETIME_MS) { + /* Delete element from list */ + list_del(&elem->list); + kfree(elem); + continue; + } + + if (ether_addr_equal(elem->addr, cl_sta->addr)) { + struct hw_rxhdr rxhdr; + s8 equivalent_rssi = cl_rssi_calc_equivalent(cl_hw, elem->rssi); + + rxhdr.rssi1 = elem->rssi[0]; + rxhdr.rssi2 = elem->rssi[1]; + rxhdr.rssi3 = elem->rssi[2]; + rxhdr.rssi4 = elem->rssi[3]; + rxhdr.rssi5 = elem->rssi[4]; + rxhdr.rssi6 = elem->rssi[5]; + + cl_rssi_rx_handler(cl_hw, cl_sta, &rxhdr, equivalent_rssi); + + /* Delete element from list */ + list_del(&elem->list); + kfree(elem); + } + } + } + + spin_unlock_bh(&cl_hw->assoc_queue.lock); +} + +void cl_rssi_sort_descending(s8 rssi[MAX_ANTENNAS], u8 num_ant) +{ + int i, j; + + for (i = 0; i < num_ant - 1; i++) + for (j = 0; j < num_ant - i - 1; j++) + if (rssi[j] < rssi[j + 1]) + swap(rssi[j], rssi[j + 1]); +} + +static s8 cl_rssi_equivalent_2_phys(s8 rssi_max, s8 rssi_min) +{ + s8 rssi_diff = rssi_min - rssi_max; + + if (rssi_diff > (-2)) + return (rssi_max + 3); + else if (rssi_diff > (-5)) + return (rssi_max + 2); + else if (rssi_diff > (-9)) + return (rssi_max + 1); + else + return rssi_max; +} + +s8 cl_rssi_calc_equivalent(struct cl_hw *cl_hw, s8 rssi[MAX_ANTENNAS]) +{ + s8 rssi_tmp[MAX_ANTENNAS] = {0}; + u8 rx_ant = cl_hw->num_antennas; + int i, j; + + /* Copy to rssi_tmp */ + memcpy(rssi_tmp, rssi, rx_ant); + + /* Sort the rssi's in desceding order */ + cl_rssi_sort_descending(rssi_tmp, rx_ant); + + /* + * 1) Calc equivalent rssi between the two lowest values. + * 2) Sort again + * 3) Repeat steps 1 and 2 according to number of antennas. + */ + for (i = 0; i < rx_ant - 1; i++) { + rssi_tmp[rx_ant - i - 2] = cl_rssi_equivalent_2_phys(rssi_tmp[rx_ant - i - 2], + rssi_tmp[rx_ant - i - 1]); + + for (j = rx_ant - i - 2; j > 0; j--) { + if (rssi_tmp[j] > rssi_tmp[j - 1]) + swap(rssi_tmp[j], rssi_tmp[j - 1]); + else + break; + } + } + + return rssi_tmp[0]; +} + +s8 cl_rssi_get_strongest(struct cl_hw *cl_hw, s8 rssi[MAX_ANTENNAS]) +{ + int i; + s8 strongest_rssi = S8_MIN; + + for (i = 0; i < cl_hw->num_antennas; i++) { + if (rssi[i] > strongest_rssi) + strongest_rssi = rssi[i]; + } + + return strongest_rssi; +} + +static void cl_update_sta_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + s8 rssi[MAX_ANTENNAS], s8 equivalent_rssi) +{ + /* Last RSSI */ + memcpy(cl_sta->last_rssi, rssi, cl_hw->num_antennas); + + if (cl_sta->manual_alpha_rssi) + return; + + /* Alpha RSSI - use alpha filter (87.5% current + 12.5% new) */ + if (cl_sta->alpha_rssi) + cl_sta->alpha_rssi = + ((cl_sta->alpha_rssi << 3) - cl_sta->alpha_rssi + equivalent_rssi) >> 3; + else + cl_sta->alpha_rssi = equivalent_rssi; +} + +static bool cl_rssi_is_valid_ru_type_factor(u8 ru_type) +{ + return (ru_type >= CL_MU_OFDMA_RU_TYPE_26 && ru_type <= CL_MU_OFDMA_RU_TYPE_106); +} + +static void cl_rssi_agg_ind_rssi_values_fill(struct cl_hw *cl_hw, + struct cl_agg_tx_report *agg_report, + s8 *rssi_buf) +{ + /* Fill the rssi buffer with the correct rssi values */ + switch (cl_hw->first_riu_chain) { + case 0: + rssi_buf[0] = agg_report->rssi1; + rssi_buf[1] = agg_report->rssi2; + rssi_buf[2] = agg_report->rssi3; + rssi_buf[3] = agg_report->rssi4; + rssi_buf[4] = agg_report->rssi5; + rssi_buf[5] = agg_report->rssi6; + break; + case 1: + rssi_buf[0] = agg_report->rssi2; + rssi_buf[1] = agg_report->rssi3; + rssi_buf[2] = agg_report->rssi4; + rssi_buf[3] = agg_report->rssi5; + rssi_buf[4] = agg_report->rssi6; + break; + case 2: + rssi_buf[0] = agg_report->rssi3; + rssi_buf[1] = agg_report->rssi4; + rssi_buf[2] = agg_report->rssi5; + rssi_buf[3] = agg_report->rssi6; + break; + case 3: + rssi_buf[0] = agg_report->rssi4; + rssi_buf[1] = agg_report->rssi5; + rssi_buf[2] = agg_report->rssi6; + break; + case 4: + rssi_buf[0] = agg_report->rssi5; + rssi_buf[1] = agg_report->rssi6; + break; + case 5: + rssi_buf[0] = agg_report->rssi6; + break; + default: + break; + } +} + +void cl_rssi_block_ack_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report) +{ + /* Handle RSSI of block-ack's */ + union cl_rate_ctrl_info rate_ctrl_info = { + .word = le32_to_cpu(agg_report->rate_cntrl_info)}; + u8 bw = rate_ctrl_info.field.bw; + + s8 rssi[MAX_ANTENNAS]; + s8 equivalent_rssi; + int i; + + cl_rssi_agg_ind_rssi_values_fill(cl_hw, agg_report, rssi); + + if (cl_hw->rssi_simulate) + for (i = 0; i < cl_hw->num_antennas; i++) + rssi[i] = cl_hw->rssi_simulate; + + if (!cl_hw->rssi_simulate) { + union cl_rate_ctrl_info_he rate_ctrl_info_he = { + .word = le32_to_cpu(agg_report->rate_cntrl_info_he)}; + u8 ru_type = rate_ctrl_info_he.field.ru_type; + u8 format_mode = rate_ctrl_info.field.format_mod; + s8 bw_factor = 0; + + /* + * RSSI adjustment according to BW + * The BA is transmitted in the BW of the aggregation it acknowledges + */ + if (format_mode == FORMATMOD_HE_MU && + cl_rssi_is_valid_ru_type_factor(ru_type)) { + if (ru_type == CL_MU_OFDMA_RU_TYPE_26) + bw_factor = -9; + else if (ru_type == CL_MU_OFDMA_RU_TYPE_52) + bw_factor = -6; + else if (ru_type == CL_MU_OFDMA_RU_TYPE_106) + bw_factor = -3; + } else { + if (bw == CHNL_BW_160) + bw_factor = 9; + else if (bw == CHNL_BW_80) + bw_factor = 6; + else if (bw == CHNL_BW_40) + bw_factor = 3; + } + + for (i = 0; i < cl_hw->num_antennas; i++) + rssi[i] += bw_factor; + } + + equivalent_rssi = cl_rssi_calc_equivalent(cl_hw, rssi); + + /* Handle RSSI after BW adjustment */ + cl_rssi_add_to_wrs(cl_hw, cl_sta, rssi); + cl_stats_update_rx_rssi(cl_hw, cl_sta, rssi); + cl_vns_handle_rssi(cl_hw, cl_sta, rssi); + cl_update_sta_rssi(cl_hw, cl_sta, rssi, equivalent_rssi); + cl_motion_sense_rssi_ba(cl_hw, cl_sta, rssi); +} + +void cl_rssi_rx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr, s8 equivalent_rssi) +{ + /* Called after BW adjustment */ + s8 rssi[MAX_ANTENNAS] = RX_HDR_RSSI(rxhdr); + + if (!IS_REAL_PHY(cl_hw->chip) && rssi[0] == 0) + return; + + cl_rssi_add_to_wrs(cl_hw, cl_sta, rssi); + cl_stats_update_rx_rssi(cl_hw, cl_sta, rssi); + cl_vns_handle_rssi(cl_hw, cl_sta, rssi); + cl_update_sta_rssi(cl_hw, cl_sta, rssi, equivalent_rssi); +} + +void cl_rssi_bw_adjust(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, s8 bw_factor) +{ + if (cl_hw->rssi_simulate) + return; + + rxhdr->rssi1 += bw_factor; + rxhdr->rssi2 += bw_factor; + rxhdr->rssi3 += bw_factor; + rxhdr->rssi4 += bw_factor; + rxhdr->rssi5 += bw_factor; + rxhdr->rssi6 += bw_factor; +} + +void cl_rssi_simulate(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr) +{ + rxhdr->rssi1 = cl_hw->rssi_simulate; + rxhdr->rssi2 = cl_hw->rssi_simulate; + rxhdr->rssi3 = cl_hw->rssi_simulate; + rxhdr->rssi4 = cl_hw->rssi_simulate; + rxhdr->rssi5 = cl_hw->rssi_simulate; + rxhdr->rssi6 = cl_hw->rssi_simulate; +} + +#define CCA_CNT_RATE_40MHZ 3 + +static void cl_cca_reset_phy_counters(struct cl_hw *cl_hw) +{ + riu_rwnxagccca_1_cca_cnt_clear_setf(cl_hw, 1); + riu_rwnxagccca_1_cca_cnt_clear_setf(cl_hw, 0); +} + +void cl_cca_init(struct cl_hw *cl_hw) +{ + /* Set PHY registers rate */ + riu_rwnxagccca_1_cca_cnt_rate_setf(cl_hw, CCA_CNT_RATE_40MHZ); +} + +void cl_cca_maintenance(struct cl_hw *cl_hw) +{ + struct cl_cca_db *cca_db = &cl_hw->cca_db; + unsigned long time = jiffies_to_usecs(jiffies); + unsigned long diff_time = time - cca_db->time; + + cca_db->time = time; + if (!diff_time) + return; + + /* Rest PHY counters */ + cl_cca_reset_phy_counters(cl_hw); +} + +void cl_prot_mode_init(struct cl_hw *cl_hw) +{ + struct cl_prot_mode *prot_mode = &cl_hw->prot_mode; + u8 init = cl_hw->conf->ce_prot_mode; + + prot_mode->current_val = init; + prot_mode->default_val = init; + prot_mode->dynamic_val = (init != TXL_NO_PROT) ? init : TXL_PROT_RTS_FW; +} + +void cl_prot_mode_set(struct cl_hw *cl_hw, u8 prot_mode_new) +{ + struct cl_prot_mode *prot_mode = &cl_hw->prot_mode; + struct cl_tcv_conf *conf = cl_hw->conf; + + if (prot_mode->current_val != prot_mode_new) { + prot_mode->current_val = prot_mode_new; + cl_msg_tx_prot_mode(cl_hw, + conf->ce_prot_log_nav_en, + prot_mode_new, + conf->ce_prot_rate_format, + conf->ce_prot_rate_mcs, + conf->ce_prot_rate_pre_type); + } +} + +u8 cl_prot_mode_get(struct cl_hw *cl_hw) +{ + return cl_hw->prot_mode.current_val; +} + +static u8 conv_to_fw_ac[EDCA_AC_MAX] = { + [EDCA_AC_BE] = AC_BE, + [EDCA_AC_BK] = AC_BK, + [EDCA_AC_VI] = AC_VI, + [EDCA_AC_VO] = AC_VO +}; + +static const char *edca_ac_str[EDCA_AC_MAX] = { + [EDCA_AC_BE] = "BE", + [EDCA_AC_BK] = "BK", + [EDCA_AC_VI] = "VI", + [EDCA_AC_VO] = "VO", +}; + +void cl_edca_hw_conf(struct cl_hw *cl_hw) +{ + u8 ac = 0; + struct cl_tcv_conf *conf = cl_hw->conf; + + for (ac = 0; ac < AC_MAX; ac++) { + struct edca_params params = { + .aifsn = conf->ce_wmm_aifsn[ac], + .cw_min = conf->ce_wmm_cwmin[ac], + .cw_max = conf->ce_wmm_cwmax[ac], + .txop = conf->ce_wmm_txop[ac] + }; + + cl_edca_set(cl_hw, ac, ¶ms, NULL); + } +} + +void cl_edca_set(struct cl_hw *cl_hw, u8 ac, struct edca_params *params, + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca) +{ + u32 edca_reg_val = 0; + + if (ac >= AC_MAX) { + pr_err("%s: Invalid AC index\n", __func__); + return; + } + + edca_reg_val = (u32)(params->aifsn); + edca_reg_val |= (u32)(params->cw_min << 4); + edca_reg_val |= (u32)(params->cw_max << 8); + edca_reg_val |= (u32)(params->txop << 12); + + memcpy(&cl_hw->edca_db.hw_params[ac], params, sizeof(struct edca_params)); + + cl_msg_tx_set_edca(cl_hw, conv_to_fw_ac[ac], edca_reg_val, mu_edca); + + cl_dbg_trace(cl_hw, "EDCA-%s: aifsn=%u, cw_min=%u, cw_max=%u, txop=%u\n", + edca_ac_str[ac], params->aifsn, params->cw_min, + params->cw_max, params->txop); +} + +void cl_edca_recovery(struct cl_hw *cl_hw) +{ + u8 ac; + + for (ac = 0; ac < AC_MAX; ac++) + cl_edca_set(cl_hw, ac, &cl_hw->edca_db.hw_params[ac], NULL); +} + From patchwork Tue May 24 11:34:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576843 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 E37B5C433F5 for ; Tue, 24 May 2022 11:40:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236660AbiEXLkK (ORCPT ); Tue, 24 May 2022 07:40:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236891AbiEXLkI (ORCPT ); Tue, 24 May 2022 07:40:08 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50045.outbound.protection.outlook.com [40.107.5.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 661738CCFF for ; Tue, 24 May 2022 04:39:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Y9jk1fJVpgxh1yYdUQsG6MrM+gMtVF1C9sJQZyjgV4b5x1jzfh0PL+c2GyDiTmkQqdqfCWGe14QPRVe/98nhuMOO86ohNciG7i5deW3INswAzPY8dHRqrm2q2Q8Awh4rn6ZUEBv4dNHdag3prDiboF72CNPKA0b9yE/QHsQnc9vEmG4zpCgUGzqiBl3ya1+dsVAKeUCK+m0iMZJwgis7MvM+zJKZVu1bRTyoWtebInWvS2IHH/dYNOahCmv93ijWSsjz+e0IybfmBiU6CpLo5j4v98VWLAj4fUd/IGQ4Xh77UQnZ5ZfHKh/iqtqAA+4JEI+BRnjwCy13XAbr97sVQA== 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=KN5/acjSrvju7EIG0eZqJXiXf6PPmxLqwR4iqqJGsXo=; b=Ke/rkm5B2aMGPG5g8IJvwSfyUsv7NEUALvmfHdDq3Ds8NXds0z2RqUVeJNFjjqk0tFfvLENRXZFkIRYFH6r7VouVBncVRAN34iWEf39L8INHKHkGNkHNOc1/Cqnv71X//mOr/9Chu8rmkwMPeIn3SQbJxyV02ANyNhfgekvazDosZrSlqxAZNTWn1UwzFVFkZY5GG2azVziVeiTBE/IrtN8/qfFswBLKedSN5bRJcWwZTdv2bbbkj890En9PT5KtVT69GupeXj/xpdR9gLlzExr3X3/dxJvlg+1FhZIKvkmE+VTsBArkj97/Ltl+Ox1uq4Ixdvb93zXMCmdjE9mugw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KN5/acjSrvju7EIG0eZqJXiXf6PPmxLqwR4iqqJGsXo=; b=Kf8ZyvhnfHEjiGLoeYtZK2JQxg9AkCLLuQJ85GzVBGzHTYFW3+0tElrF8nYrC4lLQvlr+ieIOdAW2LqAi26sKbJNQ52g6WqRSNTamTWkkQW0NxVPoCniZYIqE8B/lzG9VgKUNN/rtqoMLbU+I74A7RAiLKgTvEgBgIKP+cO4tek= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:52 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:52 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 57/96] cl8k: add radio.h Date: Tue, 24 May 2022 14:34:23 +0300 Message-Id: <20220524113502.1094459-58-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 12ba11b1-fb28-4320-7b11-08da3d79efca X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: J7XlE43Pq3iU9hJreqcCkE8AF4pVSfS+pkUCsNwZSEG4+Uvk9LKt3u+IeOqTxLo2NsZyjhgD1ZxCZBCZiZsaDsam9QauSkQrcEaO6qdXNrrleuE8uSr31/4TfBm2EqbgZZNeGNHkeZyp7ZUf78ReXqk+25kjLXk6M4npuoiacM2X1N6DSHHWiADIPGJOBzrJq8Vfo3ZBfWv9mquVTkjITupVSh9+rWXsXs3eIWlPNQ+yhTUMAGnoxXtGhjlSNI/yJigJR6PiV+AHXri7rzTO7kBbmf5guiJYjxQnaUJaZB4d9UYEjQrWA0jt7ShVMcKLRmvSzcaQGzAOorbgdlXliF3iauGrSpDoDujBT1TzCTj5oEL++yqIhAlVWzbEkzyv6zsTChn34e7V00t3qzhmZJwINbwfhFAQTz9k0DXtFa3LBkOkL2lCO+BtNBhPrbrOjLRHBakKDtBglkW2TSm4orYwJhHS1TxBIFcV3d2WOALzJtE8x+9lYi+b/jZY0O+9BW26KcAVojNV1BZLECnLl2F4TW/XG16496DH38UjuMJ3oXMvZ1Mjcd5zWvb6pBYnJSU9Ty7LN98pB5Qz9ZHbswlER92tfZs4EqHgsMqzW9otVmpJtiF7AGGVp6PLWI4EXfEMUz9jKVxQ8EzTlJ0Eo9kyVNDGwOPpT75bEntK80faaUu2OPuAnIlzwYK+MXUSLy4/2fbYlpwOuzGfOic1Rvw2fAuVT8Y8ZjZvS9A9T6A= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: /+fjcLxVwSrTTpnNQUdsZK8EkJpCEbBKw7yxdnkibOdaG/l+Lu+41V9963IVlotJ2iXoBbb1da33+QlM17WveeUAl1zMzF2eWe+UO2fHHKtdGYAN0auVob4qlbkLKphNf9+spCf0uNo0g13lABS3EJi0FIEpfcINbeuddtybyynK9JXAX5EvWwpVeQKuWNBTmGcpqOWkIHcdF77mrxynVIZJHEEBf0Pe6lAfwU8Tliq35dt9aMD1KApnHXZTMUrlvQRnonTFR6JBQLGiBfKt3G+UwYIRtkR3O+BDVsb2bHzH1d8RLaAnDuHdvrWI+CQWhwhIWWHM3Wf+g8IZi3vEggopsCHj1jCG+ok2JfYpnOb3Dl9iwv4kC3So/UG/iM3LPH7whCG9iwHieTOQBNC6hBmnj+WpP1Q+58yrMzzSq7bFJHAZ5A7UI3EgZ7HquHG2Ljqkxfv5xY8JFGhOaj8o2gxq1D7YetoYZlwU/lU+h+5lRw9B0TFKD4ghP6winxeTulkrs61Eh+RI8Tzp7dJngu02sOQ75HHvFG543sHyG/PenlkY6vBn7v0ntjlc4TXeI9feE5e88O+7mF2rfoJgEXVZSeyTxNv8QaKfqYD5eRFxHjJyvzDOHNFRZ+dV8vC9xnhJS30rGxSQxOHtuEEK+bINo2Nw6MreGWNlwa0+hTyKWWjJNeGS+PJDgEDn965gYXsNhVel3jmtcPKcPVlvk9aGslpyUEV8VF3xcPGMob8h6v7iosklO1a4U71SMmfR6XgTvmEPLc6kRxlMSDvs6IZW9yjKSeL2ENwHYk562xASDum8OrRexVnd3Co7aiCON8gbC8UU6MH0GjOS/yj+Abzgl4IddCH0K28ZHmdhXA69x98wOKeHQyNNJRo3/NKbhbOOrPnQ74hC7p4tU66WAt7T8vxHo7XoJqnZzt8RZg2GkNC3DNjYYqcizT2cRwdSc39KAhzQLQj5ePC0HKkVn7t0oAvUZx9KtbtrywImott/nXHMsN1idezf0har1+HIDrAicCLtHC3DCA/dkaMnzP+3dquS1NSwdyPQcSNYOO+0ai43ZhCNeZYezTpQOn5G1rAnovyQ80XTqHSHQTm56YdvYdgBJBW2F00f1EaHfbVRYHW1n7wzPh9zeE6GeMKZnJKKvJxPL6uol4RltYX5KWQ7n+X8NLEumbkjGzTC8UOz4464Q9KhG8NrXtiotKUF2y6YY2hkhQdilRYaDKewzTK/IHfTQagPa1GHvgzsQtJXb/HRxof9m5lj3dirTUD0ZGjUBR/a9llq2J3XA3+AVRl1eZ25CN3uIQBfE4860flvrmbq4oBBpMmm34MmhKViKsg5TX24IXx0gmZhYyvEYLFXc5unzDN45/HsIwHO+O4is4rB0YvK+jRvrYb9zHxQf8oQy/GWDbV/EAGAnH1ScJsTNAjtGQdNzcXRqqpPy8qMIVEkzWnJDj5UZRhCv5E7uv9dNereGaCY9iZfewF8juS/OZwq0QQijp63FElu7iuz6H2TZRWObhUp2CBg1m4KS8T38qFQe1w2ypVj6p2gEUQyCt+IzJsWjeOoiKOaz2BvCuOWDZwcRtR5K7Qj1ZcJxGO50BgyCexn+souxSNgPDHAiPk9NCB+rWosC+YOwlT5I3qahFA92u+er2RTLz0XmnQYPayYIomHOsSyO4vcGEld+/a/SGUai9m2zEO3J3/Mxg+L/EOUIsCrN+W6U6VdKtFbrK0JWfrsSVV5VjSwURO7nReei8YF1mlhEkWX80E= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 12ba11b1-fb28-4320-7b11-08da3d79efca X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:35.0970 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: jCpYLw2sCQHXtc+cIi0lryS4G39qjWRkwOU2px2erXhqTBNHnIho4KmTlWsIkKbgN78URtkPp+UGkDzQQMxmdA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/radio.h | 130 +++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/radio.h diff --git a/drivers/net/wireless/celeno/cl8k/radio.h b/drivers/net/wireless/celeno/cl8k/radio.h new file mode 100644 index 000000000000..b51dec5b7b1e --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/radio.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_RADIO_H +#define CL_RADIO_H + +#define RADIO_STATUS_OFF 0 +#define RADIO_STATUS_ON 1 +#define RADIO_STATUS_GOING_DOWN 2 + +int cl_radio_on(struct cl_hw *cl_hw); +void cl_radio_off_chip(struct cl_chip *chip); +void cl_radio_on_chip(struct cl_chip *chip); +bool cl_radio_is_off(struct cl_hw *cl_hw); +bool cl_radio_is_on(struct cl_hw *cl_hw); +bool cl_radio_is_going_down(struct cl_hw *cl_hw); +void cl_radio_on_start(struct cl_hw *cl_hw); +int cl_radio_boot(struct cl_chip *chip); +int cl_radio_boot_recovery(struct cl_hw *cl_hw); +/* Wakes up cl_radio_off_kthread after all the stations have disconnected. */ +void cl_radio_off_wake_up(struct cl_hw *cl_hw); + +struct cl_noise_reg { + struct list_head list; + u32 np_prim20_per_ant; + u32 np_prim20_per_ant2; + u32 nasp_prim20_per_ant; + u32 nasp_prim20_per_ant2; + u32 np_sub20_per_chn; + u32 np_sub20_per_chn2; + u32 nasp_sub20_per_chn; + u32 nasp_sub20_per_chn2; + u32 np_sec20_dens_per_ant; + u32 nasp_sec20_dens_per_ant; +}; + +struct cl_noise_db { + struct list_head reg_list; + bool hist_record; + u8 active_ant; + u8 sample_cnt; +}; + +void cl_noise_init(struct cl_hw *cl_hw); +void cl_noise_close(struct cl_hw *cl_hw); +void cl_noise_maintenance(struct cl_hw *cl_hw); + +#define RX_HDR_RSSI(rxhdr) \ + {(rxhdr)->rssi1, (rxhdr)->rssi2, (rxhdr)->rssi3, \ + (rxhdr)->rssi4, (rxhdr)->rssi5, (rxhdr)->rssi6} + +struct cl_assoc_queue { + struct list_head list; + spinlock_t lock; +}; + +void cl_rssi_assoc_init(struct cl_hw *cl_hw); +void cl_rssi_assoc_exit(struct cl_hw *cl_hw); +void cl_rssi_assoc_handle(struct cl_hw *cl_hw, u8 *mac_addr, struct hw_rxhdr *rxhdr); +void cl_rssi_assoc_find(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 num_sta); +void cl_rssi_sort_descending(s8 rssi[MAX_ANTENNAS], u8 num_ant); +s8 cl_rssi_calc_equivalent(struct cl_hw *cl_hw, s8 rssi[MAX_ANTENNAS]); +s8 cl_rssi_get_strongest(struct cl_hw *cl_hw, s8 rssi[MAX_ANTENNAS]); +void cl_rssi_block_ack_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report); +void cl_rssi_rx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr, s8 equivalent_rssi); +void cl_rssi_bw_adjust(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, s8 bw_factor); +void cl_rssi_simulate(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr); + +/** + * CCA (=Clear Channel Assessment) + */ + +struct cl_cca_db { + unsigned long time; +}; + +void cl_cca_maintenance(struct cl_hw *cl_hw); +void cl_cca_init(struct cl_hw *cl_hw); + +/** + * Protection mode (RTS/CTS) control + */ +enum cl_txl_prot_mode { + TXL_NO_PROT, + TXL_PROT_RTS, + TXL_PROT_CTS, + TXL_PROT_RTS_FW, + TXL_PROT_CTS_FW, + + TXL_PROT_MAX, +}; + +struct cl_prot_mode { + u8 current_val; + u8 default_val; + u8 dynamic_val; +}; + +void cl_prot_mode_init(struct cl_hw *cl_hw); +void cl_prot_mode_set(struct cl_hw *cl_hw, u8 prot_mode_new); +u8 cl_prot_mode_get(struct cl_hw *cl_hw); + +enum edca_ac { + EDCA_AC_BE, + EDCA_AC_BK, + EDCA_AC_VI, + EDCA_AC_VO, + + EDCA_AC_MAX +}; + +struct edca_params { + u16 txop; + u8 cw_max; + u8 cw_min; + u8 aifsn; +}; + +struct cl_edca_db { + struct edca_params hw_params[AC_MAX]; +}; + +void cl_edca_hw_conf(struct cl_hw *cl_hw); +void cl_edca_set(struct cl_hw *cl_hw, u8 ac, struct edca_params *params, + struct ieee80211_he_mu_edca_param_ac_rec *mu_edca); +void cl_edca_recovery(struct cl_hw *cl_hw); + +#endif /* CL_RADIO_H */ From patchwork Tue May 24 11:34:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576838 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 B4F83C433F5 for ; Tue, 24 May 2022 11:40:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236060AbiEXLkq (ORCPT ); Tue, 24 May 2022 07:40:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236941AbiEXLkm (ORCPT ); Tue, 24 May 2022 07:40:42 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50088.outbound.protection.outlook.com [40.107.5.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78AFB53E2D for ; Tue, 24 May 2022 04:40:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KWxQbNGLEpPvYjBAbPozztwqyoZhhuyjTSnBcp04u3nYaQdBEBOcfjxvSgT+sysoqy9qA7OWOD6Te6iNOhUaNFp0cVcC0abU4i8+wPQGLcQMst6YibeOEsuLhbLH02bi5Wu636g9Fkvy9Vvv9x9LOx2BIqb6gHIJzWXOWwp33kPO2kvLriz2iQYa2ZGcVEQqKN/JPIHo5EChUgCd+Eg1G3xUiIWYXEBTa6VJ9/uN0edq7H9/QEcAkoyQN54J9GscScdS69zT62b7i2vxBw9WeUkz+KDlDbvwUe0XDprJYWrb628dE06cnRVbaBACOYfhbCFEI2nE1CErLPMRbBpICQ== 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=WWrbZ5S+z5RiqKUpeoLStNT8JsQ8SMq6AS9e/O+xZXI=; b=K1RHzkPOdUkiOB+NKiWSwlQIiTeA8b0lII6wYqjbXxwhIddxoUmhlmCX4u+SfaJswxVc/zhGJB69iPHAxUE3FonE0/7WcCWqfQ3giDLKbFwQVUq8fc8WvSHlXeWJd7Y0EbK+wvq8502KOER2a9REhH1BYAhrUvcOVoPa5/nv6Xe38762n766DnbTgiihbipOoHAh0EoyxjIBU4+VtSN3nqSOwh7bol2sPb4lQrjtXSis2G301tASt1CidH6/zNkD8B0Mvzxt1up52YhM7YLciz3JoYQdrW/P9AYe3Tmx8XIojzMT3p44tOP20of22K/EbgTk9x1g3/Mr/wNOfwKLFw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WWrbZ5S+z5RiqKUpeoLStNT8JsQ8SMq6AS9e/O+xZXI=; b=nHniJs5Eue6A60UVaLTwgl9fdjnnTgdtQ6VCf0mqFSA1eysCjuIFmaFCI+M3qoKVlJrE1Ptf479IWmHaFawwzPx5ORh8MaSyS6NzBgPH4LPg+ndNBzKaLpKwKc1bfoNCEVVk1VuyFjGyeonSfsxArg3Mb9B3MJnyNg2rWtoLXXc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:38:52 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:52 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 58/96] cl8k: add rates.c Date: Tue, 24 May 2022 14:34:24 +0300 Message-Id: <20220524113502.1094459-59-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2c749784-4668-4dfd-8b77-08da3d79f033 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: RaWQ0KgPhK3q1SowEE7PD4aBUyxC2ZATJPNX4gMIxq+VgzN9Bh5oT8h008vqM+sYC0HX3uoPg7aA280Jjpw+HSbXN5FWMBmLMYtJuj1PQQEJ7Yar0OHFOY9uP/8BJtRQ/8U6td3BtXWG090KnU+0Gnfa8GtOg0LxAbtW6jswSyaI49joWUoOzv8y4a9evt8+xDcAFht4K/jT15gRCrmPYJHcPOfgglxkzzGGcKnM2lGcrZbdfhAvo/PTiSGzN0TNX51W4kcBd20yI3p6YBZWMf+9S/n01XvaGLh9OsSXCLPrD9nNII362PY6gKxsNNzDloNuXKZdvYCqXV3LTERJ5I/y53Se/Kllmi0E7DmUHGL4EZ8omJKrDrTdutthJssw8eRaCal2I8IqgcOXg7Jc7UZxZgDd3DSxV6RaA4S1Ygw3b26wKYQdnCjfc2hXTEON2dhpPbMUpcI5bMRSwi7R1Lmfh6FvMzydmjlVI3bLQ1W83B1cTV8BG5rMvUL+oSGuj4R91NxvpTMKaxF7pqV0u0jwL8GZZj42bYwKmFAsbG3za3rJsjo3HW9qSf5Xky7cU1Mwj3060ANP07SvDOCVPTbznM8lnhybaaN75+HPvB9pKSL7VbDHeJmXEQUkyL+6lT0JiY+ovGkQKlPKEZeZwQoYB9mI3HqEGGSXDlM7rFjr0hK3v0C6zlqUp4SCbEMPK4OAOR8R2pyP+qcp6p9jRWO0IvDjct8zPzwuheptrpY= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6666004)(6506007)(2906002)(83380400001)(508600001)(30864003)(5660300002)(6486002)(26005)(32563001)(559001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: nF59FMPeZaDLSKbTFAs0P4zIwSSWlH1akFKFjYJ62p04ogPoMNr5wE6AfmhwvjCRPFEHLlCMjfqKn95J7WH1BakoZ4Nb0eDonJJcVsjCYq7g+cTR820hPzcnH7HcmyJgEFNAOhHLgi94xPRTGwAlAsogWblSwZf5vH3c7rCXUhfOdEsVG84wicrkNpBmxVEe/9OoA+7CFVTCJUBIaBA2zuVoSp+iV75amr4J06pabG+Kw4p2sMwY8G2BFGZRYa+zRG4SUuoYrbrFYNwEuaf+qxkEWAj6Wsap9REzsLXPSB5ZMlpd/+3dE6v56OuwLbwnbIsbgYICxuRPac5yw+n44GJjFlIOC6oIikT7NzF1Z+fm+d3qvORz20P6DORtwrL1SSMr9yYE1v4Yz6ce2vOCWA6IigXucf18a0KlDWX1uOBLcpyfzP4GhFCH7bMb/Dr7JzpJ1cVImuN9KiNrjqgReTBtCJV10Fd4JlrvNGEe4NK9abIlLIDxDcI0ylvwJmIoE/G7dM7AtgJanqEZu1QqYUhTi7FS2HnnpQAGxgByfZXp86KbY5hgapbib/nJBTiSF+YF+5an8YH2ReSt+U3mpkEBFd6AJropIDEp08T3y7UAlIbtfS3vrvzE3lCbgqktn5zwaIR0DYPPnQtVVUduKTIK6xTfryLBhdjtWrNE26j5l2uw3O5ASgUNahytt+0Cz8X6D2n5hfrdz1cjSAkSRJQt0IVpcyNakq+WrGEaghqUuEiOjRoOnZqyEfDGfQWA5pdyCZFgOwRxNvsQwBH9ic2yeJ/wTu1izRYiU5Ce4Zr08jpoE9SLs6QvAztlfTRCTDc39McxkJfdTIWFKIAL356XOKTEbAqAbn8yiapMs+hrEhGJhpM+rayPH2FsWhTaacES6CS+JYW/E2Z3drHY8YSX+6lf8wbAGXTHUgh6/aDufTFNRbf/LCMLIb2Dfs2lZIQKjYYfJa9CxkN0B2J9mTD8J1gMkWsRLuHLOKOX2QY+BKqOefk8T9jeN7PAS1VHUzWITQHXYH2DiSPImvQ9S1A9BwwuC+7klSxCZWUOJYXxGPtMi1f8GGS6FPa2JFOEBEqhAKRTE/VfHG/4jhSv1WcsRSXwjL4IIczo5rvJ1dE7f7g46F5N8EBCmPqEFo0nBtRycQXdHjhniEnt+VyFUfasSxWt+ZvmsV1hySesTZ7I1dIGBuZKAwKwTRkMU6xVEpeNMqar2M/PXjdkmQz4p2ts1edq5HGZTjo/7FT6zvrzRNq9+zsWW8FM6kSGcrZnJB9I4Cn31tBFDGLLj7rqJUKtjQ1F3UmzLRgOe/w00w6+j3EYSPLK7EbNM/rVd4WgeMYoUOnhLrHqig8OFW+K3fD0SY/+AZQmjQCZqVDvuKv0BLO0p+xpRuhOFiIlIRgACANZM9dJci2sisZqP0pCdNd2kC9Uk3Nxxy7NC9oE1unFSxFNRGu50cnF2DvyJ0myf8PhK+A5M8B82H+stT1zUvgdwugqXA7Z6enWX5BfMDMSg8UI55L1Y2s7a44fCU6FBKtgH6OQNnwOP7q/9xQ65sVO0PPhcPJGXTMkpK8dCSgr1oKID94zK6WEXmkFJ/i1uVzjotEGyQbSu5k6ls0sioPS5wVhBweZBYxr9e6tU3hzdD6lnjOAu+6EN5CAqGMfEgztywb9axVLtC3/b8tcNSxd3cRknUR66PFffkNFHZuOdDy4mXUU4OJKWxnTBBuxnlEix7IhhvEx6dWlJt3uN24TOytZX6jaHc5/Y0k5DZs= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2c749784-4668-4dfd-8b77-08da3d79f033 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:35.8780 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ICc1694ChMJK1u9SScy/BDTXg4aVbfVd0rgS31qvkWFL72PWLOMFR5rSrLaoEfzhPCPVD8AN2APi1U2ZrC9yAQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rates.c | 1570 ++++++++++++++++++++++ 1 file changed, 1570 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rates.c diff --git a/drivers/net/wireless/celeno/cl8k/rates.c b/drivers/net/wireless/celeno/cl8k/rates.c new file mode 100644 index 000000000000..8f21f3d6ff84 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rates.c @@ -0,0 +1,1570 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "tx.h" +#include "bf.h" +#include "utils.h" +#include "hw.h" +#include "rates.h" + +/* + * This table of rates was taken from IEEE 802.11ax Draft v3.3, 28.5. Parameters + * for HE-HE_MCSs. The units are 1/10 Mbs. Note that we don't support DCM, so it is + * not taken into account in this table. + */ +const u16 data_rate_he_x10[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE] = { + [CHNL_BW_20][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 73, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 81, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_0][WRS_GI_VSHORT] = 86, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 146, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 163, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_1][WRS_GI_VSHORT] = 172, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 219, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 244, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_2][WRS_GI_VSHORT] = 258, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 293, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 325, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_3][WRS_GI_VSHORT] = 344, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 439, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 488, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_4][WRS_GI_VSHORT] = 516, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 585, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 650, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_5][WRS_GI_VSHORT] = 688, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 658, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 731, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_6][WRS_GI_VSHORT] = 774, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 731, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 813, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_7][WRS_GI_VSHORT] = 860, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 878, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 975, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_8][WRS_GI_VSHORT] = 1032, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 975, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 1083, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_9][WRS_GI_VSHORT] = 1147, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_10][WRS_GI_LONG] = 1097, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_10][WRS_GI_SHORT] = 1219, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_10][WRS_GI_VSHORT] = 1290, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_11][WRS_GI_LONG] = 1219, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_11][WRS_GI_SHORT] = 1354, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_11][WRS_GI_VSHORT] = 1434, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 146, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 163, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_0][WRS_GI_VSHORT] = 172, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 293, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 325, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_1][WRS_GI_VSHORT] = 344, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 439, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 488, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_2][WRS_GI_VSHORT] = 516, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 585, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 650, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_3][WRS_GI_VSHORT] = 688, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 878, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 975, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_4][WRS_GI_VSHORT] = 1032, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 1170, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 1300, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_5][WRS_GI_VSHORT] = 1376, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 1316, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 1463, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_6][WRS_GI_VSHORT] = 1549, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 1463, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 1625, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_7][WRS_GI_VSHORT] = 1721, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 1755, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 1950, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_8][WRS_GI_VSHORT] = 2065, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 1950, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 2167, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_9][WRS_GI_VSHORT] = 2294, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_10][WRS_GI_LONG] = 2194, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_10][WRS_GI_SHORT] = 2438, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_10][WRS_GI_VSHORT] = 2581, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_11][WRS_GI_LONG] = 2438, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_11][WRS_GI_SHORT] = 2708, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_11][WRS_GI_VSHORT] = 2868, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 219, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 244, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_0][WRS_GI_VSHORT] = 258, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 439, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 488, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_1][WRS_GI_VSHORT] = 516, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 658, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 731, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_2][WRS_GI_VSHORT] = 774, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 878, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 975, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_3][WRS_GI_VSHORT] = 1032, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 1316, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 1463, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_4][WRS_GI_VSHORT] = 1549, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 1755, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 1950, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_5][WRS_GI_VSHORT] = 2065, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 1974, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 2194, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_6][WRS_GI_VSHORT] = 2323, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 2194, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 2438, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_7][WRS_GI_VSHORT] = 2581, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 2633, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 2925, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_8][WRS_GI_VSHORT] = 3097, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 2925, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 3250, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_9][WRS_GI_VSHORT] = 3441, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_10][WRS_GI_LONG] = 3291, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_10][WRS_GI_SHORT] = 3656, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_10][WRS_GI_VSHORT] = 3871, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_11][WRS_GI_LONG] = 3656, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_11][WRS_GI_SHORT] = 4063, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_11][WRS_GI_VSHORT] = 4301, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 293, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 325, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_0][WRS_GI_VSHORT] = 344, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 585, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 650, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_1][WRS_GI_VSHORT] = 688, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 878, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 975, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_2][WRS_GI_VSHORT] = 1032, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 1170, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 1300, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_3][WRS_GI_VSHORT] = 1376, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 1755, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 1950, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_4][WRS_GI_VSHORT] = 2065, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 2340, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 2600, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_5][WRS_GI_VSHORT] = 2753, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 2633, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 2925, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_6][WRS_GI_VSHORT] = 3097, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 2925, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 3250, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_7][WRS_GI_VSHORT] = 3441, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 3510, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 3900, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_8][WRS_GI_VSHORT] = 4129, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 3900, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 4333, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_9][WRS_GI_VSHORT] = 4588, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_10][WRS_GI_LONG] = 4388, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_10][WRS_GI_SHORT] = 4875, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_10][WRS_GI_VSHORT] = 5162, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_11][WRS_GI_LONG] = 4875, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_11][WRS_GI_SHORT] = 5417, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_11][WRS_GI_VSHORT] = 5735, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 146, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 163, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_0][WRS_GI_VSHORT] = 172, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 293, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 325, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_1][WRS_GI_VSHORT] = 344, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 439, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 488, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_2][WRS_GI_VSHORT] = 516, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 585, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 650, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_3][WRS_GI_VSHORT] = 688, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 878, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 975, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_4][WRS_GI_VSHORT] = 1032, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 1170, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 1300, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_5][WRS_GI_VSHORT] = 1376, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 1316, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 1463, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_6][WRS_GI_VSHORT] = 1549, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 1463, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 1625, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_7][WRS_GI_VSHORT] = 1721, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 1755, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 1950, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_8][WRS_GI_VSHORT] = 2065, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 1950, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 2167, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_9][WRS_GI_VSHORT] = 2294, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_10][WRS_GI_LONG] = 2194, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_10][WRS_GI_SHORT] = 2438, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_10][WRS_GI_VSHORT] = 2581, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_11][WRS_GI_LONG] = 2438, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_11][WRS_GI_SHORT] = 2708, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_11][WRS_GI_VSHORT] = 2868, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 293, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 325, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_0][WRS_GI_VSHORT] = 344, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 585, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 650, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_1][WRS_GI_VSHORT] = 688, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 878, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 975, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_2][WRS_GI_VSHORT] = 1032, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 1170, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 1300, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_3][WRS_GI_VSHORT] = 1376, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 1755, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 1950, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_4][WRS_GI_VSHORT] = 2065, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 2340, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 2600, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_5][WRS_GI_VSHORT] = 2753, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 2633, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 2925, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_6][WRS_GI_VSHORT] = 3097, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 2925, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 3250, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_7][WRS_GI_VSHORT] = 3441, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 3510, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 3900, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_8][WRS_GI_VSHORT] = 4129, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 3900, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 4333, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_9][WRS_GI_VSHORT] = 4588, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_10][WRS_GI_LONG] = 4388, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_10][WRS_GI_SHORT] = 4875, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_10][WRS_GI_VSHORT] = 5162, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_11][WRS_GI_LONG] = 4875, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_11][WRS_GI_SHORT] = 5417, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_11][WRS_GI_VSHORT] = 5735, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 439, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 488, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_0][WRS_GI_VSHORT] = 516, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 878, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 975, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_1][WRS_GI_VSHORT] = 1032, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 1316, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 1463, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_2][WRS_GI_VSHORT] = 1549, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 1755, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 1950, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_3][WRS_GI_VSHORT] = 2065, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 2633, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 2925, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_4][WRS_GI_VSHORT] = 3097, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 3510, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 3900, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_5][WRS_GI_VSHORT] = 4129, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 3949, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 4388, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_6][WRS_GI_VSHORT] = 4646, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 4388, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 4875, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_7][WRS_GI_VSHORT] = 5162, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 5265, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 5850, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_8][WRS_GI_VSHORT] = 6194, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 5850, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 6500, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_9][WRS_GI_VSHORT] = 6882, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_10][WRS_GI_LONG] = 6581, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_10][WRS_GI_SHORT] = 7313, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_10][WRS_GI_VSHORT] = 7743, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_11][WRS_GI_LONG] = 7313, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_11][WRS_GI_SHORT] = 8125, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_11][WRS_GI_VSHORT] = 8603, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 585, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 650, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_0][WRS_GI_VSHORT] = 688, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 1170, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 1300, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_1][WRS_GI_VSHORT] = 1376, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 1755, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 1950, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_2][WRS_GI_VSHORT] = 2065, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 2340, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 2600, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_3][WRS_GI_VSHORT] = 2753, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 3510, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 3900, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_4][WRS_GI_VSHORT] = 4129, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 4680, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 5200, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_5][WRS_GI_VSHORT] = 5506, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 5265, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 5850, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_6][WRS_GI_VSHORT] = 6194, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 5850, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 6500, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_7][WRS_GI_VSHORT] = 6882, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 7020, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 7800, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_8][WRS_GI_VSHORT] = 8259, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 7800, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 8667, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_9][WRS_GI_VSHORT] = 9176, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_10][WRS_GI_LONG] = 8775, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_10][WRS_GI_SHORT] = 9750, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_10][WRS_GI_VSHORT] = 10324, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_11][WRS_GI_LONG] = 9750, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_11][WRS_GI_SHORT] = 10833, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_11][WRS_GI_VSHORT] = 11471, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 306, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 340, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_0][WRS_GI_VSHORT] = 360, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 613, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 681, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_1][WRS_GI_VSHORT] = 721, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 919, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 1021, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_2][WRS_GI_VSHORT] = 1081, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 1225, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 1361, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_3][WRS_GI_VSHORT] = 1441, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 1838, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 2042, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_4][WRS_GI_VSHORT] = 2162, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 2450, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 2722, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_5][WRS_GI_VSHORT] = 2882, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 2756, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 3063, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_6][WRS_GI_VSHORT] = 3243, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 3063, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 3403, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_7][WRS_GI_VSHORT] = 3603, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 3675, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 4083, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_8][WRS_GI_VSHORT] = 4324, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 4083, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 4537, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_9][WRS_GI_VSHORT] = 4804, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_10][WRS_GI_LONG] = 4594, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_10][WRS_GI_SHORT] = 5104, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_10][WRS_GI_VSHORT] = 5404, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_11][WRS_GI_LONG] = 5104, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_11][WRS_GI_SHORT] = 5671, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_11][WRS_GI_VSHORT] = 6004, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 613, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 681, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_0][WRS_GI_VSHORT] = 721, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 1225, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 1361, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_1][WRS_GI_VSHORT] = 1441, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 1838, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 2042, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_2][WRS_GI_VSHORT] = 2162, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 2450, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 2722, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_3][WRS_GI_VSHORT] = 2882, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 3675, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 4083, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_4][WRS_GI_VSHORT] = 4324, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 4900, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 5444, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_5][WRS_GI_VSHORT] = 5765, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 5513, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 6125, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_6][WRS_GI_VSHORT] = 6485, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 6125, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 6806, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_7][WRS_GI_VSHORT] = 7206, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 7350, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 8167, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_8][WRS_GI_VSHORT] = 8647, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 8166, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 9074, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_9][WRS_GI_VSHORT] = 9607, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_10][WRS_GI_LONG] = 9188, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_10][WRS_GI_SHORT] = 10208, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_10][WRS_GI_VSHORT] = 10809, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_11][WRS_GI_LONG] = 10208, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_11][WRS_GI_SHORT] = 11343, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_11][WRS_GI_VSHORT] = 12010, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 919, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 1021, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_0][WRS_GI_VSHORT] = 1081, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 1838, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 2042, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_1][WRS_GI_VSHORT] = 2162, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 2756, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 3063, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_2][WRS_GI_VSHORT] = 3243, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 3675, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 4083, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_3][WRS_GI_VSHORT] = 4324, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 5513, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 6125, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_4][WRS_GI_VSHORT] = 6485, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 7350, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 8167, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_5][WRS_GI_VSHORT] = 8647, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 8269, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 9188, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_6][WRS_GI_VSHORT] = 9728, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 9188, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 10208, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_7][WRS_GI_VSHORT] = 10809, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 11025, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 12250, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_8][WRS_GI_VSHORT] = 12971, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 12250, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 13611, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_9][WRS_GI_VSHORT] = 14412, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_10][WRS_GI_LONG] = 13781, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_10][WRS_GI_SHORT] = 15313, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_10][WRS_GI_VSHORT] = 16213, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_11][WRS_GI_LONG] = 15313, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_11][WRS_GI_SHORT] = 17014, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_11][WRS_GI_VSHORT] = 18015, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 1225, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 1361, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_0][WRS_GI_VSHORT] = 1441, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 2450, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 2722, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_1][WRS_GI_VSHORT] = 2882, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 3675, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 4083, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_2][WRS_GI_VSHORT] = 4324, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 4900, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 5444, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_3][WRS_GI_VSHORT] = 5765, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 7350, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 8167, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_4][WRS_GI_VSHORT] = 8647, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 9800, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 10889, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_5][WRS_GI_VSHORT] = 11529, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 11025, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 12250, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_6][WRS_GI_VSHORT] = 12971, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 12250, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 13611, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_7][WRS_GI_VSHORT] = 14412, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 14700, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 16333, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_8][WRS_GI_VSHORT] = 17294, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 16333, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 18148, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_9][WRS_GI_VSHORT] = 19215, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_10][WRS_GI_LONG] = 18375, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_10][WRS_GI_SHORT] = 20417, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_10][WRS_GI_VSHORT] = 21618, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_11][WRS_GI_LONG] = 20416, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_11][WRS_GI_SHORT] = 22685, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_11][WRS_GI_VSHORT] = 24019, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 613, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 681, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_0][WRS_GI_VSHORT] = 721, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 1225, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 1361, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_1][WRS_GI_VSHORT] = 1441, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 1838, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 2042, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_2][WRS_GI_VSHORT] = 2162, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 2450, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 2722, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_3][WRS_GI_VSHORT] = 2882, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 3675, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 4083, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_4][WRS_GI_VSHORT] = 4324, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 4900, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 5444, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_5][WRS_GI_VSHORT] = 5765, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 5513, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 6125, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_6][WRS_GI_VSHORT] = 6485, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 6125, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 6806, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_7][WRS_GI_VSHORT] = 7206, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 7350, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 8167, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_8][WRS_GI_VSHORT] = 8647, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 8166, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 9074, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_9][WRS_GI_VSHORT] = 9607, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_10][WRS_GI_LONG] = 9188, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_10][WRS_GI_SHORT] = 10208, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_10][WRS_GI_VSHORT] = 10809, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_11][WRS_GI_LONG] = 10208, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_11][WRS_GI_SHORT] = 11342, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_11][WRS_GI_VSHORT] = 12010, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 1225, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 1361, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_0][WRS_GI_VSHORT] = 1441, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 2450, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 2722, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_1][WRS_GI_VSHORT] = 2882, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 3675, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 4083, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_2][WRS_GI_VSHORT] = 4324, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 4900, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 5444, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_3][WRS_GI_VSHORT] = 5765, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 7350, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 8167, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_4][WRS_GI_VSHORT] = 8647, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 9800, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 10889, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_5][WRS_GI_VSHORT] = 11529, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 11025, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 12250, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_6][WRS_GI_VSHORT] = 12971, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 12250, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 13611, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_7][WRS_GI_VSHORT] = 14412, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 14700, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 16333, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_8][WRS_GI_VSHORT] = 17294, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 16333, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 18148, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_9][WRS_GI_VSHORT] = 19215, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_10][WRS_GI_LONG] = 18375, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_10][WRS_GI_SHORT] = 20417, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_10][WRS_GI_VSHORT] = 21618, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_11][WRS_GI_LONG] = 20416, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_11][WRS_GI_SHORT] = 22685, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_11][WRS_GI_VSHORT] = 24019, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 1838, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 2042, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_0][WRS_GI_VSHORT] = 2162, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 3675, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 4083, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_1][WRS_GI_VSHORT] = 4324, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 5513, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 6125, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_2][WRS_GI_VSHORT] = 6485, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 7350, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 8167, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_3][WRS_GI_VSHORT] = 8647, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 11025, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 12250, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_4][WRS_GI_VSHORT] = 12971, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 14700, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 16333, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_5][WRS_GI_VSHORT] = 17294, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 16538, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 18375, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_6][WRS_GI_VSHORT] = 19456, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 18375, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 20417, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_7][WRS_GI_VSHORT] = 21618, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 22050, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 24500, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_8][WRS_GI_VSHORT] = 25941, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 24500, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 27222, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_9][WRS_GI_VSHORT] = 28824, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_10][WRS_GI_LONG] = 27563, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_10][WRS_GI_SHORT] = 30625, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_10][WRS_GI_VSHORT] = 32426, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_11][WRS_GI_LONG] = 30625, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_11][WRS_GI_SHORT] = 34028, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_11][WRS_GI_VSHORT] = 36029, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 2450, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 2722, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_0][WRS_GI_VSHORT] = 2882, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 4900, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 5444, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_1][WRS_GI_VSHORT] = 5765, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 7350, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 8167, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_2][WRS_GI_VSHORT] = 8647, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 9800, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 10889, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_3][WRS_GI_VSHORT] = 11529, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 14700, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 16333, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_4][WRS_GI_VSHORT] = 17294, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 19600, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 21778, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_5][WRS_GI_VSHORT] = 23059, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 22050, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 24500, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_6][WRS_GI_VSHORT] = 25941, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 24500, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 27222, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_7][WRS_GI_VSHORT] = 28824, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 29400, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 32667, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_8][WRS_GI_VSHORT] = 34588, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 32666, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 36296, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_9][WRS_GI_VSHORT] = 38431, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_10][WRS_GI_LONG] = 36750, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_10][WRS_GI_SHORT] = 40833, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_10][WRS_GI_VSHORT] = 43235, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_11][WRS_GI_LONG] = 40833, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_11][WRS_GI_SHORT] = 45370, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_11][WRS_GI_VSHORT] = 48039, +}; + +/* + * This table of rates was taken from IEEE Std 802.11TM-2016, 21.5 Parameters + * for VHT-MCSs. The units are 1/10 Mbs. Invalid combinations are with 0's. Note + * that HT data rates are a subset of VHT data rates, so we can use a single + * table for both. + */ +const u16 data_rate_ht_vht_x10[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT] = { + [CHNL_BW_20][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 65, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 72, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 130, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 144, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 195, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 217, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 260, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 289, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 390, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 433, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 520, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 578, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 585, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 650, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 650, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 722, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 780, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 867, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 0, + [CHNL_BW_20][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 0, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 130, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 144, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 260, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 289, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 390, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 433, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 520, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 578, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 780, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 867, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 1040, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 1156, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 1170, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 1303, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 1300, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 1444, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 1560, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 1733, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 0, + [CHNL_BW_20][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 0, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 195, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 217, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 390, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 433, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 585, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 650, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 780, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 867, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 1170, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 1300, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 1560, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 1733, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 1755, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 1950, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 1950, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 2167, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 2340, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 2600, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 2600, + [CHNL_BW_20][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 2889, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 260, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 288, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 520, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 576, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 780, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 868, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 1040, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 1156, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 1560, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 1732, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 2080, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 2312, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 2340, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 2600, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 2600, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 2888, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 3120, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 3468, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 0, + [CHNL_BW_20][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 0, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 135, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 150, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 270, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 300, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 405, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 450, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 540, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 600, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 810, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 900, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 1080, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 1200, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 1215, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 1350, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 1350, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 1500, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 1620, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 1800, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 1800, + [CHNL_BW_40][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 2000, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 270, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 300, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 540, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 600, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 810, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 900, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 1080, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 1200, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 1620, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 1800, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 2160, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 2400, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 2430, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 2700, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 2700, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 3000, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 3240, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 3600, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 3600, + [CHNL_BW_40][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 4000, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 405, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 450, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 810, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 900, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 1215, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 1350, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 1620, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 1800, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 2430, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 2700, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 3240, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 3600, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 3645, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 4050, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 4050, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 4500, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 4860, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 5400, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 5400, + [CHNL_BW_40][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 6000, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 540, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 600, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 1080, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 1200, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 1620, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 1800, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 2160, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 2400, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 3240, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 3600, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 4320, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 4800, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 4860, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 5400, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 5400, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 6000, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 6480, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 7200, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 7200, + [CHNL_BW_40][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 8000, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 293, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 325, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 585, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 650, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 878, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 975, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 1170, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 1300, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 1755, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 1950, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 2340, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 2600, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 2633, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 2925, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 2925, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 3250, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 3510, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 3900, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 3900, + [CHNL_BW_80][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 4333, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 585, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 650, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 1170, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 1300, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 1755, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 1950, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 2340, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 2600, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 3510, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 3900, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 4680, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 5200, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 5265, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 5850, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 5850, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 6500, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 7020, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 7800, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 7800, + [CHNL_BW_80][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 8667, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 878, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 975, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 1755, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 1950, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 2633, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 2925, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 3510, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 3900, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 5265, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 5850, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 7020, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 7800, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 0, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 0, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 8775, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 9750, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 10530, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 11700, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 11700, + [CHNL_BW_80][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 13000, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 1172, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 1300, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 2340, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 2600, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 3512, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 3900, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 4680, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 5200, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 7020, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 7800, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 9360, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 10400, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 10532, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 11700, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 11700, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 13000, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 14040, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 15600, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 15600, + [CHNL_BW_80][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 17332, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_0][WRS_GI_LONG] = 585, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_0][WRS_GI_SHORT] = 650, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_1][WRS_GI_LONG] = 1170, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_1][WRS_GI_SHORT] = 1300, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_2][WRS_GI_LONG] = 1755, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_2][WRS_GI_SHORT] = 1950, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_3][WRS_GI_LONG] = 2340, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_3][WRS_GI_SHORT] = 2600, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_4][WRS_GI_LONG] = 3510, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_4][WRS_GI_SHORT] = 3900, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_5][WRS_GI_LONG] = 4680, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_5][WRS_GI_SHORT] = 5200, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_6][WRS_GI_LONG] = 5265, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_6][WRS_GI_SHORT] = 5850, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_7][WRS_GI_LONG] = 5850, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_7][WRS_GI_SHORT] = 6500, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_8][WRS_GI_LONG] = 7020, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_8][WRS_GI_SHORT] = 7800, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_9][WRS_GI_LONG] = 7800, + [CHNL_BW_160][WRS_SS_1][WRS_MCS_9][WRS_GI_SHORT] = 8667, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_0][WRS_GI_LONG] = 1170, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_0][WRS_GI_SHORT] = 1300, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_1][WRS_GI_LONG] = 2340, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_1][WRS_GI_SHORT] = 2600, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_2][WRS_GI_LONG] = 3510, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_2][WRS_GI_SHORT] = 3900, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_3][WRS_GI_LONG] = 4680, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_3][WRS_GI_SHORT] = 5200, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_4][WRS_GI_LONG] = 7020, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_4][WRS_GI_SHORT] = 7800, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_5][WRS_GI_LONG] = 9360, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_5][WRS_GI_SHORT] = 10400, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_6][WRS_GI_LONG] = 10530, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_6][WRS_GI_SHORT] = 11700, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_7][WRS_GI_LONG] = 11700, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_7][WRS_GI_SHORT] = 13000, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_8][WRS_GI_LONG] = 14040, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_8][WRS_GI_SHORT] = 15600, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_9][WRS_GI_LONG] = 15600, + [CHNL_BW_160][WRS_SS_2][WRS_MCS_9][WRS_GI_SHORT] = 17333, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_0][WRS_GI_LONG] = 1755, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_0][WRS_GI_SHORT] = 1950, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_1][WRS_GI_LONG] = 3510, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_1][WRS_GI_SHORT] = 3900, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_2][WRS_GI_LONG] = 5265, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_2][WRS_GI_SHORT] = 5850, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_3][WRS_GI_LONG] = 7020, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_3][WRS_GI_SHORT] = 7800, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_4][WRS_GI_LONG] = 10530, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_4][WRS_GI_SHORT] = 11700, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_5][WRS_GI_LONG] = 14040, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_5][WRS_GI_SHORT] = 15600, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_6][WRS_GI_LONG] = 15795, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_6][WRS_GI_SHORT] = 17550, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_7][WRS_GI_LONG] = 17550, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_7][WRS_GI_SHORT] = 19500, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_8][WRS_GI_LONG] = 21060, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_8][WRS_GI_SHORT] = 23400, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_9][WRS_GI_LONG] = 0, + [CHNL_BW_160][WRS_SS_3][WRS_MCS_9][WRS_GI_SHORT] = 0, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_0][WRS_GI_LONG] = 2340, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_0][WRS_GI_SHORT] = 2600, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_1][WRS_GI_LONG] = 4680, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_1][WRS_GI_SHORT] = 5200, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_2][WRS_GI_LONG] = 7020, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_2][WRS_GI_SHORT] = 7800, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_3][WRS_GI_LONG] = 9360, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_3][WRS_GI_SHORT] = 10400, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_4][WRS_GI_LONG] = 10400, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_4][WRS_GI_SHORT] = 15600, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_5][WRS_GI_LONG] = 18720, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_5][WRS_GI_SHORT] = 20800, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_6][WRS_GI_LONG] = 21060, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_6][WRS_GI_SHORT] = 23400, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_7][WRS_GI_LONG] = 23400, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_7][WRS_GI_SHORT] = 26000, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_8][WRS_GI_LONG] = 28080, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_8][WRS_GI_SHORT] = 31200, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_9][WRS_GI_LONG] = 31200, + [CHNL_BW_160][WRS_SS_4][WRS_MCS_9][WRS_GI_SHORT] = 34667, +}; + +/* OFDM Data Rates - (multiplied by 10) */ +const u16 data_rate_ofdm_x10[] = { + 60, + 90, + 120, + 180, + 240, + 360, + 480, + 540, +}; + +/* CCK Data Rates - (multiplied by 10) */ +const u16 data_rate_cck_x10[] = { + 10, + 20, + 55, + 110, +}; + +struct cl_inverse_data_rate inverse_data_rate; + +static u16 cl_data_rates_inverse_he(u8 bw, u8 nss, u8 mcs, u8 gi) +{ + return (80 << DATA_RATE_INVERSE_Q) / data_rate_he_x10[bw][nss][mcs][gi]; +} + +static u16 cl_data_rates_inverse_vht(u8 bw, u8 nss, u8 mcs, u8 gi) +{ + u16 data_rate = data_rate_ht_vht_x10[bw][nss][mcs][gi]; + + if (data_rate) + return (80 << DATA_RATE_INVERSE_Q) / data_rate; + + return 0; +} + +static u16 cl_data_rates_inverse_ofdm(u8 mcs) +{ + return (80 << DATA_RATE_INVERSE_Q) / data_rate_ofdm_x10[mcs]; +} + +static u16 cl_data_rates_inverse_cck(u8 mcs) +{ + return (80 << DATA_RATE_INVERSE_Q) / data_rate_cck_x10[mcs]; +} + +void cl_data_rates_inverse_build(void) +{ + /* + * The calculation is: round((2^15[Q] * 8[bits] * 10)/rate[Mbps]) - unit (us * 2^15) + * multiply by 10 because data rates in the above tables are also multiplied by 10 + */ + u8 bw, nss, mcs, gi; + + for (bw = 0; bw < CHNL_BW_MAX; bw++) + for (nss = 0; nss < WRS_SS_MAX; nss++) { + /* HE */ + for (mcs = 0; mcs < WRS_MCS_MAX_HE; mcs++) + for (gi = 0; gi < WRS_GI_MAX_HE; gi++) + inverse_data_rate.he[bw][nss][mcs][gi] = + cl_data_rates_inverse_he(bw, nss, mcs, gi); + + /* VHT */ + for (mcs = 0; mcs < WRS_MCS_MAX_VHT; mcs++) + for (gi = 0; gi < WRS_GI_MAX_VHT; gi++) + inverse_data_rate.ht_vht[bw][nss][mcs][gi] = + cl_data_rates_inverse_vht(bw, nss, mcs, gi); + } + + /* OFDM */ + for (mcs = 0; mcs < WRS_MCS_MAX_OFDM; mcs++) + inverse_data_rate.ofdm[mcs] = cl_data_rates_inverse_ofdm(mcs); + + /* CCK */ + for (mcs = 0; mcs < WRS_MCS_MAX_CCK; mcs++) + inverse_data_rate.cck[mcs] = cl_data_rates_inverse_cck(mcs); +} + +u16 cl_data_rates_get(u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi) +{ + return cl_data_rates_get_x10(mode, bw, nss, mcs, gi) / 10; +} + +u16 cl_data_rates_get_x10(u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi) +{ + switch (mode) { + case WRS_MODE_HE: + return data_rate_he_x10[bw][nss][mcs][gi]; + case WRS_MODE_VHT: + case WRS_MODE_HT: + return data_rate_ht_vht_x10[bw][nss][mcs][gi]; + case WRS_MODE_OFDM: + return data_rate_ofdm_x10[mcs]; + case WRS_MODE_CCK: + return data_rate_cck_x10[mcs]; + default: + return 0; + } +} + +u32 cl_rate_ctrl_generate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi, + bool fallback_en, bool mu_valid) +{ + union cl_rate_ctrl_info rate_ctrl_info; + + rate_ctrl_info.word = 0; + + /* Format_mod + mcs_index */ + if (mode == WRS_MODE_HE) { + rate_ctrl_info.field.mcs_index = (nss << 4) | mcs; + rate_ctrl_info.field.format_mod = FORMATMOD_HE_SU; + } else if (mode == WRS_MODE_VHT) { + rate_ctrl_info.field.mcs_index = (nss << 4) | mcs; + rate_ctrl_info.field.format_mod = FORMATMOD_VHT; + } else if (mode == WRS_MODE_HT) { + rate_ctrl_info.field.mcs_index = (nss << 3) | mcs; + rate_ctrl_info.field.format_mod = FORMATMOD_HT_MF; + } else if (mode == WRS_MODE_OFDM) { + rate_ctrl_info.field.mcs_index = mcs + RATE_CTRL_OFFSET_OFDM; + rate_ctrl_info.field.format_mod = + (bw == CHNL_BW_20) ? FORMATMOD_NON_HT : FORMATMOD_NON_HT_DUP_OFDM; + } else { /* WRS_MODE_CCK */ + rate_ctrl_info.field.mcs_index = mcs; + rate_ctrl_info.field.format_mod = FORMATMOD_NON_HT; + } + + /* Gi */ + rate_ctrl_info.field.gi = cl_convert_gi_format_wrs_to_fw(mode, gi); + + /* Bw */ + rate_ctrl_info.field.bw = bw; + + /* Fallback */ + rate_ctrl_info.field.fallback = fallback_en; + + /* Tx_bf */ + if (!mu_valid && cl_sta && cl_bf_is_on(cl_hw, cl_sta, nss)) + rate_ctrl_info.field.tx_bf = true; + + /* Pre_type/stbc */ + if (rate_ctrl_info.field.format_mod == FORMATMOD_NON_HT) + rate_ctrl_info.field.pre_type_or_stbc = 1; + + return rate_ctrl_info.word; +} + +void cl_rate_ctrl_convert(union cl_rate_ctrl_info *rate_ctrl_info) +{ + u32 format_mod = rate_ctrl_info->field.format_mod; + + /* + * Convert gi from firmware format to driver format + * !!! Must be done before converting the format mode !!! + */ + rate_ctrl_info->field.gi = cl_convert_gi_format_fw_to_wrs(format_mod, + rate_ctrl_info->field.gi); + + /* Convert format_mod from firmware format to WRS format */ + if (format_mod >= FORMATMOD_HE_SU) { + rate_ctrl_info->field.format_mod = WRS_MODE_HE; + } else if (format_mod == FORMATMOD_VHT) { + rate_ctrl_info->field.format_mod = WRS_MODE_VHT; + } else if (format_mod >= FORMATMOD_HT_MF) { + rate_ctrl_info->field.format_mod = WRS_MODE_HT; + } else if (format_mod == FORMATMOD_NON_HT_DUP_OFDM) { + rate_ctrl_info->field.format_mod = WRS_MODE_OFDM; + } else { + if (rate_ctrl_info->field.mcs_index >= RATE_CTRL_OFFSET_OFDM) + rate_ctrl_info->field.format_mod = WRS_MODE_OFDM; + else + rate_ctrl_info->field.format_mod = WRS_MODE_CCK; + } +} + +void cl_rate_ctrl_parse(union cl_rate_ctrl_info *rate_ctrl_info, u8 *nss, u8 *mcs) +{ + switch (rate_ctrl_info->field.format_mod) { + case WRS_MODE_HE: + case WRS_MODE_VHT: + *nss = (rate_ctrl_info->field.mcs_index >> 4); + *mcs = (rate_ctrl_info->field.mcs_index & 0xF); + break; + case WRS_MODE_HT: + *nss = (rate_ctrl_info->field.mcs_index >> 3); + *mcs = (rate_ctrl_info->field.mcs_index & 0x7); + break; + case WRS_MODE_OFDM: + *nss = 0; + *mcs = rate_ctrl_info->field.mcs_index - RATE_CTRL_OFFSET_OFDM; + break; + case WRS_MODE_CCK: + *nss = 0; + *mcs = rate_ctrl_info->field.mcs_index; + break; + default: + *nss = *mcs = 0; + } +} + +void cl_rate_ctrl_set_default(struct cl_hw *cl_hw) +{ + u32 rate_ctrl = 0; + union cl_rate_ctrl_info_he rate_ctrl_he; + + /* HE default */ + rate_ctrl_he.word = 0; + rate_ctrl_he.field.spatial_conf = RATE_CNTRL_HE_SPATIAL_CONF_DEF; + rate_ctrl = cl_rate_ctrl_generate(cl_hw, NULL, WRS_MODE_HE, + 0, 0, 0, 0, false, false); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_DEFAULT_HE, 0, 0, LTF_X4, 0, rate_ctrl_he.word); + + /* OFDM default */ + rate_ctrl = cl_rate_ctrl_generate(cl_hw, NULL, WRS_MODE_OFDM, 0, 0, + cl_hw->conf->ce_default_mcs_ofdm, 0, false, false); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_DEFAULT_OFDM, 0, 0, 0, 0, 0); + + /* CCK default */ + if (cl_band_is_24g(cl_hw)) { + rate_ctrl = cl_rate_ctrl_generate(cl_hw, NULL, WRS_MODE_CCK, 0, 0, + cl_hw->conf->ce_default_mcs_cck, 0, false, false); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_DEFAULT_CCK, 0, 0, 0, 0, 0); + } +} + +void cl_rate_ctrl_set_default_per_he_minrate(struct cl_hw *cl_hw, u8 bw, + u8 nss, u8 mcs, u8 gi) +{ + union cl_rate_ctrl_info_he rate_ctrl_he; + u32 rate_ctrl = 0; + u8 ltf = cl_map_gi_to_ltf(WRS_MODE_HE, gi); + + rate_ctrl_he.word = 0; + rate_ctrl_he.field.spatial_conf = RATE_CNTRL_HE_SPATIAL_CONF_DEF; + rate_ctrl = cl_rate_ctrl_generate(cl_hw, NULL, WRS_MODE_HE, bw, + nss, mcs, gi, false, false); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_DEFAULT_HE, 0, 0, ltf, + 0, rate_ctrl_he.word); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_MCAST, 0, 0, ltf, 0, 0); + + cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl, 0, 0, + RATE_OP_MODE_BCAST, 0, 0, ltf, 0, 0); +} + +bool cl_rate_ctrl_set_mcast(struct cl_hw *cl_hw, u8 mode, u8 mcs) +{ + u32 rate_ctrl_mcast = cl_rate_ctrl_generate(cl_hw, NULL, mode, 0, 0, mcs, + WRS_GI_LONG, false, false); + u8 ltf = cl_map_gi_to_ltf(mode, WRS_GI_LONG); + + if (cl_msg_tx_update_rate_dl(cl_hw, 0xff, rate_ctrl_mcast, 0, 0, + RATE_OP_MODE_MCAST, 0, 0, ltf, 0, 0)) + return false; + + return true; +} + +static u8 cl_rate_ctrl_get_min(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_min_he_en && + cl_hw->wireless_mode == WIRELESS_MODE_HE) + return RATE_CTRL_ENTRY_MIN_HE; + + if (cl_hw_mode_is_b_or_bg(cl_hw)) + return RATE_CTRL_ENTRY_MIN_CCK; + + return RATE_CTRL_ENTRY_MIN_OFDM; +} + +void cl_rate_ctrl_update_desc_single(struct cl_hw *cl_hw, struct tx_host_info *info, + struct cl_sw_txhdr *sw_txhdr) +{ + struct ieee80211_hdr *mac_hdr = sw_txhdr->hdr80211; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + bool is_data = ieee80211_is_data(sw_txhdr->fc); + + if (sw_txhdr->cl_sta && is_data) { + if (cl_tx_ctrl_is_eapol(tx_info)) { + info->rate_ctrl_entry = cl_rate_ctrl_get_min(cl_hw); + } else { + if (cl_hw->entry_fixed_rate) + info->rate_ctrl_entry = RATE_CTRL_ENTRY_FIXED_RATE; + else + info->rate_ctrl_entry = RATE_CTRL_ENTRY_STA; + } + } else { + if (sw_txhdr->is_bcn) { + info->rate_ctrl_entry = cl_rate_ctrl_get_min(cl_hw); + } else if (is_multicast_ether_addr(mac_hdr->addr1) && + !is_broadcast_ether_addr(mac_hdr->addr1)) { + info->rate_ctrl_entry = RATE_CTRL_ENTRY_MCAST; + } else if (is_broadcast_ether_addr(mac_hdr->addr1) && + !cl_hw->entry_fixed_rate) { + info->rate_ctrl_entry = RATE_CTRL_ENTRY_BCAST; + } else { + if (cl_hw->entry_fixed_rate && is_data) + info->rate_ctrl_entry = RATE_CTRL_ENTRY_FIXED_RATE; + else + info->rate_ctrl_entry = cl_rate_ctrl_get_min(cl_hw); + } + } +} + +void cl_rate_ctrl_update_desc_agg(struct cl_hw *cl_hw, struct tx_host_info *info) +{ + /* For aggregation there are only two options - STA and FIXED_RATE */ + if (cl_hw->entry_fixed_rate) + info->rate_ctrl_entry = RATE_CTRL_ENTRY_FIXED_RATE; + else + info->rate_ctrl_entry = RATE_CTRL_ENTRY_STA; +} + +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + +/* + * MIN_MCS | BCAST_MCS + * ------------------- + * 0 - 1 | 0 + * 2 - 3 | 1 + * 4 - 5 | 2 + * 6 - 7 | 3 + * 8 - 9 | 4 + * 10 - 11 | 5 + */ + +static u8 conv_min_mcs_to_bcast_mcs[WRS_MCS_MAX] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 +}; + +static void cl_dyn_bcast_rate_update(struct cl_hw *cl_hw, u8 min_mcs) +{ + struct cl_dyn_bcast_rate *dyn_bcast_rate = &cl_hw->dyn_bcast_rate; + u8 bcast_mcs = conv_min_mcs_to_bcast_mcs[min_mcs]; + + dyn_bcast_rate->sta_min_mcs = min_mcs; + + if (bcast_mcs != dyn_bcast_rate->bcast_mcs) + cl_dyn_bcast_rate_set(cl_hw, bcast_mcs); +} + +static struct cl_dyn_bcast_rate cl_dyn_bcast_rate_prepare(struct cl_hw *cl_hw) +{ + struct cl_dyn_bcast_rate dyn_bcast_rate; + + memset(&dyn_bcast_rate, 0, sizeof(struct cl_dyn_bcast_rate)); + dyn_bcast_rate.sta_min_mcs = 0; + dyn_bcast_rate.bcast_mcs = conv_min_mcs_to_bcast_mcs[0]; + + if (cl_band_is_6g(cl_hw)) { + dyn_bcast_rate.wrs_mode = cl_hw->conf->ci_min_he_en ? + WRS_MODE_HE : WRS_MODE_OFDM; + dyn_bcast_rate.ltf = LTF_X4; + } else if (cl_band_is_24g(cl_hw) && cl_hw_mode_is_b_or_bg(cl_hw)) { + dyn_bcast_rate.wrs_mode = WRS_MODE_CCK; + dyn_bcast_rate.ltf = 0; + } else { + dyn_bcast_rate.wrs_mode = WRS_MODE_OFDM; + dyn_bcast_rate.ltf = 0; + } + + return dyn_bcast_rate; +} + +void cl_dyn_bcast_rate_init(struct cl_hw *cl_hw) +{ + struct cl_dyn_bcast_rate dyn_bcast_rate; + + dyn_bcast_rate = cl_dyn_bcast_rate_prepare(cl_hw); + memcpy(&cl_hw->dyn_bcast_rate, &dyn_bcast_rate, sizeof(struct cl_dyn_bcast_rate)); +} + +void cl_dyn_bcast_rate_set(struct cl_hw *cl_hw, u8 bcast_mcs) +{ + struct cl_dyn_bcast_rate *dyn_bcast_rate = &cl_hw->dyn_bcast_rate; + u8 wrs_mode = dyn_bcast_rate->wrs_mode; + u8 ltf = dyn_bcast_rate->ltf; + u32 rate_ctrl; + + cl_hw->dyn_bcast_rate.bcast_mcs = bcast_mcs; + + rate_ctrl = cl_rate_ctrl_generate(cl_hw, NULL, wrs_mode, 0, 0, bcast_mcs, + 0, false, false); + cl_msg_tx_update_rate_dl(cl_hw, U8_MAX, rate_ctrl, 0, 0, + RATE_OP_MODE_BCAST, 0, 0, ltf, 0, 0); + + cl_dbg_info(cl_hw, "Broadcast MCS set to %u\n", bcast_mcs); +} + +void cl_dyn_bcast_update(struct cl_hw *cl_hw) +{ + struct cl_dyn_bcast_rate dyn_bcast_rate; + + dyn_bcast_rate = cl_dyn_bcast_rate_prepare(cl_hw); + if (cl_hw->dyn_bcast_rate.wrs_mode == dyn_bcast_rate.wrs_mode) + return; + + memcpy(&cl_hw->dyn_bcast_rate, &dyn_bcast_rate, sizeof(struct cl_dyn_bcast_rate)); + cl_dyn_bcast_rate_set(cl_hw, cl_hw->dyn_bcast_rate.bcast_mcs); +} + +void cl_dyn_bcast_rate_recovery(struct cl_hw *cl_hw) +{ + cl_dyn_bcast_rate_set(cl_hw, cl_hw->dyn_bcast_rate.bcast_mcs); +} + +void cl_dyn_bcast_rate_change(struct cl_hw *cl_hw, struct cl_sta *cl_sta_change, + u8 old_mcs, u8 new_mcs) +{ + struct cl_dyn_bcast_rate *dyn_bcast_rate = &cl_hw->dyn_bcast_rate; + struct cl_sta *cl_sta = NULL; + u8 min_mcs = WRS_MCS_MAX - 1; + u8 sta_mcs = 0; + + if (!cl_hw->conf->ce_dyn_bcast_rate_en) + return; + + if (!cl_sta_change->add_complete) + return; + + /* Single station */ + if (cl_sta_num_bh(cl_hw) == 1) { + cl_dyn_bcast_rate_update(cl_hw, new_mcs); + return; + } + + /* + * If this station did not have the minimum mcs, + * and the new rate is now below the minimum mcs there is nothing to do + */ + if (old_mcs > dyn_bcast_rate->sta_min_mcs && + new_mcs > dyn_bcast_rate->sta_min_mcs) + return; + + /* Multi station - find new minimum MCS of all stations */ + cl_sta_lock_bh(cl_hw); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) { + sta_mcs = (cl_sta->sta_idx == cl_sta_change->sta_idx) ? + new_mcs : cl_sta->wrs_sta.tx_su_params.rate_params.mcs; + + if (sta_mcs < min_mcs) { + min_mcs = sta_mcs; + + if (min_mcs == 0) + break; + } + } + + cl_sta_unlock_bh(cl_hw); + + cl_dyn_bcast_rate_update(cl_hw, min_mcs); +} + +void cl_dyn_bcast_rate_update_upon_assoc(struct cl_hw *cl_hw, u8 mcs, u8 num_sta) +{ + struct cl_dyn_bcast_rate *dyn_bcast_rate = &cl_hw->dyn_bcast_rate; + + if (!cl_hw->conf->ce_dyn_bcast_rate_en) + return; + + if (num_sta == 1 || mcs < dyn_bcast_rate->sta_min_mcs) + cl_dyn_bcast_rate_update(cl_hw, mcs); +} + +void cl_dyn_bcast_rate_update_upon_disassoc(struct cl_hw *cl_hw, u8 mcs, u8 num_sta) +{ + struct cl_dyn_bcast_rate *dyn_bcast_rate = &cl_hw->dyn_bcast_rate; + struct cl_sta *cl_sta = NULL; + u8 min_mcs = WRS_MCS_MAX - 1; + + if (!cl_hw->conf->ce_dyn_bcast_rate_en) + return; + + /* When the last station disconnects - set bcast back to 0 */ + if (num_sta == 0) { + cl_dyn_bcast_rate_update(cl_hw, 0); + return; + } + + /* If this station did not have the minimum rate there is nothing to do */ + if (mcs > dyn_bcast_rate->sta_min_mcs) + return; + + /* + * Find new minimum MCS of all station (the disassociating + * station is not in list at this stage) + */ + cl_sta_lock_bh(cl_hw); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) { + if (cl_sta->wrs_sta.tx_su_params.rate_params.mcs < min_mcs) { + min_mcs = cl_sta->wrs_sta.tx_su_params.rate_params.mcs; + + if (min_mcs == 0) + break; + } + } + + cl_sta_unlock_bh(cl_hw); + + cl_dyn_bcast_rate_update(cl_hw, min_mcs); +} +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + +static void _cl_dyn_mcast_rate_send(struct cl_hw *cl_hw, u8 wrs_mode_new) +{ + struct cl_dyn_mcast_rate *dyn_mcast_rate = &cl_hw->dyn_mcast_rate; + + if (dyn_mcast_rate->wrs_mode_curr == wrs_mode_new) + return; + + if (!cl_rate_ctrl_set_mcast(cl_hw, wrs_mode_new, cl_hw->conf->ce_mcast_rate)) + return; + + dyn_mcast_rate->wrs_mode_curr = wrs_mode_new; + cl_dbg_trace(cl_hw, "New multicast mode = %u\n", wrs_mode_new); +} + +static struct cl_dyn_mcast_rate cl_dyn_mcast_rate_prepare(struct cl_hw *cl_hw) +{ + struct cl_dyn_mcast_rate dyn_mcast_rate; + + memset(&dyn_mcast_rate, 0, sizeof(struct cl_dyn_mcast_rate)); + if (cl_hw->conf->ci_min_he_en && + cl_hw->wireless_mode == WIRELESS_MODE_HE) + dyn_mcast_rate.wrs_mode_default = WRS_MODE_HE; + else if (cl_band_is_24g(cl_hw) && cl_hw_mode_is_b_or_bg(cl_hw)) + dyn_mcast_rate.wrs_mode_default = WRS_MODE_CCK; + else + dyn_mcast_rate.wrs_mode_default = WRS_MODE_OFDM; + + return dyn_mcast_rate; +} + +void cl_dyn_mcast_rate_init(struct cl_hw *cl_hw) +{ + struct cl_dyn_mcast_rate dyn_mcast_rate; + + dyn_mcast_rate = cl_dyn_mcast_rate_prepare(cl_hw); + cl_hw->dyn_mcast_rate.wrs_mode_default = dyn_mcast_rate.wrs_mode_default; + + cl_dbg_trace(cl_hw, "mode = %u, mcs = %u\n", + dyn_mcast_rate.wrs_mode_default, cl_hw->conf->ce_mcast_rate); +} + +void cl_dyn_mcast_rate_set(struct cl_hw *cl_hw) +{ + /* + * Set wrs_mode_curr to 0xff so that the message will be sent to + * firmware when this function is called from cl_ops_start() + */ + struct cl_dyn_mcast_rate *dyn_mcast_rate = &cl_hw->dyn_mcast_rate; + + dyn_mcast_rate->wrs_mode_curr = U8_MAX; + + _cl_dyn_mcast_rate_send(cl_hw, dyn_mcast_rate->wrs_mode_default); +} + +void cl_dyn_mcast_update(struct cl_hw *cl_hw) +{ + struct cl_dyn_mcast_rate dyn_mcast_rate; + + dyn_mcast_rate = cl_dyn_mcast_rate_prepare(cl_hw); + if (cl_hw->dyn_mcast_rate.wrs_mode_default == dyn_mcast_rate.wrs_mode_default) + return; + + cl_hw->dyn_mcast_rate.wrs_mode_default = dyn_mcast_rate.wrs_mode_default; + cl_dyn_mcast_rate_set(cl_hw); +} + +void cl_dyn_mcast_rate_recovery(struct cl_hw *cl_hw) +{ + /* + * cl_dyn_mcast_rate_recovery() is called during recovery process(). + * Reset wrs_mode_curr so that message will be sent. + */ + struct cl_dyn_mcast_rate *dyn_mcast_rate = &cl_hw->dyn_mcast_rate; + u8 wrs_mode_curr = dyn_mcast_rate->wrs_mode_curr; + + dyn_mcast_rate->wrs_mode_curr = U8_MAX; + + _cl_dyn_mcast_rate_send(cl_hw, wrs_mode_curr); +} + +void cl_dyn_mcast_rate_update_upon_assoc(struct cl_hw *cl_hw, u8 wrs_mode, u8 num_sta) +{ + struct cl_dyn_mcast_rate *dyn_mcast_rate = &cl_hw->dyn_mcast_rate; + + if (!cl_hw->conf->ce_dyn_mcast_rate_en) + return; + + /* + * If the wrs_mode of the new station is lower than the current multicast + * wrs_mode, or if this is the first station to connect - update multicast mode + */ + if (wrs_mode < dyn_mcast_rate->wrs_mode_curr || num_sta == 1) + _cl_dyn_mcast_rate_send(cl_hw, wrs_mode); +} + +void cl_dyn_mcast_rate_update_upon_disassoc(struct cl_hw *cl_hw, u8 wrs_mode, u8 num_sta) +{ + struct cl_dyn_mcast_rate *dyn_mcast_rate = &cl_hw->dyn_mcast_rate; + struct cl_sta *cl_sta = NULL; + u8 wrs_mode_min = WRS_MODE_HE; + + if (!cl_hw->conf->ce_dyn_mcast_rate_en) + return; + + /* When the last station disconnects - set default mcast rate */ + if (num_sta == 0) { + _cl_dyn_mcast_rate_send(cl_hw, dyn_mcast_rate->wrs_mode_default); + return; + } + + /* + * If wrs_mode of the disassociating station is bigger + * than the current mode then there is nothing to update. + */ + if (wrs_mode > dyn_mcast_rate->wrs_mode_curr) + return; + + /* + * Find minimal wrs_mode among the connected stations (the + * disassociating station is not in list at this stage). + */ + cl_sta_lock_bh(cl_hw); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) + if (cl_sta->wrs_sta.mode < wrs_mode_min) + wrs_mode_min = cl_sta->wrs_sta.mode; + + cl_sta_unlock_bh(cl_hw); + + _cl_dyn_mcast_rate_send(cl_hw, wrs_mode_min); +} +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ From patchwork Tue May 24 11:34:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576856 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 8811FC433FE for ; Tue, 24 May 2022 11:39:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236833AbiEXLjK (ORCPT ); Tue, 24 May 2022 07:39:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233616AbiEXLjJ (ORCPT ); Tue, 24 May 2022 07:39:09 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60047.outbound.protection.outlook.com [40.107.6.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A6B3532C4 for ; Tue, 24 May 2022 04:38:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nPyCu/ZiK4GwqmFEBCdWcUOsQXuvewMEmrPOzC84QEPEUnO0/+JyoN4pqeoYL2sCRbdX/ccGwXy7V97oFHvq3i8fXl+Gaz3D9RChv/Sy8w63bw+IgLyvasfQK+uVqP4CIfqb4YHjJgTBv9llgODT/N2vD+M40HhKsRcvA22K2TzY/CJPv3lAnPwAFV7vCbq0SB2TV+kOiYdedYBJSnqjMVhGV4HOBot+pp0KIE6VpU7Tv9dNH6JtWO+Qlg04DHEISBxWeiqn6qRss1rt9IQIn612Iy73Npz30785wgmSzw9iw4jwUed4eh0C6iBKiQ+cEXk3elAkkn8yxY1Orwqaqw== 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=RcmkEnhLJ6CF6jArpVXBbfMrT/pwQUHyBkZBxXDxtHo=; b=Qj70DEXAbuFPRpYvvuD1f5XJHIx+EUrXw8GpB/461fcE5s8W53mDrq1tGdFuMjdPlPhlGbryUPrMw79VaKZN/S4z2oBCLPKWlkqB2kaUHIH/7SM5kgfPmkyj9BclavdzWeCRmhqNeqSxdrEloa2Dj3u2CtIBDEDlgOFgVxnRUbGFhvbKaznt5JN0ZIm07NdGjnUIJbcBmNLfCnOuR9DrciZY6aN1cZzqIDRzDCKmu0o2vrLRl/z++PC5OK4BTtxQAmnSGI2q3eeooTjGw22Sp9UcVKtTioNHTgesschYKF7XMKDtBUa721Lqz/FIeD4RmgsmTpwao4BJvSxFPAS5fg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RcmkEnhLJ6CF6jArpVXBbfMrT/pwQUHyBkZBxXDxtHo=; b=CpvZcNrHnHRySRissJ6L19keqhbRO1D6QJHgpO6lDVqmtp4Vf9MamkjKfquLbn7J65L79LadQHFH796TP+vg+4HAOp4jBgn135cLlAzqoM4RXzNtCWJ+Ge1Lt3wc1MBRXVkedZzcyOarIOHCSlORzIXDiYegyMRtM8r960W5f9A= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:38:53 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:53 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 59/96] cl8k: add rates.h Date: Tue, 24 May 2022 14:34:25 +0300 Message-Id: <20220524113502.1094459-60-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d866c8ef-ed8b-4388-1d81-08da3d79f0ad X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Fz5KSW1MlZR92ea3o7rifGPuJ/iwUELI1DuG5FMOVwyL89NNda2augsvsihVkykpCL3nL4zD47/kd8JBxABvEfTwKBeP2eM4rABm0tdg9F/YgkfzpvSfoToMva6+OU25MT7c+TiMFjjtTsNWdeXMo4ENQAi/Nb4WzvnOaJtUryxRWicmXWl5GqDURefVltj9UHjF0yT3T20e3jM4p+iynWjxO27nD4StjyqdcuRz7hhFyGDZWubF1p3L88gtop/NiIryp68qtY32ya4V9+xZjUxtf44cNwg0cG0BQoqPVc4Lca2rfpxLKGMvJCEXRvXqY08FCehYsv/D9b/jFsju0TpL2/SyuNJUDpQNFJMKHlp+jSER7ZZAq/IuDLHmklmrlLrQwJjk/0oYQk+Zf0/MtxuOVn02Lau12XwMhmZrZT4pXQjp9BzrICCnYmjCWQKuuELb4JOz6F+JzuGx0XcaRAd7hjYhofweX+ezLRiFF3FND1iGJrJ7G4RQG8Y3u/7y+zfCPLaJvcij3Fpqf5fLpBVry3f9k4W5KCDYgjUYjZZANLhGuISoPCZM8ZPeM6mqisuTQspUtWcHbUdhZ8r0XMnCs9TXLRUanwsnijdZtGoymCb4yIJcjAIz/2OO8VsnIN9tH5z/lUgz3/lklTZEVIE/ODZSzZTVZn0cZeWAaa8knzCLq6aJBwzWnK3z/3UVTUi7BLMHUlzGvrZtqiwhLjB6AM0EZlErUmq+9nd8KoA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: JxW/yuCO7rAWk4ST5vXd9wssBY2C5q7SPhC6jFGWga8f8DDZ398ePwy9N+dG1IsqyZ5ZzcmsnLeQYDIQAPUgpXqTCdnO5S/t5hinEq8UPu7XbBZ4rVl/Ulw+KKNocr6FZI3K/Tzy8dGQICltCTd5QpYIFaGIgU0wBgJ5PWD4FaIE46oT/CPsxk5+x48oqhQNPzQFO/pC27AF4Lfq9F3BIG3vi64pfutPybr7grcpcYD/7acgjoIuWw+JAmsb9HDQqki7PEYCVRzel4eySiu/tVSmihTmL2wFVST5oD0BvqvQo0NVqZWTEKP+GPZz90mIW8592Il5o2OsR54woI24m2WTM+P5nb1eD8uYaYP1BzmfksWEkbkQIAZcoDit7zvcwIqxbJDy0yhvdvPE5Cs3quuPoQkAIw0csxaYHZ7oMymi0KcEZc7u1ytPbZc84P5q0BtSdIotkJs0rnVletFLszodKu2uglrQUIPG/yGdWh53/idlCdpWl81COXWzFyF0ePy9d2858bboMJ/iaM2/fbAJ66koR09GCdG0XunUDcWX+Al+JegMyU9rNMCtdzK8LkF0sWU6/kX+2h9hck9WW9DK/u9kQUltCyD3iQLWNC9HRuC6F79x4Zz/L2ParxtuVDhUR54BFfATc6P5KjNa/99siOhscg0WwJp0+XYnzrt28WQTALyy7BEfmvqlnanyS8w1VhehLUGyTKMatnHTrbRQ4eC6e7NN1x9co63PhVQ8ELlmy71aNtl1GGWDwnP32/ivCG5ngdWgY1DJgxcHs0/VcAlATTRC25Cl2cYl0xJYc1d6scEcz8jxrYNARAaXezdxEppzaT3QHUXBxG5u/K5FQdwkKvwsrpTRQpG8TVS+kFcr7FenF+akpSGBUS3tyCAPZ/FAIPVGm5dKEA3FPtcCr7q48xT4Tf0BplFhSTRHS36Ipp7VYFXZljRI5HuXcyQkEF1tImLA+9B3DMIsIux3/NTh5V51yngBE2CgRSNcMQOHD9Sz3N3EGu5+NBwanN6MI1FqL92rTtKTWapTj/TuapYuUQxrH/Dtz3/lLlbjrxzZC9oUHr7eVk7vIKaJrrMgAtdHXpqWQugeBz2ij8piIk8P/tzA+SBieMR9Q9qmlaMuq7xRi1coBtVP1/0eLmAD5pQx7G1W7UzrbA1+kHHE1GFWXxrojA3uVVfFW2AEFn3NC+tFQNCQoU06atVteg7g+lpNoeHBduUtvEo+wvPvX48g+JJIfM6Hgl42fPspuaqiSnU9MGafD+ktLxF+eJMhvg0L9XNWnisqtDvcUZDh+CB4qlVxv1BHwR+ZVwWXjKdmMotkNSuLULCjiwyiOmZ5BZTItEQTnUd8xPV8v+nbj6b5AONRFEoucHj5Xw68qyvqbzmm09pTUp/zYzEn9bp2Q8UHLLNoh4l8huQ1FOqBuu92zY0ble8riLYIKE7RbF/Mgi/o6Dw3TgKf396W4a2kPqr6pRgDC5+HYWwUEmN2Eb22HQMmC3TGb0xsU01tUpdncCkt3ymR0ULtLTt2NmbxfWUwjOnARsgayNsv35L+fHfhKn6LM7ivEe7e0E5Cx55fTiIEoNIzIVHZ5W9ZeQNroXYyUD9cwDmDIjR6+QzxybwJLM7MNs+g/5soBg+0w74s1S1VWvXIZc/Q8hQnICtHSncFSsnZUuL8RKgxHG6A2D3/TqvY+TG8NtoV949L2tgUFBph0826LjTO05YgGJBDD9NsQ+MkjCBOmwcURkrgU2f7H756FupRQBGxeF4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d866c8ef-ed8b-4388-1d81-08da3d79f0ad X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:36.5966 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: h8O0x5MSZxqODJ410B1CAuq6gXln3sgLrg+6ZmqkfdizG/JF/4wp9zFMv1E/XFoOgJRXCov1gVbFE3VQvQ+B2w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rates.h | 154 +++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rates.h diff --git a/drivers/net/wireless/celeno/cl8k/rates.h b/drivers/net/wireless/celeno/cl8k/rates.h new file mode 100644 index 000000000000..223924f21dc2 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rates.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_RATE_CTRL_H +#define CL_RATE_CTRL_H + +#include + +#include "ipc_shared.h" +#include "wrs.h" + +#define RATE_CTRL_OFFSET_OFDM 4 +#define RATE_CNTRL_HE_SPATIAL_CONF_DEF 0xF + +/* Op_mode field in mm_update_rate_dl_req structure */ +enum cl_op_mode { + RATE_OP_MODE_FIXED, + RATE_OP_MODE_DEFAULT_HE, + RATE_OP_MODE_DEFAULT_OFDM, + RATE_OP_MODE_DEFAULT_CCK, + RATE_OP_MODE_STA_SU, + RATE_OP_MODE_STA_MU, + RATE_OP_MODE_MCAST, + RATE_OP_MODE_BCAST +}; + +/* Value to be set in tx_host_info */ +enum cl_rate_ctrl_entry { + RATE_CTRL_ENTRY_NA = 0, + + RATE_CTRL_ENTRY_STA, + RATE_CTRL_ENTRY_FIXED_RATE, + RATE_CTRL_ENTRY_MIN_HE, + RATE_CTRL_ENTRY_MIN_OFDM, + RATE_CTRL_ENTRY_MIN_CCK, + RATE_CTRL_ENTRY_MCAST, + RATE_CTRL_ENTRY_BCAST, + + /* Entry size in firmware is represented by 3 bits */ + RATE_CTRL_ENTRY_MAX = 8 +}; + +/* + * sw_ctrl includes eights bits (16 - 23) to be used by software. + * Bit 16 is used by driver to indicate tx_bf. + * Bit 17 is used by driver to indicate fallback. + * Bit 18 - 23 are still free. + */ +struct cl_rate_ctrl_info_fields { + u32 mcs_index : 7; /* [6:0] */ + u32 bw : 2; /* [8:7] */ + u32 gi : 2; /* [10:9] */ + u32 pre_type_or_stbc : 1; /* [11] */ + u32 format_mod : 4; /* [15:12] */ + u32 tx_bf : 1; /* [16] */ + u32 fallback : 1; /* [17] */ + u32 sw_ctrl : 6; /* [23:18] */ + u32 tx_chains : 8; /* [31:24] */ +}; + +union cl_rate_ctrl_info { + struct cl_rate_ctrl_info_fields field; + u32 word; +}; + +struct cl_rate_ctrl_info_he_fields { + u32 spatial_conf : 4; /* [3:0] */ + u32 starting_sts : 3; /* [6:4] */ + u32 ru_index : 6; /* [12:7] */ + u32 ru_type : 3; /* [15:13] */ + u32 ru_band : 1; /* [16] */ + u32 mu_usr_pos : 2; /* [18:17] */ + u32 dcm_data : 1; /* [19] */ + u32 num_usrs_mu_dl : 4; /* [23:20] */ + u32 ru_alloc : 8; /* [31:24] */ +}; + +union cl_rate_ctrl_info_he { + struct cl_rate_ctrl_info_he_fields field; + u32 word; +}; + +#define DATA_RATE_INVERSE_Q 15 + +struct cl_inverse_data_rate { + u16 he[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; + u16 ht_vht[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT]; + u16 ofdm[WRS_MCS_MAX_OFDM]; + u16 cck[WRS_MCS_MAX_CCK]; +}; + +extern struct cl_inverse_data_rate inverse_data_rate; + +extern const u16 data_rate_he_x10[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; +extern const u16 data_rate_ht_vht_x10[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT]; +extern const u16 data_rate_ofdm_x10[]; +extern const u16 data_rate_cck_x10[]; + +struct cl_hw; +struct cl_sta; +struct cl_sw_txhdr; + +u32 cl_rate_ctrl_generate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi, + bool fallback_en, bool mu_valid); +void cl_rate_ctrl_convert(union cl_rate_ctrl_info *rate_ctrl_info); +void cl_rate_ctrl_parse(union cl_rate_ctrl_info *rate_ctrl_info, u8 *nss, u8 *mcs); + +void cl_rate_ctrl_set_default(struct cl_hw *cl_hw); + +void cl_rate_ctrl_set_default_per_he_minrate(struct cl_hw *cl_hw, u8 bw, + u8 nss, u8 mcs, u8 gi); +bool cl_rate_ctrl_set_mcast(struct cl_hw *cl_hw, u8 mode, u8 mcs); +void cl_rate_ctrl_update_desc_single(struct cl_hw *cl_hw, struct tx_host_info *info, + struct cl_sw_txhdr *sw_txhdr); +void cl_rate_ctrl_update_desc_agg(struct cl_hw *cl_hw, struct tx_host_info *info); +void cl_data_rates_inverse_build(void); +u16 cl_data_rates_get(u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi); +u16 cl_data_rates_get_x10(u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi); + +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + +struct cl_dyn_bcast_rate { + u8 sta_min_mcs; + u8 bcast_mcs; + u8 wrs_mode; + u8 ltf; +}; + +void cl_dyn_bcast_rate_init(struct cl_hw *cl_hw); +void cl_dyn_bcast_rate_set(struct cl_hw *cl_hw, u8 bcast_mcs); +void cl_dyn_bcast_rate_recovery(struct cl_hw *cl_hw); +void cl_dyn_bcast_rate_change(struct cl_hw *cl_hw, struct cl_sta *cl_sta_change, + u8 old_mcs, u8 new_mcs); +void cl_dyn_bcast_rate_update_upon_assoc(struct cl_hw *cl_hw, u8 mcs, u8 num_sta); +void cl_dyn_bcast_rate_update_upon_disassoc(struct cl_hw *cl_hw, u8 mcs, u8 num_sta); +void cl_dyn_bcast_update(struct cl_hw *cl_hw); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + +struct cl_dyn_mcast_rate { + u8 wrs_mode_default; + u8 wrs_mode_curr; +}; + +void cl_dyn_mcast_rate_init(struct cl_hw *cl_hw); +void cl_dyn_mcast_rate_set(struct cl_hw *cl_hw); +void cl_dyn_mcast_rate_recovery(struct cl_hw *cl_hw); +void cl_dyn_mcast_rate_update_upon_assoc(struct cl_hw *cl_hw, u8 wrs_mode, u8 num_sta); +void cl_dyn_mcast_rate_update_upon_disassoc(struct cl_hw *cl_hw, u8 wrs_mode, u8 num_sta); +void cl_dyn_mcast_update(struct cl_hw *cl_hw); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ + +#endif /* CL_RATE_CTRL_H */ From patchwork Tue May 24 11:34:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575970 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 A8456C433FE for ; Tue, 24 May 2022 11:39:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236849AbiEXLj0 (ORCPT ); Tue, 24 May 2022 07:39:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235357AbiEXLjY (ORCPT ); Tue, 24 May 2022 07:39:24 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60047.outbound.protection.outlook.com [40.107.6.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 461428DDC1 for ; Tue, 24 May 2022 04:39:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dEIuaI9wJ9G4PkHzGhMiRyKdLQnXG4YqL7l8VjVzgbzPPWyvBFjR8US/zRV4r9E5FCbSFEq+/tYeUk+qgKgJGD+cI9yiFuhIc69+3F4UOsSsNWv/H2tHjZILsgOBH76fff5KkV/k+QAAQDsujVsjOFIQOtFtjZCH4DFVb2ve1XiOMmXV+FMJ/ncNPmVpOygJPWXR0PbJxyLDFJyqsdZLIt0aohoB/F392Fh3o9ZzRb7AX9dwAhTzB0awAoIhDei0xRPVgVWRtpD+N3Ciiyu6chAmF9LPi2bhPF/9OBIRaShyeGtgLw43Thga/HFKb14oB5iMgnMILfD48XYQDvRaEA== 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=xcDpzWGMW77bGjdY+GT2edSgQ8KR6rmN61X/5EOoDp4=; b=LLRBbnkkaRGhxjRW/AkUzbh69/iCt6N1XsfQI1gb8+k5K1uEtzljufFN1AY+H9um49XDTTTV4OGnvUnWeoPRq3BHCVNV29XU/jU1UrxiDEm8zKC1WwsDS9P0dcWa1dCJIPZStEurk61GFeKrL1/v41UvWukKXKs7mNcasnzFJX4IzPHmnr+fApBKvAPwHGE0BvEqHWR4dHn4RHMRaV6fzCzML7vTxXy7ySDikbMfcBt7jVRj7VQWMS2GDpD/j8tpPHr4ETfXPp+MWO7fTeBHugZXUZymqU0fJgOyVJaqCA32cM+kl5MWovDK7ziwLXlkFbprx7WarFIlyYrDY8c+zA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xcDpzWGMW77bGjdY+GT2edSgQ8KR6rmN61X/5EOoDp4=; b=I8UzIBvkyjXqswDrsvjU1MIkT4WjSwNkwIvTjOLVTtZ5L/JokvaRQ+bJyKM+Rk7zLVKsCfenUhdK+A4iSgAPXkNousA4RNivhm7cUdGTtk6swNnLdYUuXwsGTPjAy/OXsCwqLBA9ljB6VJCwthndNwYJX/o5zqSxPrJi9pN3EqA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:38:53 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:38:53 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 60/96] cl8k: add recovery.c Date: Tue, 24 May 2022 14:34:26 +0300 Message-Id: <20220524113502.1094459-61-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0352b016-a06e-4dc5-3016-08da3d79f116 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Jm69/zNlrjcT3cqhd6u1jbUPdZ3xUTjVOyK/SFwpCR3hJTH0LKN6bL4MOEb3Et0ETRsjFachylxbF467cjnMyyWZ1xhJCAPr82sGa2E/HxIlv5eFxEOqu0uVqzrWM81gIczZPr3eZpLynfTaZndZz27sTu2jVu/xIo0S4tjd0jC8AGsvgioPmVjm/DLyjTrzc9G5mgOW0DGtOydRkA35iAxx6WcrY9UIxdCdemUOvx+J/eneQPQSd+6GlGBqkedOvSPHqKFtSRaQ4I/O+31ZlzPgCXLZiFEI4o5GEhuCjJeBoF3A3NIXrICdNeXwhWXucr6nmPBmO8sixYyvADu9hjTh8suWjlyOCgYvueBgJQd23ilkE9yr6hTKvkvXA0jakz9FEs4MzH3bwYVq7msJkyot8eYNg4In4gwgreefkBNjuk+VSothHCEp+ePwY0lvvir5v1vWIhZOEA5B7l9K/yuRGjR9hIeXLqe99HAeyUQksZ6SEi4+QtADjqTIK6ya8ui4gyCiyiDRWWnMFJPhVmBGg9DtmtNVRpwSOU/KmkZVyxdqfBk2i2Knv5FvuzQ347uSpnGPAVu7VpQxrqrkA+Hi0pir7oc9/hg/xPzzNPBpArvvUF7f9Fm5PDbdHACil9IgiKHGlvRx9U+qNu94qPOLj1qIoW0HbYEqFEmwq49rl0J8dYvVlsto5EkjH2MfPdNDPQP92Eosn1DL435AfdA+5YLc2FjC/DnD00t8BJ8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Sk0WbPkZVGmBKz2AAOgdvA9fp+qw33jDJvu6xXPUJb1+9JkCUb9OYgKQMydCfQLlywvN+a4OrBHS3q3wfRkx3f6+17OMfJx6RQD6hGOHfYp9WxJpWgc4hKHoFlnIfYHRtMeN1RD2+5Uu8CRddZoiASPoAvYRNFdaPC3EYsfrhNESnaFHpqwLh/4KAY6JYs4jIUff9pZJFlq5nfh29Ydwg4pCNs+mDUcCLFEIYDeSG74Ah/7l3aoIQTLp8fazecR5rrOZ2gwwd+9XITLic8Tgi1n/JJjmuDwazzMb60Jw4zx23pJ+6Nide1bLORO9fLs3wB+mnlT18qd+3Vag1eMFsU5zsM92fIJBWeBrxdNIyZ6pG71h3RebqBAhf2kYX24B783I8taNoWEvtktjrfnRI3XTotRzgirVUjqSZL2vKN2WLRs7PyD8zRzeRkh9gPJ/8RPg/2E38vMquzpS6QCbBhLPgbiKpYLxDflgakbDduHOEErzFjSBbWzNIZYdo3+DN+GyfAIktEVZvgo9hW7r40aCPq2Iwas2kGxd7gl+Zj1H3oVgLdOdPo0D9N05VbkNfGXENK0xa2zBjU9WI9wFdwap7xlAvEvwOM8u7+cS29Z8TVjmdGjr1VE+Ix0sqokyBXpsoZ/TTvbiamVHisIHMijiuSpOEDYiUjZJOZd2+HEEgwtwN3py4R0Ts1BqtpEYAdo0fNEG5z1x1qRxrPp5S8tfUyDl7+uDHblZgR7LwCneHujfnx2Ds3ydVnZLIOK+TGcsE+Cv12VQ83f4hOYfwBRapYSORyRP9PafmsWcfkK5exgofD9eTfHA1Dn9kC/Fw8AZvihuMTx60vzn2AmNqCz2DC0VZ1Sr1WIjw2RT+QfHy+L4LxEhP+PjH6czM1GWLz5My29KAlzbunc5NJzWL1BCLVG8JWT4+c9ZQ1NyChp3Aq18aWLLx8vYXWpt9MZwzBUUblcQ3Fbwk7GgK1094UK1XMeTpTvpMPQcVbl6srb+rWle2QeYHxs/sol9xQB3+z+sIAs6/KjpR3kh2ycg8JXc64FOlUSH8FCk30Q03F+a5c9DM0t41lKrCexjb+e6aVwP5qfoxwbIBlERwOekggbmIG1Z8oFrEPeIx8Qa0HZ/YRSFqJgvhSG20WSuxcDgEaiqQSRqxT5uRAI+EQTjzcvSoJh8D6IzGlPM+3/OKdk/wiUD27PQeR02E7P8PE9fwk9w45bQXzTIOrsUGFx4nLpPljqDU1S3axgnjgmszxIa2paE4Ly/Ot9c0bKN16HKPiA5McM0dTY0NxCo9zFCX8CELAqZNASXev5KMtd4MMoV6Z6kjKvUpsAyWluzOmrK3gkJlnBRldCvLr9EaRr1HmH5Jq+vT5rRv3EUzSMP3Fyw0SnFo0nv/NOwJF4c8AIyfoe03F1dxYEzfDGUVrWL63Z+iLOoWwaoMehOOxyLnODRMAqlmif6wO74N4YS0xGZSsrXwVUsZTFjy2MEoZWuNcybr90h9LlaIm0Qfg8fnbYP7fA/N33DFAzxW5gsf4oeRigWq9QbNNyNZkrRI3bPiwjawAGsd+q/ExrfH4jr5q8Y+1nu/DHtEP7t9KjTKFhgXIQXvr02l4skat9TJi7ljKBrvnmVXGmV0om6g7NGWgXzWNvSxIXSMcudFB1k/DdFZxlGjpbH/tOjxZHYHzRW2wm3grcg3LWz8P7bvOAGHoiAK4Bnth0QxFd71FUukFct9r/wnGNP3iH8rFqSJeK1m4medco2MxLhijw7jZzmSjo= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0352b016-a06e-4dc5-3016-08da3d79f116 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:37.3009 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 4ftDW0wkeHF8pe2qjzQKz2AoBNDULqBMCch5okmn30I/9zHaYGhk+jO4DRArT7SkNBUVj+B9+j5l7ot3DSJpVA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/recovery.c | 280 ++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/recovery.c diff --git a/drivers/net/wireless/celeno/cl8k/recovery.c b/drivers/net/wireless/celeno/cl8k/recovery.c new file mode 100644 index 000000000000..dc0c33be9200 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/recovery.c @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "hw.h" +#include "main.h" +#include "phy.h" +#include "vif.h" +#include "dfs.h" +#include "maintenance.h" +#include "vns.h" +#include "config.h" +#include "ela.h" +#include "radio.h" +#include "recovery.h" + +struct cl_recovery_work { + struct work_struct ws; + struct cl_hw *cl_hw; + int reason; +}; + +#define RECOVERY_POLL_TIMEOUT 6 + +static void cl_recovery_poll_completion(struct cl_hw *cl_hw) +{ + u8 cntr = 0; + + while (test_bit(CL_DEV_SW_RESTART, &cl_hw->drv_flags)) { + msleep(1000); + + if (++cntr == RECOVERY_POLL_TIMEOUT) { + cl_dbg_verbose(cl_hw, "\n"); + cl_dbg_err(cl_hw, "Driver handgup was detected!..."); + break; + } + } +} + +static void cl_recovery_start_hw(struct cl_hw *cl_hw) +{ + clear_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags); + + /* Restart MAC firmware... */ + if (cl_main_on(cl_hw)) { + cl_dbg_err(cl_hw, "Couldn't turn platform on .. aborting\n"); + return; + } + + if (cl_msg_tx_reset(cl_hw)) { + cl_dbg_err(cl_hw, "Failed to send firmware reset .. aborting\n"); + return; + } + + set_bit(CL_DEV_SW_RESTART, &cl_hw->drv_flags); + clear_bit(CL_DEV_HW_RESTART, &cl_hw->drv_flags); + + /* Hand over to mac80211 from here */ + ieee80211_restart_hw(cl_hw->hw); + /* Start firmware */ + if (cl_msg_tx_start(cl_hw)) { + cl_dbg_err(cl_hw, "Failed to send firmware start .. aborting\n"); + return; + } + + cl_recovery_poll_completion(cl_hw); +} + +static void cl_recovery_stop_hw(struct cl_hw *cl_hw) +{ + /* Start recovery process */ + ieee80211_stop_queues(cl_hw->hw); + cl_hw->recovery_db.in_recovery = true; + + clear_bit(CL_DEV_STARTED, &cl_hw->drv_flags); + set_bit(CL_DEV_HW_RESTART, &cl_hw->drv_flags); + set_bit(CL_DEV_STOP_HW, &cl_hw->drv_flags); + /* Disable interrupts */ + cl_irq_disable(cl_hw, cl_hw->ipc_e2a_irq.all); + cl_maintenance_stop(cl_hw); + + mutex_lock(&cl_hw->dbginfo.mutex); + + cl_main_off(cl_hw); + + cl_hw->fw_active = false; + cl_hw->fw_send_start = false; + + mutex_unlock(&cl_hw->dbginfo.mutex); + + /* Reset it so MM_SET_FILTER_REQ will be called during the recovery */ + cl_hw->rx_filter = 0; + + /* + * Reset channel/frequency parameters so that cl_msg_tx_set_channel() + * will not be skipped in cl_ops_config() + */ + cl_hw->channel = 0; + cl_hw->primary_freq = 0; + cl_hw->center_freq = 0; +} + +static void cl_recovery_process(struct cl_hw *cl_hw) +{ + int ret; + struct cl_chip *chip = cl_hw->chip; + + mutex_lock(&chip->recovery_mutex); + + cl_dbg_verbose(cl_hw, "Start\n"); + + cl_recovery_stop_hw(cl_hw); + + if (chip->conf->ci_phy_dev != PHY_DEV_DUMMY) { + cl_phy_reset(cl_hw); + + ret = cl_phy_load_recovery(cl_hw); + if (ret) { + cl_dbg_err(cl_hw, "cl_phy_load_recovery failed %d\n", ret); + goto out; + } + } + + cl_recovery_start_hw(cl_hw); + +out: + mutex_unlock(&chip->recovery_mutex); +} + +static void cl_recovery_handler(struct cl_hw *cl_hw, int reason) +{ + unsigned long recovery_diff = jiffies_to_msecs(jiffies - cl_hw->recovery_db.last_restart); + + cl_hw->recovery_db.restart_cnt++; + + if (recovery_diff > cl_hw->conf->ce_fw_watchdog_limit_time) { + cl_hw->recovery_db.restart_cnt = 1; + } else if (cl_hw->recovery_db.restart_cnt > cl_hw->conf->ce_fw_watchdog_limit_count) { + cl_dbg_verbose(cl_hw, "Too many failures... aborting\n"); + cl_hw->conf->ce_fw_watchdog_mode = FW_WD_DISABLE; + return; + } + + cl_hw->recovery_db.last_restart = jiffies; + + /* Count recovery attempts for statistics */ + cl_hw->fw_recovery_cntr++; + cl_dbg_trace(cl_hw, "Recovering from firmware failure, attempt #%i\n", + cl_hw->fw_recovery_cntr); + + cl_recovery_process(cl_hw); +} + +static void cl_recovery_work_do(struct work_struct *ws) +{ + /* Worker for restarting hw. */ + struct cl_recovery_work *recovery_work = container_of(ws, struct cl_recovery_work, ws); + + recovery_work->cl_hw->assert_info.restart_sched = false; + cl_recovery_handler(recovery_work->cl_hw, recovery_work->reason); + kfree(recovery_work); +} + +static void cl_recovery_work_sched(struct cl_hw *cl_hw, int reason) +{ + /* + * Schedule work to restart device and firmware + * This is scheduled when driver detects hw assert storm. + */ + struct cl_recovery_work *recovery_work; + + if (!cl_hw->ipc_env || cl_hw->is_stop_context) { + cl_dbg_warn(cl_hw, "Skip recovery - Running down!\n"); + return; + } + + /* If restart is already scheduled - exit */ + if (cl_hw->assert_info.restart_sched) + return; + + cl_hw->assert_info.restart_sched = true; + + /* Recovery_work will be freed by cl_recovery_work_do */ + recovery_work = kzalloc(sizeof(*recovery_work), GFP_ATOMIC); + + if (!recovery_work) + return; + + INIT_WORK(&recovery_work->ws, cl_recovery_work_do); + recovery_work->cl_hw = cl_hw; + recovery_work->reason = reason; + + queue_work(cl_hw->drv_workqueue, &recovery_work->ws); +} + +bool cl_recovery_in_progress(struct cl_hw *cl_hw) +{ + return cl_hw->recovery_db.in_recovery; +} + +void cl_recovery_reconfig_complete(struct cl_hw *cl_hw) +{ + clear_bit(CL_DEV_SW_RESTART, &cl_hw->drv_flags); + + if (cl_ela_is_on(cl_hw->chip)) { + cl_ela_lcu_reset(cl_hw->chip); + cl_ela_lcu_apply_config(cl_hw->chip); + } + +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_rate_recovery(cl_hw); + +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_recovery(cl_hw); + +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + /* DFS recovery */ + cl_dfs_recovery(cl_hw); + + /* VNS recovery */ + cl_vns_recovery(cl_hw); + + /* Restore EDCA configuration */ + cl_edca_recovery(cl_hw); + + /* Temperature recovery */ + cl_temperature_recovery(cl_hw); + + /* Sounding recovery */ + cl_sounding_recovery(cl_hw); + + /* + * Update Tx params for all connected stations to sync firmware after the + * recovery process. Should be called after cl_mu_ofdma_grp_recovery to let + * MU-OFDMA rates in FW be updated successfully + */ + cl_wrs_api_recovery(cl_hw); + + /* Enable maintenance timers back */ + cl_maintenance_start(cl_hw); + if (cl_radio_is_on(cl_hw)) { + /* + * Rearm last_tbtt_ind so that error message will + * not be printed in cl_irq_status_tbtt() + */ + cl_hw->last_tbtt_irq = jiffies; + + cl_msg_tx_set_idle(cl_hw, MAC_ACTIVE, true); + } + + cl_hw->recovery_db.in_recovery = false; + + pr_debug("cl_recovery: complete\n"); + + cl_rx_post_recovery(cl_hw); +} + +void cl_recovery_start(struct cl_hw *cl_hw, int reason) +{ + /* Prevent new messages to be sent until firmware has recovered */ + set_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags); + + switch (cl_hw->conf->ce_fw_watchdog_mode) { + case FW_WD_DISABLE: + cl_dbg_info(cl_hw, "Skip recovery - Watchdog is off!\n"); + break; + + case FW_WD_INTERNAL_RECOVERY: + cl_recovery_work_sched(cl_hw, reason); + break; + + case FW_WD_DRV_RELOAD: + /* TODO: Implement netlink hint to the userspace */ + cl_dbg_info(cl_hw, "RELOAD handler is absent, doing nothing"); + break; + + default: + break; + } +} From patchwork Tue May 24 11:34:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576829 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 5DE4AC433EF for ; Tue, 24 May 2022 11:42:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236957AbiEXLmA (ORCPT ); Tue, 24 May 2022 07:42:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236962AbiEXLky (ORCPT ); Tue, 24 May 2022 07:40:54 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC1EC9346A for ; Tue, 24 May 2022 04:40:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=E47LHLsqXIGVjuNwdpUvVZpSBlfqZ9wCpjunADypRoLus79dbUHAPz8NUBIKtCfXsPbXa/H1IIRQssgV/59xaFVE5XtHD04k0Hl424B7YDHpr9QQMGokJYsBze9oxp2ynTFUNKXFMbl7MA3LoWU43lQwjd+bPiYvLQEX/sYQ7VqiEoFFygCiCwovCAHtFXMGRhxahXyhVBEV0ydlsnJu1KsQFDJadaMwwgk9sDnax+MRtb9ZoJ15kW/C5QZSMJ4LBVi2/SlgkicF/uqeVLraDWu29nwDkfHh2wyrbl+g5OOI1ZY8ufFrWthuBTIC+wMAUkYdxrnu0eRO17RunH3qcQ== 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=0hz9hn2VBY/kFqcnhWJGsFs6PUGJeFU2PTE6ZifvSUo=; b=bXdWZH3dXX0MvuybUB5hlN7rutLIyUtMJrr5dMaLE6e2KypVvPo6KLcQK5LaKrgWXulLcbdQFZnWfjJ5d9D1UeOiw/Sf7eagi7kTbly9LC/XIj+BiM0P8qQZMCkiOp+6+dKJnu3QLelMGy8WD9iN+VUmayui9Xs5e+qyqXQhk+cr10sOZlObolSRkf0b6xUf62AEjIh/b+VCFU2R0/CO9MhRfP6Vd+C9YkH3mQUFo1YM9stzGhpoIBgtQyL12Op+FIRZ7KHvFgZOEh/GGIoQ2SmY5bNpYkA/pBG7CYx8ZcgGDVJUPvtApdalglpwvW9a4fPRHQLR2fOptdC/1WR2mg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0hz9hn2VBY/kFqcnhWJGsFs6PUGJeFU2PTE6ZifvSUo=; b=y94WDjyBVhuLD0GgT/1NEJuZA5cncwHaWImHHq/p9HUxUvSAMvrp2v6kCMRA70Lt5rW2yM2cl9YVXSqach4FX1XYECI2G25yLNOV/9708iL/+dZFoqCaOJTmwPWd/2guZF436rtMPAt/ara3a0R9A1cgBbxBKyZ+VTVahYo+JXg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:39:23 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:23 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 61/96] cl8k: add recovery.h Date: Tue, 24 May 2022 14:34:27 +0300 Message-Id: <20220524113502.1094459-62-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ff6e7bea-8fd4-4aa3-74a5-08da3d79f181 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 0fkh921AaPuQWYXQUuDu2SJSoWYXyONxVF8/dC/Aw36YOxnqnH6oWwR2f0TqXll+3Gnj1ZEiGHNvo9UZ7pFMRFlBSU4BD0dgc/ze1q3dCoOZTOnhyCw9EZNrQtyjTIsEnkV4yFGCMkUkyYgF+t3ZCMs+XyOTbvKzVSwSDMXx7L60W0xpl6ebwmzvBRMT6M4BeWxDI0h7vel5l05HGcc6Hfjyp8HF5s/6i2KggE3vYuLRp4TrFJoCEkmorQh3+zX4O8giH9zMVxiRr3ydZ1GnM2hIqV6Xso5G41BC2GC1SpyAUeJaALq4Et9GJJuqSL9mVP4ZDXBr74p6oQyGBvB0iOnF363IFVouyRz7sSzWMoy7nopiWIsEBMcDNiE3jPyobtBLXMfSo07vu3wml55J/p3ILvDHGfnG9PU7JuIJQfuNZefy6Xh7AtJFUEn4RrY7p+Klwj6B6XCc9wxpgvZbK+LCPMMYZ/Plhfww6204KyaPL/3jrYqNr1qda6u2NGh9ymmZg41tH31LLQqOjqk5XY6Pu3Sjh3rdACB4U3TBFgJxD3MbD1Uun7GNDo/DGplAGpom8m/xahU7Fo0rN6cIHEaC6PYfPXuwfaaWmj3Kh9sG8h2KFb3/c03hesJASzwivDypxAaZ9rNY92gICed2hJY1g5d99RBaq2P02EhgUVf519GjuTaKRrXD2G1psoLE5LpxAdi/Atsa42SEyZrWRCI2i9VmfiX33+dTRwcdyW8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: RU1unefGxGsI/UYulhYuf9bIAf1vQWJr5Uq5XJjD997lJhQYWZbFS3yb0MbSlqMEVLFUZZupYQIx2d+QQm8mZkLkrOFle4Um9DJhpXKOfoUdXziLTONIbiDPq8T0LTNbKMzIUGjqv5EJjMCJsWNKU4c3K+BDVAybFxUK4JlcWuziP8mCOi8MPNQXf9kbmRsa9m42A22xwH2gA6hG08p6e6LPNKopWcahKkdptUepdVXv2JV/tANOyV2gRnizQr+irc5CxMe/l0yoQayY9AujAkDyJJm97BLqqF4IBZOgwK3iSn54bKK7DLtVFwWnWqlyKicKz+dv2oDn4BsxohoB8vYe4DM063/dIO70g05ao5bUKMG/pUmbOAWJNnx7/uFT1KG3l7hrw5mZGhheYBMlC+Q7WDWWCaXaTCooJp+DhGzIjPUUOcg6Q4y9OoOymSiBZVoVnchOUzuemmZKlHB7M3bqxa9iXMXf6H3PFeyNl9NIDkmN4f35dqcaf2wU5GYmU6hhhOS6U/kdT1fABwonpdZzOMC+rHoaadxFS5aE/jeXx7XnqSYjqScT640cOzePb0G8IsAq0PrO3QcB/VqoGFnDLqC6H445grdC3rOzrfyyLldkMJKYtybLLJuj2kGM4dCwKOepwfcBHNJqmjkUPFnOt6Vc+GTC6+nrPrUACIz/XdwzlgyORSmKR6xRGEWjWdeg00F4Jh+rXrwVLTPQrUG1VgZg+1AdrfdkCpO2MMnqbPmf7KdMlm/GkHsIL8hSBwmZ3Muk0iwPZavT4Y5K2HbCtHQbX3rIeN56ig/53RSdkwE2/TbRNGkxU9LLO+MGECUdskrx/fkKrEH9DrvARydhQeivC5/K/G+8LbkCTB9FKgm5scxI+guAKLvN6g1+yXm/G9OxkuuZKFWyXe4QkCiyCY7uKDyTdyj5Tigp7EauKXf5P00w05HzCRY0zqTqTVkhLVf/O586clrMbBi2YSzTsdiwIusAnTmOo1KTT1cvRO39jmRWl/QwVmfV/cswDuJVIXVHIys6IfB59pPBdwNfsT59yPLnDzLRQVPGe9KypKKW6g8BQVmqZLIwdYtzkJ2V0X+nLsUVR+qlPi0wmBWO07LlDg8wStSroRdG25rwn7e2eKzMBH3ZdnVg9YQDJCeiNhyDf8oLYgE/UYPjGNV6bV9/+KbG/EkP0sOqYbd/DO/+MhPtxT1GH91fphC60BqTieg2Aua4wgB+KTjOXtqOctTcVnZDYuLVrOFlkblG2+t6K6K3rxWYBFe8bM4Z535ct5f+JBojFwDTFs9f+Rqka5JgoBUhkFJcArVhMRny1ENKdTBJOMiMkUsholGOaAoGiG1X1YAyoQU9AL4DaE47tFPAbqMJD+w/DRzWS0dbhtCn+amtMqGVTbfikXvRAdI8O/3tSGX0NDd5fWHFGh49otEnfdcI4xl5jdJVGLObCYYaB6Gfcd3ohwrh3apYKF4ikEUtTJxskHJ6YJrHxNyZb8LBu+i74Lrn5xyk9K8pqYpuI/9H4PM7/yETFemtFcOjHwkxMXx2YwGHPDFc4TPaT8nAV0Xp4ZRpDTGZf2Ix21mtQxB6MKL47h4llY3Lf4s7RH1pRyOZczQBpV6jOpUxD1Qc0ScAa1TFQqe79M7mrDtnp519JBlZDTF1wU2a+wl3uro0YlA9qoOjbwv5FgHrXkufRWBZS3AlbuFJn+HVJIiXJwlrzk0qoTBDPVQWPy0rKQmxT6R3gXt7F/bTSHzGqxkRsAshdPz9QdhPS30= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ff6e7bea-8fd4-4aa3-74a5-08da3d79f181 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:37.9882 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: F7Y2EIGN3fnuulX4lrV0EytKFqvYHDvKkVgUu111+Giei2Yte03hNhaTrWLsRmgHK1HBv8lsUA3Nx6XfUW29hg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/recovery.h | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/recovery.h diff --git a/drivers/net/wireless/celeno/cl8k/recovery.h b/drivers/net/wireless/celeno/cl8k/recovery.h new file mode 100644 index 000000000000..303259d5d802 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/recovery.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_RECOVERY_H +#define CL_RECOVERY_H + +#include + +enum recovery_reason { + RECOVERY_WAIT4CFM, + RECOVERY_UNRECOVERABLE_ASSERT, + RECOVERY_UNRECOVERABLE_ASSERT_NO_DUMP, + RECOVERY_ASSERT_STORM_DETECT, + RECOVERY_DRV_FAILED, +}; + +enum cl_fw_wd_mode { + FW_WD_DISABLE, + FW_WD_INTERNAL_RECOVERY, + FW_WD_DRV_RELOAD, +}; + +struct cl_recovery_db { + unsigned long last_restart; + u32 restart_cnt; + + u32 ela_en; + u32 ela_sel_a; + u32 ela_sel_b; + u32 ela_sel_c; + + bool in_recovery; +}; + +bool cl_recovery_in_progress(struct cl_hw *cl_hw); +void cl_recovery_reconfig_complete(struct cl_hw *cl_hw); +void cl_recovery_start(struct cl_hw *cl_hw, int reason); + +#endif /* CL_RECOVERY_H */ From patchwork Tue May 24 11:34:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576836 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 568ECC433F5 for ; Tue, 24 May 2022 11:41:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232816AbiEXLlX (ORCPT ); Tue, 24 May 2022 07:41:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237022AbiEXLlI (ORCPT ); Tue, 24 May 2022 07:41:08 -0400 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50088.outbound.protection.outlook.com [40.107.5.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27223939ED for ; Tue, 24 May 2022 04:40:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OposxdHX6iXMzQtqc4LyunGqTy7GlVmUVdfVSRKB2J+qXQ/6yF4X8fUCQKZGCDql9mcRR/5k+VgtkNqKbzTi0WcBU66cqO+lvSOxNoHdrVCBrD4NwPXT4YvTxk8qh5/AHq6mzrxdKdTDL7CcoWu1EfY41fvNnS9vnwSMFT4tsovBHc1OYA0TS6SrVOTHndo7trdWihGasE3I4j11XplpZ7A6iR+rPd/wgArjlhc4vGBOdUAG+M0mVRtT12utcZqOYCa5QtqkaciISXhozf3XqDr0QTPw3aXdM/ry6jW8lAcFSZQa26PIvo2LOpjoaZIEFFqun8rVNo1z54WfJWccrA== 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=tdvy+fmVaRleE850ad4Twf1GMSPGF8g1EV1GqhxKpOk=; b=kg4RWjAj5fb5AjkS3xUiw8QL3YwGyfLVUJPXn60PhFkkXSljYl+7R51Uq5Nakk0SBxEwDLk1D8gd3231JBr03/c1ulD4477QtS8/FuFbGo1xIVR86qYmLUv49bBRJ6yqn82cETUEBOQILCDRnJ130L28ChRRzEtXx6PATm+oV+8gnZV99CFHbQgMOkEFJZlZPSpIyo1DaJfWMqyn/Y3a0sf+uqIvVUY/m+mP4Nj317//XESQ3BMEyPvCIvk3v7CmBdvM7PWOzSrwXA7fm64J7fYJneFPZl8J3yyp2Uy++BwCn1gQ6NwRnWVBh0KaDWAHfO14LSSU/RKEocH7IyXd6w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tdvy+fmVaRleE850ad4Twf1GMSPGF8g1EV1GqhxKpOk=; b=jX7dPnNM0nbrnkOCf4eRW++RUkWpwFOzhbu8DStzKIo1YmfkDAHin6gTBUENPKA046iHlAWNR5qX/MEwoYLjT1/EIbImkbUdeJmMplHpPYenCFUNw3FkOmV7rj3512ynH7uTJB1LfonkVqLxUNN5UxFDKCo72SPUkBfqzUqVbVY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DU0P192MB1571.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:34c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.23; Tue, 24 May 2022 11:39:24 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:24 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 62/96] cl8k: add regdom.c Date: Tue, 24 May 2022 14:34:28 +0300 Message-Id: <20220524113502.1094459-63-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4c93e2ce-b602-4d90-dd03-08da3d79f212 X-MS-TrafficTypeDiagnostic: DU0P192MB1571:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +iiI+cts60/sVPiTjDDyBxaRC+7Mlb/j9nqO0U6E2OmvrRIzZGOsvFw0FS6epTKkic1Y+IIX+yyH/Fo4VExkaSO+8iCezFBwBYzWqlshC6DqCGnVlNd/3+FmuGE9MDDXaCe7EZT5PNtg74PKqbDP5B23KuY+8b6sutBcvfPjgArpPv97n8/2lIUsh2SRBJl/4K3n6DFXzSFpAimJqgusNatA19jLaeK8Zy2YWd1t+JDQSuNz8lsdU7SSCHLzHj+xafOP15gMvvqDrVGmmd6ElvFxr67jvMHeKtOOcrHxe8ZhVkHa5KT9piNimI6YJPDYR2Jcq1rNLiuh/+CG6bVP+qJzq7VcVjUJxlGQnabpkbTYo84Nce8/doUcIBi9F6oJElPAjqsVA9UesmWeP6JmWSYOuVbkiSiv55Xw1TcyV6iRRT+HUgMQ7pm9QXzYAyNBcj+ehiut+UU5sAX3ZxS0/pt3DlSobrdYDEkdGgwbhZEQ326DwZ5GObH7KPf0HkXr0+VBK23ljueiTX4DlyqX3HQmqTK9ukd1Y0bmH3mZRrIIT3pgFTC7p4ouCi+1FHwm0Kh5+1MVUfKf6cwEkkXPxV/OhASRwj1bLNJZR/fcZAshx8Cs2DJv/74omWX0t4oDE/r8rq2qykPzTzNzAOwUO8s5Wknp4dHPJI+af+abhROv6Vry13IfSKiJkdkq1A5gu0Ycot7h4IQ5kAKLJL2ipzACJ7i49fl+okwKYM3XpCE= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(39850400004)(346002)(396003)(376002)(6512007)(186003)(6916009)(9686003)(38350700002)(38100700002)(41300700001)(36756003)(316002)(54906003)(2616005)(1076003)(86362001)(107886003)(8676002)(66476007)(4326008)(66556008)(66946007)(52116002)(8936002)(6506007)(2906002)(83380400001)(508600001)(5660300002)(6486002)(26005)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: LJ09zz5jpBXIv9eS28G63EIFRCy6/dL+oqrmKwjqdoRPKArl0LQfI+RFFJV+25QZz9usMDT7LqFSU0Lds34BgN5pbOru3VgO2eUkCn7i5PHWChUVt3xqpgd5iosNjpmz8Ihbgl4XqYQry2k3xQckLFAkjxa3hHGpBLWKGw2xh0s6ZpqCzFFkF4XdL4hHodyeI4knynKQjSJLy7ATpeYC40UsmeQPMHv+jVKdD1lTNdLJ1U/tAoGRS/otbECMMOuxVVsjeryw9IEx3HmNggB2tZ0ocyCKK1EEFBm4ZB87P1pETZGJE18XQt0s0m3XpVT7mFzLVRQIp+ih7j7lsrE38Y08EFHUexDjIQp6LYpFS8xs7Z2pKjw4hjKIKVqtsYzUY84Y2y0eF6JOw1IHam6Y1LCV5PBMhxFAjVKNqw5MpEO0i6BSu5WWmqgcmSpZ17Pjx0vMGBem1o3fZwID7wdmxtca+Z/S+ZoQvGop9Cip/HTSwWsThwCWRReldZXHCFwlFPoyUtq45cZM0n5A7XoqLh+YJjdxzrc+0XE1bXJspaWocaeixv8qUDav2/ZRXUlCPSuKhYbKEcfVE8B3p+sFpRFOYNdzILW3CLgRCpv2rFJWgUwJmupdBpsb7mllmBxypgjYvdS+4Fkvxq1c4VPCj0+wC275w5+d2YTMovXKVqH8IKC5dhqNoUBUM9P0Reyd+TgTZ+ODstOiQz46DiJwelzlPMTKyDc8UOtbzraZKo37XlvYJgu2ez1h7KaYRpMUia9vxkLASuugTivXsCKxNm4GU8g9chkMOCy4IkKkbE5K1hMs+nReNuM0z8XY8ElyytW8rm0tToz9r2eSCR9hgcevuR5qRQnLaemyTCy3FVWEgqvXv3Z8lc9s2NJpXnWThqQjowoozl0KC35BJFWozfZ/Yq8GVudyGuNlqqAY/Fp8ToEp4T3qJAUEeVvwU6scms6il2AMPjw+MmlW2JM7REbQKadFc/6du2+FWOvr8xp9/7E3yPJt0nOL2EzjgX9GWme8DhP5yAuWEkb+BxetYcs+dC5WkYMVQ5/sxIaBzuSRzCgOzcuBQqry5V/k6U63x+R9+bmkdukcuKytXVFbYu6jlnGHFHBmDZiQZypAtptnrOK44/PZzqZ31ZxUQPkUhpfw+o+6+SKUeQj1dd59q8AhdjkNM3b+zbYtYrZkRWuTcOY6YSYhNhh295eqoWLVfM90PgPtvEj7vK7jBfsM+Q2lSWbxj1f4tPCo0jpRZosHstgI07/pqZUoLU894/TMXknxci+aC28X2JBFpnqJmFAtftNbxmCH1lNcC7L4fMl8CFwYwandYztyt4VWpH4iDltjMxQW87orzamjXS87ssJF4esydZJ2+p2b2LMdreYcriIkCnsQdq4A8Nl1d7Lu4UnEryYoBBkoo0Q5zQYHqFVn8HDmu7qBiNpBB74CKraPHhA+FyidwMa7y51SUmELzNSRq6MoWWDSyPYWZxV+2YkJWnJbAG2h7g1NGqDJIAePK8fRgoEzWbxcr/iKBvYAWTEPtuoSgqCsRuXcMmwrMBPD/vbzJ3IFY0MZNEL0rkPM3T4OYhHhQZUpnUD/Vps0UQgdOApQQ7uY2/VSRK7OBFQVqhy4242gSoyqtPkbtxSYyiX/ThRp6YztpgT70mwKQbAKUnKDe7R7FslcJt69/a1Bdn9/fk8Nk2mNldVTS8hjaQb75eAqmTALFKeBXtWuXQ7eNMG8tJbmShWxA5Mx/imRvS2TFcNxUojbSWwGYFY= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4c93e2ce-b602-4d90-dd03-08da3d79f212 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:38.9556 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hg8uLvWEQ7OGBAGtpis58JQEIfReZ+4liALeWSEJf+g2iLRPi5OmTT/26r7KCPcKzea9v3JaI1fB/KUu+Hj8iQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P192MB1571 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/regdom.c | 301 ++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/regdom.c diff --git a/drivers/net/wireless/celeno/cl8k/regdom.c b/drivers/net/wireless/celeno/cl8k/regdom.c new file mode 100644 index 000000000000..1b9d33a33d98 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/regdom.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "dfs.h" +#include "core.h" +#include "debug.h" +#include "hw.h" +#include "utils.h" +#include "regdom.h" + +static struct ieee80211_regdomain cl_regdom_24g = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + REG_RULE(2412 - 10, 2472 + 10, 40, 6, 20, 0), + REG_RULE(2484 - 10, 2484 + 10, 20, 6, 20, 0), + } +}; + +static struct ieee80211_regdomain cl_regdom_5g = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + REG_RULE(5150 - 10, 5850 + 10, 80, 6, 30, 0), + } +}; + +static struct ieee80211_regdomain cl_regdom_6g = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + REG_RULE(5935 - 10, 7115 + 10, 80, 6, 30, 0), + } +}; + +static int cl_regd_is_legal_bw(int freq_diff) +{ + int bw = 0; + + for (bw = CHNL_BW_20; bw < CHNL_BW_MAX; bw++) + if (freq_diff == BW_TO_KHZ(bw)) + return bw; + + return -EINVAL; +} + +static int cl_regd_domain_update_rule(struct cl_hw *cl_hw, struct ieee80211_regdomain *rd, + int freq, int power, u8 max_bw, u32 flags, u32 dfs_cac_ms) +{ + struct ieee80211_reg_rule *reg_rule = &rd->reg_rules[rd->n_reg_rules - 1]; + struct ieee80211_power_rule *power_rule = ®_rule->power_rule; + int bw, diff; + + reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(freq + 10); + if (power_rule->max_eirp < DBM_TO_MBM(power)) + power_rule->max_eirp = DBM_TO_MBM(power); + + diff = reg_rule->freq_range.end_freq_khz - reg_rule->freq_range.start_freq_khz; + /* if freq diff is equal to legal BW then update max_bandwidth_khz */ + bw = cl_regd_is_legal_bw(diff); + if (bw >= 0) + reg_rule->freq_range.max_bandwidth_khz = BW_TO_KHZ(min((u8)bw, max_bw)); + + reg_rule->flags |= flags; + reg_rule->dfs_cac_ms = max_t(u32, reg_rule->dfs_cac_ms, dfs_cac_ms); + + return diff; +} + +/* + * Add first rule with minimal BW and increase then in cl_regd_domain_update_rule + * if new freq range will added + */ +static void cl_regd_domain_add_rule(struct cl_hw *cl_hw, struct ieee80211_regdomain *rd, + int freq, int max_power, u8 min_bw, u32 flags, u32 dfs_cac_ms) +{ + struct ieee80211_reg_rule *reg_rule = &rd->reg_rules[rd->n_reg_rules]; + struct ieee80211_freq_range *freq_range = ®_rule->freq_range; + struct ieee80211_power_rule *power_rule = ®_rule->power_rule; + + freq_range->start_freq_khz = MHZ_TO_KHZ(freq - 10); + freq_range->end_freq_khz = MHZ_TO_KHZ(freq + 10); + freq_range->max_bandwidth_khz = BW_TO_KHZ(min_bw); + + power_rule->max_eirp = DBM_TO_MBM(max_power); + power_rule->max_antenna_gain = DBI_TO_MBI(3); + + reg_rule->flags |= flags; + reg_rule->dfs_cac_ms = dfs_cac_ms; + + rd->n_reg_rules++; +} + +static u32 cl_regd_map_reg_flags(u32 reg_flags) +{ + u32 flags = 0; + + if (reg_flags & IEEE80211_CHAN_NO_IR) + flags = NL80211_RRF_NO_IR; + + if (reg_flags & IEEE80211_CHAN_RADAR) + flags |= NL80211_RRF_DFS; + + if (reg_flags & IEEE80211_CHAN_NO_OFDM) + flags |= NL80211_RRF_NO_OFDM; + + if (reg_flags & IEEE80211_CHAN_INDOOR_ONLY) + flags |= NL80211_RRF_NO_OUTDOOR; + + if (reg_flags & (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)) + flags |= NL80211_RRF_NO_HT40; + + if (reg_flags & IEEE80211_CHAN_NO_80MHZ) + flags |= NL80211_RRF_NO_80MHZ; + + if (reg_flags & IEEE80211_CHAN_NO_160MHZ) + flags |= NL80211_RRF_NO_160MHZ; + + return flags; +} + +void cl_regd_set(struct cl_hw *cl_hw, struct ieee80211_regdomain *rd, + struct regulatory_request *request) +{ + int j = 0; + int power = 0, prev_power = 0; + u8 bw = 0, prev_bw = 0; + int freq = 0, prev_freq = 0; + u8 chan = 0; + u32 flags = 0, prev_flags = 0; + u32 dfs_cac_ms = 0; + + spin_lock_bh(&cl_hw->channel_info_lock); + + memset(rd, 0, sizeof(*rd) + NL80211_MAX_SUPP_REG_RULES * sizeof(struct ieee80211_reg_rule)); + memcpy(rd->alpha2, request->alpha2, 2); + + rd->dfs_region = request->dfs_region; + + if (request->dfs_region == NL80211_DFS_FCC) + cl_hw->channel_info.standard = NL80211_DFS_FCC; + else if (request->dfs_region == NL80211_DFS_ETSI) + cl_hw->channel_info.standard = NL80211_DFS_ETSI; + else + cl_hw->channel_info.standard = NL80211_DFS_UNSET; + + for (j = 0; j < cl_channel_num(cl_hw); j++) { + struct cl_chan_info *chan_info = &cl_hw->channel_info.channels[CHNL_BW_20][j]; + + chan = chan_info->channel; + if (!chan) + continue; + + /* Translate from country_power (.25dBm) to max_power (1dBm) */ + power = cl_hw->channel_info.channels[CHNL_BW_20][j].country_max_power_q2 >> 2; + bw = cl_chan_info_get_max_bw(cl_hw, chan); + freq = ieee80211_channel_to_frequency(chan, cl_hw->nl_band); + flags = cl_regd_map_reg_flags(chan_info->flags); + dfs_cac_ms = chan_info->dfs_cac_ms; + if (freq - prev_freq > 20 || prev_power != power || prev_bw != bw || + prev_flags != flags) + cl_regd_domain_add_rule(cl_hw, rd, freq, power, + CHNL_BW_20, flags, dfs_cac_ms); + else + cl_regd_domain_update_rule(cl_hw, rd, freq, power, bw, flags, dfs_cac_ms); + + prev_freq = freq; + prev_power = power; + prev_bw = bw; + prev_flags = flags; + } + + spin_unlock_bh(&cl_hw->channel_info_lock); +} + +static void cl_regd_update_channels(struct cl_hw *cl_hw, struct wiphy *wiphy) +{ + enum nl80211_band band; + const struct ieee80211_supported_band *cfg_band = NULL; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (band != cl_hw->nl_band) + continue; + + cfg_band = wiphy->bands[band]; + if (!cfg_band) + continue; + + cl_chan_update_channels_info(cl_hw, cfg_band); + } +} + +static void cl_regd_set_by_user(struct cl_hw *cl_hw, struct wiphy *wiphy, + struct regulatory_request *request) +{ + if (!cl_hw->channel_info.use_channel_info) + return; + + cl_regd_update_channels(cl_hw, wiphy); + /* + * Here is updated cl_hw->channel_info, + * let's generates new regdom rules into cl_hw->channel_info.rd + */ + cl_regd_set(cl_hw, cl_hw->channel_info.rd, request); + if (cl_band_is_5g(cl_hw)) + cl_dfs_reinit(cl_hw); + /* TODO: calib callback for channels update */ +} + +static bool cl_regd_dyn_mode_enabled(struct cl_hw *cl_hw) +{ + return !strcmp(cl_hw->chip->conf->ci_regdom_mode, "auto"); +} + +static void cl_regd_notifier_apply(struct cl_hw *cl_hw, + struct wiphy *wiphy, + struct regulatory_request *request) +{ + if (!request) + return; + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_CORE: + break; + case NL80211_REGDOM_SET_BY_DRIVER: + break; + case NL80211_REGDOM_SET_BY_USER: + if (cl_regd_dyn_mode_enabled(cl_hw)) + cl_regd_set_by_user(cl_hw, wiphy, request); + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + break; + default: + break; + } +} + +static void cl_regd_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + + cl_regd_notifier_apply(hw->priv, wiphy, request); +} + +static int _cl_regd_init(struct cl_hw *cl_hw, struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + if (cl_regd_dyn_mode_enabled(cl_hw)) { + const struct ieee80211_regdomain *regd = cl_hw->channel_info.rd; + + wiphy->reg_notifier = reg_notifier; + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | + REGULATORY_DISABLE_BEACON_HINTS | + REGULATORY_COUNTRY_IE_IGNORE; + + wiphy_apply_custom_regulatory(wiphy, regd); + + return 0; + } + + /* default is self managed mode */ + wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; + + return regulatory_set_wiphy_regd(wiphy, cl_hw->channel_info.rd); +} + +int cl_regd_init(struct cl_hw *cl_hw, struct wiphy *wiphy) +{ + if (cl_hw->channel_info.use_channel_info) { + cl_hw->channel_info.rd = kzalloc(sizeof(*cl_hw->channel_info.rd) + + NL80211_MAX_SUPP_REG_RULES * + sizeof(struct ieee80211_reg_rule), + GFP_KERNEL); + if (!cl_hw->channel_info.rd) { + cl_dbg_err(cl_hw, "memory allocation failed!\n"); + return -ENOMEM; + } + + struct regulatory_request request = { + .alpha2[0] = cl_hw->chip->conf->ci_country_code[0], + .alpha2[1] = cl_hw->chip->conf->ci_country_code[1], + .alpha2[2] = 0, + .dfs_region = cl_hw->channel_info.standard, + }; + + cl_regd_set(cl_hw, cl_hw->channel_info.rd, &request); + } else { + if (cl_band_is_6g(cl_hw)) + cl_hw->channel_info.rd = &cl_regdom_6g; + else if (cl_band_is_5g(cl_hw)) + cl_hw->channel_info.rd = &cl_regdom_5g; + else + cl_hw->channel_info.rd = &cl_regdom_24g; + } + + return _cl_regd_init(cl_hw, wiphy, cl_regd_notifier); +} + From patchwork Tue May 24 11:34:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576848 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 2B846C433F5 for ; Tue, 24 May 2022 11:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236855AbiEXLjs (ORCPT ); Tue, 24 May 2022 07:39:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236865AbiEXLjq (ORCPT ); Tue, 24 May 2022 07:39:46 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60065.outbound.protection.outlook.com [40.107.6.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2829441F81 for ; Tue, 24 May 2022 04:39:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NozRaV399Llfr/B185YuROSaEhp8giLZGGxojeYASKOvfLL32hvsoHrbtSsEBipHmPKNgsIB6IkZQ76leZ6dpS2zU3L1xCqSXx6F2asQ5+9g4o8UxAV/X0c2bBfKZi8S8s+TUTdqmb4FIqjzu3h5r0F/h2ITb5PMvDJYyGx/ZQ0MA0x5pFdrvY32s2P/CN1FbWZk+AdFVX3SDep6trssVsofm0zqqwPppN2v1deZAH4oTL26fVlV0C0qGZ2xc+FshdLp1gT/vMwc/YpjXGYNE3NTSGK6+VZPpqd35tWGqWnvMWZIGTv+lova6Upv37IP7m6RUXL2hSE8mJdJi6TF8Q== 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=05Zcz7jJOp44uHsXdmERQ5BchjseNQnAvpdC03MLf4g=; b=jMrXg0IKay6BsmU+vpwD+LOzKtVsMXhboi0xypOIJAz+w7gfaUmNEyR2LF5XG3GuDha8mx0mGcteonurkPuTH0tOlARcgQbbqn7rWhOMDeaq1vpjq4MNMvp7m3gjQ3kgIjvAAAoVQNjDL7qOLtVFNZTnxTEB06ZQsMiVfDBzYanzneE87oIC0rs4EBkTajN/rG9jdzVNJWOeJp/RdftwIVh36IfFebyQVrcBz8w32gcFuFf1GVIe8v9yUApi27TZqcYpN0eadK5l0TBQNH2zlIVnddkTDrza3r+bNXdUmrMp0ybhAFtb/b/LOjw/7sLBRJYX9cmfkTFLOv02Bo8Hww== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=05Zcz7jJOp44uHsXdmERQ5BchjseNQnAvpdC03MLf4g=; b=GvDJ0MxMPy4NEjHSM0LAtFzwKqAlPbhHpY9DT2O2BNPNUHuP+BGEAN2IcGQQZ8nQq2A3XM68xEdS1k9ooFWV7XF66jRHXEEKsn81lWsjKN6zKtkeCu1O0+1oF+pN2aS+t+doApbxbiT0NIFrSDiGYaUQDbwXLNotFgTE7IPZSew= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:24 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:24 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 63/96] cl8k: add regdom.h Date: Tue, 24 May 2022 14:34:29 +0300 Message-Id: <20220524113502.1094459-64-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2994a499-edb1-45f7-afc1-08da3d79f287 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: pU7JO73yxJv5UggH3EBJ8/ZIVmjTcyHT2tJU1L/tu1pxKV8jMukQnpNQsYMd8/s0tO7tfIJpTgwvUzie30PziINTJ8MgIcipADL9rirNx3uX6DENy+sS144v4Gg8tycUl67XBoKR/aAXlB0hyJ1O6wU6c2+bhV+/SpJUvenjVJjzeolFdqZUyme9b+j/OR3gIkXT5ugNodlHLUscvB5jPtppryvuCunUIVHAB9razksx1bNSfg58lEzbGAwWKVH2Fpn9rX3JDUxDHpEc05mgtWI6rzImeFViBPkko3pW631867zTEoRDzXE0BIGabzjthqMZulD4mM3qgzsRIrmMeYwK0GA7mpC+zeyplK8OV6YJUHANQclBLHOnx51mBRjlULDhj24mSKYrakDdgnONHkWUbmSDoYl/NGYVVhpW8i6xN0MRYNohFWIpL/ClPO9yFuzAwXQxyhZGTcUCkEqJ2x2VKUVyBXCsGBkkyY3v+ws/bVQO7vZp95wB7XrOWz65YwgTcjgh21VflreQ3L7WLoxefG84mRYw1TRZh1MAbWzQo+7yd20PZ7cl4jJlDqzJgCvmS6TfQAbkNuEE4GG7Ewco5JFwupnKQPWod9NSEBOVLZicnYhN4J/qEI++CPNhS0KStF9yDsb0KVNmaHl4kYmxBpuPvC7tHdMh0A5l2PL+F/O+3c5RuYWgZklir5O3i2pA+1JiO/4Ymm6aRdt+5Zjgc0KEPFNQNcdfKIhmgfo= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(4744005)(1076003)(6916009)(41300700001)(66946007)(8936002)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: leLugU6z10WVJf3OQ2dte4pAdWwh/oTowDKw7nwWdPC1Yhhm0Zs/tStQ/rOttQzc1JXRrWg/lOFlEOlBB2n7SEI2+CxQTPD1qmL1f5wpv5PdWLWCaTK1gtaJiUFnx1R3o28nqFBi2boLURnKd701MR1GGugJQw2KsF7OH/n1kt1bjnzHRAZ29tWC+7ze9oqCmhoYfI8sirhOlIzthDxhvCyW1TFb+6YTSHNpxytqzX3v/rcGu3kQ0+FAJEVQsUg7kSkwRaFC2Wucp6FQEYDOivqgsF5zgZYMcA6srPvrg9Bd54W6aAAREEKww8h36rFaqn2vkCZsWZnQG9YBAPrYSPD8naUrFX5oclHmDSBICGDvMeGAbPdFqXDpn5EbIvkqpb7DuCNGjY/nsgCbOe9VRMNbcCVnRVyj+9slqwTce3xCo7lbxts4LcdD1vLuaS7VspCc9B/uF3Cya+AxqxieqUeQSyBfAlfWYG84pln5C6sF6j+SdeEc79RTSxRMCSmYx6Os7fiui1uSxjNKCQBwla42BRJ+gK1ynbivZPHWOHrfGtJklBdZBUrHViWmkk0QaH7qrWoMlZrjenCssiBFH2uVEWX+qkobN810kajuyYOm+stNuOKF+OMs7hkUUxz2aotlo/LIriyMOFYNV61XOxun+0mKEISHySscTw5ZlCk/Ja8bpqa6jn+2kW4Gwb2xfcjP7hXz9aeyb1Ir3ZWs5T2lS5/MfSirgu3SZipMFMkrIAu/b5Sjm1gCQ6khD7fVLZe84eC4SavEaeVDLbQJQ1EDONwuXOCNhpeO1+4So6ali7S8DuvocEfYP4axyeRQQrRKoiAx69G+jdDe2OHXC2S/H9M4B6f5/g1JkAKovoyeSxukp9yHkQZMV9XbC64W9HC5t4NMbKY/c+cFfAjJyesgXqioRJDHuAM8IlPm+tz71qcBObQtAn82YeI250MEeteHrZofYOvKad3tXebqr405YyICAFINSxE0ojNZJYb9jjqiYF46iP99/dNqVx3pm19z7lyL4ORtzXvF11Qa2CLo8AxbuOlAg+3b0ylG2fgPNaZ5ei5QmSQ9+j4dTinwLKw8egk/wlri+jAlnzJnrz79MTLDsXQdwFb0z2TvE9mGOkvX25lrip8obo/76nooaHeLAcOFm2XbhgjVoPkauOHrXYuPU8zHi5tSdRNZH5r0c7acewgupQncqt8uQqrrg0fraAIyWOsMQ4HWU2rBBDuQHnpiFDpo7mGGngq34mn6fVNxQU+T+Y2zW0JpL40XxKZTK5+xaXkp6L2HyEEGOFr4aEVnR0RGMYGlPfcN2ich2REHCgmEPcuMsxBJ+U8OcGyjALXOWhnEt06SI4bBznfl0GnUcP4iBimiO4k2jL4UDJZkZuRCuMh3X6tr/782yegJ8vSsxnOQeqtlQ6dBKgaVdT9TVuBz+dcujCNXT5vMO9sVY3BDjazUhzi31/Z5kIEka2PgS6SzyjWalaQ55AmJsMkfbiDoWuNdUTiXhvd3SLsbFkhPznbSlHI3UlKu13V80glK5KqYu2jdRnd2/6lTMa9Go8XJj6iFzvarY82eQ8Jv01OQjxGPDd2oKtA0sNvRUkWlfBudc5cz/cYNl9WGQ2hzxHPJgYaidSW5aeEuMAwsScE4lTjFSEoD93TzSlJHtuNkt3TlIpLYzLOdQq1iX1QLbImoeZ0fTE3NYlax4whOfMVIaVPU9oVnDvMNXDRlxfAl0gAX/6pVbIabIxETKCx7FZLMBd7VE0bLxys= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2994a499-edb1-45f7-afc1-08da3d79f287 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:39.6911 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Q4TRJeRi66B039HsBE/ocHsyzMqi3NXTHsVQWpAJdJqoTbmeyRxLyu8swVUq+K7ENtaKwjRG6V76MfuBRc5EgQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/regdom.h | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/regdom.h diff --git a/drivers/net/wireless/celeno/cl8k/regdom.h b/drivers/net/wireless/celeno/cl8k/regdom.h new file mode 100644 index 000000000000..0a063716ef4f --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/regdom.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_REGDOM_H +#define CL_REGDOM_H + +int cl_regd_init(struct cl_hw *cl_hw, struct wiphy *wiphy); +void cl_regd_set(struct cl_hw *cl_hw, struct ieee80211_regdomain *rd, + struct regulatory_request *request); + +#endif /* CL_REGDOM_H */ From patchwork Tue May 24 11:34:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576846 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 6CFD2C433F5 for ; Tue, 24 May 2022 11:40:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236878AbiEXLkA (ORCPT ); Tue, 24 May 2022 07:40:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236864AbiEXLjx (ORCPT ); Tue, 24 May 2022 07:39:53 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60067.outbound.protection.outlook.com [40.107.6.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74C3750440 for ; Tue, 24 May 2022 04:39:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Cea0pbHX91opWFBxEPtDcLISIu7fYaix9TENfi4sVHSSwBp4ydyEAPUXTFkMVGsx1MmK62paPFJm1m8TvSHuyYhdLJIngPCbl/n92pL/DS+0QRxFbg7X7a7qv9MCD2UT8l/c69QDrp/ZkduFNz1PtoHcNQbMrWrCYrDMO7qUIjPPtmn0rc3QaibGaFp/L6BNXXbTVJCISgufwLJN1TByW4R34LXh9BlmwZB9RGBYNn9DpkSgr00rKaPJHf33cNJEFD97UTX3FG9fzu9tyo2A8lxlQzrpCoCRr1SBLBVv7vLJiL7nYKp8FKumPLH5Y7+jAuDn/0KEGKWqDvvydplakg== 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=7q7JCX6RqfDahvqWt6iGrau9gXDxsxbj0qFlt0nzXWE=; b=kgbPdbeMAQij7eC/r8nHo4kZnTj/pH4FB59EjYLi0VupAvlt55sDdiB7NpGbAAXJYHS+1nsUG9UPb7TMpzC9P0thHDfQ5suBhieymGECzsXsqxV6cvUWDhgS0HkYg9mb6txSWAAP/YBSfVunp5/fW57lGEVrfGG23P1ICTjzmbp+HqzxK78PBIMQ2gRR4m7uFIzxEFLyKmPkNT4xFjGKlvi8c+sJkftuXYmKYf8KAXR0tXSkC8Qb8N+YP6w3Q8Gi9rs9Gvvm1W65eyTYQYvtyCgz6b113yYKgMskfYj9VGo69TtFT81yFKl3yoFTJ4MsmHhNyz7yqxjRLIWxzkTO+A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7q7JCX6RqfDahvqWt6iGrau9gXDxsxbj0qFlt0nzXWE=; b=ZYX5H8wZl7tZEB6b00r+EDie7F5m1M1hxbx8DYKmRhUgvFAgAzaHAlDmyQOloWMvPwvyILTQFA7B+bVnDlv4NhL2LRDGgdY/ifJEFyJPC6xGNMYvJbxEepTAD+vzTg/v9OKWJBTNWnCf94v9DtHqVJkHFJqHitTDLrDyaCuEuUM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:24 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:24 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 64/96] cl8k: add reg/reg_access.h Date: Tue, 24 May 2022 14:34:30 +0300 Message-Id: <20220524113502.1094459-65-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 921d2494-d491-4037-9050-08da3d79f2f0 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: RDkXVEsrinw4+ZJnxW6g36nJgACdyPiLWHlnKHhuRWyUxaWpgg03WYYdD0LtU8KIDkxArYJM8Bhj21I52wbWvdQ/H8pXTP1gptM/yl9OCARqBbDW08p43JH4szGH58JER4UnU25VbpCyf9KYZbBoQtctAXESQmgj7T8V952f1X8MH8CCN35rD5s0ep2YqzzfZK01c6z/9vtqvOm+46vNq8x8cJnYjNMVwGMIUrmMOCVx2TIyYsUWy4uVMoMDOHKrFCWET78J1NBQy0KtBF4ePkr9FB51jo5EWNNVyiOmJqXCjsyCcwBYbmZiPSjR+HIpoQsSFUsoMVWr9o2hDTIUglCuZ0KmHXbYfuwEdjfvolkGt6zsMrkhqO/EoQfZNgW2c9wHBJAdb7azgyU/2p7Ro2uEBcfGJbr08lBKrL9WHYhaILjLyKiesHmre7hKgcgypFOGXEm7LGK5sCw6XP3J9wJ2X6fKwgu0D+ZNzPf//D6yhAU/07I8ZiiY8lGMbqpN3/RKRSOxbZ8dn+4AsvIQtDN1mSMfmDcYg2kLreUCCiHo9y4lCT9i21zrVuGWkyUL0CRlmQahiJ4iPLfDER48izwZdgHt4luoYYkqQ+5EKsc4xX2TKrZ2tYPTselaW1ETGgEUBr4G+G0kqJGYbE2ZJX2nqnC8sHOX/66CCyj20y9lR8Udsrrb4PZ9F7r9doziFFk3x7czUlZKQG9aHwamc3/uKoRoqVj4p/Nqvtqs2w8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 1KTfuCkzapNDPJq+tNlOmW4LwhkFS5pEjzKoXksX+PtqMq68ATN5pwajPHEJCOo340d/lZL6f3+UDnPZY7Gyqv4Wn7Gtt70u/Ea7QyIJuf0W72Ly4qjZGthi6TtxODpmcYO55RWZtx4S8Wx4+LP/J+4/FcVz0dU2dHxxPKFPTI0KTV6MnICaOpRCZbPeZxYjP9BQphEUFdZ1EZH1pykrHJwMJhhfCwo8tu3lUF78Sn5RycxUtH5z8wxbueIuklPyu0hAGUuUccRlZkiZHEN+z1ZL7smzyVg5zzrPtHK90q5RsaEbpwzvXZ0Sd/rsXQIt1BJZRmefEjRAwQSuWfON7h7Mipl1G/7Wp59r7cEqiOWver6d/GKXuViXiQP+SJhZvg6zGEWK2dkomD//8VyeNsKnpcxnXJ43VGhMZkCsNfJJsx50AD3lSHKv5tlm41a3VdAbTCLRqS/4O5RVqQ/ogUqPzoSFDkB5PyUIEWINvIIHcGKVxcnCzMYbXhpFvRwptMkwNVw27EQiETeGhR6AdAuBrnhHjYDzCEtTHz3R4PeMhgwGcf0iZri9iYwTwGnt47a2xhgpx5EGiGcqKLfU5nYxaXzRsRJ10yUyaiY/XpSqb73ZaXSqTrwtA1E10GICqOm7qKinQcQVdUrQl2fJaMiorDnT4TrLu9MLz2Z8S1EGHSRmByswu27jRdX8WbUEoWdx/4mhEC++cc7Ly3yvUHHQsfBFhitBqA8ZUQOiPgeRxIjjRAHxPPBPmOq6OSwyA/S2pgkNZWs88M6QPKUIbPY+ea4VtkdJs28j6atbnday2SWtsagqbmLbTEhxEU9bddv5qmYYBXKv2G7Hb1RM/omqCCMYzpvQg8sTJqZBCLAoDwpcA+y9hr0M79e4GwK9BlaX4X43ZAaH4BRioUJXAlPQYuLA34TZ5NjiAv4AtBzRHle/tKxYp+/2OtlawMOISlx3sQ24SSLnO1pqIXTuJEUjwccHlbWqA9TNfar7XkzaIZpASYcYqi5ennLKpvI3R+Bc6K0fgGdX8vwy+hOeO0N1+e60jrOQvDOcoEIKh0oy0yEJ3U/296U2Q1S4f2sdTUVUqfmU926INw2SskQUjjf6fHmYsJCsJRXYPTbOmzePPbwIRUCKIaYK8QYk6kB5DfIqk2fyT/HBKm0CTsxG8r41x35jGhtrbRMAbpeakXsP+Z/AIgBGgMn7C+4VdWfb6IMh8+zoQM9G8sm3VB431OrFLJpXdczTNouj6H2AMGR9v8XuEqsPvmKiiazVIjwWi4voqCE6Cjh7HYU0CK4V2hC0gcDNnMtqj6oadUW2RbtOqexHlnZyTqw0Zvp8DFxZzRnehLQrLoe15zTkDlGwvFKgUBPhb7MQfZnruuGn9QsXaSRDPDjeRSABpEZ+oSnAqTconMahQ1TfwXVjrIjYWQYBfkKHjJT2QE7iu1tLLy+4rw/X75jP3hBL1bRfbdOaHSZYnYBAFvl4R1cDXm3dxdpvu7RwK85h7WjK0u5JLGEA9BPhPvsw9g/VLpDsuAXZHD2ignJvXVnQ8ME2gFMl3XMFzMX0kVd6B9j12ncpo7n3z9UGkOIfAcNgZHdetp7PhgQv20wmwK8QVda5bIRLEqw+CSJDNuZVZSw5cNnD2xlbxEAIutCgW/SxD8a6p84rytLT37Xl8wjCg4EvzrulccSuxENNCmFPqQ6F1r1+3we1gCkU15l17AZA2epQ5fu8kqyQmVRQl8apkrlr4aFseIjTHsJiKXwfqgB8EdxkGGM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 921d2494-d491-4037-9050-08da3d79f2f0 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:40.4097 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Dp2uMt65eg8rpIkeSK/jidCbV+V3P5v/Nyaf8fL+l2j4xL/ZcL7kBoepKloFjMgrWTkRrEStHRJV+ZoVO9YXRw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/reg/reg_access.h | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/reg/reg_access.h diff --git a/drivers/net/wireless/celeno/cl8k/reg/reg_access.h b/drivers/net/wireless/celeno/cl8k/reg/reg_access.h new file mode 100644 index 000000000000..c9d00f7553ea --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/reg/reg_access.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_REG_ACCESS_H +#define CL_REG_ACCESS_H + +#include "hw.h" +#include "chip.h" + +#define hwreg_pr(...) \ + do { \ + if (cl_hw->reg_dbg) \ + cl_dbg_verbose(__VA_ARGS__); \ + } while (0) + +#define chipreg_pr(...) \ + do { \ + if (chip->reg_dbg) \ + cl_dbg_chip_verbose(__VA_ARGS__); \ + } while (0) + +#define XTENSA_PIF_BASE_ADDR 0x60000000 + +/* + * SHARED_RAM Address. + * Actually the PCI BAR4 window will be configured such as SHARED RAM + * is accessed with offset 0 (within the AHB Bridge main window) + */ +#define SHARED_RAM_START_ADDR 0x00000000 +#define REG_MAC_HW_SMAC_OFFSET 0x80000 +#define REG_PHY_LMAC_OFFSET 0x000000 +#define REG_PHY_SMAC_OFFSET 0x100000 +#define REG_MACDSP_API_BASE_ADDR 0x00400000 +#define REG_MAC_HW_BASE_ADDR 0x00600000 +#define REG_RIU_BASE_ADDR 0x00486000 +#define REG_RICU_BASE_ADDR 0x004B4000 +#define APB_REGS_BASE_ADDR 0x007C0000 +#define I2C_REG_BASE_ADDR (APB_REGS_BASE_ADDR + 0x3000) + +/* MACSYS_GCU_XT_CONTROL fields */ +#define SMAC_DEBUG_ENABLE BIT(21) +#define SMAC_BREAKPOINT BIT(20) +#define SMAC_OCD_HALT_ON_RESET BIT(19) +#define SMAC_RUN_STALL BIT(18) +#define SMAC_DRESET BIT(17) +#define SMAC_BRESET BIT(16) +#define UMAC_DEBUG_ENABLE BIT(13) +#define UMAC_BREAKPOINT BIT(11) +#define UMAC_OCD_HALT_ON_RESET BIT(11) +#define UMAC_RUN_STALL BIT(10) +#define UMAC_DRESET BIT(9) +#define UMAC_BRESET BIT(8) +#define LMAC_DEBUG_ENABLE BIT(5) +#define LMAC_BREAKPOINT BIT(4) +#define LMAC_OCD_HALT_ON_RESET BIT(3) +#define LMAC_RUN_STALL BIT(2) +#define LMAC_DRESET BIT(1) +#define LMAC_BRESET BIT(0) + +#define XMAC_BRESET \ + (LMAC_BRESET | SMAC_BRESET | UMAC_BRESET) +#define XMAC_DRESET \ + (LMAC_DRESET | SMAC_DRESET | UMAC_DRESET) +#define XMAC_RUN_STALL \ + (LMAC_RUN_STALL | SMAC_RUN_STALL | UMAC_RUN_STALL) +#define XMAC_OCD_HALT_ON_RESET \ + (LMAC_OCD_HALT_ON_RESET | SMAC_OCD_HALT_ON_RESET | UMAC_OCD_HALT_ON_RESET) +#define XMAC_DEBUG_ENABLE \ + (LMAC_DEBUG_ENABLE | SMAC_DEBUG_ENABLE | UMAC_DEBUG_ENABLE) + +static inline u32 get_actual_reg(struct cl_hw *cl_hw, u32 reg) +{ + if (!cl_hw) + return -1; + + if ((reg & 0x00ff0000) == REG_MAC_HW_BASE_ADDR) + return cl_hw->mac_hw_regs_offset + reg; + + if ((reg & 0x00f00000) == REG_MACDSP_API_BASE_ADDR) { + if (cl_hw->chip->conf->ci_phy_dev == PHY_DEV_DUMMY) + return -1; + return cl_hw->phy_regs_offset + reg; + } + + return reg; +} + +static inline bool cl_reg_is_phy_tcvX(u32 phy_reg, u32 reg_offset) +{ + return (phy_reg & 0xf00000) == (REG_MACDSP_API_BASE_ADDR + reg_offset); +} + +static inline bool cl_reg_is_phy_tcv0(u32 phy_reg) +{ + return cl_reg_is_phy_tcvX(phy_reg, REG_PHY_LMAC_OFFSET); +} + +static inline bool cl_reg_is_phy_tcv1(u32 phy_reg) +{ + return cl_reg_is_phy_tcvX(phy_reg, REG_PHY_SMAC_OFFSET); +} + +static inline u32 cl_reg_read(struct cl_hw *cl_hw, u32 reg) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + u32 val = 0; + + if (actual_reg == (u32)(-1)) + return 0xff; + + val = ioread32(cl_hw->chip->pci_bar0_virt_addr + actual_reg); + hwreg_pr(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + return val; +} + +static inline void cl_reg_write_direct(struct cl_hw *cl_hw, u32 reg, u32 val) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + + if (actual_reg == (u32)(-1)) + return; + + hwreg_pr(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + iowrite32(val, cl_hw->chip->pci_bar0_virt_addr + actual_reg); +} + +#define BASE_ADDR(reg) ((ptrdiff_t)(reg) & 0x00fff000) + +static inline bool should_send_msg(struct cl_hw *cl_hw, u32 reg) +{ + /* + * Check in what cases we should send a message to the firmware, + * and in what cases we should write directly. + */ + if (!cl_hw->fw_active) + return false; + + return ((BASE_ADDR(reg) == REG_RIU_BASE_ADDR) || + (BASE_ADDR(reg) == REG_MAC_HW_BASE_ADDR)); +} + +static inline int cl_reg_write(struct cl_hw *cl_hw, u32 reg, u32 val) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + int ret = 0; + + if (actual_reg == (u32)(-1)) + return -1; + + if (should_send_msg(cl_hw, reg)) { + hwreg_pr(cl_hw, "calling cl_msg_tx_reg_write: reg=0x%x, val=0x%x\n", + actual_reg, val); + cl_msg_tx_reg_write(cl_hw, (XTENSA_PIF_BASE_ADDR + actual_reg), val, U32_MAX); + } else { + hwreg_pr(cl_hw, "reg=0x%x, val=0x%x\n", actual_reg, val); + iowrite32(val, cl_hw->chip->pci_bar0_virt_addr + actual_reg); + } + + return ret; +} + +static inline int cl_reg_write_mask(struct cl_hw *cl_hw, u32 reg, u32 val, u32 mask) +{ + u32 actual_reg = get_actual_reg(cl_hw, reg); + int ret = 0; + + if (actual_reg == (u32)(-1)) + return -1; + + if (should_send_msg(cl_hw, reg)) { + hwreg_pr(cl_hw, "calling cl_msg_tx_reg_write: reg=0x%x, val=0x%x, mask=0x%x\n", + actual_reg, val, mask); + cl_msg_tx_reg_write(cl_hw, (XTENSA_PIF_BASE_ADDR + actual_reg), val, mask); + } else { + u32 reg_rd = ioread32(cl_hw->chip->pci_bar0_virt_addr + actual_reg); + u32 val_write = ((reg_rd & ~mask) | (val & mask)); + + hwreg_pr(cl_hw, "reg=0x%x, mask=0x%x, val=0x%x\n", actual_reg, mask, val_write); + iowrite32(val_write, cl_hw->chip->pci_bar0_virt_addr + actual_reg); + } + + return ret; +} + +static inline void cl_reg_write_chip(struct cl_chip *chip, u32 reg, u32 val) +{ + chipreg_pr(chip, "reg=0x%x, val=0x%x\n", reg, val); + iowrite32(val, chip->pci_bar0_virt_addr + reg); +} + +static inline u32 cl_reg_read_chip(struct cl_chip *chip, u32 reg) +{ + u32 val = ioread32(chip->pci_bar0_virt_addr + reg); + + chipreg_pr(chip, "reg=0x%x, val=0x%x\n", reg, val); + return val; +} + +#endif /* CL_REG_ACCESS_H */ From patchwork Tue May 24 11:34:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575945 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 C7856C433EF for ; Tue, 24 May 2022 11:42:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237010AbiEXLmO (ORCPT ); Tue, 24 May 2022 07:42:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236972AbiEXLmB (ORCPT ); Tue, 24 May 2022 07:42:01 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60065.outbound.protection.outlook.com [40.107.6.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F300BEE34 for ; Tue, 24 May 2022 04:41:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YhikojmybDZCiOW1+lNWrre4NqIiII60Z5zPW1Yvt2lQaOF4tNn2h/A4FaCAhhdwbtf30RWikK4FCYZUY02lCKq/VDZKpaycbrKtKV28rDxZg/JwuXlENgt8Q4NX0oZdtj83/KPLGz6K38PYsltha4TSPsK60OzQbJwV1/lRgll7SyatGiLQE4oOJzLjE0nrmp2Hpf7rSMbH/C9Feuzv32kDk3sVrahP8/fcWfs3OlQK3lk0fzMjKpDrxMZKfFYZmCtqgIULmyICEiGvcTu6Q+PGTvn5Xt9MYAcSdGnOGpOUezM0mFWY8EV6HFkDVbFxxUbKlVMJeGrGohVTNdxDlw== 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=j2Xp1gIlEZIft5Fk3scSlNJo0F3sTiv+SgrYEySUfEQ=; b=RCAQeXaou8LmaFfwC8VLSXd8zLn7vh4bGvnMYFuWxH08yB1D8baV4X5zm1zV0gS3IhwvWccVkuD+3OgvTCnnSjntPKkSXysLXwVvz0OQYYv8RCuTxikCJc25eZPvw8hnoeuHzf07xUilS23NMQv4v6ajmZxvMGc52KjWrBwJvs5mt1Edd0bIrPrxfK8QlISA7sf0FcB6cURgG6IvgdNPNnT4/kniALKLEBQC+BJpZ3sXG7+CsGH/GmwxOwFpZ97Do3bjmNY+Xf7eyhh97ZtKAA2P4yjTqmHhJq3P7IN7L7aRauSjgvoDx8HlYelBwq5FR2Ol2r+i0aCnqQEBZYNWYg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=j2Xp1gIlEZIft5Fk3scSlNJo0F3sTiv+SgrYEySUfEQ=; b=QKc0eXk3lueznT4fdJuLCj7MMLWYXRBR9/yAGq5pHS/bmibUdslJEoEe2MQ//+D0stu7Ckrn3Mh097fbzikKBS/nWZT3a6SkgN3+0zhRATD5JqH/vl3KfKnXIXLMrdMQyfdAkb28Nrjo8C6DtKAwDJ+6J1PyG4gmx4p2z1e8mO0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:25 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:25 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 65/96] cl8k: add reg/reg_defs.h Date: Tue, 24 May 2022 14:34:31 +0300 Message-Id: <20220524113502.1094459-66-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2bfdb656-edf0-415e-8d13-08da3d79f36a X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mSetrELk2CODB5IH4LIGdnrDHP4X5jOy9x9CITV8kpQsD9LIvipqGeCRv50DZVYfiFnd7YuDjSlIFRfRgjsXCDgX+K0jPgm9v/Ow036h/7sHixB7HG+YNaikm/ZefapQ1D92KX0Tl4AHgENxzEz+XLM115g0xGdyxeP3SHsGcuERH9satojN6URSGAodRQ6c7SkIxJPM5TrzP3TI6ksAHVKyZAEK5oUE1Q3sU+cIPvPkr5BKb2GZ2YkCoNVE9Jq4oV4FnA4gzrQpeGVwo+JAHvnlpJdy+F+6FfDHF5k6fPeLk/0FAVYniIt93PJRlmWGojwl3ycYKRsI9PiTX5/yBCrFLkJ3RP0vFSGyzEh+l6MHOhJFME2+h+GqO2g7PicwhTkkxXD1bbVolG/DMuOzcZWK6Q1+UpDr9pb4X9pELuVNh4dqZGs75T01irVocrcNGP9dhjLDTcPC4EoRjTSjNJWfYK8JPkZxDP1ZWk1m++2y5vU8GIXcn0aBJpOW4vQJdIF0bZXJ15KJOfwz5oVjYYfDucpFvrxJ7fQ9l4tV5iFvdOnwACRK9o/S9RBagT44VqUJJjI+WF8yW3pN2rR6CRaGBCI1WAbFjjtKaksc22ruaIpwK0FLjwein1UHLb1iNX/o2kRBmDnEaSyUo/yJ0cTHkVsWEuWxIK+mw8gjer/U5bwnCqVO9Ln7UpRKOVJKww824KkEcv5Z/fFZVbcxYALTDu1UO3DHogUqZec+FXJm6iwwFnMCaZTOGJG6lq3I41fQK/3GIVBXmUI4iRZA2DNsAfvLDybpMzhJwR/e2ms= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(66574015)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001)(579004)(559001)(473944003)(414714003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: O16/a+Y7TZRECkt0maXxEJB5nHISbCIXlpkxtm6H6wSUwCDJtai+6N/hiW89UC1JmDEIDEtoVuGmnA+61fkaqGJ+IqbqrcL6iHN4wIQRVba5LBnWEQIcgFF4r5SjYa28RUhKoENMRMAQfFRty+ecCMIxqd27//Idz3aH5lrEeJ+TOWKtiDCKsCKeCM3iSR1Gm8NsE9qSnFSNVLaCgq+D8Ew8/aO3VlVYwDJFdpe8+R/1hQ+gasLKkTNsRxTV59AjCOEiDp3yM7RPgn1WmeXJdjeFOIBfgIsNbMXRkZdbQ5+vXhyfXAqc6C9P1Xp4Rggc++5IVJu5GsQSsnBMoCs9NSgt43oxpuFKbsvhFIXZ3Xz2sHXSsc0U9m3jRjHNRdUbLvBuHsNsVQBZ7ZG/V3hIc8vlNT5s6Hzh9i/cH3z5k68qTSRxohrxunYAeEknsd/lsWZO2ed46t+BUzC9g4qYPj4HSJxkz+qNoBx8vgwtt93bDIFd0kQkecdwBV1KEU0LpVRrww8sLxzv8387pEDxPZulhtQRniuD8uU39MgLnvjYxSvd1OuVQCwdjx35oGFD8fXKpODn6+Y4pph2KNg38t+KxPfWjfTQzD+S4gf0QQsbE5rBOlClQZO5gA5+Bh3W5soAebqYdcsGKLgPGsbBiDTeZ93hHgbWTFywlbLZArEKgZ4qca1+RuR1PsFIfVPPoNiJ6Pn22NYx6gGPEKHgjbqyo28jLUpynSqm7KwQoDl8k/Uio/l5aCHu/oRRFCTgsCdtuT66KbCdEReMbLjqdpJAXaD52cPOtmoMLjUe7fykdqkdVeC/XjP5e8/OGvw0nFLFBARs+WcuyhfuBHs8TSrpOptUPyPv1jga7sGx6zizCfNhKzMY1sySkkUv90AlUJqmiswKaNgCe94/wxWwC+gB/hX89RLgGqMvexwB9RvjKkPoFLLVLF8Ghskc+j8t9RMNGS2DCIWE6ZWwB4FAGObCJRsJb1Ex2C9tHkmrRFDIaLQ5YzjNkyd0LcjW2jh7K7Ac1ikEulFRK0HVM38plrbAPTsTADVEP9KzQiH/t3Fh1OgcqyfNuVBS9b9e6FVAvSEdWwT90vnzgNX+fDijhtOIVNJnQkOgo/TxEnKLup+4YlDfaJFmqLNSaDsiVa4FYgJHry4V8Gwc2c5dbk75VMDXVtdmip4yDQYhs5Y1U1LmSDK23G9wFSQK6RnodwCaEXfXq6YehQi5ZOzgx5ZoeWO8r5/UEoV1ySD1eu9rkEV7k8h7UFfuF3xDO1m+bT7Elb3+Y/ToxDc2lilt7ZxB1MQb+9n2hP4pJraq4jabHsmI3vnWuj4yf+mmsVd+dE/NNRV/pCtWrVzheEESPWFH5DR5BVHN2qMy0GEza9AyrwAWURlJhhTxNCemtZpWfiMQKMy6CMuE6Uyke/T4fskHsbnrHQkIH+EneiyiBej9/RVvLhnUHFLqSI8+GB1wehFwh9DY9H+SpLZ5OyWzbCvp0I5UK+mL/Joc/s1XtvgOjqpqNjPZy/j1TfrpKhdnwNr4PEU5OEEch13Lj+mATDVBo9KcHCVBqtbyQAlf9pmITQVkU8QctNg8pSY6hwEI243PdgBCbiTzlsr7shWez2Dm7stJKSZthhy5q4NqoIBcQbuXHUfYTmEVr0lEfRvBnSY4Zk4G/XGI8w5/ZjF+A1kGU6jA0p72c+Lkh6lXJVTU/S5O1quakLLxdMhWHQHXz0BFEVOmEAxmZY+4O32x2IFlm9K34W0Ltzh7eqnMiO1fC2M= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2bfdb656-edf0-415e-8d13-08da3d79f36a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:41.6310 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: fm1WVvsDhxzHWTTaaIbH1MGzS8VB3OAwuIW1QM1NvwiydEJlEWjzEdJJLrrM5J4dTXlFcvMKl5XE1jDFyk86Kg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/reg/reg_defs.h | 5494 +++++++++++++++++ 1 file changed, 5494 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/reg/reg_defs.h diff --git a/drivers/net/wireless/celeno/cl8k/reg/reg_defs.h b/drivers/net/wireless/celeno/cl8k/reg/reg_defs.h new file mode 100644 index 000000000000..6dd137629ab5 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/reg/reg_defs.h @@ -0,0 +1,5494 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_REG_DEFS_H +#define CL_REG_DEFS_H + +#include +#include "reg/reg_access.h" +#include "hw.h" +#include "chip.h" + +#define CEVA_MCCI_BASE_ADDR 0x004B0000 + +#define CEVA_CORE_VERSION_ADDR (CEVA_MCCI_BASE_ADDR + 0x1000) +#define CEVA_CORE_ID_ADDR (CEVA_MCCI_BASE_ADDR + 0x1004) + +#define CEVA_CPM_BASE_ADDR (CEVA_MCCI_BASE_ADDR + 0x2000) + +/* PDMA */ +#define CEVA_CPM_PDEA_REG (CEVA_CPM_BASE_ADDR + 0x0008) /* External */ +#define CEVA_CPM_PDIA_REG (CEVA_CPM_BASE_ADDR + 0x000C) /* Internal */ +#define CEVA_CPM_PDTC_REG (CEVA_CPM_BASE_ADDR + 0x0010) /* Control */ + +/* DDMA */ +#define CEVA_CPM_DDEA_REG (CEVA_CPM_BASE_ADDR + 0x001c) /* External */ +#define CEVA_CPM_DDIA_REG (CEVA_CPM_BASE_ADDR + 0x0020) /* Internal */ +#define CEVA_CPM_DDTC_REG (CEVA_CPM_BASE_ADDR + 0x0024) /* Control */ + +#define CEVA_CPM_DDTC_WRITE_COMMAND 0x40000000 + +/* Translated internally to 0x60600000. */ +#define CEVA_SHARED_PMEM_BASE_ADDR_FROM_HOST 0x004C0000 + +/* Internal address to access Shared */ +#define CEVA_SHARED_PMEM_BASE_ADDR_INTERNAL 0x60600000 /* PMEM */ +#define CEVA_SHARED_XMEM_BASE_ADDR_INTERNAL 0x60900000 /* XMEM */ + +#define CEVA_DSP_DATA_SIZE 0x80000 /* 512kB. */ +#define CEVA_DSP_EXT_DATA_SIZE 0x60000 /* 384kB. */ + +/* 512kb */ +#define CEVA_INTERNAL_PMEM_SIZE 0x80000 + +#define CEVA_SHARED_PMEM_SIZE 0x20000 /* 128kb */ +#define CEVA_SHARED_XMEM_SIZE 0x60000 /* 384kB */ + +#define CEVA_MAX_PAGES (CEVA_INTERNAL_PMEM_SIZE / CEVA_SHARED_PMEM_SIZE) + +#define CEVA_SHARED_PMEM_CACHE_SIZE 0x8000 /* 32kb */ + +#define REG_CMU_BASE_ADDR 0x007C6000 + +/* + * @brief CMU_CLK_EN register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    spare_afe_gnrl_en         0
+ *    30    spare_sys_gnrl_en         0
+ *    27    spare_riu44_clk_en        0
+ *    26    spare_riu_clk_en          0
+ *    25    spare_riu2x_clk_en        0
+ *    24    spare_riu4x_clk_en        0
+ *    23    spare_phy_clk_en          0
+ *    22    spare_phy2x_clk_en        0
+ *    21    spare_sysx_clk_en         0
+ *    20    spare_sys2x_clk_en        0
+ *    19    ricu_clk_en               0
+ *    05    smac_proc_clk_en          1
+ *    04    umac_proc_clk_en          1
+ *    03    lmac_proc_clk_en          1
+ * 
+ */ +#define CMU_CLK_EN_ADDR (REG_CMU_BASE_ADDR + 0x00000000) +#define CMU_CLK_EN_OFFSET 0x00000000 +#define CMU_CLK_EN_INDEX 0x00000000 +#define CMU_CLK_EN_RESET 0x00000038 + +static inline void cmu_clk_en_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_CLK_EN_ADDR, value); +} + +/* Field definitions */ +#define CMU_SPARE_AFE_GNRL_EN_BIT ((u32)0x80000000) +#define CMU_SPARE_AFE_GNRL_EN_POS 31 +#define CMU_SPARE_SYS_GNRL_EN_BIT ((u32)0x40000000) +#define CMU_SPARE_SYS_GNRL_EN_POS 30 +#define CMU_SPARE_RIU_44_CLK_EN_BIT ((u32)0x08000000) +#define CMU_SPARE_RIU_44_CLK_EN_POS 27 +#define CMU_SPARE_RIU_CLK_EN_BIT ((u32)0x04000000) +#define CMU_SPARE_RIU_CLK_EN_POS 26 +#define CMU_SPARE_RIU_2_X_CLK_EN_BIT ((u32)0x02000000) +#define CMU_SPARE_RIU_2_X_CLK_EN_POS 25 +#define CMU_SPARE_RIU_4_X_CLK_EN_BIT ((u32)0x01000000) +#define CMU_SPARE_RIU_4_X_CLK_EN_POS 24 +#define CMU_SPARE_PHY_CLK_EN_BIT ((u32)0x00800000) +#define CMU_SPARE_PHY_CLK_EN_POS 23 +#define CMU_SPARE_PHY_2_X_CLK_EN_BIT ((u32)0x00400000) +#define CMU_SPARE_PHY_2_X_CLK_EN_POS 22 +#define CMU_SPARE_SYSX_CLK_EN_BIT ((u32)0x00200000) +#define CMU_SPARE_SYSX_CLK_EN_POS 21 +#define CMU_SPARE_SYS_2_X_CLK_EN_BIT ((u32)0x00100000) +#define CMU_SPARE_SYS_2_X_CLK_EN_POS 20 +#define CMU_RICU_CLK_EN_BIT ((u32)0x00080000) +#define CMU_RICU_CLK_EN_POS 19 +#define CMU_SMAC_PROC_CLK_EN_BIT ((u32)0x00000020) +#define CMU_SMAC_PROC_CLK_EN_POS 5 +#define CMU_UMAC_PROC_CLK_EN_BIT ((u32)0x00000010) +#define CMU_UMAC_PROC_CLK_EN_POS 4 +#define CMU_LMAC_PROC_CLK_EN_BIT ((u32)0x00000008) +#define CMU_LMAC_PROC_CLK_EN_POS 3 + +#define CMU_MAC_ALL_CLK_EN (CMU_RICU_CLK_EN_BIT | \ + CMU_SMAC_PROC_CLK_EN_BIT | \ + CMU_UMAC_PROC_CLK_EN_BIT | \ + CMU_LMAC_PROC_CLK_EN_BIT) + +/* + * @brief CMU_PHY_0_CLK_EN register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    02    ceva0_clk_en              0
+ *    01    phy0_apb_clk_en           0
+ *    00    phy0_main_clk_en          0
+ * 
+ */ +#define CMU_PHY_0_CLK_EN_ADDR (REG_CMU_BASE_ADDR + 0x00000004) +#define CMU_PHY_0_CLK_EN_OFFSET 0x00000004 +#define CMU_PHY_0_CLK_EN_INDEX 0x00000001 +#define CMU_PHY_0_CLK_EN_RESET 0x00000000 + +static inline void cmu_phy_0_clk_en_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_PHY_0_CLK_EN_ADDR, value); +} + +/* Field definitions */ +#define CMU_CEVA_0_CLK_EN_BIT ((u32)0x00000004) +#define CMU_CEVA_0_CLK_EN_POS 2 +#define CMU_PHY_0_APB_CLK_EN_BIT ((u32)0x00000002) +#define CMU_PHY_0_APB_CLK_EN_POS 1 +#define CMU_PHY_0_MAIN_CLK_EN_BIT ((u32)0x00000001) +#define CMU_PHY_0_MAIN_CLK_EN_POS 0 + +#define CMU_PHY0_CLK_EN (CMU_CEVA_0_CLK_EN_BIT | \ + CMU_PHY_0_APB_CLK_EN_BIT | \ + CMU_PHY_0_MAIN_CLK_EN_BIT) + +static inline void cmu_phy_0_clk_en_pack(struct cl_chip *chip, u8 ceva0clken, + u8 phy0apbclken, u8 phy0mainclken) +{ + ASSERT_ERR_CHIP((((u32)ceva0clken << 2) & ~((u32)0x00000004)) == 0); + ASSERT_ERR_CHIP((((u32)phy0apbclken << 1) & ~((u32)0x00000002)) == 0); + ASSERT_ERR_CHIP((((u32)phy0mainclken << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, CMU_PHY_0_CLK_EN_ADDR, + ((u32)ceva0clken << 2) | ((u32)phy0apbclken << 1) | + ((u32)phy0mainclken << 0)); +} + +static inline void cmu_phy_0_clk_en_ceva_0_clk_en_setf(struct cl_chip *chip, u8 ceva0clken) +{ + ASSERT_ERR_CHIP((((u32)ceva0clken << 2) & ~((u32)0x00000004)) == 0); + cl_reg_write_chip(chip, CMU_PHY_0_CLK_EN_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_0_CLK_EN_ADDR) & ~((u32)0x00000004)) | + ((u32)ceva0clken << 2)); +} + +static inline void cmu_phy_0_clk_en_phy_0_apb_clk_en_setf(struct cl_chip *chip, u8 phy0apbclken) +{ + ASSERT_ERR_CHIP((((u32)phy0apbclken << 1) & ~((u32)0x00000002)) == 0); + cl_reg_write_chip(chip, CMU_PHY_0_CLK_EN_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_0_CLK_EN_ADDR) & ~((u32)0x00000002)) | + ((u32)phy0apbclken << 1)); +} + +/* + * @brief CMU_PHY_1_CLK_EN register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    02    ceva1_clk_en              0
+ *    01    phy1_apb_clk_en           0
+ *    00    phy1_main_clk_en          0
+ * 
+ */ +#define CMU_PHY_1_CLK_EN_ADDR (REG_CMU_BASE_ADDR + 0x00000008) +#define CMU_PHY_1_CLK_EN_OFFSET 0x00000008 +#define CMU_PHY_1_CLK_EN_INDEX 0x00000002 +#define CMU_PHY_1_CLK_EN_RESET 0x00000000 + +static inline void cmu_phy_1_clk_en_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_PHY_1_CLK_EN_ADDR, value); +} + +/* Field definitions */ +#define CMU_CEVA_1_CLK_EN_BIT ((u32)0x00000004) +#define CMU_CEVA_1_CLK_EN_POS 2 +#define CMU_PHY_1_APB_CLK_EN_BIT ((u32)0x00000002) +#define CMU_PHY_1_APB_CLK_EN_POS 1 +#define CMU_PHY_1_MAIN_CLK_EN_BIT ((u32)0x00000001) +#define CMU_PHY_1_MAIN_CLK_EN_POS 0 + +#define CMU_PHY1_CLK_EN (CMU_CEVA_1_CLK_EN_BIT | \ + CMU_PHY_1_APB_CLK_EN_BIT | \ + CMU_PHY_1_MAIN_CLK_EN_BIT) + +static inline void cmu_phy_1_clk_en_pack(struct cl_chip *chip, u8 ceva1clken, + u8 phy1apbclken, u8 phy1mainclken) +{ + ASSERT_ERR_CHIP((((u32)ceva1clken << 2) & ~((u32)0x00000004)) == 0); + ASSERT_ERR_CHIP((((u32)phy1apbclken << 1) & ~((u32)0x00000002)) == 0); + ASSERT_ERR_CHIP((((u32)phy1mainclken << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, CMU_PHY_1_CLK_EN_ADDR, + ((u32)ceva1clken << 2) | ((u32)phy1apbclken << 1) | + ((u32)phy1mainclken << 0)); +} + +static inline void cmu_phy_1_clk_en_ceva_1_clk_en_setf(struct cl_chip *chip, u8 ceva1clken) +{ + ASSERT_ERR_CHIP((((u32)ceva1clken << 2) & ~((u32)0x00000004)) == 0); + cl_reg_write_chip(chip, CMU_PHY_1_CLK_EN_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_1_CLK_EN_ADDR) & ~((u32)0x00000004)) | + ((u32)ceva1clken << 2)); +} + +static inline void cmu_phy_1_clk_en_phy_1_apb_clk_en_setf(struct cl_chip *chip, u8 phy1apbclken) +{ + ASSERT_ERR_CHIP((((u32)phy1apbclken << 1) & ~((u32)0x00000002)) == 0); + cl_reg_write_chip(chip, CMU_PHY_1_CLK_EN_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_1_CLK_EN_ADDR) & ~((u32)0x00000002)) | + ((u32)phy1apbclken << 1)); +} + +/* + * @brief CMU_CONTROL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    gl_mux_sel                0
+ * 
+ */ +#define CMU_CONTROL_ADDR (REG_CMU_BASE_ADDR + 0x0000000C) +#define CMU_CONTROL_OFFSET 0x0000000C +#define CMU_CONTROL_INDEX 0x00000003 +#define CMU_CONTROL_RESET 0x00000000 + +static inline void cmu_control_gl_mux_sel_setf(struct cl_chip *chip, u8 glmuxsel) +{ + ASSERT_ERR_CHIP((((u32)glmuxsel << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, CMU_CONTROL_ADDR, (u32)glmuxsel << 0); +} + +/* + * @brief CMU_RST register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    18    spare_riu44_reset_n       0
+ *    17    spare_modem_reset_n       0
+ *    16    spare_sys_reset_n         0
+ *    15    n_RICURst                 1
+ * 
+ */ +#define CMU_RST_ADDR (REG_CMU_BASE_ADDR + 0x00000010) +#define CMU_RST_OFFSET 0x00000010 +#define CMU_RST_INDEX 0x00000004 +#define CMU_RST_RESET 0x0000FF80 + +static inline void cmu_rst_n_ricurst_setf(struct cl_chip *chip, u8 nricurst) +{ + ASSERT_ERR_CHIP((((u32)nricurst << 15) & ~((u32)0x00008000)) == 0); + cl_reg_write_chip(chip, CMU_RST_ADDR, + (cl_reg_read_chip(chip, CMU_RST_ADDR) & ~((u32)0x00008000)) | + ((u32)nricurst << 15)); +} + +/* + * @brief CMU_PHY_0_RST register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    03    ceva0_global_rst_n        1
+ *    02    mpif0_rst_n               1
+ *    01    phy0_preset_n             1
+ *    00    phy0_rst_n                1
+ * 
+ */ +#define CMU_PHY_0_RST_ADDR (REG_CMU_BASE_ADDR + 0x00000014) +#define CMU_PHY_0_RST_OFFSET 0x00000014 +#define CMU_PHY_0_RST_INDEX 0x00000005 +#define CMU_PHY_0_RST_RESET 0x0000000F + +static inline void cmu_phy_0_rst_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_PHY_0_RST_ADDR, value); +} + +/* Field definitions */ +#define CMU_CEVA_0_GLOBAL_RST_N_BIT ((u32)0x00000008) +#define CMU_CEVA_0_GLOBAL_RST_N_POS 3 +#define CMU_MPIF_0_RST_N_BIT ((u32)0x00000004) +#define CMU_MPIF_0_RST_N_POS 2 +#define CMU_PHY_0_PRESET_N_BIT ((u32)0x00000002) +#define CMU_PHY_0_PRESET_N_POS 1 +#define CMU_PHY_0_RST_N_BIT ((u32)0x00000001) +#define CMU_PHY_0_RST_N_POS 0 + +#define CMU_PHY0_RST_EN (CMU_PHY_0_PRESET_N_BIT | \ + CMU_MPIF_0_RST_N_BIT | \ + CMU_PHY_0_RST_N_BIT | \ + CMU_CEVA_0_GLOBAL_RST_N_BIT) + +static inline void cmu_phy_0_rst_ceva_0_global_rst_n_setf(struct cl_chip *chip, u8 ceva0globalrstn) +{ + ASSERT_ERR_CHIP((((u32)ceva0globalrstn << 3) & ~((u32)0x00000008)) == 0); + cl_reg_write_chip(chip, CMU_PHY_0_RST_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_0_RST_ADDR) & ~((u32)0x00000008)) | + ((u32)ceva0globalrstn << 3)); +} + +/* + * @brief CMU_PHY_1_RST register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    03    ceva1_global_rst_n        1
+ *    02    mpif1_rst_n               1
+ *    01    phy1_preset_n             1
+ *    00    phy1_rst_n                1
+ * 
+ */ +#define CMU_PHY_1_RST_ADDR (REG_CMU_BASE_ADDR + 0x00000018) +#define CMU_PHY_1_RST_OFFSET 0x00000018 +#define CMU_PHY_1_RST_INDEX 0x00000006 +#define CMU_PHY_1_RST_RESET 0x0000000F + +static inline void cmu_phy_1_rst_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_PHY_1_RST_ADDR, value); +} + +/* Field definitions */ +#define CMU_CEVA_1_GLOBAL_RST_N_BIT ((u32)0x00000008) +#define CMU_CEVA_1_GLOBAL_RST_N_POS 3 +#define CMU_MPIF_1_RST_N_BIT ((u32)0x00000004) +#define CMU_MPIF_1_RST_N_POS 2 +#define CMU_PHY_1_PRESET_N_BIT ((u32)0x00000002) +#define CMU_PHY_1_PRESET_N_POS 1 +#define CMU_PHY_1_RST_N_BIT ((u32)0x00000001) +#define CMU_PHY_1_RST_N_POS 0 + +#define CMU_PHY1_RST_EN (CMU_PHY_1_PRESET_N_BIT | \ + CMU_MPIF_1_RST_N_BIT | \ + CMU_PHY_1_RST_N_BIT | \ + CMU_CEVA_1_GLOBAL_RST_N_BIT) + +static inline void cmu_phy_1_rst_ceva_1_global_rst_n_setf(struct cl_chip *chip, u8 ceva1globalrstn) +{ + ASSERT_ERR_CHIP((((u32)ceva1globalrstn << 3) & ~((u32)0x00000008)) == 0); + cl_reg_write_chip(chip, CMU_PHY_1_RST_ADDR, + (cl_reg_read_chip(chip, CMU_PHY_1_RST_ADDR) & ~((u32)0x00000008)) | + ((u32)ceva1globalrstn << 3)); +} + +/* + * @brief CMU_PLL_0_STAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    pll_lock                  0
+ * 
+ */ +#define CMU_PLL_0_STAT_ADDR (REG_CMU_BASE_ADDR + 0x00000040) +#define CMU_PLL_0_STAT_OFFSET 0x00000040 +#define CMU_PLL_0_STAT_INDEX 0x00000010 +#define CMU_PLL_0_STAT_RESET 0x00000000 + +static inline u8 cmu_pll_0_stat_pll_lock_getf(struct cl_chip *chip) +{ + u32 local_val = cl_reg_read_chip(chip, CMU_PLL_0_STAT_ADDR); + + ASSERT_ERR_CHIP((local_val & ~((u32)0x80000000)) == 0); + return (local_val >> 31); +} + +/* + * @brief CMU_PLL_1_STAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    pll_lock                  0
+ * 
+ */ +#define CMU_PLL_1_STAT_ADDR (REG_CMU_BASE_ADDR + 0x00000050) +#define CMU_PLL_1_STAT_OFFSET 0x00000050 +#define CMU_PLL_1_STAT_INDEX 0x00000014 +#define CMU_PLL_1_STAT_RESET 0x00000000 + +static inline u8 cmu_pll_1_stat_pll_lock_getf(struct cl_chip *chip) +{ + u32 local_val = cl_reg_read_chip(chip, CMU_PLL_1_STAT_ADDR); + + ASSERT_ERR_CHIP((local_val & ~((u32)0x80000000)) == 0); + return (local_val >> 31); +} + +/* + * @brief CMU_PHASE_SEL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    20    gp_clk_phase_sel          1
+ *    19    dac_cdb_clk_phase_sel     0
+ *    18    adc_cdb_clk_phase_sel     0
+ *    17    dac_clk_phase_sel         0
+ *    16    adc_clk_phase_sel         0
+ * 
+ */ +#define CMU_PHASE_SEL_ADDR (REG_CMU_BASE_ADDR + 0x00000060) +#define CMU_PHASE_SEL_OFFSET 0x00000060 +#define CMU_PHASE_SEL_INDEX 0x00000018 +#define CMU_PHASE_SEL_RESET 0x00100000 + +static inline void cmu_phase_sel_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, CMU_PHASE_SEL_ADDR, value); +} + +/* Field definitions */ +#define CMU_GP_CLK_PHASE_SEL_BIT ((u32)0x00100000) +#define CMU_GP_CLK_PHASE_SEL_POS 20 +#define CMU_DAC_CDB_CLK_PHASE_SEL_BIT ((u32)0x00080000) +#define CMU_DAC_CDB_CLK_PHASE_SEL_POS 19 +#define CMU_ADC_CDB_CLK_PHASE_SEL_BIT ((u32)0x00040000) +#define CMU_ADC_CDB_CLK_PHASE_SEL_POS 18 +#define CMU_DAC_CLK_PHASE_SEL_BIT ((u32)0x00020000) +#define CMU_DAC_CLK_PHASE_SEL_POS 17 +#define CMU_ADC_CLK_PHASE_SEL_BIT ((u32)0x00010000) +#define CMU_ADC_CLK_PHASE_SEL_POS 16 + +struct cl_fem_lna_enable_gpio { + union { + struct { +#ifdef __LITTLE_ENDIAN_BITFIELD + u16 b0 : 1, + b1 : 1, + b2 : 1, + b3 : 1, + b4 : 1, + b5 : 1, + b6 : 1, + b7 : 1, + b8 : 1, + b9 : 1, + b10 : 1, + b11 : 1, + rsv : 4; +#else /* __BIG_ENDIAN_BITFIELD */ + u16 rsv : 4, + b11 : 1, + b10 : 1, + b9 : 1, + b8 : 1, + b7 : 1, + b6 : 1, + b5 : 1, + b4 : 1, + b3 : 1, + b2 : 1, + b1 : 1, + b0 : 1; +#endif + } bits; + u16 val; + }; +}; + +struct cl_fem_pa_enable_gpio { + union { + struct { +#ifdef __LITTLE_ENDIAN_BITFIELD + u16 b0 : 1, + b1 : 1, + b2 : 1, + b3 : 1, + b4 : 1, + b5 : 1, + b6 : 1, + b7 : 1, + b8 : 1, + b9 : 1, + b10 : 1, + b11 : 1, + rsv : 4; +#else /* __BIG_ENDIAN_BITFIELD */ + u16 rsv : 4, + b11 : 1, + b10 : 1, + b9 : 1, + b8 : 1, + b7 : 1, + b6 : 1, + b5 : 1, + b4 : 1, + b3 : 1, + b2 : 1, + b1 : 1, + b0 : 1; +#endif + } bits; + u16 val; + }; +}; + +struct cl_fem_rx_active_gpio { + union { + struct { +#ifdef __LITTLE_ENDIAN_BITFIELD + u8 b0 : 1, + b1 : 1, + b2 : 1, + b3 : 1, + b4 : 1, + b5 : 1, + b6 : 1, + b7 : 1; +#else /* __BIG_ENDIAN_BITFIELD */ + u8 b7 : 1, + b6 : 1, + b5 : 1, + b4 : 1, + b3 : 1, + b2 : 1, + b1 : 1, + b0 : 1; +#endif + } bits; + u8 val; + }; +}; + +#define EXTRACT_BYPASS_LUT(lut) ((lut) & 0x7) +#define FEM_LUT_MASK 0x7777 + +#define PA_ENABLE_POS 0 +#define LNA_ENABLE_POS 1 +#define RX_ACTIVE_POS 2 +#define GET_BIT(reg, pos) (((reg) >> (pos)) & 0x1) + +#define LNA_ENABLE_GPIO_OUT_CFG(val) \ + (((1 << IO_CTRL_LNA_ENABLE_0_GPIO_ENABLE_POS) & IO_CTRL_LNA_ENABLE_0_GPIO_ENABLE_BIT) | \ + ((1 << IO_CTRL_LNA_ENABLE_0_GPIO_OE_POS) & IO_CTRL_LNA_ENABLE_0_GPIO_OE_BIT) | \ + (((u32)(val) << IO_CTRL_LNA_ENABLE_0_GPIO_OUT_POS) & IO_CTRL_LNA_ENABLE_0_GPIO_OUT_BIT)) +#define PA_ENABLE_GPIO_OUT_CFG(val) \ + (((1 << IO_CTRL_PA_ENABLE_0_GPIO_ENABLE_POS) & IO_CTRL_PA_ENABLE_0_GPIO_ENABLE_BIT) | \ + ((1 << IO_CTRL_PA_ENABLE_0_GPIO_OE_POS) & IO_CTRL_PA_ENABLE_0_GPIO_OE_BIT) | \ + (((u32)(val) << IO_CTRL_PA_ENABLE_0_GPIO_OUT_POS) & IO_CTRL_PA_ENABLE_0_GPIO_OUT_BIT)) +#define RX_ACTIVE_GPIO_OUT_CFG(val) \ + (((1 << IO_CTRL_RX_ACTIVE_0_GPIO_ENABLE_POS) & IO_CTRL_RX_ACTIVE_0_GPIO_ENABLE_BIT) | \ + ((1 << IO_CTRL_RX_ACTIVE_0_GPIO_OE_POS) & IO_CTRL_RX_ACTIVE_0_GPIO_OE_BIT) | \ + (((u32)(val) << IO_CTRL_RX_ACTIVE_0_GPIO_OUT_POS) & IO_CTRL_RX_ACTIVE_0_GPIO_OUT_BIT)) + +#define REG_IPC_BASE_ADDR 0x007C4000 + +/* + * @brief XMAC_2_HOST_RAW_STATUS register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 xmac2host_raw_status      0x0
+ * 
+ */ +#define IPC_XMAC_2_HOST_RAW_STATUS_ADDR (REG_IPC_BASE_ADDR + 0x00000004) +#define IPC_XMAC_2_HOST_RAW_STATUS_OFFSET 0x00000004 +#define IPC_XMAC_2_HOST_RAW_STATUS_INDEX 0x00000001 +#define IPC_XMAC_2_HOST_RAW_STATUS_RESET 0x00000000 + +static inline u32 ipc_xmac_2_host_raw_status_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, IPC_XMAC_2_HOST_RAW_STATUS_ADDR); +} + +/* + * @brief XMAC_2_HOST_ACK register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 xmac2host_trigger_clr     0x0
+ * 
+ */ +#define IPC_XMAC_2_HOST_ACK_ADDR (REG_IPC_BASE_ADDR + 0x00000008) +#define IPC_XMAC_2_HOST_ACK_OFFSET 0x00000008 +#define IPC_XMAC_2_HOST_ACK_INDEX 0x00000002 +#define IPC_XMAC_2_HOST_ACK_RESET 0x00000000 + +static inline void ipc_xmac_2_host_ack_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_XMAC_2_HOST_ACK_ADDR, value); +} + +/* + * @brief XMAC_2_HOST_ENABLE_SET register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 xmac2host_enable_set      0x0
+ * 
+ */ +#define IPC_XMAC_2_HOST_ENABLE_SET_ADDR (REG_IPC_BASE_ADDR + 0x0000000C) +#define IPC_XMAC_2_HOST_ENABLE_SET_OFFSET 0x0000000C +#define IPC_XMAC_2_HOST_ENABLE_SET_INDEX 0x00000003 +#define IPC_XMAC_2_HOST_ENABLE_SET_RESET 0x00000000 + +static inline void ipc_xmac_2_host_enable_set_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_XMAC_2_HOST_ENABLE_SET_ADDR, value); +} + +/* + * @brief XMAC_2_HOST_ENABLE_CLEAR register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 xmac2host_enable_clear    0x0
+ * 
+ */ +#define IPC_XMAC_2_HOST_ENABLE_CLEAR_ADDR (REG_IPC_BASE_ADDR + 0x00000010) +#define IPC_XMAC_2_HOST_ENABLE_CLEAR_OFFSET 0x00000010 +#define IPC_XMAC_2_HOST_ENABLE_CLEAR_INDEX 0x00000004 +#define IPC_XMAC_2_HOST_ENABLE_CLEAR_RESET 0x00000000 + +static inline void ipc_xmac_2_host_enable_clear_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_XMAC_2_HOST_ENABLE_CLEAR_ADDR, value); +} + +/* + * @brief XMAC_2_HOST_STATUS register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 xmac2host_status          0x0
+ * 
+ */ +#define IPC_XMAC_2_HOST_STATUS_ADDR (REG_IPC_BASE_ADDR + 0x00000014) +#define IPC_XMAC_2_HOST_STATUS_OFFSET 0x00000014 +#define IPC_XMAC_2_HOST_STATUS_INDEX 0x00000005 +#define IPC_XMAC_2_HOST_STATUS_RESET 0x00000000 + +static inline u32 ipc_xmac_2_host_status_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, IPC_XMAC_2_HOST_STATUS_ADDR); +} + +/* + * @brief HOST_GLOBAL_INT_EN register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    master_int_enable         0
+ * 
+ */ +#define IPC_HOST_GLOBAL_INT_EN_ADDR (REG_IPC_BASE_ADDR + 0x00000030) +#define IPC_HOST_GLOBAL_INT_EN_OFFSET 0x00000030 +#define IPC_HOST_GLOBAL_INT_EN_INDEX 0x0000000C +#define IPC_HOST_GLOBAL_INT_EN_RESET 0x00000000 + +static inline void ipc_host_global_int_en_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_HOST_GLOBAL_INT_EN_ADDR, value); +} + +/* + * @brief HOST_2_LMAC_TRIGGER register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 host2lmac_trigger         0x0
+ * 
+ */ +#define IPC_HOST_2_LMAC_TRIGGER_ADDR (REG_IPC_BASE_ADDR + 0x00000080) +#define IPC_HOST_2_LMAC_TRIGGER_OFFSET 0x00000080 +#define IPC_HOST_2_LMAC_TRIGGER_INDEX 0x00000020 +#define IPC_HOST_2_LMAC_TRIGGER_RESET 0x00000000 + +static inline void ipc_host_2_lmac_trigger_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_HOST_2_LMAC_TRIGGER_ADDR, value); +} + +/* + * @brief HOST_2_UMAC_TRIGGER register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 host2umac_trigger         0x0
+ * 
+ */ +#define IPC_HOST_2_UMAC_TRIGGER_ADDR (REG_IPC_BASE_ADDR + 0x00000084) +#define IPC_HOST_2_UMAC_TRIGGER_OFFSET 0x00000084 +#define IPC_HOST_2_UMAC_TRIGGER_INDEX 0x00000021 +#define IPC_HOST_2_UMAC_TRIGGER_RESET 0x00000000 + +static inline void ipc_host_2_umac_trigger_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_HOST_2_UMAC_TRIGGER_ADDR, value); +} + +/* + * @brief HOST_2_SMAC_TRIGGER register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 host2smac_trigger         0x0
+ * 
+ */ +#define IPC_HOST_2_SMAC_TRIGGER_ADDR (REG_IPC_BASE_ADDR + 0x00000088) +#define IPC_HOST_2_SMAC_TRIGGER_OFFSET 0x00000088 +#define IPC_HOST_2_SMAC_TRIGGER_INDEX 0x00000022 +#define IPC_HOST_2_SMAC_TRIGGER_RESET 0x00000000 + +static inline void ipc_host_2_smac_trigger_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IPC_HOST_2_SMAC_TRIGGER_ADDR, value); +} + +#define REG_LCU_COMMON_BASE_ADDR 0x007CF000 + +/* + * @brief LCU_COMMON_SW_RST register definition + * Software reset register description + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    SW_RST                    0
+ * 
+ */ +#define LCU_COMMON_SW_RST_ADDR (REG_LCU_COMMON_BASE_ADDR + 0x00000048) +#define LCU_COMMON_SW_RST_OFFSET 0x00000048 +#define LCU_COMMON_SW_RST_INDEX 0x00000012 +#define LCU_COMMON_SW_RST_RESET 0x00000000 + +static inline void lcu_common_sw_rst_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, LCU_COMMON_SW_RST_ADDR, value); +} + +#define REG_LCU_PHY_BASE_ADDR 0x0048E000 + +/* + * @brief LCU_CH_0_START register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    CH0_START                 0
+ * 
+ */ +#define LCU_PHY_LCU_CH_0_START_ADDR (REG_LCU_PHY_BASE_ADDR + 0x00000020) +#define LCU_PHY_LCU_CH_0_START_OFFSET 0x00000020 +#define LCU_PHY_LCU_CH_0_START_INDEX 0x00000008 +#define LCU_PHY_LCU_CH_0_START_RESET 0x00000000 + +/* + * @brief LCU_CH_0_STOP register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    CH0_STOP                  0
+ * 
+ */ +#define LCU_PHY_LCU_CH_0_STOP_ADDR (REG_LCU_PHY_BASE_ADDR + 0x00000070) +#define LCU_PHY_LCU_CH_0_STOP_OFFSET 0x00000070 +#define LCU_PHY_LCU_CH_0_STOP_INDEX 0x0000001C +#define LCU_PHY_LCU_CH_0_STOP_RESET 0x00000000 + +static inline void lcu_phy_lcu_ch_0_stop_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, LCU_PHY_LCU_CH_0_STOP_ADDR, value); +} + +/* + * @brief LCU_CH_1_STOP register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    CH1_STOP                  0
+ * 
+ */ +#define LCU_PHY_LCU_CH_1_STOP_ADDR (REG_LCU_PHY_BASE_ADDR + 0x00000074) +#define LCU_PHY_LCU_CH_1_STOP_OFFSET 0x00000074 +#define LCU_PHY_LCU_CH_1_STOP_INDEX 0x0000001D +#define LCU_PHY_LCU_CH_1_STOP_RESET 0x00000000 + +static inline void lcu_phy_lcu_ch_1_stop_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, LCU_PHY_LCU_CH_1_STOP_ADDR, value); +} + +/* + * @brief LCU_CH_0_STOP_EN register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    02    CH0_EXT_STOP_EN           0
+ *    01    CH0_FIC_STOP_EN           0
+ *    00    CH0_STOP_PTRN_EN          0
+ * 
+ */ +#define LCU_PHY_LCU_CH_0_STOP_EN_ADDR (REG_LCU_PHY_BASE_ADDR + 0x00000078) +#define LCU_PHY_LCU_CH_0_STOP_EN_OFFSET 0x00000078 +#define LCU_PHY_LCU_CH_0_STOP_EN_INDEX 0x0000001E +#define LCU_PHY_LCU_CH_0_STOP_EN_RESET 0x00000000 + +/* + * @brief LCU_SW_RST register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    00    SW_RST                    0
+ * 
+ */ +#define LCU_PHY_LCU_SW_RST_ADDR (REG_LCU_PHY_BASE_ADDR + 0x00000154) +#define LCU_PHY_LCU_SW_RST_OFFSET 0x00000154 +#define LCU_PHY_LCU_SW_RST_INDEX 0x00000055 +#define LCU_PHY_LCU_SW_RST_RESET 0x00000000 + +static inline void lcu_phy_lcu_sw_rst_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, LCU_PHY_LCU_SW_RST_ADDR, value); +} + +/* + * @brief CONFIG_SPACE register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:26 ActiveAntennaSet          0x0
+ *    25:20 RxCckActiveChain          0x0
+ *    19:14 RxOfdmActiveChain         0x0
+ *    13:08 TxCckActiveChain          0x0
+ *    07:06 Band                      0x0
+ *    05:04 ChannelBandwidth          0x0
+ *    03    OfdmOnly                  0
+ *    02    RxSensingMode             0
+ *    01    UpdateSync                0
+ *    00    StartupSync               0
+ * 
+ */ +#define MACDSP_API_CONFIG_SPACE_ADDR (REG_MACDSP_API_BASE_ADDR + 0x00000010) +#define MACDSP_API_CONFIG_SPACE_OFFSET 0x00000010 +#define MACDSP_API_CONFIG_SPACE_INDEX 0x00000004 +#define MACDSP_API_CONFIG_SPACE_RESET 0x00000000 + +static inline void macdsp_api_config_space_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MACDSP_API_CONFIG_SPACE_ADDR, value); +} + +/* + * @brief STATE_CNTRL register definition + * This register controls the core's state transitions. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   07:04 NEXT_STATE                0x0
+ *   03:00 CURRENT_STATE             0x0
+ * 
+ */ +#define MAC_HW_STATE_CNTRL_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000038) +#define MAC_HW_STATE_CNTRL_OFFSET 0x00000038 +#define MAC_HW_STATE_CNTRL_INDEX 0x0000000E +#define MAC_HW_STATE_CNTRL_RESET 0x00000000 + +static inline void mac_hw_state_cntrl_next_state_setf(struct cl_hw *cl_hw, u8 nextstate) +{ + ASSERT_ERR((((u32)nextstate << 4) & ~((u32)0x000000F0)) == 0); + cl_reg_write(cl_hw, MAC_HW_STATE_CNTRL_ADDR, + (cl_reg_read(cl_hw, MAC_HW_STATE_CNTRL_ADDR) & ~((u32)0x000000F0)) | + ((u32)nextstate << 4)); +} + +/* + * @brief MAC_CNTRL_1 register definition + * Contains various settings for controlling the operation of the core. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31    EOF_PAD_FOR_HE            1
+ *   30    EOF_PAD_FOR_VHT           0
+ *   29:28 IMPLICIT_BF_INT_CONF      0x0
+ *   27    DISABLE_BFR_RESP          0
+ *   26    RX_RIFS_EN                0
+ *   25    TSF_MGT_DISABLE           0
+ *   24    TSF_UPDATED_BY_SW         0
+ *   22    MAC_DETECT_UNDERRUN_EN    0
+ *   21    DISABLE_MU_CTS_RESP       0
+ *   20    BQRP_RESP_BY_FW           0
+ *   19    BSRP_RESP_BY_FW           0
+ *   18    ENABLE_NORMAL_ACK_RESP_IN_HE_MU_W_TRIG 0
+ *   17    DISABLE_NORMAL_ACK_RESP_IN_HE_MU_WO_TRIG 0
+ *   16:14 ABGN_MODE                 0x3
+ *   13    KEY_STO_RAM_RESET         0
+ *   12    MIB_TABLE_RESET           0
+ *   11    RATE_CONTROLLER_MPIF      1
+ *   10    DISABLE_BA_RESP           0
+ *   09    DISABLE_CTS_RESP          0
+ *   08    DISABLE_ACK_RESP          0
+ *   07    ACTIVE_CLK_GATING         1
+ *   06    ENABLE_LP_CLK_SWITCH      0
+ *   05    FORCE_MSTA_BA             0
+ *   04    DISABLE_FAST_COMPARE      0
+ *   03    CFP_AWARE                 0
+ *   02    PWR_MGT                   0
+ *   01    AP                        0
+ *   00    BSS_TYPE                  1
+ * 
+ */ +#define MAC_HW_MAC_CNTRL_1_ADDR (REG_MAC_HW_BASE_ADDR + 0x0000004C) +#define MAC_HW_MAC_CNTRL_1_OFFSET 0x0000004C +#define MAC_HW_MAC_CNTRL_1_INDEX 0x00000013 +#define MAC_HW_MAC_CNTRL_1_RESET 0x8000C881 + +static inline void mac_hw_mac_cntrl_1_active_clk_gating_setf(struct cl_hw *cl_hw, + u8 activeclkgating) +{ + ASSERT_ERR((((u32)activeclkgating << 7) & ~((u32)0x00000080)) == 0); + cl_reg_write(cl_hw, MAC_HW_MAC_CNTRL_1_ADDR, + (cl_reg_read(cl_hw, MAC_HW_MAC_CNTRL_1_ADDR) & ~((u32)0x00000080)) | + ((u32)activeclkgating << 7)); +} + +/* + * @brief EDCA_CCA_BUSY register definition + * Indicates the CCA busy time. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 CCA_BUSY_DUR              0x0
+ * 
+ */ +#define MAC_HW_EDCA_CCA_BUSY_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000220) +#define MAC_HW_EDCA_CCA_BUSY_OFFSET 0x00000220 +#define MAC_HW_EDCA_CCA_BUSY_INDEX 0x00000088 +#define MAC_HW_EDCA_CCA_BUSY_RESET 0x00000000 + +static inline u32 mac_hw_edca_cca_busy_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_EDCA_CCA_BUSY_ADDR); +} + +/* + * @brief TX_MINE_BUSY register definition + * TX BUSY time by my TX frames register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 TX_MINE_TIME              0x0
+ * 
+ */ +#define MAC_HW_TX_MINE_BUSY_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000238) +#define MAC_HW_TX_MINE_BUSY_OFFSET 0x00000238 +#define MAC_HW_TX_MINE_BUSY_INDEX 0x0000008E +#define MAC_HW_TX_MINE_BUSY_RESET 0x00000000 + +static inline u32 mac_hw_tx_mine_busy_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_TX_MINE_BUSY_ADDR); +} + +/* + * @brief ADD_CCA_BUSY_SEC_20 register definition + * Indicates the CCA on Secondary 20MHz busy time. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 CCA_BUSY_DUR_SEC_20       0x0
+ * 
+ */ +#define MAC_HW_ADD_CCA_BUSY_SEC_20_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000290) +#define MAC_HW_ADD_CCA_BUSY_SEC_20_OFFSET 0x00000290 +#define MAC_HW_ADD_CCA_BUSY_SEC_20_INDEX 0x000000A4 +#define MAC_HW_ADD_CCA_BUSY_SEC_20_RESET 0x00000000 + +static inline u32 mac_hw_add_cca_busy_sec_20_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_ADD_CCA_BUSY_SEC_20_ADDR); +} + +/* + * @brief ADD_CCA_BUSY_SEC_40 register definition + * Indicates the CCA on Secondary 40MHz busy time. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 CCA_BUSY_DUR_SEC_40       0x0
+ * 
+ */ +#define MAC_HW_ADD_CCA_BUSY_SEC_40_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000294) +#define MAC_HW_ADD_CCA_BUSY_SEC_40_OFFSET 0x00000294 +#define MAC_HW_ADD_CCA_BUSY_SEC_40_INDEX 0x000000A5 +#define MAC_HW_ADD_CCA_BUSY_SEC_40_RESET 0x00000000 + +static inline u32 mac_hw_add_cca_busy_sec_40_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_ADD_CCA_BUSY_SEC_40_ADDR); +} + +/* + * @brief ADD_CCA_BUSY_SEC_80 register definition + * Indicates the CCA on Secondary 80MHz busy time. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 CCA_BUSY_DUR_SEC_80       0x0
+ * 
+ */ +#define MAC_HW_ADD_CCA_BUSY_SEC_80_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000298) +#define MAC_HW_ADD_CCA_BUSY_SEC_80_OFFSET 0x00000298 +#define MAC_HW_ADD_CCA_BUSY_SEC_80_INDEX 0x000000A6 +#define MAC_HW_ADD_CCA_BUSY_SEC_80_RESET 0x00000000 + +static inline u32 mac_hw_add_cca_busy_sec_80_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_ADD_CCA_BUSY_SEC_80_ADDR); +} + +/* + * @brief INTRA_BSS_NAV_BUSY register definition + * Count intra BSS NAV busy period register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 INTRA_BSS_NAV_BUSY_DUR    0x0
+ * 
+ */ +#define MAC_HW_INTRA_BSS_NAV_BUSY_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000408) +#define MAC_HW_INTRA_BSS_NAV_BUSY_OFFSET 0x00000408 +#define MAC_HW_INTRA_BSS_NAV_BUSY_INDEX 0x00000102 +#define MAC_HW_INTRA_BSS_NAV_BUSY_RESET 0x00000000 + +static inline u32 mac_hw_intra_bss_nav_busy_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_INTRA_BSS_NAV_BUSY_ADDR); +} + +/* + * @brief INTER_BSS_NAV_BUSY register definition + * Count inter BSS NAV busy period register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 INTER_BSS_NAV_BUSY_DUR    0x0
+ * 
+ */ +#define MAC_HW_INTER_BSS_NAV_BUSY_ADDR (REG_MAC_HW_BASE_ADDR + 0x0000040C) +#define MAC_HW_INTER_BSS_NAV_BUSY_OFFSET 0x0000040C +#define MAC_HW_INTER_BSS_NAV_BUSY_INDEX 0x00000103 +#define MAC_HW_INTER_BSS_NAV_BUSY_RESET 0x00000000 + +static inline u32 mac_hw_inter_bss_nav_busy_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_INTER_BSS_NAV_BUSY_ADDR); +} + +/* + * @brief DEBUG_PORT_SEL_A register definition + * Used to multiplex different sets of signals on the debug pins. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   15:08 DEBUG_PORT_SEL_1          0x0
+ *   07:00 DEBUG_PORT_SEL_0          0x0
+ * 
+ */ +#define MAC_HW_DEBUG_PORT_SEL_A_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000510) +#define MAC_HW_DEBUG_PORT_SEL_A_OFFSET 0x00000510 +#define MAC_HW_DEBUG_PORT_SEL_A_INDEX 0x00000144 +#define MAC_HW_DEBUG_PORT_SEL_A_RESET 0x00000000 + +static inline u32 mac_hw_debug_port_sel_a_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_DEBUG_PORT_SEL_A_ADDR); +} + +static inline void mac_hw_debug_port_sel_a_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MAC_HW_DEBUG_PORT_SEL_A_ADDR, value); +} + +/* + * @brief DEBUG_PORT_SEL_B register definition + * Used to multiplex different sets of signals on the register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   15:08 DEBUG_PORT_SEL_3          0x0
+ *   07:00 DEBUG_PORT_SEL_2          0x0
+ * 
+ */ +#define MAC_HW_DEBUG_PORT_SEL_B_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000530) +#define MAC_HW_DEBUG_PORT_SEL_B_OFFSET 0x00000530 +#define MAC_HW_DEBUG_PORT_SEL_B_INDEX 0x0000014C +#define MAC_HW_DEBUG_PORT_SEL_B_RESET 0x00000000 + +static inline u32 mac_hw_debug_port_sel_b_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_DEBUG_PORT_SEL_B_ADDR); +} + +static inline void mac_hw_debug_port_sel_b_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MAC_HW_DEBUG_PORT_SEL_B_ADDR, value); +} + +/* + * @brief DEBUG_PORT_SEL_C register definition + * Used to multiplex different sets of signals on the register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   15:08 DEBUG_PORT_SEL_5          0x0
+ *   07:00 DEBUG_PORT_SEL_4          0x0
+ * 
+ */ +#define MAC_HW_DEBUG_PORT_SEL_C_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000534) +#define MAC_HW_DEBUG_PORT_SEL_C_OFFSET 0x00000534 +#define MAC_HW_DEBUG_PORT_SEL_C_INDEX 0x0000014D +#define MAC_HW_DEBUG_PORT_SEL_C_RESET 0x00000000 + +static inline u32 mac_hw_debug_port_sel_c_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_DEBUG_PORT_SEL_C_ADDR); +} + +static inline void mac_hw_debug_port_sel_c_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MAC_HW_DEBUG_PORT_SEL_C_ADDR, value); +} + +/* + * @brief DEBUG_PORT_EN register definition + * Used to determine which debug ports are enabled register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   05    EN5                       0
+ *   04    EN4                       0
+ *   03    EN3                       0
+ *   02    EN2                       0
+ *   01    EN1                       0
+ *   00    EN0                       0
+ * 
+ */ +#define MAC_HW_DEBUG_PORT_EN_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000538) +#define MAC_HW_DEBUG_PORT_EN_OFFSET 0x00000538 +#define MAC_HW_DEBUG_PORT_EN_INDEX 0x0000014E +#define MAC_HW_DEBUG_PORT_EN_RESET 0x00000000 + +static inline u32 mac_hw_debug_port_en_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, MAC_HW_DEBUG_PORT_EN_ADDR); +} + +static inline void mac_hw_debug_port_en_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MAC_HW_DEBUG_PORT_EN_ADDR, value); +} + +/* + * @brief DOZE_CNTRL_2 register definition + * Contains settings for controlling DOZE state. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31    WAKE_UP_FROM_DOZE         0
+ *   00    WAKE_UP_SW                1
+ * 
+ */ +#define MAC_HW_DOZE_CNTRL_2_ADDR (REG_MAC_HW_BASE_ADDR + 0x00008048) +#define MAC_HW_DOZE_CNTRL_2_OFFSET 0x00008048 +#define MAC_HW_DOZE_CNTRL_2_INDEX 0x00002012 +#define MAC_HW_DOZE_CNTRL_2_RESET 0x00000001 + +static inline void mac_hw_doze_cntrl_2_wake_up_sw_setf(struct cl_hw *cl_hw, u8 wakeupsw) +{ + ASSERT_ERR((((u32)wakeupsw << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write(cl_hw, MAC_HW_DOZE_CNTRL_2_ADDR, + (cl_reg_read(cl_hw, MAC_HW_DOZE_CNTRL_2_ADDR) & ~((u32)0x00000001)) | + ((u32)wakeupsw << 0)); +} + +#define MU_ADDR_OFFSET(i) ((i) << 16) +#define MAX_MU_CNT 8 + +/* + * @brief MAC_CNTRL_2 register definition + * Contains various settings for controlling the operation of the core. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   00    SOFT_RESET                0
+ * 
+ */ +#define MAC_HW_MU_MAC_CNTRL_2_ADDR (REG_MAC_HW_BASE_ADDR + 0x00008050) +#define MAC_HW_MU_MAC_CNTRL_2_OFFSET 0x00008050 +#define MAC_HW_MU_MAC_CNTRL_2_INDEX 0x00002014 +#define MAC_HW_MU_MAC_CNTRL_2_RESET 0x00000000 + +static inline void mac_hw_mu_mac_cntrl_2_set(struct cl_hw *cl_hw, u32 value, u8 mu_idx) +{ + ASSERT_ERR(mu_idx < MAX_MU_CNT); + cl_reg_write(cl_hw, (MAC_HW_MU_MAC_CNTRL_2_ADDR + MU_ADDR_OFFSET(mu_idx)), value); +} + +/* + * @brief MIB_TABLE register definition + * MIB table register description + * 1024 memory size + * + */ +#define MAC_HW_MU_MIB_TABLE_ADDR (REG_MAC_HW_BASE_ADDR + 0x00000800) +#define MAC_HW_MU_MIB_TABLE_OFFSET 0x00000800 +#define MAC_HW_MU_MIB_TABLE_SIZE 0x00000400 +#define MAC_HW_MU_MIB_TABLE_END_ADDR (MAC_HW_MU_MIB_TABLE_ADDR + MAC_HW_MU_MIB_TABLE_SIZE - 1) + +#define REG_MACSYS_GCU_BASE_ADDR 0x007C5000 + +/* + * @brief CHIP_VERSION register definition + * Chip Version 8000B0 register description + *
+ * Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *  23:08 PRODUCT_ID                0x8000
+ *  07:04 STEP_ID                   0xB
+ *  03:00 REV_ID                    0x0
+ * 
+ */ +#define MACSYS_GCU_CHIP_VERSION_ADDR (REG_MACSYS_GCU_BASE_ADDR + 0x00000050) +#define MACSYS_GCU_CHIP_VERSION_OFFSET 0x00000050 +#define MACSYS_GCU_CHIP_VERSION_INDEX 0x00000014 +#define MACSYS_GCU_CHIP_VERSION_RESET 0x008000B0 + +static inline u8 macsys_gcu_chip_version_step_id_getf(struct cl_chip *chip) +{ + u32 local_val = cl_reg_read_chip(chip, MACSYS_GCU_CHIP_VERSION_ADDR); + + return ((local_val & ((u32)0x000000F0)) >> 4); +} + +/* + * @brief XT_CONTROL register definition + * Tensilica control register description + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   21    smac_debug_en             0
+ *   20    smac_break_in             0
+ *   19    smac_ocd_halt_on_reset    1
+ *   18    smac_run_stall            0
+ *   17    smac_dreset_n             1
+ *   16    smac_breset_n             0
+ *   13    umac_debug_en             0
+ *   12    umac_break_in             0
+ *   11    umac_ocd_halt_on_reset    1
+ *   10    umac_run_stall            0
+ *   09    umac_dreset_n             1
+ *   08    umac_breset_n             0
+ *   05    lmac_debug_en             0
+ *   04    lmac_break_in             0
+ *   03    lmac_ocd_halt_on_reset    1
+ *   02    lmac_run_stall            0
+ *   01    lmac_dreset_n             1
+ *   00    lmac_breset_n             0
+ * 
+ */ +#define MACSYS_GCU_XT_CONTROL_ADDR (REG_MACSYS_GCU_BASE_ADDR + 0x000000F0) +#define MACSYS_GCU_XT_CONTROL_OFFSET 0x000000F0 +#define MACSYS_GCU_XT_CONTROL_INDEX 0x0000003C +#define MACSYS_GCU_XT_CONTROL_RESET 0x000A0A0A + +static inline u32 macsys_gcu_xt_control_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, MACSYS_GCU_XT_CONTROL_ADDR); +} + +static inline void macsys_gcu_xt_control_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, MACSYS_GCU_XT_CONTROL_ADDR, value); +} + +#define REG_MODEM_GCU_BASE_ADDR 0x00480000 + +/* + * @brief MPU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   21    MPU_CLK_F                 0
+ *   20    MPU_REG_CLK_F             0
+ *   13    MPU_CLK_EN                0
+ *   12    MPU_REG_CLK_EN            0
+ *   01    MPU_RST_N                 0
+ *   00    MPU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_MPU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000004) +#define MODEM_GCU_MPU_OFFSET 0x00000004 +#define MODEM_GCU_MPU_INDEX 0x00000001 +#define MODEM_GCU_MPU_RESET 0x00000000 + +static inline void modem_gcu_mpu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_MPU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_MPU_CLK_F_BIT ((u32)0x00200000) +#define MODEM_GCU_MPU_CLK_F_POS 21 +#define MODEM_GCU_MPU_REG_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_MPU_REG_CLK_F_POS 20 +#define MODEM_GCU_MPU_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_MPU_CLK_EN_POS 13 +#define MODEM_GCU_MPU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_MPU_REG_CLK_EN_POS 12 +#define MODEM_GCU_MPU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_MPU_RST_N_POS 1 +#define MODEM_GCU_MPU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_MPU_REG_RST_N_POS 0 + +/* + * @brief BPU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   24    BPUL_RX_CLK_F             0
+ *   23    BPU_CLK_F                 0
+ *   22    BPU_RX_CLK_F              0
+ *   21    BPU_TX_CLK_F              0
+ *   20    BPU_REG_CLK_F             0
+ *   16    BPUL_RX_CLK_EN            0
+ *   15    BPU_CLK_EN                0
+ *   14    BPU_RX_CLK_EN             0
+ *   13    BPU_TX_CLK_EN             0
+ *   12    BPU_REG_CLK_EN            0
+ *   03    BPU_RST_N                 0
+ *   02    BPU_RX_RST_N              0
+ *   01    BPU_TX_RST_N              0
+ *   00    BPU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_BPU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000008) +#define MODEM_GCU_BPU_OFFSET 0x00000008 +#define MODEM_GCU_BPU_INDEX 0x00000002 +#define MODEM_GCU_BPU_RESET 0x00000000 + +static inline void modem_gcu_bpu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_BPU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_BPU_BPUL_RX_CLK_F_BIT ((u32)0x01000000) +#define MODEM_GCU_BPU_BPUL_RX_CLK_F_POS 24 +#define MODEM_GCU_BPU_CLK_F_BIT ((u32)0x00800000) +#define MODEM_GCU_BPU_CLK_F_POS 23 +#define MODEM_GCU_BPU_RX_CLK_F_BIT ((u32)0x00400000) +#define MODEM_GCU_BPU_RX_CLK_F_POS 22 +#define MODEM_GCU_BPU_TX_CLK_F_BIT ((u32)0x00200000) +#define MODEM_GCU_BPU_TX_CLK_F_POS 21 +#define MODEM_GCU_BPU_REG_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_BPU_REG_CLK_F_POS 20 +#define MODEM_GCU_BPU_BPUL_RX_CLK_EN_BIT ((u32)0x00010000) +#define MODEM_GCU_BPU_BPUL_RX_CLK_EN_POS 16 +#define MODEM_GCU_BPU_CLK_EN_BIT ((u32)0x00008000) +#define MODEM_GCU_BPU_CLK_EN_POS 15 +#define MODEM_GCU_BPU_RX_CLK_EN_BIT ((u32)0x00004000) +#define MODEM_GCU_BPU_RX_CLK_EN_POS 14 +#define MODEM_GCU_BPU_TX_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_BPU_TX_CLK_EN_POS 13 +#define MODEM_GCU_BPU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_BPU_REG_CLK_EN_POS 12 +#define MODEM_GCU_BPU_RST_N_BIT ((u32)0x00000008) +#define MODEM_GCU_BPU_RST_N_POS 3 +#define MODEM_GCU_BPU_RX_RST_N_BIT ((u32)0x00000004) +#define MODEM_GCU_BPU_RX_RST_N_POS 2 +#define MODEM_GCU_BPU_TX_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_BPU_TX_RST_N_POS 1 +#define MODEM_GCU_BPU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_BPU_REG_RST_N_POS 0 + +/* + * @brief TFU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   21    TFU_CLK_F                 0
+ *   20    TFU_REG_CLK_F             0
+ *   13    TFU_CLK_EN                0
+ *   12    TFU_REG_CLK_EN            0
+ *   01    TFU_RST_N                 0
+ *   00    TFU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_TFU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x0000000C) +#define MODEM_GCU_TFU_OFFSET 0x0000000C +#define MODEM_GCU_TFU_INDEX 0x00000003 +#define MODEM_GCU_TFU_RESET 0x00000000 + +static inline void modem_gcu_tfu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_TFU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_TFU_CLK_F_BIT ((u32)0x00200000) +#define MODEM_GCU_TFU_CLK_F_POS 21 +#define MODEM_GCU_TFU_REG_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_TFU_REG_CLK_F_POS 20 +#define MODEM_GCU_TFU_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_TFU_CLK_EN_POS 13 +#define MODEM_GCU_TFU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_TFU_REG_CLK_EN_POS 12 +#define MODEM_GCU_TFU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_TFU_RST_N_POS 1 +#define MODEM_GCU_TFU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_TFU_REG_RST_N_POS 0 + +/* + * @brief SMU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   21    SMU_CLK_F                 0
+ *   20    SMU_REG_CLK_F             0
+ *   13    SMU_CLK_EN                0
+ *   12    SMU_REG_CLK_EN            0
+ *   01    SMU_RST_N                 0
+ *   00    SMU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_SMU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000010) +#define MODEM_GCU_SMU_OFFSET 0x00000010 +#define MODEM_GCU_SMU_INDEX 0x00000004 +#define MODEM_GCU_SMU_RESET 0x00000000 + +static inline void modem_gcu_smu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_SMU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_SMU_CLK_F_BIT ((u32)0x00200000) +#define MODEM_GCU_SMU_CLK_F_POS 21 +#define MODEM_GCU_SMU_REG_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_SMU_REG_CLK_F_POS 20 +#define MODEM_GCU_SMU_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_SMU_CLK_EN_POS 13 +#define MODEM_GCU_SMU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_SMU_REG_CLK_EN_POS 12 +#define MODEM_GCU_SMU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_SMU_RST_N_POS 1 +#define MODEM_GCU_SMU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_SMU_REG_RST_N_POS 0 + +/* + * @brief MUX_FIC register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   20    MUX_FIC_CLK_F             0
+ *   12    MUX_FIC_CLK_EN            0
+ *   01    FIC_MUX_SOFT_RST_N        1
+ *   00    MUX_FIC_RST_N             0
+ * 
+ */ +#define MODEM_GCU_MUX_FIC_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000014) +#define MODEM_GCU_MUX_FIC_OFFSET 0x00000014 +#define MODEM_GCU_MUX_FIC_INDEX 0x00000005 +#define MODEM_GCU_MUX_FIC_RESET 0x00000002 + +static inline void modem_gcu_mux_fic_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_MUX_FIC_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_MUX_FIC_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_MUX_FIC_CLK_F_POS 20 +#define MODEM_GCU_MUX_FIC_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_MUX_FIC_CLK_EN_POS 12 +#define MODEM_GCU_MUX_FIC_SOFT_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_MUX_FIC_SOFT_RST_N_POS 1 +#define MODEM_GCU_MUX_FIC_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_MUX_FIC_RST_N_POS 0 + +/* + * @brief MUX_FIC_CONFIG register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31    FIC_ISOLATED              0
+ *   17    FIC_ISOLATE               0
+ *   16    DISABLE_FIC_MESS          0
+ *   15:08 MUX_FIC_CONFLICT_DELAY_WRITE 0x0
+ *   07:00 MUX_FIC_CONFLICT_DELAY_READ 0x0
+ * 
+ */ +#define MODEM_GCU_MUX_FIC_CONFIG_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x0000001C) +#define MODEM_GCU_MUX_FIC_CONFIG_OFFSET 0x0000001C +#define MODEM_GCU_MUX_FIC_CONFIG_INDEX 0x00000007 +#define MODEM_GCU_MUX_FIC_CONFIG_RESET 0x00000000 + +static inline void modem_gcu_mux_fic_config_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_MUX_FIC_CONFIG_ADDR, value); +} + +static inline u8 modem_gcu_mux_fic_config_fic_isolated_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, MODEM_GCU_MUX_FIC_CONFIG_ADDR); + + return ((local_val & ((u32)0x80000000)) >> 31); +} + +static inline void modem_gcu_mux_fic_config_fic_isolate_setf(struct cl_hw *cl_hw, u8 ficisolate) +{ + ASSERT_ERR((((u32)ficisolate << 17) & ~((u32)0x00020000)) == 0); + cl_reg_write(cl_hw, MODEM_GCU_MUX_FIC_CONFIG_ADDR, + (cl_reg_read(cl_hw, MODEM_GCU_MUX_FIC_CONFIG_ADDR) & ~((u32)0x00020000)) | + ((u32)ficisolate << 17)); +} + +/* + * @brief RIU_RST register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   07    RIUFE_RST_N               0
+ *   06    RIUAGC_RST_N              0
+ *   05    RIU_MDM_B_RST_N           0
+ *   04    RIULB_RST_N               0
+ *   03    RIURC_RST_N               0
+ *   02    RIU_RADAR_RST_N           0
+ *   01    RIU_RST_N                 0
+ *   00    RIU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_RIU_RST_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000020) +#define MODEM_GCU_RIU_RST_OFFSET 0x00000020 +#define MODEM_GCU_RIU_RST_INDEX 0x00000008 +#define MODEM_GCU_RIU_RST_RESET 0x00000000 + +static inline void modem_gcu_riu_rst_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_RIU_RST_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_RIU_FE_RST_N_BIT ((u32)0x00000080) +#define MODEM_GCU_RIU_FE_RST_N_POS 7 +#define MODEM_GCU_RIU_AGC_RST_N_BIT ((u32)0x00000040) +#define MODEM_GCU_RIU_AGC_RST_N_POS 6 +#define MODEM_GCU_RIU_MDM_B_RST_N_BIT ((u32)0x00000020) +#define MODEM_GCU_RIU_MDM_B_RST_N_POS 5 +#define MODEM_GCU_RIU_LB_RST_N_BIT ((u32)0x00000010) +#define MODEM_GCU_RIU_LB_RST_N_POS 4 +#define MODEM_GCU_RIU_RC_RST_N_BIT ((u32)0x00000008) +#define MODEM_GCU_RIU_RC_RST_N_POS 3 +#define MODEM_GCU_RIU_RADAR_RST_N_BIT ((u32)0x00000004) +#define MODEM_GCU_RIU_RADAR_RST_N_POS 2 +#define MODEM_GCU_RIU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_RIU_RST_N_POS 1 +#define MODEM_GCU_RIU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_RIU_REG_RST_N_POS 0 + +/* + * @brief RIU_CLK register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31    RIUADC_PWR_CLK_F          0
+ *   30    RIUFEA_5_CLK_F            0
+ *   29    RIUFEA_4_CLK_F            0
+ *   28    RIUFEA_3_CLK_F            0
+ *   27    RIUFEA_2_CLK_F            0
+ *   26    RIUFEA_1_CLK_F            0
+ *   25    RIUFEA_0_CLK_F            0
+ *   24    RIU_MDM_B_TX_CLK_F        0
+ *   23    RIU_MDM_B_RX_CLK_F        0
+ *   22    RIU_MDM_B_CLK_F           0
+ *   21    RIULB_CLK_F               0
+ *   20    RIURC_CLK_F               0
+ *   19    RIU_RADAR_CLK_F           0
+ *   18    RIUAGC_CLK_F              0
+ *   17    RIU_CLK_F                 0
+ *   16    RIU_REG_CLK_F             0
+ *   15    RIUADC_PWR_CLK_EN         0
+ *   14    RIUFEA_5_CLK_EN           0
+ *   13    RIUFEA_4_CLK_EN           0
+ *   12    RIUFEA_3_CLK_EN           0
+ *   11    RIUFEA_2_CLK_EN           0
+ *   10    RIUFEA_1_CLK_EN           0
+ *   09    RIUFEA_0_CLK_EN           0
+ *   08    RIU_MDM_B_TX_CLK_EN       0
+ *   07    RIU_MDM_B_RX_CLK_EN       0
+ *   06    RIU_MDM_B_CLK_EN          0
+ *   05    RIULB_CLK_EN              0
+ *   04    RIURCR_CLK_EN             0
+ *   03    RIU_RADAR_CLK_EN          0
+ *   02    RIUAGC_CLK_EN             0
+ *   01    RIU_CLK_EN                0
+ *   00    RIU_REG_CLK_EN            0
+ * 
+ */ +#define MODEM_GCU_RIU_CLK_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000024) +#define MODEM_GCU_RIU_CLK_OFFSET 0x00000024 +#define MODEM_GCU_RIU_CLK_INDEX 0x00000009 +#define MODEM_GCU_RIU_CLK_RESET 0x00000000 + +static inline void modem_gcu_riu_clk_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_RIU_CLK_ADDR, value); +} + +/* + * @brief SPU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   21    SPU_CLK_F                 0
+ *   20    SPU_REG_CLK_F             0
+ *   13    SPU_CLK_EN                0
+ *   12    SPU_REG_CLK_EN            0
+ *   01    SPU_RST_N                 0
+ *   00    SPU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_SPU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000030) +#define MODEM_GCU_SPU_OFFSET 0x00000030 +#define MODEM_GCU_SPU_INDEX 0x0000000C +#define MODEM_GCU_SPU_RESET 0x00000000 + +static inline void modem_gcu_spu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_SPU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_SPU_CLK_F_BIT ((u32)0x00200000) +#define MODEM_GCU_SPU_CLK_F_POS 21 +#define MODEM_GCU_SPU_REG_CLK_F_BIT ((u32)0x00100000) +#define MODEM_GCU_SPU_REG_CLK_F_POS 20 +#define MODEM_GCU_SPU_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_SPU_CLK_EN_POS 13 +#define MODEM_GCU_SPU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_SPU_REG_CLK_EN_POS 12 +#define MODEM_GCU_SPU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_SPU_RST_N_POS 1 +#define MODEM_GCU_SPU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_SPU_REG_RST_N_POS 0 + +/* + * @brief LCU register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   14    LCU_HLF_CLK_EN            0
+ *   13    LCU_CLK_EN                0
+ *   12    LCU_REG_CLK_EN            0
+ *   02    LCU_HLF_RST_N             0
+ *   01    LCU_RST_N                 0
+ *   00    LCU_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_LCU_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000034) +#define MODEM_GCU_LCU_OFFSET 0x00000034 +#define MODEM_GCU_LCU_INDEX 0x0000000D +#define MODEM_GCU_LCU_RESET 0x00000000 + +static inline void modem_gcu_lcu_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_LCU_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_LCU_HLF_CLK_EN_BIT ((u32)0x00004000) +#define MODEM_GCU_LCU_HLF_CLK_EN_POS 14 +#define MODEM_GCU_LCU_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_LCU_CLK_EN_POS 13 +#define MODEM_GCU_LCU_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_LCU_REG_CLK_EN_POS 12 +#define MODEM_GCU_LCU_HLF_RST_N_BIT ((u32)0x00000004) +#define MODEM_GCU_LCU_HLF_RST_N_POS 2 +#define MODEM_GCU_LCU_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_LCU_RST_N_POS 1 +#define MODEM_GCU_LCU_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_LCU_REG_RST_N_POS 0 + +/* + * @brief EPA register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   13    EPA_CLK_EN                0
+ *   12    EPA_REG_CLK_EN            0
+ *   01    EPA_RST_N                 0
+ *   00    EPA_REG_RST_N             0
+ * 
+ */ +#define MODEM_GCU_EPA_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000038) +#define MODEM_GCU_EPA_OFFSET 0x00000038 +#define MODEM_GCU_EPA_INDEX 0x0000000E +#define MODEM_GCU_EPA_RESET 0x00000000 + +static inline void modem_gcu_epa_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_EPA_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_EPA_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_EPA_CLK_EN_POS 13 +#define MODEM_GCU_EPA_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_EPA_REG_CLK_EN_POS 12 +#define MODEM_GCU_EPA_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_EPA_RST_N_POS 1 +#define MODEM_GCU_EPA_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_EPA_REG_RST_N_POS 0 + +/* + * @brief BF register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   13    BF_CLK_EN                 0
+ *   12    BF_REG_CLK_EN             0
+ *   01    BF_RST_N                  0
+ *   00    BF_REG_RST_N              0
+ * 
+ */ +#define MODEM_GCU_BF_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x0000003C) +#define MODEM_GCU_BF_OFFSET 0x0000003C +#define MODEM_GCU_BF_INDEX 0x0000000F +#define MODEM_GCU_BF_RESET 0x00000000 + +static inline void modem_gcu_bf_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_BF_ADDR, value); +} + +/* Field definitions */ +#define MODEM_GCU_BF_CLK_EN_BIT ((u32)0x00002000) +#define MODEM_GCU_BF_CLK_EN_POS 13 +#define MODEM_GCU_BF_REG_CLK_EN_BIT ((u32)0x00001000) +#define MODEM_GCU_BF_REG_CLK_EN_POS 12 +#define MODEM_GCU_BF_RST_N_BIT ((u32)0x00000002) +#define MODEM_GCU_BF_RST_N_POS 1 +#define MODEM_GCU_BF_REG_RST_N_BIT ((u32)0x00000001) +#define MODEM_GCU_BF_REG_RST_N_POS 0 + +/* + * @brief RIU_CLK_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   17    RIUFE_EXT_CLK_F           0
+ *   16    RIUFRC_CLK_F              0
+ *   01    RIUFE_EXT_CLK_EN          0
+ *   00    RIUFRC_CLK_EN             0
+ * 
+ */ +#define MODEM_GCU_RIU_CLK_1_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00000124) +#define MODEM_GCU_RIU_CLK_1_OFFSET 0x00000124 +#define MODEM_GCU_RIU_CLK_1_INDEX 0x00000049 +#define MODEM_GCU_RIU_CLK_1_RESET 0x00000000 + +static inline void modem_gcu_riu_clk_1_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_RIU_CLK_1_ADDR, value); +} + +/* + * @brief CEVA_CTRL register definition + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   16    MCCI_ADDR_BASE            0
+ *   14    VINTC                     0
+ *   12    NMI                       0
+ *   10:09 EXT_VOM                   0x0
+ *   08    EXT_PV                    0
+ *   07:06 UIA                       0x0
+ *   05    STOP_SD                   0
+ *   04    MON_STAT                  0
+ *   02    EXTERNAL_WAIT             1
+ *   00    BOOT                      0
+ * 
+ */ +#define MODEM_GCU_CEVA_CTRL_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00001004) +#define MODEM_GCU_CEVA_CTRL_OFFSET 0x00001004 +#define MODEM_GCU_CEVA_CTRL_INDEX 0x00000401 +#define MODEM_GCU_CEVA_CTRL_RESET 0x00000004 + +static inline void modem_gcu_ceva_ctrl_external_wait_setf(struct cl_hw *cl_hw, u8 externalwait) +{ + ASSERT_ERR((((u32)externalwait << 2) & ~((u32)0x00000004)) == 0); + cl_reg_write(cl_hw, MODEM_GCU_CEVA_CTRL_ADDR, + (cl_reg_read(cl_hw, MODEM_GCU_CEVA_CTRL_ADDR) & ~((u32)0x00000004)) | + ((u32)externalwait << 2)); +} + +static inline void modem_gcu_ceva_ctrl_boot_setf(struct cl_hw *cl_hw, u8 boot) +{ + ASSERT_ERR((((u32)boot << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write(cl_hw, MODEM_GCU_CEVA_CTRL_ADDR, + (cl_reg_read(cl_hw, MODEM_GCU_CEVA_CTRL_ADDR) & ~((u32)0x00000001)) | + ((u32)boot << 0)); +} + +/* + * @brief CEVA_VEC register definition + * Ceva Vector register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   31:00 VECTOR                    0x0
+ * 
+ */ +#define MODEM_GCU_CEVA_VEC_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00001008) +#define MODEM_GCU_CEVA_VEC_OFFSET 0x00001008 +#define MODEM_GCU_CEVA_VEC_INDEX 0x00000402 +#define MODEM_GCU_CEVA_VEC_RESET 0x00000000 + +static inline void modem_gcu_ceva_vec_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_CEVA_VEC_ADDR, value); +} + +/* + * @brief RIU_CLK_BW register definition + * RIU clocks BW. register description + *
+ *  Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *   13    agc_clk_bw                0
+ *   12:10 lb_mem_clk_bw             0x2
+ *   09:08 agc_mem_clk_bw            0x1
+ *   07:06 riu_afe_clk_bw            0x2
+ *   05:04 phyfesync_bw              0x2
+ *   03:02 adcpowclk_bw              0x2
+ *   01:00 riulbgclk_bw              0x2
+ * 
+ */ +#define MODEM_GCU_RIU_CLK_BW_ADDR (REG_MODEM_GCU_BASE_ADDR + 0x00001240) +#define MODEM_GCU_RIU_CLK_BW_OFFSET 0x00001240 +#define MODEM_GCU_RIU_CLK_BW_INDEX 0x00000490 +#define MODEM_GCU_RIU_CLK_BW_RESET 0x000009AA + +static inline void modem_gcu_riu_clk_bw_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, MODEM_GCU_RIU_CLK_BW_ADDR, value); +} + +static inline void modem_gcu_riu_clk_bw_agc_mem_clk_bw_setf(struct cl_hw *cl_hw, u8 agcmemclkbw) +{ + ASSERT_ERR((((u32)agcmemclkbw << 8) & ~((u32)0x00000300)) == 0); + cl_reg_write(cl_hw, MODEM_GCU_RIU_CLK_BW_ADDR, + (cl_reg_read(cl_hw, MODEM_GCU_RIU_CLK_BW_ADDR) & ~((u32)0x00000300)) | + ((u32)agcmemclkbw << 8)); +} + +/* + * @brief STATIC_CONF_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30    ARB_ONESHOT_BYPASS        1
+ *    28    BTC_SEL                   0
+ *    27    CLK_SAVE_MODE             0
+ *    26    RF_RST_N_DEFAULT          0
+ *    25    RF_RST_N_REQ              0
+ *    24    FORCE_RSSI_ON             0
+ *    23:20 RSSI_M                    0x2
+ *    19:16 RSSI_N                    0x6
+ *    03:00 CDB_MODE_MAJ              0x0
+ * 
+ */ +#define RICU_STATIC_CONF_0_ADDR (REG_RICU_BASE_ADDR + 0x00000004) +#define RICU_STATIC_CONF_0_OFFSET 0x00000004 +#define RICU_STATIC_CONF_0_INDEX 0x00000001 +#define RICU_STATIC_CONF_0_RESET 0x40260000 + +static inline void ricu_static_conf_0_btc_sel_setf(struct cl_chip *chip, u8 btcsel) +{ + ASSERT_ERR_CHIP((((u32)btcsel << 28) & ~((u32)0x10000000)) == 0); + cl_reg_write_chip(chip, RICU_STATIC_CONF_0_ADDR, + (cl_reg_read_chip(chip, RICU_STATIC_CONF_0_ADDR) & ~((u32)0x10000000)) | + ((u32)btcsel << 28)); +} + +static inline void ricu_static_conf_0_clk_save_mode_setf(struct cl_chip *chip, u8 clksavemode) +{ + ASSERT_ERR_CHIP((((u32)clksavemode << 27) & ~((u32)0x08000000)) == 0); + cl_reg_write_chip(chip, RICU_STATIC_CONF_0_ADDR, + (cl_reg_read_chip(chip, RICU_STATIC_CONF_0_ADDR) & ~((u32)0x08000000)) | + ((u32)clksavemode << 27)); +} + +static inline void ricu_static_conf_0_rf_rst_n_req_setf(struct cl_chip *chip, u8 rfrstnreq) +{ + ASSERT_ERR_CHIP((((u32)rfrstnreq << 25) & ~((u32)0x02000000)) == 0); + cl_reg_write_chip(chip, RICU_STATIC_CONF_0_ADDR, + (cl_reg_read_chip(chip, RICU_STATIC_CONF_0_ADDR) & ~((u32)0x02000000)) | + ((u32)rfrstnreq << 25)); +} + +static inline u8 ricu_static_conf_0_cdb_mode_maj_getf(struct cl_chip *chip) +{ + u32 local_val = cl_reg_read_chip(chip, RICU_STATIC_CONF_0_ADDR); + + return ((local_val & ((u32)0x0000000F)) >> 0); +} + +static inline void ricu_static_conf_0_cdb_mode_maj_setf(struct cl_chip *chip, u8 cdbmodemaj) +{ + ASSERT_ERR_CHIP((((u32)cdbmodemaj << 0) & ~((u32)0x0000000F)) == 0); + cl_reg_write_chip(chip, RICU_STATIC_CONF_0_ADDR, + (cl_reg_read_chip(chip, RICU_STATIC_CONF_0_ADDR) & ~((u32)0x0000000F)) | + ((u32)cdbmodemaj << 0)); +} + +/* + * @brief AFE_CTL_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    PBIAS_CTRL_EN_LC          0
+ *    30    PBIAS_CTRL_EN             0
+ *    29    LRD_EN_LC                 0
+ *    28    LRD_EN                    0
+ *    27    LOCK_EN_LC                0
+ *    26    LOCK_EN                   1
+ *    25    EN_GPADC_CLK              0
+ *    24    EN_GPADC                  0
+ *    23    FEED_EN_LC                0
+ *    22    FEED_EN                   0
+ *    21    EN_CS                     1
+ *    20    EN_CML_GEN                1
+ *    18    EN_AFE_LDO                1
+ *    17    EN_ADC_CLK                1
+ *    15    AFC_ENB_LC                0
+ *    14    AFC_ENB                   0
+ *    13    CP_MODE_LC                1
+ *    12    BYPASS_LC                 0
+ *    11    BYPASS                    0
+ *    10    AFCINIT_SEL_LC            1
+ *    09    AFCINIT_SEL               1
+ *    08    EN_CLK_MON                0
+ *    07    EN_DAC_CLK                1
+ *    06    EN_CDB_DAC_CLK            0
+ *    05    EN_CDB_ADC_CLK            0
+ *    03    EN_CDB_GEN                0
+ *    02    DACCLK_PHASESEL           0
+ *    01    ADCCLK_PHASESEL           0
+ *    00    CDB_CLK_RESETB            0
+ * 
+ */ +#define RICU_AFE_CTL_0_ADDR (REG_RICU_BASE_ADDR + 0x00000010) +#define RICU_AFE_CTL_0_OFFSET 0x00000010 +#define RICU_AFE_CTL_0_INDEX 0x00000004 +#define RICU_AFE_CTL_0_RESET 0x04362680 + +static inline u32 ricu_afe_ctl_0_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTL_0_ADDR); +} + +static inline void ricu_afe_ctl_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_0_ADDR, value); +} + +static inline void ricu_afe_ctl_0_lock_en_lc_setf(struct cl_chip *chip, u8 lockenlc) +{ + ASSERT_ERR_CHIP((((u32)lockenlc << 27) & ~((u32)0x08000000)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_0_ADDR) & ~((u32)0x08000000)) | + ((u32)lockenlc << 27)); +} + +/* Field definitions */ +#define RICU_AFE_CTL_0_PBIAS_CTRL_EN_LC_BIT ((u32)0x80000000) +#define RICU_AFE_CTL_0_PBIAS_CTRL_EN_LC_POS 31 +#define RICU_AFE_CTL_0_PBIAS_CTRL_EN_BIT ((u32)0x40000000) +#define RICU_AFE_CTL_0_PBIAS_CTRL_EN_POS 30 +#define RICU_AFE_CTL_0_LRD_EN_LC_BIT ((u32)0x20000000) +#define RICU_AFE_CTL_0_LRD_EN_LC_POS 29 +#define RICU_AFE_CTL_0_LRD_EN_BIT ((u32)0x10000000) +#define RICU_AFE_CTL_0_LRD_EN_POS 28 +#define RICU_AFE_CTL_0_LOCK_EN_LC_BIT ((u32)0x08000000) +#define RICU_AFE_CTL_0_LOCK_EN_LC_POS 27 +#define RICU_AFE_CTL_0_LOCK_EN_BIT ((u32)0x04000000) +#define RICU_AFE_CTL_0_LOCK_EN_POS 26 +#define RICU_AFE_CTL_0_EN_GPADC_CLK_BIT ((u32)0x02000000) +#define RICU_AFE_CTL_0_EN_GPADC_CLK_POS 25 +#define RICU_AFE_CTL_0_EN_GPADC_BIT ((u32)0x01000000) +#define RICU_AFE_CTL_0_EN_GPADC_POS 24 +#define RICU_AFE_CTL_0_FEED_EN_LC_BIT ((u32)0x00800000) +#define RICU_AFE_CTL_0_FEED_EN_LC_POS 23 +#define RICU_AFE_CTL_0_FEED_EN_BIT ((u32)0x00400000) +#define RICU_AFE_CTL_0_FEED_EN_POS 22 +#define RICU_AFE_CTL_0_EN_CS_BIT ((u32)0x00200000) +#define RICU_AFE_CTL_0_EN_CS_POS 21 +#define RICU_AFE_CTL_0_EN_CML_GEN_BIT ((u32)0x00100000) +#define RICU_AFE_CTL_0_EN_CML_GEN_POS 20 +#define RICU_AFE_CTL_0_EN_AFE_LDO_BIT ((u32)0x00040000) +#define RICU_AFE_CTL_0_EN_AFE_LDO_POS 18 +#define RICU_AFE_CTL_0_EN_ADC_CLK_BIT ((u32)0x00020000) +#define RICU_AFE_CTL_0_EN_ADC_CLK_POS 17 +#define RICU_AFE_CTL_0_AFC_ENB_LC_BIT ((u32)0x00008000) +#define RICU_AFE_CTL_0_AFC_ENB_LC_POS 15 +#define RICU_AFE_CTL_0_AFC_ENB_BIT ((u32)0x00004000) +#define RICU_AFE_CTL_0_AFC_ENB_POS 14 +#define RICU_AFE_CTL_0_CP_MODE_LC_BIT ((u32)0x00002000) +#define RICU_AFE_CTL_0_CP_MODE_LC_POS 13 +#define RICU_AFE_CTL_0_BYPASS_LC_BIT ((u32)0x00001000) +#define RICU_AFE_CTL_0_BYPASS_LC_POS 12 +#define RICU_AFE_CTL_0_BYPASS_BIT ((u32)0x00000800) +#define RICU_AFE_CTL_0_BYPASS_POS 11 +#define RICU_AFE_CTL_0_AFCINIT_SEL_LC_BIT ((u32)0x00000400) +#define RICU_AFE_CTL_0_AFCINIT_SEL_LC_POS 10 +#define RICU_AFE_CTL_0_AFCINIT_SEL_BIT ((u32)0x00000200) +#define RICU_AFE_CTL_0_AFCINIT_SEL_POS 9 +#define RICU_AFE_CTL_0_EN_CLK_MON_BIT ((u32)0x00000100) +#define RICU_AFE_CTL_0_EN_CLK_MON_POS 8 +#define RICU_AFE_CTL_0_EN_DAC_CLK_BIT ((u32)0x00000080) +#define RICU_AFE_CTL_0_EN_DAC_CLK_POS 7 +#define RICU_AFE_CTL_0_EN_CDB_DAC_CLK_BIT ((u32)0x00000040) +#define RICU_AFE_CTL_0_EN_CDB_DAC_CLK_POS 6 +#define RICU_AFE_CTL_0_EN_CDB_ADC_CLK_BIT ((u32)0x00000020) +#define RICU_AFE_CTL_0_EN_CDB_ADC_CLK_POS 5 +#define RICU_AFE_CTL_0_EN_CDB_GEN_BIT ((u32)0x00000008) +#define RICU_AFE_CTL_0_EN_CDB_GEN_POS 3 +#define RICU_AFE_CTL_0_DACCLK_PHASESEL_BIT ((u32)0x00000004) +#define RICU_AFE_CTL_0_DACCLK_PHASESEL_POS 2 +#define RICU_AFE_CTL_0_ADCCLK_PHASESEL_BIT ((u32)0x00000002) +#define RICU_AFE_CTL_0_ADCCLK_PHASESEL_POS 1 +#define RICU_AFE_CTL_0_CDB_CLK_RESETB_BIT ((u32)0x00000001) +#define RICU_AFE_CTL_0_CDB_CLK_RESETB_POS 0 + +static inline void ricu_afe_ctl_0_pbias_ctrl_en_lc_setf(struct cl_chip *chip, u8 pbiasctrlenlc) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_0_ADDR) & ~((u32)0x80000000)) | + ((u32)pbiasctrlenlc << 31)); +} + +static inline void ricu_afe_ctl_0_cdb_clk_resetb_setf(struct cl_chip *chip, u8 cdbclkresetb) +{ + ASSERT_ERR_CHIP((((u32)cdbclkresetb << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_0_ADDR) & ~((u32)0x00000001)) | + ((u32)cdbclkresetb << 0)); +} + +/* + * @brief AFE_CTL_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    14    VCO_BOOST                 0
+ *    13    SYS_ADCCLK_SEL            0
+ *    12    SOC_PHASE_SEL             1
+ *    11    SOC_CLK_SEL               1
+ *    10    RESETB_LC                 0
+ *    09    RESETB                    1
+ *    08    PBIAS_CTRL_LC             0
+ *    07    PBIAS_CTRL                0
+ *    06    GP_CLK_PHASESEL           0
+ *    05    FSEL_LC                   0
+ *    04    FSEL                      0
+ *    03    FOUT_MASK_LC              0
+ *    02    FOUT_MASK                 0
+ *    01    EXTCLK_SEL                0
+ *    00    EN_PLL_LDO                0
+ * 
+ */ +#define RICU_AFE_CTL_1_ADDR (REG_RICU_BASE_ADDR + 0x00000014) +#define RICU_AFE_CTL_1_OFFSET 0x00000014 +#define RICU_AFE_CTL_1_INDEX 0x00000005 +#define RICU_AFE_CTL_1_RESET 0x00001A00 + +static inline void ricu_afe_ctl_1_resetb_lc_setf(struct cl_chip *chip, u8 resetblc) +{ + ASSERT_ERR_CHIP((((u32)resetblc << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_1_ADDR) & ~((u32)0x00000400)) | + ((u32)resetblc << 10)); +} + +static inline void ricu_afe_ctl_1_en_pll_ldo_setf(struct cl_chip *chip, u8 enpllldo) +{ + ASSERT_ERR_CHIP((((u32)enpllldo << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_1_ADDR) & ~((u32)0x00000001)) | + ((u32)enpllldo << 0)); +} + +/* + * @brief AFE_CTL_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:22 LOCK_CON_REV_LC           0x0
+ *    21:20 LOCK_CON_REV              0x0
+ *    19:18 LOCK_CON_OUT_LC           0x3
+ *    17:16 LOCK_CON_OUT              0x3
+ *    15:14 LOCK_CON_IN_LC            0x3
+ *    13:12 LOCK_CON_IN               0x3
+ *    11:10 LOCK_CON_DLY_LC           0x3
+ *    09:08 LOCK_CON_DLY              0x3
+ *    07:06 ICP                       0x1
+ *    03:02 CTRL_IB                   0x2
+ *    01:00 CLK_MON_SEL               0x0
+ * 
+ */ +#define RICU_AFE_CTL_2_ADDR (REG_RICU_BASE_ADDR + 0x00000018) +#define RICU_AFE_CTL_2_OFFSET 0x00000018 +#define RICU_AFE_CTL_2_INDEX 0x00000006 +#define RICU_AFE_CTL_2_RESET 0x000FFF48 + +static inline void ricu_afe_ctl_2_lock_con_rev_lc_setf(struct cl_chip *chip, u8 lockconrevlc) +{ + ASSERT_ERR_CHIP((((u32)lockconrevlc << 22) & ~((u32)0x00C00000)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_2_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_2_ADDR) & ~((u32)0x00C00000)) | + ((u32)lockconrevlc << 22)); +} + +/* + * @brief AFE_CTL_3 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:28 RSEL                      0x0
+ *    27:24 I_CSEL_LC                 0xc
+ *    23:20 GM_LC                     0xf
+ *    19:16 CSEL_LC                   0x3
+ *    15:12 CML_SEL                   0x9
+ *    11:09 S_LC                      0x0
+ *    08:06 S                         0x0
+ *    05:03 LBW_LC                    0x7
+ *    02:00 ICP_LC                    0x7
+ * 
+ */ +#define RICU_AFE_CTL_3_ADDR (REG_RICU_BASE_ADDR + 0x0000001C) +#define RICU_AFE_CTL_3_OFFSET 0x0000001C +#define RICU_AFE_CTL_3_INDEX 0x00000007 +#define RICU_AFE_CTL_3_RESET 0x0CF3903F + +static inline void ricu_afe_ctl_3_cml_sel_setf(struct cl_chip *chip, u8 cmlsel) +{ + ASSERT_ERR_CHIP((((u32)cmlsel << 12) & ~((u32)0x0000F000)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_3_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_3_ADDR) & ~((u32)0x0000F000)) | + ((u32)cmlsel << 12)); +} + +/* + * @brief AFE_CTL_5 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:18 MAIN_SEL_7_2              0x0
+ *    17:12 P_LC                      0x1
+ *    11:06 P                         0xA
+ *    05:00 CAP_BIAS_CODE_LC          0x4
+ * 
+ */ +#define RICU_AFE_CTL_5_ADDR (REG_RICU_BASE_ADDR + 0x00000024) +#define RICU_AFE_CTL_5_OFFSET 0x00000024 +#define RICU_AFE_CTL_5_INDEX 0x00000009 +#define RICU_AFE_CTL_5_RESET 0x00001284 + +static inline void ricu_afe_ctl_5_main_sel_7_2_setf(struct cl_chip *chip, u8 mainsel72) +{ + ASSERT_ERR_CHIP((((u32)mainsel72 << 18) & ~((u32)0x00FC0000)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_5_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTL_5_ADDR) & ~((u32)0x00FC0000)) | + ((u32)mainsel72 << 18)); +} + +/* + * @brief AFE_CTL_8 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    EN_REF7                   0
+ *    30    EN_REF6                   0
+ *    29    EN_REF5                   0
+ *    28    EN_REF4                   0
+ *    27    EN_REF3                   0
+ *    26    EN_REF2                   0
+ *    25    EN_REF1                   0
+ *    24    EN_REF0                   0
+ *    23    EN_EXT_LOAD7              0
+ *    22    EN_EXT_LOAD6              0
+ *    21    EN_EXT_LOAD5              0
+ *    20    EN_EXT_LOAD4              0
+ *    19    EN_EXT_LOAD3              0
+ *    18    EN_EXT_LOAD2              0
+ *    17    EN_EXT_LOAD1              0
+ *    16    EN_EXT_LOAD0              0
+ *    15    CH_CML_SEL7               0
+ *    14    CH_CML_SEL6               0
+ *    13    CH_CML_SEL5               0
+ *    12    CH_CML_SEL4               0
+ *    11    CH_CML_SEL3               0
+ *    10    CH_CML_SEL2               0
+ *    09    CH_CML_SEL1               0
+ *    08    CH_CML_SEL0               0
+ *    07    EN_BGR7                   0
+ *    06    EN_BGR6                   0
+ *    05    EN_BGR5                   0
+ *    04    EN_BGR4                   0
+ *    03    EN_BGR3                   0
+ *    02    EN_BGR2                   0
+ *    01    EN_BGR1                   0
+ *    00    EN_BGR0                   0
+ * 
+ */ +#define RICU_AFE_CTL_8_ADDR (REG_RICU_BASE_ADDR + 0x00000030) +#define RICU_AFE_CTL_8_OFFSET 0x00000030 +#define RICU_AFE_CTL_8_INDEX 0x0000000C +#define RICU_AFE_CTL_8_RESET 0x00000000 + +static inline u32 ricu_afe_ctl_8_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTL_8_ADDR); +} + +static inline void ricu_afe_ctl_8_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_8_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTL_8_EN_REF_7_BIT ((u32)0x80000000) +#define RICU_AFE_CTL_8_EN_REF_7_POS 31 +#define RICU_AFE_CTL_8_EN_REF_6_BIT ((u32)0x40000000) +#define RICU_AFE_CTL_8_EN_REF_6_POS 30 +#define RICU_AFE_CTL_8_EN_REF_5_BIT ((u32)0x20000000) +#define RICU_AFE_CTL_8_EN_REF_5_POS 29 +#define RICU_AFE_CTL_8_EN_REF_4_BIT ((u32)0x10000000) +#define RICU_AFE_CTL_8_EN_REF_4_POS 28 +#define RICU_AFE_CTL_8_EN_REF_3_BIT ((u32)0x08000000) +#define RICU_AFE_CTL_8_EN_REF_3_POS 27 +#define RICU_AFE_CTL_8_EN_REF_2_BIT ((u32)0x04000000) +#define RICU_AFE_CTL_8_EN_REF_2_POS 26 +#define RICU_AFE_CTL_8_EN_REF_1_BIT ((u32)0x02000000) +#define RICU_AFE_CTL_8_EN_REF_1_POS 25 +#define RICU_AFE_CTL_8_EN_REF_0_BIT ((u32)0x01000000) +#define RICU_AFE_CTL_8_EN_REF_0_POS 24 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_7_BIT ((u32)0x00800000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_7_POS 23 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_6_BIT ((u32)0x00400000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_6_POS 22 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_5_BIT ((u32)0x00200000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_5_POS 21 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_4_BIT ((u32)0x00100000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_4_POS 20 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_3_BIT ((u32)0x00080000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_3_POS 19 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_2_BIT ((u32)0x00040000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_2_POS 18 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_1_BIT ((u32)0x00020000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_1_POS 17 +#define RICU_AFE_CTL_8_EN_EXT_LOAD_0_BIT ((u32)0x00010000) +#define RICU_AFE_CTL_8_EN_EXT_LOAD_0_POS 16 +#define RICU_AFE_CTL_8_CH_CML_SEL_7_BIT ((u32)0x00008000) +#define RICU_AFE_CTL_8_CH_CML_SEL_7_POS 15 +#define RICU_AFE_CTL_8_CH_CML_SEL_6_BIT ((u32)0x00004000) +#define RICU_AFE_CTL_8_CH_CML_SEL_6_POS 14 +#define RICU_AFE_CTL_8_CH_CML_SEL_5_BIT ((u32)0x00002000) +#define RICU_AFE_CTL_8_CH_CML_SEL_5_POS 13 +#define RICU_AFE_CTL_8_CH_CML_SEL_4_BIT ((u32)0x00001000) +#define RICU_AFE_CTL_8_CH_CML_SEL_4_POS 12 +#define RICU_AFE_CTL_8_CH_CML_SEL_3_BIT ((u32)0x00000800) +#define RICU_AFE_CTL_8_CH_CML_SEL_3_POS 11 +#define RICU_AFE_CTL_8_CH_CML_SEL_2_BIT ((u32)0x00000400) +#define RICU_AFE_CTL_8_CH_CML_SEL_2_POS 10 +#define RICU_AFE_CTL_8_CH_CML_SEL_1_BIT ((u32)0x00000200) +#define RICU_AFE_CTL_8_CH_CML_SEL_1_POS 9 +#define RICU_AFE_CTL_8_CH_CML_SEL_0_BIT ((u32)0x00000100) +#define RICU_AFE_CTL_8_CH_CML_SEL_0_POS 8 +#define RICU_AFE_CTL_8_EN_BGR_7_BIT ((u32)0x00000080) +#define RICU_AFE_CTL_8_EN_BGR_7_POS 7 +#define RICU_AFE_CTL_8_EN_BGR_6_BIT ((u32)0x00000040) +#define RICU_AFE_CTL_8_EN_BGR_6_POS 6 +#define RICU_AFE_CTL_8_EN_BGR_5_BIT ((u32)0x00000020) +#define RICU_AFE_CTL_8_EN_BGR_5_POS 5 +#define RICU_AFE_CTL_8_EN_BGR_4_BIT ((u32)0x00000010) +#define RICU_AFE_CTL_8_EN_BGR_4_POS 4 +#define RICU_AFE_CTL_8_EN_BGR_3_BIT ((u32)0x00000008) +#define RICU_AFE_CTL_8_EN_BGR_3_POS 3 +#define RICU_AFE_CTL_8_EN_BGR_2_BIT ((u32)0x00000004) +#define RICU_AFE_CTL_8_EN_BGR_2_POS 2 +#define RICU_AFE_CTL_8_EN_BGR_1_BIT ((u32)0x00000002) +#define RICU_AFE_CTL_8_EN_BGR_1_POS 1 +#define RICU_AFE_CTL_8_EN_BGR_0_BIT ((u32)0x00000001) +#define RICU_AFE_CTL_8_EN_BGR_0_POS 0 + +/* + * @brief AFE_CTL_9 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    EN_SIN2_BIAS7             1
+ *    30    EN_SIN2_BIAS6             1
+ *    29    EN_SIN2_BIAS5             1
+ *    28    EN_SIN2_BIAS4             1
+ *    27    EN_SIN2_BIAS3             1
+ *    26    EN_SIN2_BIAS2             1
+ *    25    EN_SIN2_BIAS1             1
+ *    24    EN_SIN2_BIAS0             1
+ *    23    EN_DAC_REF7               0
+ *    22    EN_DAC_REF6               0
+ *    21    EN_DAC_REF5               0
+ *    20    EN_DAC_REF4               0
+ *    19    EN_DAC_REF3               0
+ *    18    EN_DAC_REF2               0
+ *    17    EN_DAC_REF1               0
+ *    16    EN_DAC_REF0               0
+ * 
+ */ +#define RICU_AFE_CTL_9_ADDR (REG_RICU_BASE_ADDR + 0x00000034) +#define RICU_AFE_CTL_9_OFFSET 0x00000034 +#define RICU_AFE_CTL_9_INDEX 0x0000000D +#define RICU_AFE_CTL_9_RESET 0xFF000000 + +static inline u32 ricu_afe_ctl_9_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTL_9_ADDR); +} + +static inline void ricu_afe_ctl_9_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_9_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_7_BIT ((u32)0x80000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_7_POS 31 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_6_BIT ((u32)0x40000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_6_POS 30 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_5_BIT ((u32)0x20000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_5_POS 29 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_4_BIT ((u32)0x10000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_4_POS 28 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_3_BIT ((u32)0x08000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_3_POS 27 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_2_BIT ((u32)0x04000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_2_POS 26 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_1_BIT ((u32)0x02000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_1_POS 25 +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_0_BIT ((u32)0x01000000) +#define RICU_AFE_CTL_9_EN_SIN_2_BIAS_0_POS 24 +#define RICU_AFE_CTL_9_EN_DAC_REF_7_BIT ((u32)0x00800000) +#define RICU_AFE_CTL_9_EN_DAC_REF_7_POS 23 +#define RICU_AFE_CTL_9_EN_DAC_REF_6_BIT ((u32)0x00400000) +#define RICU_AFE_CTL_9_EN_DAC_REF_6_POS 22 +#define RICU_AFE_CTL_9_EN_DAC_REF_5_BIT ((u32)0x00200000) +#define RICU_AFE_CTL_9_EN_DAC_REF_5_POS 21 +#define RICU_AFE_CTL_9_EN_DAC_REF_4_BIT ((u32)0x00100000) +#define RICU_AFE_CTL_9_EN_DAC_REF_4_POS 20 +#define RICU_AFE_CTL_9_EN_DAC_REF_3_BIT ((u32)0x00080000) +#define RICU_AFE_CTL_9_EN_DAC_REF_3_POS 19 +#define RICU_AFE_CTL_9_EN_DAC_REF_2_BIT ((u32)0x00040000) +#define RICU_AFE_CTL_9_EN_DAC_REF_2_POS 18 +#define RICU_AFE_CTL_9_EN_DAC_REF_1_BIT ((u32)0x00020000) +#define RICU_AFE_CTL_9_EN_DAC_REF_1_POS 17 +#define RICU_AFE_CTL_9_EN_DAC_REF_0_BIT ((u32)0x00010000) +#define RICU_AFE_CTL_9_EN_DAC_REF_0_POS 16 + +/* + * @brief AFE_CTL_10 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    VC_LD7                    0
+ *    30    VC_LD6                    0
+ *    29    VC_LD5                    0
+ *    28    VC_LD4                    0
+ *    27    VC_LD3                    0
+ *    26    VC_LD2                    0
+ *    25    VC_LD1                    0
+ *    24    VC_LD0                    0
+ *    23    TWOS7                     0
+ *    22    TWOS6                     0
+ *    21    TWOS5                     0
+ *    20    TWOS4                     0
+ *    19    TWOS3                     0
+ *    18    TWOS2                     0
+ *    17    TWOS1                     0
+ *    16    TWOS0                     0
+ *    07    MINV7                     1
+ *    06    MINV6                     1
+ *    05    MINV5                     1
+ *    04    MINV4                     1
+ *    03    MINV3                     1
+ *    02    MINV2                     1
+ *    01    MINV1                     1
+ *    00    MINV0                     1
+ * 
+ */ +#define RICU_AFE_CTL_10_ADDR (REG_RICU_BASE_ADDR + 0x00000038) +#define RICU_AFE_CTL_10_OFFSET 0x00000038 +#define RICU_AFE_CTL_10_INDEX 0x0000000E +#define RICU_AFE_CTL_10_RESET 0x000000FF + +static inline void ricu_afe_ctl_10_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_10_ADDR, value); +} + +/* + * @brief AFE_CTL_12 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:30 EOC_CTRL7                 0x0
+ *    29:28 EOC_CTRL6                 0x0
+ *    27:26 EOC_CTRL5                 0x0
+ *    25:24 EOC_CTRL4                 0x0
+ *    23:22 EOC_CTRL3                 0x0
+ *    21:20 EOC_CTRL2                 0x0
+ *    19:18 EOC_CTRL1                 0x0
+ *    17:16 EOC_CTRL0                 0x0
+ *    15:14 IC_REFSSF7                0x1
+ *    13:12 IC_REFSSF6                0x1
+ *    11:10 IC_REFSSF5                0x1
+ *    09:08 IC_REFSSF4                0x1
+ *    07:06 IC_REFSSF3                0x1
+ *    05:04 IC_REFSSF2                0x1
+ *    03:02 IC_REFSSF1                0x1
+ *    01:00 IC_REFSSF0                0x1
+ * 
+ */ +#define RICU_AFE_CTL_12_ADDR (REG_RICU_BASE_ADDR + 0x00000040) +#define RICU_AFE_CTL_12_OFFSET 0x00000040 +#define RICU_AFE_CTL_12_INDEX 0x00000010 +#define RICU_AFE_CTL_12_RESET 0x00005555 + +static inline void ricu_afe_ctl_12_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_12_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTL_12_EOC_CTRL_7_MASK ((u32)0xC0000000) +#define RICU_AFE_CTL_12_EOC_CTRL_7_LSB 30 +#define RICU_AFE_CTL_12_EOC_CTRL_7_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_6_MASK ((u32)0x30000000) +#define RICU_AFE_CTL_12_EOC_CTRL_6_LSB 28 +#define RICU_AFE_CTL_12_EOC_CTRL_6_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_5_MASK ((u32)0x0C000000) +#define RICU_AFE_CTL_12_EOC_CTRL_5_LSB 26 +#define RICU_AFE_CTL_12_EOC_CTRL_5_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_4_MASK ((u32)0x03000000) +#define RICU_AFE_CTL_12_EOC_CTRL_4_LSB 24 +#define RICU_AFE_CTL_12_EOC_CTRL_4_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_3_MASK ((u32)0x00C00000) +#define RICU_AFE_CTL_12_EOC_CTRL_3_LSB 22 +#define RICU_AFE_CTL_12_EOC_CTRL_3_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_2_MASK ((u32)0x00300000) +#define RICU_AFE_CTL_12_EOC_CTRL_2_LSB 20 +#define RICU_AFE_CTL_12_EOC_CTRL_2_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_1_MASK ((u32)0x000C0000) +#define RICU_AFE_CTL_12_EOC_CTRL_1_LSB 18 +#define RICU_AFE_CTL_12_EOC_CTRL_1_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_EOC_CTRL_0_MASK ((u32)0x00030000) +#define RICU_AFE_CTL_12_EOC_CTRL_0_LSB 16 +#define RICU_AFE_CTL_12_EOC_CTRL_0_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_7_MASK ((u32)0x0000C000) +#define RICU_AFE_CTL_12_IC_REFSSF_7_LSB 14 +#define RICU_AFE_CTL_12_IC_REFSSF_7_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_6_MASK ((u32)0x00003000) +#define RICU_AFE_CTL_12_IC_REFSSF_6_LSB 12 +#define RICU_AFE_CTL_12_IC_REFSSF_6_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_5_MASK ((u32)0x00000C00) +#define RICU_AFE_CTL_12_IC_REFSSF_5_LSB 10 +#define RICU_AFE_CTL_12_IC_REFSSF_5_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_4_MASK ((u32)0x00000300) +#define RICU_AFE_CTL_12_IC_REFSSF_4_LSB 8 +#define RICU_AFE_CTL_12_IC_REFSSF_4_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_3_MASK ((u32)0x000000C0) +#define RICU_AFE_CTL_12_IC_REFSSF_3_LSB 6 +#define RICU_AFE_CTL_12_IC_REFSSF_3_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_2_MASK ((u32)0x00000030) +#define RICU_AFE_CTL_12_IC_REFSSF_2_LSB 4 +#define RICU_AFE_CTL_12_IC_REFSSF_2_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_1_MASK ((u32)0x0000000C) +#define RICU_AFE_CTL_12_IC_REFSSF_1_LSB 2 +#define RICU_AFE_CTL_12_IC_REFSSF_1_WIDTH ((u32)0x00000002) +#define RICU_AFE_CTL_12_IC_REFSSF_0_MASK ((u32)0x00000003) +#define RICU_AFE_CTL_12_IC_REFSSF_0_LSB 0 +#define RICU_AFE_CTL_12_IC_REFSSF_0_WIDTH ((u32)0x00000002) + +/* + * @brief AFE_CTL_13 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    FORCE_ADC_ON_PHY1         0
+ *    30    FORCE_ADC_ON_PHY0         0
+ *    16    EN_LB8_AUX                0
+ *    15    EN_LB7                    0
+ *    14    EN_LB6                    0
+ *    13    EN_LB5                    0
+ *    12    EN_LB4                    0
+ *    11    EN_LB3                    0
+ *    10    EN_LB2                    0
+ *    09    EN_LB1                    0
+ *    08    EN_LB0                    0
+ * 
+ */ +#define RICU_AFE_CTL_13_ADDR (REG_RICU_BASE_ADDR + 0x00000044) +#define RICU_AFE_CTL_13_OFFSET 0x00000044 +#define RICU_AFE_CTL_13_INDEX 0x00000011 +#define RICU_AFE_CTL_13_RESET 0x00000000 + +static inline void ricu_afe_ctl_13_pack(struct cl_chip *chip, u8 forceadconphy1, u8 forceadconphy0, + u8 enlb8aux, u8 enlb7, u8 enlb6, u8 enlb5, u8 enlb4, + u8 enlb3, u8 enlb2, u8 enlb1, u8 enlb0) +{ + ASSERT_ERR_CHIP((((u32)forceadconphy0 << 30) & ~((u32)0x40000000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb8aux << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb7 << 15) & ~((u32)0x00008000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb6 << 14) & ~((u32)0x00004000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb5 << 13) & ~((u32)0x00002000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb4 << 12) & ~((u32)0x00001000)) == 0); + ASSERT_ERR_CHIP((((u32)enlb3 << 11) & ~((u32)0x00000800)) == 0); + ASSERT_ERR_CHIP((((u32)enlb2 << 10) & ~((u32)0x00000400)) == 0); + ASSERT_ERR_CHIP((((u32)enlb1 << 9) & ~((u32)0x00000200)) == 0); + ASSERT_ERR_CHIP((((u32)enlb0 << 8) & ~((u32)0x00000100)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_13_ADDR, + ((u32)forceadconphy1 << 31) | ((u32)forceadconphy0 << 30) | + ((u32)enlb8aux << 16) | ((u32)enlb7 << 15) | ((u32)enlb6 << 14) | + ((u32)enlb5 << 13) | ((u32)enlb4 << 12) | ((u32)enlb3 << 11) | + ((u32)enlb2 << 10) | ((u32)enlb1 << 9) | ((u32)enlb0 << 8)); +} + +/* + * @brief AFE_CTL_15 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 EN_OUT_CM7                0x0
+ *    26:24 EN_OUT_CM6                0x0
+ *    22:20 EN_OUT_CM5                0x0
+ *    18:16 EN_OUT_CM4                0x0
+ *    14:12 EN_OUT_CM3                0x0
+ *    10:08 EN_OUT_CM2                0x0
+ *    06:04 EN_OUT_CM1                0x0
+ *    02:00 EN_OUT_CM0                0x0
+ * 
+ */ +#define RICU_AFE_CTL_15_ADDR (REG_RICU_BASE_ADDR + 0x0000004C) +#define RICU_AFE_CTL_15_OFFSET 0x0000004C +#define RICU_AFE_CTL_15_INDEX 0x00000013 +#define RICU_AFE_CTL_15_RESET 0x00000000 + +static inline void ricu_afe_ctl_15_pack(struct cl_chip *chip, u8 enoutcm7, u8 enoutcm6, + u8 enoutcm5, u8 enoutcm4, u8 enoutcm3, + u8 enoutcm2, u8 enoutcm1, u8 enoutcm0) +{ + ASSERT_ERR_CHIP((((u32)enoutcm7 << 28) & ~((u32)0x70000000)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm6 << 24) & ~((u32)0x07000000)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm5 << 20) & ~((u32)0x00700000)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm4 << 16) & ~((u32)0x00070000)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm3 << 12) & ~((u32)0x00007000)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm2 << 8) & ~((u32)0x00000700)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm1 << 4) & ~((u32)0x00000070)) == 0); + ASSERT_ERR_CHIP((((u32)enoutcm0 << 0) & ~((u32)0x00000007)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_15_ADDR, + ((u32)enoutcm7 << 28) | ((u32)enoutcm6 << 24) | ((u32)enoutcm5 << 20) | + ((u32)enoutcm4 << 16) | ((u32)enoutcm3 << 12) | ((u32)enoutcm2 << 8) | + ((u32)enoutcm1 << 4) | ((u32)enoutcm0 << 0)); +} + +/* + * @brief AFE_CTL_17 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 VC_REF7                   0x1
+ *    26:24 VC_REF6                   0x1
+ *    22:20 VC_REF5                   0x1
+ *    18:16 VC_REF4                   0x1
+ *    14:12 VC_REF3                   0x1
+ *    10:08 VC_REF2                   0x1
+ *    06:04 VC_REF1                   0x1
+ *    02:00 VC_REF0                   0x1
+ * 
+ */ +#define RICU_AFE_CTL_17_ADDR (REG_RICU_BASE_ADDR + 0x00000054) +#define RICU_AFE_CTL_17_OFFSET 0x00000054 +#define RICU_AFE_CTL_17_INDEX 0x00000015 +#define RICU_AFE_CTL_17_RESET 0x11111111 + +static inline void ricu_afe_ctl_17_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_17_ADDR, value); +} + +/* + * @brief AFE_CTL_19 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:28 COMP_CTRL7                0x4
+ *    27:24 COMP_CTRL6                0x4
+ *    23:20 COMP_CTRL5                0x4
+ *    19:16 COMP_CTRL4                0x4
+ *    15:12 COMP_CTRL3                0x4
+ *    11:08 COMP_CTRL2                0x4
+ *    07:04 COMP_CTRL1                0x4
+ *    03:00 COMP_CTRL0                0x4
+ * 
+ */ +#define RICU_AFE_CTL_19_ADDR (REG_RICU_BASE_ADDR + 0x0000005C) +#define RICU_AFE_CTL_19_OFFSET 0x0000005C +#define RICU_AFE_CTL_19_INDEX 0x00000017 +#define RICU_AFE_CTL_19_RESET 0x44444444 + +static inline void ricu_afe_ctl_19_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_19_ADDR, value); +} + +/* + * @brief AFE_CTL_23 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 VC_LD_AVDI7               0x3
+ *    26:24 VC_LD_AVDI6               0x3
+ *    22:20 VC_LD_AVDI5               0x3
+ *    18:16 VC_LD_AVDI4               0x3
+ *    14:12 VC_LD_AVDI3               0x3
+ *    10:08 VC_LD_AVDI2               0x3
+ *    06:04 VC_LD_AVDI1               0x3
+ *    02:00 VC_LD_AVDI0               0x3
+ * 
+ */ +#define RICU_AFE_CTL_23_ADDR (REG_RICU_BASE_ADDR + 0x0000006C) +#define RICU_AFE_CTL_23_OFFSET 0x0000006C +#define RICU_AFE_CTL_23_INDEX 0x0000001B +#define RICU_AFE_CTL_23_RESET 0x33333333 + +static inline void ricu_afe_ctl_23_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_23_ADDR, value); +} + +/* + * @brief AFE_CTL_24 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 VC_LD_AVDQ7               0x3
+ *    26:24 VC_LD_AVDQ6               0x3
+ *    22:20 VC_LD_AVDQ5               0x3
+ *    18:16 VC_LD_AVDQ4               0x3
+ *    14:12 VC_LD_AVDQ3               0x3
+ *    10:08 VC_LD_AVDQ2               0x3
+ *    06:04 VC_LD_AVDQ1               0x3
+ *    02:00 VC_LD_AVDQ0               0x3
+ * 
+ */ +#define RICU_AFE_CTL_24_ADDR (REG_RICU_BASE_ADDR + 0x00000070) +#define RICU_AFE_CTL_24_OFFSET 0x00000070 +#define RICU_AFE_CTL_24_INDEX 0x0000001C +#define RICU_AFE_CTL_24_RESET 0x33333333 + +static inline void ricu_afe_ctl_24_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_24_ADDR, value); +} + +/* + * @brief AFE_CTL_25 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL0                    0
+ *    14:08 RO_CTRLQ0                 0x7
+ *    06:00 RO_CTRLI0                 0x7
+ * 
+ */ +#define RICU_AFE_CTL_25_ADDR (REG_RICU_BASE_ADDR + 0x00000074) +#define RICU_AFE_CTL_25_OFFSET 0x00000074 +#define RICU_AFE_CTL_25_INDEX 0x0000001D +#define RICU_AFE_CTL_25_RESET 0x00000707 + +static inline void ricu_afe_ctl_25_pack(struct cl_chip *chip, u8 rosel0, u8 roctrlq0, u8 roctrli0) +{ + ASSERT_ERR_CHIP((((u32)rosel0 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq0 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli0 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_25_ADDR, + ((u32)rosel0 << 16) | ((u32)roctrlq0 << 8) | ((u32)roctrli0 << 0)); +} + +/* + * @brief AFE_CTL_26 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL1                    0
+ *    14:08 RO_CTRLQ1                 0x7
+ *    06:00 RO_CTRLI1                 0x7
+ * 
+ */ +#define RICU_AFE_CTL_26_ADDR (REG_RICU_BASE_ADDR + 0x00000078) +#define RICU_AFE_CTL_26_OFFSET 0x00000078 +#define RICU_AFE_CTL_26_INDEX 0x0000001E +#define RICU_AFE_CTL_26_RESET 0x00000707 + +static inline void ricu_afe_ctl_26_pack(struct cl_chip *chip, u8 rosel1, u8 roctrlq1, u8 roctrli1) +{ + ASSERT_ERR_CHIP((((u32)rosel1 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq1 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli1 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_26_ADDR, + ((u32)rosel1 << 16) | ((u32)roctrlq1 << 8) | ((u32)roctrli1 << 0)); +} + +/* + * @brief AFE_CTL_27 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL2                    0
+ *    14:08 RO_CTRLQ2                 0x7
+ *    06:00 RO_CTRLI2                 0x7
+ * 
+ */ +#define RICU_AFE_CTL_27_ADDR (REG_RICU_BASE_ADDR + 0x0000007C) +#define RICU_AFE_CTL_27_OFFSET 0x0000007C +#define RICU_AFE_CTL_27_INDEX 0x0000001F +#define RICU_AFE_CTL_27_RESET 0x00000707 + +static inline void ricu_afe_ctl_27_pack(struct cl_chip *chip, u8 rosel2, u8 roctrlq2, u8 roctrli2) +{ + ASSERT_ERR_CHIP((((u32)rosel2 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq2 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli2 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_27_ADDR, + ((u32)rosel2 << 16) | ((u32)roctrlq2 << 8) | ((u32)roctrli2 << 0)); +} + +/* + * @brief AFE_CTL_29 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 VC_CML7_I                 0x5
+ *    26:24 VC_CML6_I                 0x5
+ *    22:20 VC_CML5_I                 0x5
+ *    18:16 VC_CML4_I                 0x5
+ *    14:12 VC_CML3_I                 0x5
+ *    10:08 VC_CML2_I                 0x5
+ *    06:04 VC_CML1_I                 0x5
+ *    02:00 VC_CML0_I                 0x5
+ * 
+ */ +#define RICU_AFE_CTL_29_ADDR (REG_RICU_BASE_ADDR + 0x00000084) +#define RICU_AFE_CTL_29_OFFSET 0x00000084 +#define RICU_AFE_CTL_29_INDEX 0x00000021 +#define RICU_AFE_CTL_29_RESET 0x55555555 + +static inline void ricu_afe_ctl_29_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_29_ADDR, value); +} + +/* + * @brief AFE_CTL_30 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    30:28 VC_CML7_Q                 0x5
+ *    26:24 VC_CML6_Q                 0x5
+ *    22:20 VC_CML5_Q                 0x5
+ *    18:16 VC_CML4_Q                 0x5
+ *    14:12 VC_CML3_Q                 0x5
+ *    10:08 VC_CML2_Q                 0x5
+ *    06:04 VC_CML1_Q                 0x5
+ *    02:00 VC_CML0_Q                 0x5
+ * 
+ */ +#define RICU_AFE_CTL_30_ADDR (REG_RICU_BASE_ADDR + 0x00000088) +#define RICU_AFE_CTL_30_OFFSET 0x00000088 +#define RICU_AFE_CTL_30_INDEX 0x00000022 +#define RICU_AFE_CTL_30_RESET 0x55555555 + +static inline void ricu_afe_ctl_30_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTL_30_ADDR, value); +} + +/* + * @brief AFE_CTL_33 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL3                    0
+ *    14:08 RO_CTRL3_Q                0x7
+ *    06:00 RO_CTRL3_I                0x7
+ * 
+ */ +#define RICU_AFE_CTL_33_ADDR (REG_RICU_BASE_ADDR + 0x00000094) +#define RICU_AFE_CTL_33_OFFSET 0x00000094 +#define RICU_AFE_CTL_33_INDEX 0x00000025 +#define RICU_AFE_CTL_33_RESET 0x00000707 + +static inline void ricu_afe_ctl_33_pack(struct cl_chip *chip, u8 rosel3, u8 roctrl3q, u8 roctrl3i) +{ + ASSERT_ERR_CHIP((((u32)rosel3 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrl3q << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrl3i << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTL_33_ADDR, + ((u32)rosel3 << 16) | ((u32)roctrl3q << 8) | ((u32)roctrl3i << 0)); +} + +/* + * @brief AFE_CTRL_34_PHY_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    06    PHY0_ADC_SB_IGNORE_FIFO_INDICATION 0
+ *    05:02 PHY0_ADC_SB_RD_DELAY      0x4
+ *    01:00 PHY0_ADC_SB_MODE          0x0
+ * 
+ */ +#define RICU_AFE_CTRL_34_PHY_0_ADDR (REG_RICU_BASE_ADDR + 0x0000009C) +#define RICU_AFE_CTRL_34_PHY_0_OFFSET 0x0000009C +#define RICU_AFE_CTRL_34_PHY_0_INDEX 0x00000027 +#define RICU_AFE_CTRL_34_PHY_0_RESET 0x00000010 + +static inline +void ricu_afe_ctrl_34_phy_0_adc_sb_ignore_fifo_indication_setf(struct cl_chip *chip, + u8 phy0adcsbignorefifoindication) +{ + ASSERT_ERR_CHIP((((u32)phy0adcsbignorefifoindication << 6) & ~((u32)0x00000040)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_34_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_34_PHY_0_ADDR) & + ~((u32)0x00000040)) | ((u32)phy0adcsbignorefifoindication << 6)); +} + +static inline void ricu_afe_ctrl_34_phy_0_adc_sb_rd_delay_setf(struct cl_chip *chip, + u8 phy0adcsbrddelay) +{ + ASSERT_ERR_CHIP((((u32)phy0adcsbrddelay << 2) & ~((u32)0x0000003C)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_34_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_34_PHY_0_ADDR) & + ~((u32)0x0000003C)) | ((u32)phy0adcsbrddelay << 2)); +} + +/* + * @brief AFE_CTRL_36_PHY_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    07    PHY0_ADC_ALWAYS_EN_LD_IR  0
+ *    06    PHY0_ADC_ALWAYS_EN_LD_AVDQ 0
+ *    05    PHY0_ADC_ALWAYS_EN_LD_AVDI 0
+ *    04    PHY0_ADC_ALWAYS_EN_ADCQ   0
+ *    03    PHY0_ADC_ALWAYS_EN_ADCI   0
+ *    01    PHY0_HW_MODE_DAC          0
+ *    00    PHY0_HW_MODE_ADC          0
+ * 
+ */ +#define RICU_AFE_CTRL_36_PHY_0_ADDR (REG_RICU_BASE_ADDR + 0x000000A0) +#define RICU_AFE_CTRL_36_PHY_0_OFFSET 0x000000A0 +#define RICU_AFE_CTRL_36_PHY_0_INDEX 0x00000028 +#define RICU_AFE_CTRL_36_PHY_0_RESET 0x00000000 + +static inline u32 ricu_afe_ctrl_36_phy_0_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR); +} + +static inline void ricu_afe_ctrl_36_phy_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_IR_BIT ((u32)0x00000080) +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_IR_POS 7 +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDQ_BIT ((u32)0x00000040) +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDQ_POS 6 +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDI_BIT ((u32)0x00000020) +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_LD_AVDI_POS 5 +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_BIT ((u32)0x00000010) +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCQ_POS 4 +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_BIT ((u32)0x00000008) +#define RICU_AFE_CTRL_36_PHY_0_ADC_ALWAYS_EN_ADCI_POS 3 +#define RICU_AFE_CTRL_36_PHY_0_HW_MODE_DAC_BIT ((u32)0x00000002) +#define RICU_AFE_CTRL_36_PHY_0_HW_MODE_DAC_POS 1 +#define RICU_AFE_CTRL_36_PHY_0_HW_MODE_ADC_BIT ((u32)0x00000001) +#define RICU_AFE_CTRL_36_PHY_0_HW_MODE_ADC_POS 0 + +static inline void ricu_afe_ctrl_36_phy_0_hw_mode_dac_setf(struct cl_chip *chip, u8 phy0hwmodedac) +{ + ASSERT_ERR_CHIP((((u32)phy0hwmodedac << 1) & ~((u32)0x00000002)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR) & + ~((u32)0x00000002)) | ((u32)phy0hwmodedac << 1)); +} + +static inline void ricu_afe_ctrl_36_phy_0_hw_mode_adc_setf(struct cl_chip *chip, u8 phy0hwmodeadc) +{ + ASSERT_ERR_CHIP((((u32)phy0hwmodeadc << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_0_ADDR) & + ~((u32)0x00000001)) | ((u32)phy0hwmodeadc << 0)); +} + +/* + * @brief AFE_CTRL_34_PHY_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    06    PHY1_ADC_SB_IGNORE_FIFO_INDICATION 0
+ *    05:02 PHY1_ADC_SB_RD_DELAY      0x4
+ *    01:00 PHY1_ADC_SB_MODE          0x0
+ * 
+ */ +#define RICU_AFE_CTRL_34_PHY_1_ADDR (REG_RICU_BASE_ADDR + 0x000000A4) +#define RICU_AFE_CTRL_34_PHY_1_OFFSET 0x000000A4 +#define RICU_AFE_CTRL_34_PHY_1_INDEX 0x00000029 +#define RICU_AFE_CTRL_34_PHY_1_RESET 0x00000010 + +static inline +void ricu_afe_ctrl_34_phy_1_adc_sb_ignore_fifo_indication_setf(struct cl_chip *chip, + u8 phy1adcsbignorefifoindication) +{ + ASSERT_ERR_CHIP((((u32)phy1adcsbignorefifoindication << 6) & ~((u32)0x00000040)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_34_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_34_PHY_1_ADDR) & + ~((u32)0x00000040)) | ((u32)phy1adcsbignorefifoindication << 6)); +} + +static inline void ricu_afe_ctrl_34_phy_1_adc_sb_rd_delay_setf(struct cl_chip *chip, + u8 phy1adcsbrddelay) +{ + ASSERT_ERR_CHIP((((u32)phy1adcsbrddelay << 2) & ~((u32)0x0000003C)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_34_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_34_PHY_1_ADDR) & + ~((u32)0x0000003C)) | ((u32)phy1adcsbrddelay << 2)); +} + +/* + * @brief AFE_CTRL_35_PHY_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    06    PHY0_DAC_SB_IGNORE_FIFO_INDICATION 0
+ *    05:02 PHY0_DAC_SB_RD_DELAY      0x1
+ *    01:00 PHY0_DAC_SB_MODE          0x0
+ * 
+ */ +#define RICU_AFE_CTRL_35_PHY_0_ADDR (REG_RICU_BASE_ADDR + 0x000000A8) +#define RICU_AFE_CTRL_35_PHY_0_OFFSET 0x000000A8 +#define RICU_AFE_CTRL_35_PHY_0_INDEX 0x0000002A +#define RICU_AFE_CTRL_35_PHY_0_RESET 0x00000004 + +static inline +void ricu_afe_ctrl_35_phy_0_dac_sb_ignore_fifo_indication_setf(struct cl_chip *chip, + u8 phy0dacsbignorefifoindication) +{ + ASSERT_ERR_CHIP((((u32)phy0dacsbignorefifoindication << 6) & ~((u32)0x00000040)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_35_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_35_PHY_0_ADDR) & + ~((u32)0x00000040)) | ((u32)phy0dacsbignorefifoindication << 6)); +} + +static inline void ricu_afe_ctrl_35_phy_0_dac_sb_rd_delay_setf(struct cl_chip *chip, + u8 phy0dacsbrddelay) +{ + ASSERT_ERR_CHIP((((u32)phy0dacsbrddelay << 2) & ~((u32)0x0000003C)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_35_PHY_0_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_35_PHY_0_ADDR) & + ~((u32)0x0000003C)) | ((u32)phy0dacsbrddelay << 2)); +} + +/* + * @brief AFE_CTRL_35_PHY_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    06    PHY1_DAC_SB_IGNORE_FIFO_INDICATION 0
+ *    05:02 PHY1_DAC_SB_RD_DELAY      0x1
+ *    01:00 PHY1_DAC_SB_MODE          0x0
+ * 
+ */ +#define RICU_AFE_CTRL_35_PHY_1_ADDR (REG_RICU_BASE_ADDR + 0x000000AC) +#define RICU_AFE_CTRL_35_PHY_1_OFFSET 0x000000AC +#define RICU_AFE_CTRL_35_PHY_1_INDEX 0x0000002B +#define RICU_AFE_CTRL_35_PHY_1_RESET 0x00000004 + +static inline +void ricu_afe_ctrl_35_phy_1_dac_sb_ignore_fifo_indication_setf(struct cl_chip *chip, + u8 phy1dacsbignorefifoindication) +{ + ASSERT_ERR_CHIP((((u32)phy1dacsbignorefifoindication << 6) & ~((u32)0x00000040)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_35_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_35_PHY_1_ADDR) & + ~((u32)0x00000040)) | ((u32)phy1dacsbignorefifoindication << 6)); +} + +static inline void ricu_afe_ctrl_35_phy_1_dac_sb_rd_delay_setf(struct cl_chip *chip, + u8 phy1dacsbrddelay) +{ + ASSERT_ERR_CHIP((((u32)phy1dacsbrddelay << 2) & ~((u32)0x0000003C)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_35_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_35_PHY_1_ADDR) & + ~((u32)0x0000003C)) | ((u32)phy1dacsbrddelay << 2)); +} + +/* + * @brief AFE_CTRL_37_PHY_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    05    PHY0_EN_DAC5              0
+ *    04    PHY0_EN_DAC4              0
+ *    03    PHY0_EN_DAC3              0
+ *    02    PHY0_EN_DAC2              0
+ *    01    PHY0_EN_DAC1              0
+ *    00    PHY0_EN_DAC0              0
+ * 
+ */ +#define RICU_AFE_CTRL_37_PHY_0_ADDR (REG_RICU_BASE_ADDR + 0x000000BC) +#define RICU_AFE_CTRL_37_PHY_0_OFFSET 0x000000BC +#define RICU_AFE_CTRL_37_PHY_0_INDEX 0x0000002F +#define RICU_AFE_CTRL_37_PHY_0_RESET 0x00000000 + +static inline u32 ricu_afe_ctrl_37_phy_0_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTRL_37_PHY_0_ADDR); +} + +static inline void ricu_afe_ctrl_37_phy_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTRL_37_PHY_0_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_5_BIT ((u32)0x00000020) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_5_POS 5 +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_4_BIT ((u32)0x00000010) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_4_POS 4 +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_BIT ((u32)0x00000008) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_3_POS 3 +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_BIT ((u32)0x00000004) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_2_POS 2 +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_BIT ((u32)0x00000002) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_1_POS 1 +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_BIT ((u32)0x00000001) +#define RICU_AFE_CTRL_37_PHY_0_EN_DAC_0_POS 0 + +/* + * @brief AFE_CTRL_37_PHY_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    05    PHY1_EN_DAC5              0
+ *    04    PHY1_EN_DAC4              0
+ *    03    PHY1_EN_DAC3              0
+ *    02    PHY1_EN_DAC2              0
+ *    01    PHY1_EN_DAC1              0
+ *    00    PHY1_EN_DAC0              0
+ * 
+ */ +#define RICU_AFE_CTRL_37_PHY_1_ADDR (REG_RICU_BASE_ADDR + 0x000000C0) +#define RICU_AFE_CTRL_37_PHY_1_OFFSET 0x000000C0 +#define RICU_AFE_CTRL_37_PHY_1_INDEX 0x00000030 +#define RICU_AFE_CTRL_37_PHY_1_RESET 0x00000000 + +static inline u32 ricu_afe_ctrl_37_phy_1_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTRL_37_PHY_1_ADDR); +} + +static inline void ricu_afe_ctrl_37_phy_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTRL_37_PHY_1_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_5_BIT ((u32)0x00000020) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_5_POS 5 +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_4_BIT ((u32)0x00000010) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_4_POS 4 +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_BIT ((u32)0x00000008) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_3_POS 3 +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_BIT ((u32)0x00000004) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_2_POS 2 +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_BIT ((u32)0x00000002) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_1_POS 1 +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_BIT ((u32)0x00000001) +#define RICU_AFE_CTRL_37_PHY_1_EN_DAC_0_POS 0 + +/* + * @brief AFE_CTRL_39 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL4                    0
+ *    14:08 RO_CTRLQ4                 0x7
+ *    06:00 RO_CTRLI4                 0x7
+ * 
+ */ +#define RICU_AFE_CTRL_39_ADDR (REG_RICU_BASE_ADDR + 0x000000CC) +#define RICU_AFE_CTRL_39_OFFSET 0x000000CC +#define RICU_AFE_CTRL_39_INDEX 0x00000033 +#define RICU_AFE_CTRL_39_RESET 0x00000707 + +static inline void ricu_afe_ctrl_39_pack(struct cl_chip *chip, u8 rosel4, u8 roctrlq4, u8 roctrli4) +{ + ASSERT_ERR_CHIP((((u32)rosel4 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq4 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli4 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_39_ADDR, + ((u32)rosel4 << 16) | ((u32)roctrlq4 << 8) | ((u32)roctrli4 << 0)); +} + +/* + * @brief AFE_CTRL_40 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL5                    0
+ *    14:08 RO_CTRLQ5                 0x7
+ *    06:00 RO_CTRLI5                 0x7
+ * 
+ */ +#define RICU_AFE_CTRL_40_ADDR (REG_RICU_BASE_ADDR + 0x000000D0) +#define RICU_AFE_CTRL_40_OFFSET 0x000000D0 +#define RICU_AFE_CTRL_40_INDEX 0x00000034 +#define RICU_AFE_CTRL_40_RESET 0x00000707 + +static inline void ricu_afe_ctrl_40_pack(struct cl_chip *chip, u8 rosel5, u8 roctrlq5, u8 roctrli5) +{ + ASSERT_ERR_CHIP((((u32)rosel5 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq5 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli5 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_40_ADDR, + ((u32)rosel5 << 16) | ((u32)roctrlq5 << 8) | ((u32)roctrli5 << 0)); +} + +/* + * @brief AFE_CTRL_41 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL6                    0
+ *    14:08 RO_CTRLQ6                 0x7
+ *    06:00 RO_CTRLI6                 0x7
+ * 
+ */ +#define RICU_AFE_CTRL_41_ADDR (REG_RICU_BASE_ADDR + 0x000000D4) +#define RICU_AFE_CTRL_41_OFFSET 0x000000D4 +#define RICU_AFE_CTRL_41_INDEX 0x00000035 +#define RICU_AFE_CTRL_41_RESET 0x00000707 + +static inline void ricu_afe_ctrl_41_pack(struct cl_chip *chip, u8 rosel6, u8 roctrlq6, u8 roctrli6) +{ + ASSERT_ERR_CHIP((((u32)rosel6 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq6 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli6 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_41_ADDR, + ((u32)rosel6 << 16) | ((u32)roctrlq6 << 8) | ((u32)roctrli6 << 0)); +} + +/* + * @brief AFE_CTRL_42 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    16    ROSEL7                    0
+ *    14:08 RO_CTRLQ7                 0x7
+ *    06:00 RO_CTRLI7                 0x7
+ * 
+ */ +#define RICU_AFE_CTRL_42_ADDR (REG_RICU_BASE_ADDR + 0x000000D8) +#define RICU_AFE_CTRL_42_OFFSET 0x000000D8 +#define RICU_AFE_CTRL_42_INDEX 0x00000036 +#define RICU_AFE_CTRL_42_RESET 0x00000707 + +static inline void ricu_afe_ctrl_42_pack(struct cl_chip *chip, u8 rosel7, u8 roctrlq7, u8 roctrli7) +{ + ASSERT_ERR_CHIP((((u32)rosel7 << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR_CHIP((((u32)roctrlq7 << 8) & ~((u32)0x00007F00)) == 0); + ASSERT_ERR_CHIP((((u32)roctrli7 << 0) & ~((u32)0x0000007F)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_42_ADDR, + ((u32)rosel7 << 16) | ((u32)roctrlq7 << 8) | ((u32)roctrli7 << 0)); +} + +/* + * @brief AFE_CTRL_43 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    01:00 FREQ_SEL                  0x3
+ * 
+ */ +#define RICU_AFE_CTRL_43_ADDR (REG_RICU_BASE_ADDR + 0x000000DC) +#define RICU_AFE_CTRL_43_OFFSET 0x000000DC +#define RICU_AFE_CTRL_43_INDEX 0x00000037 +#define RICU_AFE_CTRL_43_RESET 0x00000003 + +static inline void ricu_afe_ctrl_43_freq_sel_setf(struct cl_chip *chip, u8 freqsel) +{ + ASSERT_ERR_CHIP((((u32)freqsel << 0) & ~((u32)0x00000003)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_43_ADDR, (u32)freqsel << 0); +} + +/* + * @brief AFE_CTRL_44 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    01:00 CDB_FREQ_SEL              0x3
+ * 
+ */ +#define RICU_AFE_CTRL_44_ADDR (REG_RICU_BASE_ADDR + 0x000000E0) +#define RICU_AFE_CTRL_44_OFFSET 0x000000E0 +#define RICU_AFE_CTRL_44_INDEX 0x00000038 +#define RICU_AFE_CTRL_44_RESET 0x00000003 + +static inline void ricu_afe_ctrl_44_cdb_freq_sel_setf(struct cl_chip *chip, u8 cdbfreqsel) +{ + ASSERT_ERR_CHIP((((u32)cdbfreqsel << 0) & ~((u32)0x00000003)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_44_ADDR, (u32)cdbfreqsel << 0); +} + +/* + * @brief SPI_CLK_CTRL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    05:00 SPI_CLK_BITMAP            0xE
+ * 
+ */ +#define RICU_SPI_CLK_CTRL_ADDR (REG_RICU_BASE_ADDR + 0x000000E4) +#define RICU_SPI_CLK_CTRL_OFFSET 0x000000E4 +#define RICU_SPI_CLK_CTRL_INDEX 0x00000039 +#define RICU_SPI_CLK_CTRL_RESET 0x0000000E + +static inline void ricu_spi_clk_ctrl_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_SPI_CLK_CTRL_ADDR, value); +} + +/* + * @brief FEM_CONF_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:20 FEM5_CTL_SEL              0x5
+ *    19:16 FEM4_CTL_SEL              0x4
+ *    15:12 FEM3_CTL_SEL              0x3
+ *    11:08 FEM2_CTL_SEL              0x2
+ *    07:04 FEM1_CTL_SEL              0x1
+ *    03:00 FEM0_CTL_SEL              0x0
+ * 
+ */ +#define RICU_FEM_CONF_0_ADDR (REG_RICU_BASE_ADDR + 0x000000F0) +#define RICU_FEM_CONF_0_OFFSET 0x000000F0 +#define RICU_FEM_CONF_0_INDEX 0x0000003C +#define RICU_FEM_CONF_0_RESET 0x00543210 + +static inline void ricu_fem_conf_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_FEM_CONF_0_ADDR, value); +} + +/* + * @brief FEM_CONF_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:20 FEM11_CTL_SEL             0xd
+ *    19:16 FEM10_CTL_SEL             0xc
+ *    15:12 FEM9_CTL_SEL              0xb
+ *    11:08 FEM8_CTL_SEL              0xa
+ *    07:04 FEM7_CTL_SEL              0x9
+ *    03:00 FEM6_CTL_SEL              0x8
+ * 
+ */ +#define RICU_FEM_CONF_1_ADDR (REG_RICU_BASE_ADDR + 0x000000F4) +#define RICU_FEM_CONF_1_OFFSET 0x000000F4 +#define RICU_FEM_CONF_1_INDEX 0x0000003D +#define RICU_FEM_CONF_1_RESET 0x00DCBA98 + +static inline void ricu_fem_conf_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_FEM_CONF_1_ADDR, value); +} + +/* + * @brief AFE_CTRL_36_PHY_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    07    PHY1_ADC_ALWAYS_EN_LD_IR  0
+ *    06    PHY1_ADC_ALWAYS_EN_LD_AVDQ 0
+ *    05    PHY1_ADC_ALWAYS_EN_LD_AVDI 0
+ *    04    PHY1_ADC_ALWAYS_EN_ADCQ   0
+ *    03    PHY1_ADC_ALWAYS_EN_ADCI   0
+ *    01    PHY1_HW_MODE_DAC          0
+ *    00    PHY1_HW_MODE_ADC          0
+ * 
+ */ +#define RICU_AFE_CTRL_36_PHY_1_ADDR (REG_RICU_BASE_ADDR + 0x000000F8) +#define RICU_AFE_CTRL_36_PHY_1_OFFSET 0x000000F8 +#define RICU_AFE_CTRL_36_PHY_1_INDEX 0x0000003E +#define RICU_AFE_CTRL_36_PHY_1_RESET 0x00000000 + +static inline u32 ricu_afe_ctrl_36_phy_1_get(struct cl_chip *chip) +{ + return cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR); +} + +static inline void ricu_afe_ctrl_36_phy_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR, value); +} + +/* Field definitions */ +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_IR_BIT ((u32)0x00000080) +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_IR_POS 7 +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDQ_BIT ((u32)0x00000040) +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDQ_POS 6 +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDI_BIT ((u32)0x00000020) +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_LD_AVDI_POS 5 +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_BIT ((u32)0x00000010) +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCQ_POS 4 +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_BIT ((u32)0x00000008) +#define RICU_AFE_CTRL_36_PHY_1_ADC_ALWAYS_EN_ADCI_POS 3 +#define RICU_AFE_CTRL_36_PHY_1_HW_MODE_DAC_BIT ((u32)0x00000002) +#define RICU_AFE_CTRL_36_PHY_1_HW_MODE_DAC_POS 1 +#define RICU_AFE_CTRL_36_PHY_1_HW_MODE_ADC_BIT ((u32)0x00000001) +#define RICU_AFE_CTRL_36_PHY_1_HW_MODE_ADC_POS 0 + +static inline void ricu_afe_ctrl_36_phy_1_hw_mode_dac_setf(struct cl_chip *chip, u8 phy1hwmodedac) +{ + ASSERT_ERR_CHIP((((u32)phy1hwmodedac << 1) & ~((u32)0x00000002)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR) & + ~((u32)0x00000002)) | ((u32)phy1hwmodedac << 1)); +} + +static inline void ricu_afe_ctrl_36_phy_1_hw_mode_adc_setf(struct cl_chip *chip, u8 phy1hwmodeadc) +{ + ASSERT_ERR_CHIP((((u32)phy1hwmodeadc << 0) & ~((u32)0x00000001)) == 0); + cl_reg_write_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR, + (cl_reg_read_chip(chip, RICU_AFE_CTRL_36_PHY_1_ADDR) & + ~((u32)0x00000001)) | ((u32)phy1hwmodeadc << 0)); +} + +/* + * @brief AFE_ADC_CH_ALLOC register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    07:00 AFE_ADC_CH_ALLOC          0xFF
+ * 
+ */ +#define RICU_AFE_ADC_CH_ALLOC_ADDR (REG_RICU_BASE_ADDR + 0x000000FC) +#define RICU_AFE_ADC_CH_ALLOC_OFFSET 0x000000FC +#define RICU_AFE_ADC_CH_ALLOC_INDEX 0x0000003F +#define RICU_AFE_ADC_CH_ALLOC_RESET 0x000000FF + +static inline u8 ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_getf(struct cl_chip *chip) +{ + u32 local_val = cl_reg_read_chip(chip, RICU_AFE_ADC_CH_ALLOC_ADDR); + + return (local_val >> 0); +} + +static inline void ricu_afe_adc_ch_alloc_afe_adc_ch_alloc_setf(struct cl_chip *chip, + u8 afeadcchalloc) +{ + cl_reg_write_chip(chip, RICU_AFE_ADC_CH_ALLOC_ADDR, (u32)afeadcchalloc << 0); +} + +#define RIU_RSF_FILE_SIZE 0x60C + +/* + * @brief RSF_CONTROL register definition + * resampling filter operation mode register description + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    rsf_init_en               1
+ *    07    rsf_tx_bypass_type        0
+ *    06    rsf_tx_bypass_mode        1
+ *    05    rsf_rx_bypass_type        0
+ *    04    rsf_rx_bypass_mode        1
+ *    01    rsf_rx_ctl_from_reg       1
+ * 
+ */ +#define RIU_RSF_CONTROL_ADDR (REG_RIU_BASE_ADDR + 0x000001A8) +#define RIU_RSF_CONTROL_OFFSET 0x000001A8 +#define RIU_RSF_CONTROL_INDEX 0x0000006A +#define RIU_RSF_CONTROL_RESET 0x80000053 + +static inline void riu_rsf_control_rsf_init_en_setf(struct cl_hw *cl_hw, u8 rsfiniten) +{ + cl_reg_write(cl_hw, RIU_RSF_CONTROL_ADDR, + (cl_reg_read(cl_hw, RIU_RSF_CONTROL_ADDR) & ~((u32)0x80000000)) | + ((u32)rsfiniten << 31)); +} + +/* + * @brief RSF_INIT register definition + * resampling filter initialization data register description + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 RSF_INIT_DATA             0x0
+ * 
+ */ +#define RIU_RSF_INIT_ADDR (REG_RIU_BASE_ADDR + 0x000001AC) +#define RIU_RSF_INIT_OFFSET 0x000001AC +#define RIU_RSF_INIT_INDEX 0x0000006B +#define RIU_RSF_INIT_RESET 0x00000000 + +static inline void riu_rsf_init_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, RIU_RSF_INIT_ADDR, value); +} + +/* + * @brief AGCFSM_RAM_INIT_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    AGC_FSM_RAM_INIT_EN       0
+ *    29    AGC_FSM_RAM_INIT_AINC2    0
+ *    28    AGC_FSM_RAM_INIT_AINC1    0
+ *    12    AGC_FSM_RAM_INIT_WPTR_SET 0
+ *    10:00 AGC_FSM_RAM_INIT_WPTR     0x0
+ * 
+ */ +#define RIU_AGCFSM_RAM_INIT_1_ADDR (REG_RIU_BASE_ADDR + 0x000001B0) +#define RIU_AGCFSM_RAM_INIT_1_OFFSET 0x000001B0 +#define RIU_AGCFSM_RAM_INIT_1_INDEX 0x0000006C +#define RIU_AGCFSM_RAM_INIT_1_RESET 0x00000000 + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_en_setf(struct cl_hw *cl_hw, + u8 agcfsmraminiten) +{ + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x80000000)) | + ((u32)agcfsmraminiten << 31)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_ainc_1_setf(struct cl_hw *cl_hw, + u8 agcfsmraminitainc1) +{ + ASSERT_ERR((((u32)agcfsmraminitainc1 << 28) & ~((u32)0x10000000)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x10000000)) | + ((u32)agcfsmraminitainc1 << 28)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_set_setf(struct cl_hw *cl_hw, + u8 agcfsmraminitwptrset) +{ + ASSERT_ERR((((u32)agcfsmraminitwptrset << 12) & ~((u32)0x00001000)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x00001000)) | + ((u32)agcfsmraminitwptrset << 12)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_setf(struct cl_hw *cl_hw, + u16 agcfsmraminitwptr) +{ + ASSERT_ERR((((u32)agcfsmraminitwptr << 0) & ~((u32)0x000007FF)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x000007FF)) | + ((u32)agcfsmraminitwptr << 0)); +} + +/* + * @brief AGCFSM_RAM_INIT_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 AGC_FSM_RAM_INIT_WDATA    0x0
+ * 
+ */ +#define RIU_AGCFSM_RAM_INIT_2_ADDR (REG_RIU_BASE_ADDR + 0x000001B4) +#define RIU_AGCFSM_RAM_INIT_2_OFFSET 0x000001B4 +#define RIU_AGCFSM_RAM_INIT_2_INDEX 0x0000006D +#define RIU_AGCFSM_RAM_INIT_2_RESET 0x00000000 + +static inline void riu_agcfsm_ram_init_2_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_2_ADDR, value); +} + +/* + * @brief AGCINBDPOW_20_PNOISESTAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PNOISEDBM3      0x0
+ *    23:16 INBDPOW20_PNOISEDBM2      0x0
+ *    15:08 INBDPOW20_PNOISEDBM1      0x0
+ *    07:00 INBDPOW20_PNOISEDBM0      0x0
+ * 
+ */ +#define RIU_AGCINBDPOW_20_PNOISESTAT_ADDR (REG_RIU_BASE_ADDR + 0x00000228) +#define RIU_AGCINBDPOW_20_PNOISESTAT_OFFSET 0x00000228 +#define RIU_AGCINBDPOW_20_PNOISESTAT_INDEX 0x0000008A +#define RIU_AGCINBDPOW_20_PNOISESTAT_RESET 0x00000000 + +static inline u32 riu_agcinbdpow_20_pnoisestat_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOW_20_PNOISESTAT_ADDR); +} + +/* + * @brief AGCINBDPOWSECNOISESTAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:16 INBDPOW80_SNOISEDBM       0x0
+ *    15:08 INBDPOW40_SNOISEDBM       0x0
+ *    07:00 INBDPOW20_SNOISEDBM       0x0
+ * 
+ */ +#define RIU_AGCINBDPOWSECNOISESTAT_ADDR (REG_RIU_BASE_ADDR + 0x00000230) +#define RIU_AGCINBDPOWSECNOISESTAT_OFFSET 0x00000230 +#define RIU_AGCINBDPOWSECNOISESTAT_INDEX 0x0000008C +#define RIU_AGCINBDPOWSECNOISESTAT_RESET 0x00000000 + +static inline u32 riu_agcinbdpowsecnoisestat_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWSECNOISESTAT_ADDR); +} + +/* + * @brief RWNXAGCCNTL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:26 COMBPATHSEL               0x3F
+ *    25:20 GAINKEEP                  0x0
+ *    16    HTSTFGAINEN               1
+ *    15    NOISE_CAPTURE_DELAY_MODE  0
+ *    14    EST_PATH_SEL_2            0
+ *    13    CCA_MDM_ST_CLEAR          0
+ *    12    AGCFSMRESET               0
+ *    11    RADARDETEN                0
+ *    10    RIFSDETEN                 1
+ *    09    DSSSONLY                  0
+ *    08    OFDMONLY                  0
+ *    07:04 GPSTATUS                  0x0
+ *    03    EST_PATH_SEL              0
+ *    01    ADC_SEL_RADAR_DETECTOR    0
+ *    00    ADC_SEL_COMP_MODULE       0
+ * 
+ */ +#define RIU_RWNXAGCCNTL_ADDR (REG_RIU_BASE_ADDR + 0x00000390) +#define RIU_RWNXAGCCNTL_OFFSET 0x00000390 +#define RIU_RWNXAGCCNTL_INDEX 0x000000E4 +#define RIU_RWNXAGCCNTL_RESET 0xFC010400 + +static inline void riu_rwnxagccntl_agcfsmreset_setf(struct cl_hw *cl_hw, u8 agcfsmreset) +{ + ASSERT_ERR((((u32)agcfsmreset << 12) & ~((u32)0x00001000)) == 0); + cl_reg_write(cl_hw, RIU_RWNXAGCCNTL_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCNTL_ADDR) & ~((u32)0x00001000)) | + ((u32)agcfsmreset << 12)); +} + +/* + * @brief RWNXAGCDSP_3 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    27:20 INBDPOWMINDBV             0xBF
+ *    17:16 INBDRND                   0x3
+ *    15:08 INBDPOWMINDBM_ANT1        0x9C
+ *    07:00 INBDPOWMINDBM_ANT0        0x9C
+ * 
+ */ +#define RIU_RWNXAGCDSP_3_ADDR (REG_RIU_BASE_ADDR + 0x000003A0) +#define RIU_RWNXAGCDSP_3_OFFSET 0x000003A0 +#define RIU_RWNXAGCDSP_3_INDEX 0x000000E8 +#define RIU_RWNXAGCDSP_3_RESET 0x0BF39C9C + +static inline u8 riu_rwnxagcdsp_3_inbdpowmindbm_ant_1_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_3_ADDR); + + return ((local_val & ((u32)0x0000FF00)) >> 8); +} + +static inline void riu_rwnxagcdsp_3_inbdpowmindbm_ant_1_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant1) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_3_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_3_ADDR) & ~((u32)0x0000FF00)) | + ((u32)inbdpowmindbmant1 << 8)); +} + +static inline u8 riu_rwnxagcdsp_3_inbdpowmindbm_ant_0_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_3_ADDR); + + return ((local_val & ((u32)0x000000FF)) >> 0); +} + +static inline void riu_rwnxagcdsp_3_inbdpowmindbm_ant_0_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant0) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_3_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_3_ADDR) & ~((u32)0x000000FF)) | + ((u32)inbdpowmindbmant0 << 0)); +} + +/* + * @brief RWNXAGCCCA_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    CCA_CNT_CLEAR             0
+ *    30:29 CCA_CNT_RATE              0x0
+ *    28:20 INBDCCAPOWMINDBM          0x1B5
+ *    19:12 CCAFALLTHRDBM             0xBF
+ *    10    CCAEnergy_Reset_Type      0
+ *    09    DISCCAEN                  1
+ *    08    SATCCAEN                  1
+ *    07:00 CCARISETHRDBM             0xC2
+ * 
+ */ +#define RIU_RWNXAGCCCA_1_ADDR (REG_RIU_BASE_ADDR + 0x000003AC) +#define RIU_RWNXAGCCCA_1_OFFSET 0x000003AC +#define RIU_RWNXAGCCCA_1_INDEX 0x000000EB +#define RIU_RWNXAGCCCA_1_RESET 0x1B5BF3C2 + +static inline void riu_rwnxagccca_1_cca_cnt_clear_setf(struct cl_hw *cl_hw, u8 ccacntclear) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCCCA_1_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCCA_1_ADDR) & ~((u32)0x80000000)) | + ((u32)ccacntclear << 31)); +} + +static inline void riu_rwnxagccca_1_cca_cnt_rate_setf(struct cl_hw *cl_hw, u8 ccacntrate) +{ + ASSERT_ERR((((u32)ccacntrate << 29) & ~((u32)0x60000000)) == 0); + cl_reg_write_direct(cl_hw, RIU_RWNXAGCCCA_1_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCCA_1_ADDR) & ~((u32)0x60000000)) | + ((u32)ccacntrate << 29)); +} + +/* + * @brief RWNXAGCDSP_5 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWMINDBM_ANT5        0x9C
+ *    23:16 INBDPOWMINDBM_ANT4        0x9C
+ *    15:08 INBDPOWMINDBM_ANT3        0x9C
+ *    07:00 INBDPOWMINDBM_ANT2        0x9C
+ * 
+ */ +#define RIU_RWNXAGCDSP_5_ADDR (REG_RIU_BASE_ADDR + 0x000003EC) +#define RIU_RWNXAGCDSP_5_OFFSET 0x000003EC +#define RIU_RWNXAGCDSP_5_INDEX 0x000000FB +#define RIU_RWNXAGCDSP_5_RESET 0x9C9C9C9C + +static inline u8 riu_rwnxagcdsp_5_inbdpowmindbm_ant_5_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR); + + return ((local_val & ((u32)0xFF000000)) >> 24); +} + +static inline void riu_rwnxagcdsp_5_inbdpowmindbm_ant_5_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant5) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_5_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR) & ~((u32)0xFF000000)) | + ((u32)inbdpowmindbmant5 << 24)); +} + +static inline u8 riu_rwnxagcdsp_5_inbdpowmindbm_ant_4_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR); + + return ((local_val & ((u32)0x00FF0000)) >> 16); +} + +static inline void riu_rwnxagcdsp_5_inbdpowmindbm_ant_4_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant4) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_5_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR) & ~((u32)0x00FF0000)) | + ((u32)inbdpowmindbmant4 << 16)); +} + +static inline u8 riu_rwnxagcdsp_5_inbdpowmindbm_ant_3_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR); + + return ((local_val & ((u32)0x0000FF00)) >> 8); +} + +static inline void riu_rwnxagcdsp_5_inbdpowmindbm_ant_3_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant3) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_5_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR) & ~((u32)0x0000FF00)) | + ((u32)inbdpowmindbmant3 << 8)); +} + +static inline u8 riu_rwnxagcdsp_5_inbdpowmindbm_ant_2_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR); + + return ((local_val & ((u32)0x000000FF)) >> 0); +} + +static inline void riu_rwnxagcdsp_5_inbdpowmindbm_ant_2_setf(struct cl_hw *cl_hw, + u8 inbdpowmindbmant2) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCDSP_5_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCDSP_5_ADDR) & ~((u32)0x000000FF)) | + ((u32)inbdpowmindbmant2 << 0)); +} + +/* + * @brief AGCINBDPOWNOISEPER_20_STAT_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWNOISEDBMPER20_3    0x0
+ *    23:16 INBDPOWNOISEDBMPER20_2    0x0
+ *    15:08 INBDPOWNOISEDBMPER20_1    0x0
+ *    07:00 INBDPOWNOISEDBMPER20_0    0x0
+ * 
+ */ +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_ADDR (REG_RIU_BASE_ADDR + 0x00000478) +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_OFFSET 0x00000478 +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_INDEX 0x0000011E +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_RESET 0x00000000 + +static inline u32 riu_agcinbdpownoiseper_20_stat_0_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWNOISEPER_20_STAT_0_ADDR); +} + +/* + * @brief AGCINBDPOWNOISEPER_20_STAT_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWNOISEDBMPER20_7    0x0
+ *    23:16 INBDPOWNOISEDBMPER20_6    0x0
+ *    15:08 INBDPOWNOISEDBMPER20_5    0x0
+ *    07:00 INBDPOWNOISEDBMPER20_4    0x0
+ * 
+ */ +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_ADDR (REG_RIU_BASE_ADDR + 0x0000047C) +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_OFFSET 0x0000047C +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_INDEX 0x0000011F +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_RESET 0x00000000 + +static inline u32 riu_agcinbdpownoiseper_20_stat_1_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWNOISEPER_20_STAT_1_ADDR); +} + +/* + * @brief INBDPOWFORMAC_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PDBMA3_MAC      0x0
+ *    23:16 INBDPOW20_PDBMA2_MAC      0x0
+ *    15:08 INBDPOW20_PDBMA1_MAC      0x0
+ *    07:00 INBDPOW20_PDBMA0_MAC      0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_0_ADDR (REG_RIU_BASE_ADDR + 0x00000480) +#define RIU_INBDPOWFORMAC_0_OFFSET 0x00000480 +#define RIU_INBDPOWFORMAC_0_INDEX 0x00000120 +#define RIU_INBDPOWFORMAC_0_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_0_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_0_ADDR); +} + +/* + * @brief INBDPOWFORMAC_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    15:08 INBDPOW20_PDBMA5_MAC      0x0
+ *    07:00 INBDPOW20_PDBMA4_MAC      0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_1_ADDR (REG_RIU_BASE_ADDR + 0x00000484) +#define RIU_INBDPOWFORMAC_1_OFFSET 0x00000484 +#define RIU_INBDPOWFORMAC_1_INDEX 0x00000121 +#define RIU_INBDPOWFORMAC_1_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_1_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_1_ADDR); +} + +/* + * @brief INBDPOWFORMAC_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:16 INBDPOW80_SDBM_MAC        0x0
+ *    15:08 INBDPOW40_SDBM_MAC        0x0
+ *    07:00 INBDPOW20_SDBM_MAC        0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_2_ADDR (REG_RIU_BASE_ADDR + 0x00000488) +#define RIU_INBDPOWFORMAC_2_OFFSET 0x00000488 +#define RIU_INBDPOWFORMAC_2_INDEX 0x00000122 +#define RIU_INBDPOWFORMAC_2_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_2_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_2_ADDR); +} + +/* + * @brief INBDPOWFORMAC_3 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWPER20_PDBM_3_MAC   0x0
+ *    23:16 INBDPOWPER20_PDBM_2_MAC   0x0
+ *    15:08 INBDPOWPER20_PDBM_1_MAC   0x0
+ *    07:00 INBDPOWPER20_PDBM_0_MAC   0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_3_ADDR (REG_RIU_BASE_ADDR + 0x0000048C) +#define RIU_INBDPOWFORMAC_3_OFFSET 0x0000048C +#define RIU_INBDPOWFORMAC_3_INDEX 0x00000123 +#define RIU_INBDPOWFORMAC_3_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_3_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_3_ADDR); +} + +/* + * @brief INBDPOWFORMAC_4 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWPER20_PDBM_7_MAC   0x0
+ *    23:16 INBDPOWPER20_PDBM_6_MAC   0x0
+ *    15:08 INBDPOWPER20_PDBM_5_MAC   0x0
+ *    07:00 INBDPOWPER20_PDBM_4_MAC   0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_4_ADDR (REG_RIU_BASE_ADDR + 0x00000490) +#define RIU_INBDPOWFORMAC_4_OFFSET 0x00000490 +#define RIU_INBDPOWFORMAC_4_INDEX 0x00000124 +#define RIU_INBDPOWFORMAC_4_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_4_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_4_ADDR); +} + +/* + * @brief AGCINBDPOW_20_PNOISESTAT_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PNOISEDBM5      0x0
+ *    23:16 INBDPOW20_PNOISEDBM4      0x0
+ *    15:08 ADCPOWDBM5                0x0
+ *    07:00 ADCPOWDBM4                0x0
+ * 
+ */ +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_ADDR (REG_RIU_BASE_ADDR + 0x0000067C) +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_OFFSET 0x0000067C +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_INDEX 0x0000019F +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_RESET 0x00000000 + +static inline u32 riu_agcinbdpow_20_pnoisestat_2_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOW_20_PNOISESTAT_2_ADDR); +} + +#define REG_RIU_RC_BASE_ADDR 0x00485000 + +/* + * @brief SW_CTRL register definition + * This register provides write access to the radio SPI interface register description + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   31    START_DONE                0
+ *   30    MORE                      0
+ *   29    FASTWR_SPD                0
+ *   28    FASTWR_FORCE              0
+ *   27    FWR_HW_ENABLE             1
+ *   26    FWR_SW_ENABLE             1
+ *   25    FWR_ENABLE                1
+ *   24    RF_RESET_B                0
+ *   23:19 PRESCALER                 0x1
+ *   16    READNOTWRITE              0
+ *   14:08 ADDRESS                   0x0
+ *   07:00 DATA                      0x0
+ * 
+ */ +#define RIU_RC_SW_CTRL_ADDR (REG_RIU_RC_BASE_ADDR + 0x00000000) +#define RIU_RC_SW_CTRL_OFFSET 0x00000000 +#define RIU_RC_SW_CTRL_INDEX 0x00000000 +#define RIU_RC_SW_CTRL_RESET 0x0E080000 + +static inline void riu_rc_sw_ctrl_pack(struct cl_hw *cl_hw, u8 startdone, u8 more, + u8 fastwrspd, u8 fastwrforce, u8 fwrhwenable, + u8 fwrswenable, u8 fwrenable, u8 rfresetb, + u8 prescaler, u8 readnotwrite, u8 address, u8 data) +{ + ASSERT_ERR((((u32)more << 30) & ~((u32)0x40000000)) == 0); + ASSERT_ERR((((u32)fastwrspd << 29) & ~((u32)0x20000000)) == 0); + ASSERT_ERR((((u32)fastwrforce << 28) & ~((u32)0x10000000)) == 0); + ASSERT_ERR((((u32)fwrhwenable << 27) & ~((u32)0x08000000)) == 0); + ASSERT_ERR((((u32)fwrswenable << 26) & ~((u32)0x04000000)) == 0); + ASSERT_ERR((((u32)fwrenable << 25) & ~((u32)0x02000000)) == 0); + ASSERT_ERR((((u32)rfresetb << 24) & ~((u32)0x01000000)) == 0); + ASSERT_ERR((((u32)prescaler << 19) & ~((u32)0x00F80000)) == 0); + ASSERT_ERR((((u32)readnotwrite << 16) & ~((u32)0x00010000)) == 0); + ASSERT_ERR((((u32)address << 8) & ~((u32)0x00007F00)) == 0); + cl_reg_write(cl_hw, RIU_RC_SW_CTRL_ADDR, + ((u32)startdone << 31) | ((u32)more << 30) | + ((u32)fastwrspd << 29) | ((u32)fastwrforce << 28) | + ((u32)fwrhwenable << 27) | ((u32)fwrswenable << 26) | + ((u32)fwrenable << 25) | ((u32)rfresetb << 24) | + ((u32)prescaler << 19) | ((u32)readnotwrite << 16) | + ((u32)address << 8) | ((u32)data << 0)); +} + +static inline u8 riu_rc_sw_ctrl_start_done_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RC_SW_CTRL_ADDR); + + return ((local_val & ((u32)0x80000000)) >> 31); +} + +static inline u8 riu_rc_sw_ctrl_data_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RC_SW_CTRL_ADDR); + + return ((local_val & ((u32)0x000000FF)) >> 0); +} + +/* + * @brief RF_LNA_LUT register definition + * These registers provide control of the RF LNA assertion by decoding each possible value + * the AGC LNA gain setting, from minimum LNA gain to maximum LNA gain. register description + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   26:24 RFLNALUT6                 0x6
+ *   22:20 RFLNALUT5                 0x5
+ *   18:16 RFLNALUT4                 0x4
+ *   14:12 RFLNALUT3                 0x3
+ *   10:08 RFLNALUT2                 0x2
+ *   06:04 RFLNALUT1                 0x1
+ *   02:00 RFLNALUT0                 0x0
+ * 
+ */ + +/* Field definitions */ +#define RIU_RC_RF_LNA_LUT_RFLNALUT_6_MASK ((u32)0x07000000) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_6_LSB 24 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_6_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_5_MASK ((u32)0x00700000) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_5_LSB 20 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_5_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_4_MASK ((u32)0x00070000) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_4_LSB 16 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_4_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_3_MASK ((u32)0x00007000) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_3_LSB 12 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_3_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_2_MASK ((u32)0x00000700) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_2_LSB 8 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_2_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_1_MASK ((u32)0x00000070) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_1_LSB 4 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_1_WIDTH ((u32)0x00000003) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK ((u32)0x00000007) +#define RIU_RC_RF_LNA_LUT_RFLNALUT_0_LSB 0 +#define RIU_RC_RF_LNA_LUT_RFLNALUT_0_WIDTH ((u32)0x00000003) + +#define REG_IO_CTRL_BASE_ADDR 0x007C7000 + +/* + * @brief RX_ACTIVE_0 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_0_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000005C) +#define IO_CTRL_RX_ACTIVE_0_OFFSET 0x0000005C +#define IO_CTRL_RX_ACTIVE_0_INDEX 0x00000017 +#define IO_CTRL_RX_ACTIVE_0_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_0_ADDR, value); +} + +/* Field definitions */ +#define IO_CTRL_RX_ACTIVE_0_GPIO_IN_BIT ((u32)0x00002000) +#define IO_CTRL_RX_ACTIVE_0_GPIO_IN_POS 13 +#define IO_CTRL_RX_ACTIVE_0_GPIO_OUT_BIT ((u32)0x00001000) +#define IO_CTRL_RX_ACTIVE_0_GPIO_OUT_POS 12 +#define IO_CTRL_RX_ACTIVE_0_GPIO_OE_BIT ((u32)0x00000800) +#define IO_CTRL_RX_ACTIVE_0_GPIO_OE_POS 11 +#define IO_CTRL_RX_ACTIVE_0_GPIO_ENABLE_BIT ((u32)0x00000400) +#define IO_CTRL_RX_ACTIVE_0_GPIO_ENABLE_POS 10 +#define IO_CTRL_RX_ACTIVE_0_INPUT_ENABLE_BIT ((u32)0x00000200) +#define IO_CTRL_RX_ACTIVE_0_INPUT_ENABLE_POS 9 +#define IO_CTRL_RX_ACTIVE_0_SLEW_RATE_BIT ((u32)0x00000100) +#define IO_CTRL_RX_ACTIVE_0_SLEW_RATE_POS 8 +#define IO_CTRL_RX_ACTIVE_0_DRIVER_PULL_STATE_MASK ((u32)0x000000C0) +#define IO_CTRL_RX_ACTIVE_0_DRIVER_PULL_STATE_LSB 6 +#define IO_CTRL_RX_ACTIVE_0_DRIVER_PULL_STATE_WIDTH ((u32)0x00000002) +#define IO_CTRL_RX_ACTIVE_0_OUTPUT_PAD_STRENGTH_MASK ((u32)0x00000030) +#define IO_CTRL_RX_ACTIVE_0_OUTPUT_PAD_STRENGTH_LSB 4 +#define IO_CTRL_RX_ACTIVE_0_OUTPUT_PAD_STRENGTH_WIDTH ((u32)0x00000002) +#define IO_CTRL_RX_ACTIVE_0_SCHMIT_TRIGER_BIT ((u32)0x00000008) +#define IO_CTRL_RX_ACTIVE_0_SCHMIT_TRIGER_POS 3 +#define IO_CTRL_RX_ACTIVE_0_MUX_SELECT_MASK ((u32)0x00000007) +#define IO_CTRL_RX_ACTIVE_0_MUX_SELECT_LSB 0 +#define IO_CTRL_RX_ACTIVE_0_MUX_SELECT_WIDTH ((u32)0x00000003) + +static inline void io_ctrl_rx_active_0_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_0_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_0_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_1_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000060) +#define IO_CTRL_RX_ACTIVE_1_OFFSET 0x00000060 +#define IO_CTRL_RX_ACTIVE_1_INDEX 0x00000018 +#define IO_CTRL_RX_ACTIVE_1_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_1_ADDR, value); +} + +static inline void io_ctrl_rx_active_1_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_1_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_1_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_2 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_2_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000064) +#define IO_CTRL_RX_ACTIVE_2_OFFSET 0x00000064 +#define IO_CTRL_RX_ACTIVE_2_INDEX 0x00000019 +#define IO_CTRL_RX_ACTIVE_2_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_2_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_2_ADDR, value); +} + +static inline void io_ctrl_rx_active_2_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_2_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_2_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_3 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_3_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000068) +#define IO_CTRL_RX_ACTIVE_3_OFFSET 0x00000068 +#define IO_CTRL_RX_ACTIVE_3_INDEX 0x0000001A +#define IO_CTRL_RX_ACTIVE_3_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_3_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_3_ADDR, value); +} + +static inline void io_ctrl_rx_active_3_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_3_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_3_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_4 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_4_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000006C) +#define IO_CTRL_RX_ACTIVE_4_OFFSET 0x0000006C +#define IO_CTRL_RX_ACTIVE_4_INDEX 0x0000001B +#define IO_CTRL_RX_ACTIVE_4_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_4_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_4_ADDR, value); +} + +static inline void io_ctrl_rx_active_4_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_4_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_4_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_5 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_5_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000070) +#define IO_CTRL_RX_ACTIVE_5_OFFSET 0x00000070 +#define IO_CTRL_RX_ACTIVE_5_INDEX 0x0000001C +#define IO_CTRL_RX_ACTIVE_5_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_5_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_5_ADDR, value); +} + +static inline void io_ctrl_rx_active_5_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_5_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_5_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_6 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_6_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000074) +#define IO_CTRL_RX_ACTIVE_6_OFFSET 0x00000074 +#define IO_CTRL_RX_ACTIVE_6_INDEX 0x0000001D +#define IO_CTRL_RX_ACTIVE_6_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_6_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_6_ADDR, value); +} + +static inline void io_ctrl_rx_active_6_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_6_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_6_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief RX_ACTIVE_7 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   1
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x3
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_RX_ACTIVE_7_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000078) +#define IO_CTRL_RX_ACTIVE_7_OFFSET 0x00000078 +#define IO_CTRL_RX_ACTIVE_7_INDEX 0x0000001E +#define IO_CTRL_RX_ACTIVE_7_RESET 0x000026D8 + +static inline void io_ctrl_rx_active_7_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_7_ADDR, value); +} + +static inline void io_ctrl_rx_active_7_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_RX_ACTIVE_7_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_RX_ACTIVE_7_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_0 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_0_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000007C) +#define IO_CTRL_LNA_ENABLE_0_OFFSET 0x0000007C +#define IO_CTRL_LNA_ENABLE_0_INDEX 0x0000001F +#define IO_CTRL_LNA_ENABLE_0_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_0_ADDR, value); +} + +/* Field definitions */ +#define IO_CTRL_LNA_ENABLE_0_GPIO_IN_BIT ((u32)0x00002000) +#define IO_CTRL_LNA_ENABLE_0_GPIO_IN_POS 13 +#define IO_CTRL_LNA_ENABLE_0_GPIO_OUT_BIT ((u32)0x00001000) +#define IO_CTRL_LNA_ENABLE_0_GPIO_OUT_POS 12 +#define IO_CTRL_LNA_ENABLE_0_GPIO_OE_BIT ((u32)0x00000800) +#define IO_CTRL_LNA_ENABLE_0_GPIO_OE_POS 11 +#define IO_CTRL_LNA_ENABLE_0_GPIO_ENABLE_BIT ((u32)0x00000400) +#define IO_CTRL_LNA_ENABLE_0_GPIO_ENABLE_POS 10 +#define IO_CTRL_LNA_ENABLE_0_INPUT_ENABLE_BIT ((u32)0x00000200) +#define IO_CTRL_LNA_ENABLE_0_INPUT_ENABLE_POS 9 +#define IO_CTRL_LNA_ENABLE_0_SLEW_RATE_BIT ((u32)0x00000100) +#define IO_CTRL_LNA_ENABLE_0_SLEW_RATE_POS 8 +#define IO_CTRL_LNA_ENABLE_0_DRIVER_PULL_STATE_MASK ((u32)0x000000C0) +#define IO_CTRL_LNA_ENABLE_0_DRIVER_PULL_STATE_LSB 6 +#define IO_CTRL_LNA_ENABLE_0_DRIVER_PULL_STATE_WIDTH ((u32)0x00000002) +#define IO_CTRL_LNA_ENABLE_0_OUTPUT_PAD_STRENGTH_MASK ((u32)0x00000030) +#define IO_CTRL_LNA_ENABLE_0_OUTPUT_PAD_STRENGTH_LSB 4 +#define IO_CTRL_LNA_ENABLE_0_OUTPUT_PAD_STRENGTH_WIDTH ((u32)0x00000002) +#define IO_CTRL_LNA_ENABLE_0_SCHMIT_TRIGER_BIT ((u32)0x00000008) +#define IO_CTRL_LNA_ENABLE_0_SCHMIT_TRIGER_POS 3 +#define IO_CTRL_LNA_ENABLE_0_MUX_SELECT_MASK ((u32)0x00000007) +#define IO_CTRL_LNA_ENABLE_0_MUX_SELECT_LSB 0 +#define IO_CTRL_LNA_ENABLE_0_MUX_SELECT_WIDTH ((u32)0x00000003) + +static inline void io_ctrl_lna_enable_0_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_0_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_0_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_1_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000080) +#define IO_CTRL_LNA_ENABLE_1_OFFSET 0x00000080 +#define IO_CTRL_LNA_ENABLE_1_INDEX 0x00000020 +#define IO_CTRL_LNA_ENABLE_1_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_1_ADDR, value); +} + +static inline void io_ctrl_lna_enable_1_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_1_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_1_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_2 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_2_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000084) +#define IO_CTRL_LNA_ENABLE_2_OFFSET 0x00000084 +#define IO_CTRL_LNA_ENABLE_2_INDEX 0x00000021 +#define IO_CTRL_LNA_ENABLE_2_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_2_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_2_ADDR, value); +} + +static inline void io_ctrl_lna_enable_2_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_2_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_2_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_3 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_3_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000088) +#define IO_CTRL_LNA_ENABLE_3_OFFSET 0x00000088 +#define IO_CTRL_LNA_ENABLE_3_INDEX 0x00000022 +#define IO_CTRL_LNA_ENABLE_3_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_3_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_3_ADDR, value); +} + +static inline void io_ctrl_lna_enable_3_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_3_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_3_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_4 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_4_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000008C) +#define IO_CTRL_LNA_ENABLE_4_OFFSET 0x0000008C +#define IO_CTRL_LNA_ENABLE_4_INDEX 0x00000023 +#define IO_CTRL_LNA_ENABLE_4_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_4_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_4_ADDR, value); +} + +static inline void io_ctrl_lna_enable_4_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_4_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_4_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_5 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_5_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000090) +#define IO_CTRL_LNA_ENABLE_5_OFFSET 0x00000090 +#define IO_CTRL_LNA_ENABLE_5_INDEX 0x00000024 +#define IO_CTRL_LNA_ENABLE_5_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_5_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_5_ADDR, value); +} + +static inline void io_ctrl_lna_enable_5_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_5_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_5_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_6 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_6_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000094) +#define IO_CTRL_LNA_ENABLE_6_OFFSET 0x00000094 +#define IO_CTRL_LNA_ENABLE_6_INDEX 0x00000025 +#define IO_CTRL_LNA_ENABLE_6_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_6_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_6_ADDR, value); +} + +static inline void io_ctrl_lna_enable_6_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_6_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_6_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_7 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_7_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000098) +#define IO_CTRL_LNA_ENABLE_7_OFFSET 0x00000098 +#define IO_CTRL_LNA_ENABLE_7_INDEX 0x00000026 +#define IO_CTRL_LNA_ENABLE_7_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_7_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_7_ADDR, value); +} + +static inline void io_ctrl_lna_enable_7_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_7_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_7_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_8 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_8_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000009C) +#define IO_CTRL_LNA_ENABLE_8_OFFSET 0x0000009C +#define IO_CTRL_LNA_ENABLE_8_INDEX 0x00000027 +#define IO_CTRL_LNA_ENABLE_8_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_8_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_8_ADDR, value); +} + +static inline void io_ctrl_lna_enable_8_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_8_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_8_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_9 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_9_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000A0) +#define IO_CTRL_LNA_ENABLE_9_OFFSET 0x000000A0 +#define IO_CTRL_LNA_ENABLE_9_INDEX 0x00000028 +#define IO_CTRL_LNA_ENABLE_9_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_9_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_9_ADDR, value); +} + +static inline void io_ctrl_lna_enable_9_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_9_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_9_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_10 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_10_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000A4) +#define IO_CTRL_LNA_ENABLE_10_OFFSET 0x000000A4 +#define IO_CTRL_LNA_ENABLE_10_INDEX 0x00000029 +#define IO_CTRL_LNA_ENABLE_10_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_10_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_10_ADDR, value); +} + +static inline void io_ctrl_lna_enable_10_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_10_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_10_ADDR) & + ~((u32)0x00000400)) | ((u32)gpioenable << 10)); +} + +/* + * @brief LNA_ENABLE_11 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_LNA_ENABLE_11_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000A8) +#define IO_CTRL_LNA_ENABLE_11_OFFSET 0x000000A8 +#define IO_CTRL_LNA_ENABLE_11_INDEX 0x0000002A +#define IO_CTRL_LNA_ENABLE_11_RESET 0x00000698 + +static inline void io_ctrl_lna_enable_11_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_11_ADDR, value); +} + +static inline void io_ctrl_lna_enable_11_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_LNA_ENABLE_11_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_LNA_ENABLE_11_ADDR) & + ~((u32)0x00000400)) | ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_0 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_0_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000AC) +#define IO_CTRL_PA_ENABLE_0_OFFSET 0x000000AC +#define IO_CTRL_PA_ENABLE_0_INDEX 0x0000002B +#define IO_CTRL_PA_ENABLE_0_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_0_ADDR, value); +} + +/* Field definitions */ +#define IO_CTRL_PA_ENABLE_0_GPIO_IN_BIT ((u32)0x00002000) +#define IO_CTRL_PA_ENABLE_0_GPIO_IN_POS 13 +#define IO_CTRL_PA_ENABLE_0_GPIO_OUT_BIT ((u32)0x00001000) +#define IO_CTRL_PA_ENABLE_0_GPIO_OUT_POS 12 +#define IO_CTRL_PA_ENABLE_0_GPIO_OE_BIT ((u32)0x00000800) +#define IO_CTRL_PA_ENABLE_0_GPIO_OE_POS 11 +#define IO_CTRL_PA_ENABLE_0_GPIO_ENABLE_BIT ((u32)0x00000400) +#define IO_CTRL_PA_ENABLE_0_GPIO_ENABLE_POS 10 +#define IO_CTRL_PA_ENABLE_0_INPUT_ENABLE_BIT ((u32)0x00000200) +#define IO_CTRL_PA_ENABLE_0_INPUT_ENABLE_POS 9 +#define IO_CTRL_PA_ENABLE_0_SLEW_RATE_BIT ((u32)0x00000100) +#define IO_CTRL_PA_ENABLE_0_SLEW_RATE_POS 8 +#define IO_CTRL_PA_ENABLE_0_DRIVER_PULL_STATE_MASK ((u32)0x000000C0) +#define IO_CTRL_PA_ENABLE_0_DRIVER_PULL_STATE_LSB 6 +#define IO_CTRL_PA_ENABLE_0_DRIVER_PULL_STATE_WIDTH ((u32)0x00000002) +#define IO_CTRL_PA_ENABLE_0_OUTPUT_PAD_STRENGTH_MASK ((u32)0x00000030) +#define IO_CTRL_PA_ENABLE_0_OUTPUT_PAD_STRENGTH_LSB 4 +#define IO_CTRL_PA_ENABLE_0_OUTPUT_PAD_STRENGTH_WIDTH ((u32)0x00000002) +#define IO_CTRL_PA_ENABLE_0_SCHMIT_TRIGER_BIT ((u32)0x00000008) +#define IO_CTRL_PA_ENABLE_0_SCHMIT_TRIGER_POS 3 +#define IO_CTRL_PA_ENABLE_0_MUX_SELECT_MASK ((u32)0x00000007) +#define IO_CTRL_PA_ENABLE_0_MUX_SELECT_LSB 0 +#define IO_CTRL_PA_ENABLE_0_MUX_SELECT_WIDTH ((u32)0x00000003) + +static inline void io_ctrl_pa_enable_0_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_0_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_0_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_1_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000B0) +#define IO_CTRL_PA_ENABLE_1_OFFSET 0x000000B0 +#define IO_CTRL_PA_ENABLE_1_INDEX 0x0000002C +#define IO_CTRL_PA_ENABLE_1_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_1_ADDR, value); +} + +static inline void io_ctrl_pa_enable_1_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_1_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_1_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_2 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_2_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000B4) +#define IO_CTRL_PA_ENABLE_2_OFFSET 0x000000B4 +#define IO_CTRL_PA_ENABLE_2_INDEX 0x0000002D +#define IO_CTRL_PA_ENABLE_2_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_2_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_2_ADDR, value); +} + +static inline void io_ctrl_pa_enable_2_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_2_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_2_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_3 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_3_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000B8) +#define IO_CTRL_PA_ENABLE_3_OFFSET 0x000000B8 +#define IO_CTRL_PA_ENABLE_3_INDEX 0x0000002E +#define IO_CTRL_PA_ENABLE_3_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_3_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_3_ADDR, value); +} + +static inline void io_ctrl_pa_enable_3_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_3_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_3_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_4 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_4_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000BC) +#define IO_CTRL_PA_ENABLE_4_OFFSET 0x000000BC +#define IO_CTRL_PA_ENABLE_4_INDEX 0x0000002F +#define IO_CTRL_PA_ENABLE_4_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_4_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_4_ADDR, value); +} + +static inline void io_ctrl_pa_enable_4_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_4_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_4_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_5 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_5_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000C0) +#define IO_CTRL_PA_ENABLE_5_OFFSET 0x000000C0 +#define IO_CTRL_PA_ENABLE_5_INDEX 0x00000030 +#define IO_CTRL_PA_ENABLE_5_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_5_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_5_ADDR, value); +} + +static inline void io_ctrl_pa_enable_5_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_5_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_5_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_6 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_6_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000C4) +#define IO_CTRL_PA_ENABLE_6_OFFSET 0x000000C4 +#define IO_CTRL_PA_ENABLE_6_INDEX 0x00000031 +#define IO_CTRL_PA_ENABLE_6_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_6_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_6_ADDR, value); +} + +static inline void io_ctrl_pa_enable_6_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_6_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_6_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_7 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_7_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000C8) +#define IO_CTRL_PA_ENABLE_7_OFFSET 0x000000C8 +#define IO_CTRL_PA_ENABLE_7_INDEX 0x00000032 +#define IO_CTRL_PA_ENABLE_7_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_7_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_7_ADDR, value); +} + +static inline void io_ctrl_pa_enable_7_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_7_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_7_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_8 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_8_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000CC) +#define IO_CTRL_PA_ENABLE_8_OFFSET 0x000000CC +#define IO_CTRL_PA_ENABLE_8_INDEX 0x00000033 +#define IO_CTRL_PA_ENABLE_8_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_8_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_8_ADDR, value); +} + +static inline void io_ctrl_pa_enable_8_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_8_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_8_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_9 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_9_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000D0) +#define IO_CTRL_PA_ENABLE_9_OFFSET 0x000000D0 +#define IO_CTRL_PA_ENABLE_9_INDEX 0x00000034 +#define IO_CTRL_PA_ENABLE_9_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_9_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_9_ADDR, value); +} + +static inline void io_ctrl_pa_enable_9_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_9_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_9_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_10 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_10_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000D4) +#define IO_CTRL_PA_ENABLE_10_OFFSET 0x000000D4 +#define IO_CTRL_PA_ENABLE_10_INDEX 0x00000035 +#define IO_CTRL_PA_ENABLE_10_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_10_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_10_ADDR, value); +} + +static inline void io_ctrl_pa_enable_10_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_10_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_10_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief PA_ENABLE_11 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               1
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 0
+ *   07:06 DRIVER_PULL_STATE         0x2
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_PA_ENABLE_11_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000D8) +#define IO_CTRL_PA_ENABLE_11_OFFSET 0x000000D8 +#define IO_CTRL_PA_ENABLE_11_INDEX 0x00000036 +#define IO_CTRL_PA_ENABLE_11_RESET 0x00000698 + +static inline void io_ctrl_pa_enable_11_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_11_ADDR, value); +} + +static inline void io_ctrl_pa_enable_11_gpio_enable_setf(struct cl_chip *chip, u8 gpioenable) +{ + ASSERT_ERR_CHIP((((u32)gpioenable << 10) & ~((u32)0x00000400)) == 0); + cl_reg_write_chip(chip, IO_CTRL_PA_ENABLE_11_ADDR, + (cl_reg_read_chip(chip, IO_CTRL_PA_ENABLE_11_ADDR) & ~((u32)0x00000400)) | + ((u32)gpioenable << 10)); +} + +/* + * @brief SPICLK register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_SPICLK_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000DC) +#define IO_CTRL_SPICLK_OFFSET 0x000000DC +#define IO_CTRL_SPICLK_INDEX 0x00000037 +#define IO_CTRL_SPICLK_RESET 0x00000318 + +static inline void io_ctrl_spiclk_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_SPICLK_ADDR, value); +} + +/* + * @brief FWR_EN_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FWR_EN_1_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000F0) +#define IO_CTRL_FWR_EN_1_OFFSET 0x000000F0 +#define IO_CTRL_FWR_EN_1_INDEX 0x0000003C +#define IO_CTRL_FWR_EN_1_RESET 0x00000318 + +static inline void io_ctrl_fwr_en_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FWR_EN_1_ADDR, value); +} + +/* + * @brief FASTWR_7 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_7_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000F8) +#define IO_CTRL_FASTWR_7_OFFSET 0x000000F8 +#define IO_CTRL_FASTWR_7_INDEX 0x0000003E +#define IO_CTRL_FASTWR_7_RESET 0x00000318 + +static inline void io_ctrl_fastwr_7_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_7_ADDR, value); +} + +/* + * @brief FASTWR_6 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_6_ADDR (REG_IO_CTRL_BASE_ADDR + 0x000000FC) +#define IO_CTRL_FASTWR_6_OFFSET 0x000000FC +#define IO_CTRL_FASTWR_6_INDEX 0x0000003F +#define IO_CTRL_FASTWR_6_RESET 0x00000318 + +static inline void io_ctrl_fastwr_6_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_6_ADDR, value); +} + +/* + * @brief FASTWR_5 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_5_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000100) +#define IO_CTRL_FASTWR_5_OFFSET 0x00000100 +#define IO_CTRL_FASTWR_5_INDEX 0x00000040 +#define IO_CTRL_FASTWR_5_RESET 0x00000318 + +static inline void io_ctrl_fastwr_5_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_5_ADDR, value); +} + +/* + * @brief FASTWR_4 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_4_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000104) +#define IO_CTRL_FASTWR_4_OFFSET 0x00000104 +#define IO_CTRL_FASTWR_4_INDEX 0x00000041 +#define IO_CTRL_FASTWR_4_RESET 0x00000318 + +static inline void io_ctrl_fastwr_4_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_4_ADDR, value); +} + +/* + * @brief FASTWR_3 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_3_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000108) +#define IO_CTRL_FASTWR_3_OFFSET 0x00000108 +#define IO_CTRL_FASTWR_3_INDEX 0x00000042 +#define IO_CTRL_FASTWR_3_RESET 0x00000318 + +static inline void io_ctrl_fastwr_3_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_3_ADDR, value); +} + +/* + * @brief FASTWR_2 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_2_ADDR (REG_IO_CTRL_BASE_ADDR + 0x0000010C) +#define IO_CTRL_FASTWR_2_OFFSET 0x0000010C +#define IO_CTRL_FASTWR_2_INDEX 0x00000043 +#define IO_CTRL_FASTWR_2_RESET 0x00000318 + +static inline void io_ctrl_fastwr_2_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_2_ADDR, value); +} + +/* + * @brief FASTWR_1 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_1_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000110) +#define IO_CTRL_FASTWR_1_OFFSET 0x00000110 +#define IO_CTRL_FASTWR_1_INDEX 0x00000044 +#define IO_CTRL_FASTWR_1_RESET 0x00000318 + +static inline void io_ctrl_fastwr_1_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_1_ADDR, value); +} + +/* + * @brief FASTWR_0 register definition + *
+ *  Bits           Field Name   Reset Value
+ * -----   ------------------   -----------
+ *   13    GPIO_IN                   0
+ *   12    GPIO_OUT                  0
+ *   11    GPIO_OE                   0
+ *   10    GPIO_ENABLE               0
+ *   09    input_enable              1
+ *   08    SLEW_RATE                 1
+ *   07:06 DRIVER_PULL_STATE         0x0
+ *   05:04 OUTPUT_PAD_STRENGTH       0x1
+ *   03    SCHMIT_TRIGER             1
+ *   02:00 MUX_SELECT                0x0
+ * 
+ */ +#define IO_CTRL_FASTWR_0_ADDR (REG_IO_CTRL_BASE_ADDR + 0x00000114) +#define IO_CTRL_FASTWR_0_OFFSET 0x00000114 +#define IO_CTRL_FASTWR_0_INDEX 0x00000045 +#define IO_CTRL_FASTWR_0_RESET 0x00000318 + +static inline void io_ctrl_fastwr_0_set(struct cl_chip *chip, u32 value) +{ + cl_reg_write_chip(chip, IO_CTRL_FASTWR_0_ADDR, value); +} + +#endif /*CL_REG_DEFS_H */ From patchwork Tue May 24 11:34:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575963 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 D595EC433F5 for ; Tue, 24 May 2022 11:40:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236874AbiEXLkD (ORCPT ); Tue, 24 May 2022 07:40:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235061AbiEXLj6 (ORCPT ); Tue, 24 May 2022 07:39:58 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60044.outbound.protection.outlook.com [40.107.6.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7AD4492D18 for ; Tue, 24 May 2022 04:39:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gzKh56PrVvIFjkn7Wu4NmBKGdPI3XhHA/d4QGMrqJmlPds13JgStkWrHU6vSV+wXgqKVRtFzkYBbeNUS0EBnH0OH+DW2wK6sGDjtE5//oUIC3iZstPVl+kb5xPQuWi4O1ugN6vNtP8uL/xb+YgtJo/p9JK/Tpdp2fxt348pFCKnzLQRHkKf7otvHRFJwH4/VgjVzRcwr0nuoJYWq0oxyK5+23acB5OceiaGbRpw7354dBqDFZyiQghBCaabr+ydah/rnrsh7RZl4wpcFZuYIemd+MBgSuL6hm/RKGKmvmnwr396tHBmfSh6MJic3bUMLISAueH+YqTxKaru6bZFrVA== 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=CVBs+OrzaqPeKNdbELV8FHA0fl9VpL9yoculXcSaNbs=; b=XxdG6Um4MZauZ0Oyy/XFPmu4SjwArQnjTPDt51+TPKm8oQuxkl1vOl7b5sqUZgPVzO9FCTwLiLvi7u9KjrAgr0k/+vIH3EZnilXcmxS4KVqRhEXPeBep+bn77g7jWZkZFB5nbEXbcV0g4y6J2C8ug1IgDXoTHzH6kg/yWYUdpWWKdKV3RaH/r2trKKUFu1BXX2wd+0ojReoWvlfOFu4FzAJCpZn6Li12VHwJlRDR442/l74QmyCHvclM7E/W0WFUig4GUgWd/vk+XRfhVKpbrbMhj0HDZqHBr7RSMjzg7YrL5W3bLV2lWOqYg7cJ7HeMXWycXqt9xyygLxHjySN00Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=CVBs+OrzaqPeKNdbELV8FHA0fl9VpL9yoculXcSaNbs=; b=CqBN29rocrCihAmVqfu95Ysx2TR/Gt7imY6ibL/246zL5YhirdmDYEmY+EkJWohJptCBoxRQEwa0walisHRg6Q6o+U0gUag6cwnu8FWKsrtUHgtxs2kQ/uZOqoVDx1r6NGEazE+AjQ0D6GJmECMLlUQW/5rBYC3FIPs8fQV6N98= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:25 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:25 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 66/96] cl8k: add rfic.c Date: Tue, 24 May 2022 14:34:32 +0300 Message-Id: <20220524113502.1094459-67-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7960a886-33ec-4ad1-b719-08da3d79f41f X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: JynXxgYDd9Ixqd+PmQMGA0X5aYxVYoW4wYjMKhTwzSGsBYL7adGQ+Q4hn95Ky34eAIKPmdnZDciPPJqUpQX6BX2RqjpQzSFLyCtTUYk8/aCq5zyfp9tA30A73EKU7XdJqw4N8xBnwHQ4y0PlrBNFFRhTjQ/dCE4Ek+ErN6dfKWn0QyViokTWthFZswlWeAHikXK3g2HtM8WQYSP3n2SDbE2uduqAN9eqlllRDzWnyhVS8FjocFLRyDtQlBmnkM6ZdTlBD7yWucY34SoiKD6P38OovU+AodPl6CBj1aNSPhnqLdzVp+oShlXTJYgfokgsH2SyTTUW5cLJAoE24ZQPKRrDPSoiz9Cb2YVxLSgMDG8a+zgtlvJDtjpFM1PfY1Wo78yOL4XzxuRq5H0PV5DB+BfOTEYZVrFNMcwaQ5zuTQQosoSFNpzlkSp8zv6fQJuJZOgh6aDukJekoWBk9I18fMeCVoEzvhfRHs4K3SVBlEn5zjzwocsJ2jTqidIhVYN+nnK7VMgwsayuo4TGsFoNz+//1Y5Vwt4bTnk3xc3BJblGuZG5rjN5iao+3vxc67DVwMf10jaZCNnjgVz0DxMuM+G9qMjo6K8BOv3Rb6Etkc1uKSA2pYTr9iw1AYh2UerxmOAkWFYILk2oCYDqPLHJEpe3ktDDjkuLPQ8N87uH2dyk3d+GYqgUtSn8NEWD5a5s4WBXYVP13xse45f8TQO6meD+6R4HjR7fJ/9g6s8WoS8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 1ZAdAt/809rnHySXeZ0Ytyc87ibbCpVYPo4rfaOGED1hUfhRh+Pv6tWYg9YXnaar4wQAAQLuYT4Har1OnV8EeIkZgRPVs1xlO5kKTMtDqVgmpS5hBePSzD0hsugehLKEPPPyQury/sWcbjN5MRyc8VZ+ahKpPP4ABAxzvcCC09n1nutjgMYklaCXlo6BiOLBNLsJnPH+nl6WewYMbD9Jg8JWxaxgV/RepoOqv2w+lrJrLLl/oX2Uq8KHiYB5cqS5mgudj31lP0JbfBn53B/lAOVHy9DG2w65a53PZOdgO6DQSBf2H49oOzQX1SV0zYgwhP85T1WYNsAZV6YSe3sgh1fR55i7HXGVhqcUbW8EAEW7u6cebo8skhg3QN4ovZiVhmw04dg0ekxBG6KmE64pGo/ngqaPMd8xnCwOqFtDUTxAmZNJn2Ago4GDmMllDUxwQti/ZhrLNkx4zk+ilOEKFgSrBcy0A6qIAIDSXNIOqDP77nhZyOWPHtZqac4JxKw3bIILq1XFQJWuRPwgojS4jwbOvRF3Msm3cMeggSXALMfS/e0VoZ6kT7clsUntMA/xp01dUdqcJfjruFPbO0e37zZoBX5AC4Tv7xjxB6bBAAYZ4629oK0Jol3PxFfmM+myYzhSb6fk+ODCG4Q3AiHVnK7vLe3dhacI9woK6628Z3TEVlAFYeik063ParH0YI6YtpXtKYDwVGZFsa90hR2pgLSwPOJl/1I2p6CEhz9lGlvby4o6IfaXEPwzCC50n7n9uWLggECRT3jInvf7W5MPg6NjyjO612YNgh3hQ3VyEMH4lfSKI3VvVeQIsYMOGV6iZojjUv9txH4G8zL5IPkWlnq8uUMnb0oySJc6E9iHkgOua1VougQGnCMKhizqRHIvlGxdNdDlGHA/WjkCZOXWx25zf7AJ6Iik49SLJ2fmoBB1QIO0sUJnscGYpzuCA4bDSYBfz9KM69TcRYG0iioLipeODIUpoHMpZcKh2rAj/10Nl1Ag6bdYbjrvlwWuaclePKTYd8jC6ByEJN6RGdQvRbeHHstr9N899VqxArynXPdKYegmov8uqowLyerOKS2El8ojbKlL9Yj6nFg62A6OO5/b0wEZZzCfH4cA4od69RcnFn7+P1gM7ZbJgmKmfuY4dNoXQbKClwY0pFs8akCOeaXoQnj0YX4xg4JsBfqdlROyaBlF6PKJs7oZJ8JyNfMYS5V51MEGW+BXpdGgi9SfWpyfKQkCjvCreXW28RASoO43bjQ03rqN9eYRjYF/z30YiQYBqx7cxpSNCfLfyGstMF21zJZEa12O1PYZf11X7KmUhCYnUvw8E2h+7bTv+YVAAYdUNDPD3bN+qTqwUnr91b+hX+/MpM8bBiIWiS+/hZMy/UcMkemhbDmpX585wCYPi4VCFesCi3ffpYkVNfmqWPqfPkFnd6xNh3qcQhLr1hWW9vxcguJhKBImaSvMXngz4effkDpnwDGXLYwOl5uIaCEgVUWchB3XbnsYjNBzpZy5MfZw8l6Eh9k551HNfueCDzdZMet0CTYR025yR9hQ0Af7M0mbcWo1rYD63rvj3ZKOyONN05imhEe/fPNvVOg+HrpbEYPOQVWDQGHKVnj1WU2Cdv2EeEp+1myhAD4RGjXiYf63WSgNHjLWyWVzcY8KW41wOToPwYZNC2suVu5RBvC+3StFBUMB/sz5iBkV4puJ7nClTYG2WkClafqJksXHACb7lmSMUKLwiEV7zCz5yR1JM0evizarY0ffnON48O0= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7960a886-33ec-4ad1-b719-08da3d79f41f X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:42.4433 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2pPY5UK35vJksPSmXHwLIR7I5nl/aAnpF9dBWcg+g3fKkURNUPxSkawnXbKNzYijpDwI7WI2xpVK55mAD8leQg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rfic.c | 232 ++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rfic.c diff --git a/drivers/net/wireless/celeno/cl8k/rfic.c b/drivers/net/wireless/celeno/cl8k/rfic.c new file mode 100644 index 000000000000..5a3a595694b5 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rfic.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_defs.h" +#include "phy.h" +#include "utils.h" +#include "rfic.h" + +#define PHY_DEV_NON_PHYSICAL 0x0 +#define MAX_LOOPS 15 +#define READ_REQ 1 +#define WRITE_REQ 0 + +int cl_spi_read(struct cl_hw *cl_hw, u8 page, u8 addr, u8 *val) +{ + struct mm_spi_read_cfm *cfm; + int ret = cl_msg_tx_spi_read(cl_hw, page, addr); + + if (ret) + goto out; + + cfm = (struct mm_spi_read_cfm *)(cl_hw->msg_cfm_params[MM_SPI_READ_CFM]); + if (!cfm) { + ret = -ENOMSG; + goto out; + } + + if (cfm->status == 0) { + *val = cfm->val; + } else { + cl_dbg_err(cl_hw, "SPI read failed\n"); + *val = 0; + } + + cl_msg_tx_free_cfm_params(cl_hw, MM_SPI_READ_CFM); + return 0; + +out: + *val = 0; + return ret; +} + +static int _cl_spi_driver_read(struct cl_hw *cl_hw, u8 more, u8 addr, u8 *val) +{ + u8 prescaler = 4; + int loops = MAX_LOOPS; + + riu_rc_sw_ctrl_pack(cl_hw, 1, more, 0, 0, 1, 1, 1, 1, prescaler, READ_REQ, addr, 0xFF); + while (riu_rc_sw_ctrl_start_done_getf(cl_hw) && --loops) + ; + + if (!loops) { + cl_dbg_verbose(cl_hw, "Read error - addr [0x%02x]\n", addr); + return -EBADE; + } + + *val = riu_rc_sw_ctrl_data_getf(cl_hw); + + hwreg_pr(cl_hw, "more=%d, addr=0x%x, *val=0x%x\n", more, addr, *val); + + return 0; +} + +static int _cl_spi_driver_write(struct cl_hw *cl_hw, u8 more, u8 addr, u8 val) +{ + u8 prescaler = 4; + int loops = MAX_LOOPS; + + hwreg_pr(cl_hw, "more=%d, addr=0x%x, val=0x%x\n", more, addr, val); + + riu_rc_sw_ctrl_pack(cl_hw, 1, more, 0, 0, 1, 1, 1, 1, prescaler, WRITE_REQ, addr, val); + + while (riu_rc_sw_ctrl_start_done_getf(cl_hw) && --loops) + ; + + if (!loops) { + cl_dbg_verbose(cl_hw, "Write error - addr [0x%02x] val [0x%02x]\n", addr, val); + return -EBADE; + } + + return 0; +} + +int cl_spi_driver_read_byte(struct cl_hw *cl_hw, u8 page, u8 addr, u8 *val) +{ + /* cl_spi_driver_read_byte should only be used when mac fw not loaded, + * else use cl_spi_read + */ + int ret = 0; + + spin_lock_bh(&cl_hw->chip->isr_lock); + + ret = _cl_spi_driver_write(cl_hw, 1, 0x03, page); + if (ret) + goto read_exit; + + ret = _cl_spi_driver_read(cl_hw, 0, addr, val); + if (ret) + goto read_exit; + +read_exit: + spin_unlock_bh(&cl_hw->chip->isr_lock); + + return ret; +} + +static u8 cl_rfic_str_to_cmd(struct cl_hw *cl_hw, char *str) +{ + if (!strcmp(str, "DONE")) + return OVERWRITE_DONE; + else if (!strcmp(str, "SPI_R")) + return SPI_RD_CMD; + else if (!strcmp(str, "SPI_W")) + return SPI_WR_CMD; + else if (!strcmp(str, "GCU_W")) + return GCU_WR_CMD; + else if (!strcmp(str, "RIU_W")) + return RIU_WR_CMD; + else if (!strcmp(str, "GEN_W")) + return GEN_WR_CMD; + else if (!strcmp(str, "DELAY")) + return UDELAY_CMD; + + cl_dbg_err(cl_hw, "unknown command %s\n", str); + return OVERWRITE_DONE; +} + +static void cl_parse_rf_command(struct cl_hw *cl_hw, char *str, + struct cl_rf_reg_overwrite_info *info) +{ + int i = 0; + char *ptr = NULL; + u32 res = 0; + + while ((ptr = strsep(&str, " ")) && (*ptr != '\n')) { + if (i == 0) { + info->cmd = cl_rfic_str_to_cmd(cl_hw, ptr); + } else { + if (kstrtou32(ptr, 16, &res) != 0) { + pr_err("%s: invalid data - %s\n", __func__, ptr); + return; + } + + info->data[i - 1] = cpu_to_le32(res); + res = 0; + } + i++; + } +} + +#define RF_CMD_MAX_LEN 64 + +static void cl_parse_rf_commands_from_buf(struct cl_hw *cl_hw, char *buf, loff_t size, + struct cl_rf_reg_overwrite_info *info) +{ + int i = 0; + char *line = buf; + char str[RF_CMD_MAX_LEN]; + char *end; + int line_length = 0; + + while (line && (line != (buf + size))) { + if ((*line == '#') || (*line == '\n')) { + /* Skip comment or blank line */ + line = strstr(line, "\n") + 1; + } else if (*line) { + end = strstr(line, "\n") + 1; + line_length = end - line; + + if (line_length >= RF_CMD_MAX_LEN) { + cl_dbg_err(cl_hw, "Command too long (%u)\n", line_length); + return; + } + + snprintf(str, line_length, "%s", line); + cl_parse_rf_command(cl_hw, str, &info[i++]); + line += line_length; + } + } +} + +int cl_rfic_read_overwrite_file(struct cl_hw *cl_hw, struct cl_rf_reg_overwrite_info *info, + bool init) +{ + char *buf = NULL; + size_t size = 0; + char filename[CL_FILENAME_MAX] = {0}; + char path_name[CL_PATH_MAX] = {0}; + struct path path; + + if (init) + snprintf(filename, sizeof(filename), "rf_init_overwrite.txt"); + else + snprintf(filename, sizeof(filename), "rf_tcv%d_overwrite.txt", cl_hw->tcv_idx); + + snprintf(path_name, sizeof(path_name), "/lib/firmware/cl8k/%s", filename); + if (kern_path(path_name, LOOKUP_FOLLOW, &path) < 0) + return 0; + + size = cl_file_open_and_read(cl_hw->chip, filename, &buf); + + if (!buf) + return 0; + + cl_dbg_trace(cl_hw, "parsing %s !!!\n", filename); + cl_parse_rf_commands_from_buf(cl_hw, buf, size, info); + kfree(buf); + return 0; +} + +static u8 cl_rfic_version(struct cl_hw *cl_hw) +{ + u8 value = 0xff; + int ret = cl_spi_driver_read_byte(cl_hw, 0, 0, &value); + + if (ret < 0) + cl_dbg_err(cl_hw, "%s: spi read failed", __func__); + + return value; +} + +void cl_chip_set_rfic_version(struct cl_hw *cl_hw) +{ /* Read version only on a physical phy */ + if (cl_hw->chip->conf->ci_phy_dev == PHY_DEV_ATHOS || + cl_hw->chip->conf->ci_phy_dev == PHY_DEV_OLYMPUS) { + cl_hw->chip->rfic_version = cl_rfic_version(cl_hw); + } else { + cl_hw->chip->rfic_version = PHY_DEV_NON_PHYSICAL; + } +} From patchwork Tue May 24 11:34:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576842 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 A76DEC433F5 for ; Tue, 24 May 2022 11:40:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236892AbiEXLkW (ORCPT ); Tue, 24 May 2022 07:40:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236893AbiEXLkT (ORCPT ); Tue, 24 May 2022 07:40:19 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60065.outbound.protection.outlook.com [40.107.6.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF9339347A for ; Tue, 24 May 2022 04:39:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ecfibF+oT7v2poIJNkNSLUrFFaNRyfUQ+EpLiwan8Oj7KCc/rGNkuSwy0Uu0G+7fkBKQ/qqM/GY79XysFhDZViLMTApIcWSMGn+q/VksKFeFGtVhsP4cTe78y42Qe1HYwvvlzZB8sm/ByMCIZijKg3zxASINNKbElFZ6rf+hruJM2AL0J7/TxyI6na0gKauoh5Mq7Is3P0Mcq+27CfQ5fbr7aDh+T1zYpAJv1Ixfi9AVsObTxkUyw+gtZxqlv5dO4pxlx96sQs2lZjEtIe71d8eGD8EjzazECi9fM/y0cbZNCB8lBvmIelQtDejAnCK+Sr5YXCJnAqdcTyoKxIMUSQ== 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=8sfqBqthfKltNiBd3RvGRGTDowfw7pLuSZ4n6NX/EeY=; b=BpwD+SjxAFEDyaGsMSTe7ldZW25tU67j4FWJ7bUZguQ+8zaUr8mT1vWayMZIEHQl8VlP3pb7zLreDmpgebgSsLLIVuOjmlnzmukN5L+pqIx5dc1D2bM2z8BCiJin82ri28IUecufhhJ7digB3LtijeMHsi/6cgChVhgHbPF/2Q5Q2/7VqeIqVK2O4ZsW83SFUu//yOJ+FAjUo9LAOe7GTEut9ZlDa+7NMx3fYqNIqXNV4v8xb3wDnKVXBaQNfgN4aq9OmZKRoj668k6CG9gpqgUIxHlBtml+8PAXpx+wSXgsduuSTJlihZpdx4rrnFwIzYmcXOcZQZuVDx3xZind9g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8sfqBqthfKltNiBd3RvGRGTDowfw7pLuSZ4n6NX/EeY=; b=OCmXVIMK10bDREw+0HCo/V+jSrlIcAf3Y9paM+azCWv/zbZCT9acfevwI/dUmktosjvduIDui+nkK50AzrMdgmWe0nWnkxLXg5H88eiDTqeTo7cXnvzNHiuUrQ2f9f9OAqBDOFllOvcvz0BYPQKQ1kp1iomHgMhXbW7ioBwPshM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:25 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:25 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 67/96] cl8k: add rfic.h Date: Tue, 24 May 2022 14:34:33 +0300 Message-Id: <20220524113502.1094459-68-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4abede78-bd41-437d-a188-08da3d79f4a0 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: eZVZ7NV/vWdjvKlxCLnAYFRuCR7AnaCXNgHQGva031HhpiR8Zrt5Hb9rBhocq/JlR19knUMm5slbhfkOf6ZqtpJmjzaQew0iXcCz/WQT1PHMUb+FyIc4T8AEwBQy4kSrB6SkXf1XUKqvzEzuWBdz39eSm9f/mssBnYtTQb5u92m8HHnLWDiqB5fVJw93FZBI+xOU/hTdShCBUqY82tMEC46tFQmVx9dI+nCdLaihaMkG6HZTypuz6ORJDRSTUg9Ly93PTrkrDpdNS/RVauu9rjYdLMkW3y9clQ1bJ4zogF7P2HIzKjel7jm3rSnW6PLzS2fZe3ZcVuhohtoTJ2dS1ZR/LfpSshHmyDKgUriY/89QWmKUVqyo9j0P3bax/0mpo82dEmwkbNxG4FLtB5tzrg9MtlUNsTbi9ISQw+WI1sQYnGvkgjFxHOTOv2JNDZRONPEFbqFhQ8jERTrxngRUueHEfoNVRvaryFN+LqQ+hDVz1gR7bZ5svtVUge1Y68Y4DQNl1yCirLvLlIFF771tL8meWKicQLYaTHBYA6GDDPqu5TEhZ+L+DsNMxpm00Tw4aEvuyB7kv/PSQLqQG3/uVt92X8XbW6TbBM6gVJO8tNc76V3clrRWu+pG0SEydnNIW356dS/hTicovwha1HinJP9TQTKXBO0l7+JoVBHK9AZT7g8JgUCkhOBEXT2p1X/wnmHPXG4oE+rxobmtWMXUUqCoIv1Y4nqVdzUHkHB2p+4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: voanQE+X5ed7Vo7o3fflAy/3B6/cLBynZQv5IfjQORSb426bMFmpL5kWwKX6wrxrgBLpxvduYkkjRCpNjVK0LyPARGq/qzY107Oq9XKKvCxixeAXIv9Zfkc6+r6OTIj/3rw/pMCmPVp21ikJIHS2FW5QtrIFYPgf/aHwFZDnu++L1aLIL++/LGGCbxKkN9w3r0OEP7hapQABz+AIHXSUwApAu+uVnPkL0KW0mtboxLlCiNbzw2s8xoiWMxgLWvUCaQA1YhVjotKNbR1SJ6aeKU8l4Bn3knMRm2j0z7Qiya9mhnuygRpattoi1Mwtdk3GiTMQCMlyRdTLHwN1OSJ7J7zmI+d4y0Gdt565l+hR1YAgwaSHi9sZQsB16eO/TmmEpNlzGnI8Eb/YCnDFSQVB/b9sE079N6EPjuhwzgvm7mK3G68qbTvSCzTYGCXbuImin8eZHfm/Qi4oMPdROOhVzNdcYQBmRW+faGrgfSIS43InG/MAn8gprL1QmAK7R9SyIJyFizNUioUMtcKT6XtGTqdAVMY133M1NWbXQzQ8vGzjxBo97xW9Pw8hF75ouIY++suIz0Gw5yKaFMQMpiOGBP/u0EUXmWU/tANioGT3Bxy75SWVXrMGMcP0GaUp8g6AfcdrG5poLd1PItdljVASY6IXvTCZYh/farfvz7q2GkNLNCqM0xahATgVqPQb8Np1Ld2MhRi96uA0CuReVxwUEujKA/xZYNAgMWpDJORDLou+0t+ZGOgOdV32gjLECtcj6T+XYXoj1i/RFk8ieN4SA7N5jmSK/jH7j72HfuN2RFCEba7i1NObnINmaudvVTCgFgmiTJik9vfpSeqbMrjGdlDom2uv0eSADc52jxNVhWt9LsXMlnwdWtca+wahTVJRHgil9cU0FtmZF3AxiGC3yw1tNawl7qokh5zHzyS63ecPAE/ogZG/0A4X4MgALNnd+E2IRO/SQmVEqS0NhSV6DS5456IwpYbEehtFAX0AjlWZBiW+YT6ScSzAdOzpraQMO/8HuwCp8lJsm1mmChSR226pbrrPSJ8fF0BpX6Y1W6GubvS/LVmVcK9qz/Tm29ae5X/DfGWTEkReQO5G/gvTNN4Qy0eWY0ettn2Ft5oaQwDG72wfmXH3/yNJFh/MGSZ8jppWtyZ10CgnQJvVtjQMLTEOkp7VXrri62wcP+N1cDo8LhT3BZXRvKFnYlbm+J5msx3ksKpUJA8ih1Mz2TB+v82Q+gMYcVe4KkdOHbAbmpaOYi8hh6PK0KfD+6wZ8XkIv2v+HW086TzyEBKoDC3z4iG1Ttpt2wXk9VYg6FwYObfzX7ijJuuI4I939HgauZJSy6uoAdg57WueFaLENmkzloFZTyBVaJlegYEIR+Q3CLZVx3uirGcj7sw7MTnISsubeEsLw+Tac4Gc93E5GaSfT/TwSaLLRasr4hRXtFin8Od3amZMZ/3kfWm1jt/KvChGBkSzvR6rS4fsQ+w6vlMx4ZNZDfIWS8x0EmavYMo2GRzymsg3mejdD/a4kIaTH+qZW8htvrGVrMH7UdtUeKpY2rF9IRMIDGlCinNrUEUF+8X99E9lfEY0wiTti9qrs3prC5pEU3/aPMj6+Zxq+4YGXQbLsts5wOsuPiSp8Gx1lcNAtgARjNYLQs01U+KNs5uS3fcRo7H2+3S9sy+0jSF5Q8mZFVYg5pZOyexpkfukm50Yp0JIhCkRcSerXsDt2Bjy8rGszG0mhJxN+TOl2XncYeAdU67S2sFBjCrQ8pygzws= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4abede78-bd41-437d-a188-08da3d79f4a0 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:43.2726 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 8Hf3N87l43+4CZ56JPwZ9/TKANAC7lCWUfhnJYy7hMbKNp+8pPEe8g4YFUV+sdr/kmHlwuuw4IEMgIEE2903gg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rfic.h | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rfic.h diff --git a/drivers/net/wireless/celeno/cl8k/rfic.h b/drivers/net/wireless/celeno/cl8k/rfic.h new file mode 100644 index 000000000000..686ebd6fcd98 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rfic.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_RFIC_H +#define CL_RFIC_H + +#include "hw.h" + +#define ATHOS_A_VER 0xB1 +#define ATHOS_B_VER 0xB2 + +enum cl_rf_overwrite_cmd { + OVERWRITE_DONE, + SPI_RD_CMD, + SPI_WR_CMD, + GCU_WR_CMD, + RIU_WR_CMD, + UDELAY_CMD, + GEN_WR_CMD, + RF_OVERWRITE_CMD_MAX = OVERWRITE_DONE +}; + +int cl_spi_driver_read_byte(struct cl_hw *cl_hw, u8 page, u8 addr, u8 *val); +int cl_spi_read(struct cl_hw *cl_hw, u8 page, u8 addr, u8 *val); +int cl_rfic_read_overwrite_file(struct cl_hw *cl_hw, + struct cl_rf_reg_overwrite_info *info, + bool init); +void cl_chip_set_rfic_version(struct cl_hw *cl_hw); +#endif /* CL_RFIC_H */ From patchwork Tue May 24 11:34:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575947 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 DA6D6C433EF for ; Tue, 24 May 2022 11:42:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234369AbiEXLmE (ORCPT ); Tue, 24 May 2022 07:42:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236984AbiEXLk6 (ORCPT ); Tue, 24 May 2022 07:40:58 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60067.outbound.protection.outlook.com [40.107.6.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2DE28D6AC for ; Tue, 24 May 2022 04:40:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Sj2PBQ5SDS9u+ud60n3gX29n+Syybu8HjDOzrAaoiLB9vU/YIo4dZcStc3kURX9r10oO/hYzc68yBNV+HpAIoW/09Sl/Vm7bFm21iba4tUPRWcnrZurGSYKW/j8BlVh/hKFuJbYasGcojcfkWq9Gl6hYZWAnLuaqHNHALzGcqiMj94lK7inPWAv3wBY2DQegNH9VYr+f+wdqm+K058VvRzma/OUdtccnuYj3Amn+VPQkUOuaYkyuwWaMEwKSFhj5H6ysiXQeDN33g+S8guIAZtF4/cciaY8eAcCHXsvYGeUsVGCZVQHrb8SOAqknK7F7z1GVJPgYWFwFlnDf2yUsaQ== 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=dWPv2bBc/3vHcY8w0lhcSHgUwFeyFMSeAZDvhG4Mirc=; b=KPvXBtfMsVEHQLziAqT8Wl8OSlvNuxi3M49Fsto3RJNbAbNKVSYHvtcHE0ZBMzqXV+kdh0HHuf8p8x0KV1T/pFB/1hMq0k/ytl4z8S4tuLjMpW2F8Z4jetHM6y278sgi0dbKw3AJB96YOiABJe4SLMPcxBZMGwe2+NVNcxcDccVtgAhf2HUP6ZglTjhhx1pdBuDM6qj/lM7O3NcN2aQ6iPOHK01PNdDeksIXzbriaknOk2Vih5BKbMI9YhqWY2YvPwp/5rpPhKcbZ0ygjySbTrzh2lEZg9tM6kwQljyP+6x+yJUT9v8xAmPLxBnMnaldJyamQPhs4ulKTtBOJ2Sr1w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=dWPv2bBc/3vHcY8w0lhcSHgUwFeyFMSeAZDvhG4Mirc=; b=zo/zi2wak0TosQxPs16UuPW1Jn2HCd/2WtMkTlscTyqXwwex/UYc5MVYFclWjcGZOhCB5XzqOEslJ+r+OFOPehKHcfnS+uzJt3ZwmLv5f/LnbR93XxIhWx4ToBh9dLOYwQWuxKmyiZFRPJS8YdKBW/eYviYZaI8vpZL54yUQCrQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:25 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:25 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 68/96] cl8k: add rx.c Date: Tue, 24 May 2022 14:34:34 +0300 Message-Id: <20220524113502.1094459-69-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f11bf062-e223-4200-a3c3-08da3d79f51e X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 10hvZMv6slXztpl7Y5dNZ2kdvaRZX09tvBs1ElVdj0PpDckLyf9+riWeMyRZQKy5ZMke+D7sDS4wh3X9FQUc5Lb3zGmR6lrTgCrww+u8KMzb7KAEmAVJyWISIFJzG9mMZZBm4OlaoQ6Txv4sG/o1ZfPJnNyG7CpCuWIHHNmMmmb2yyDgs1/rtmLn3NugyQAf5Y9UyoVfxLVNv8qqwU0R7e77QO4PtfL6no70pq+uI1MlQwNj+It8bV83IBfa4JlKiWxABoCJ3/2uvfGgu7M6lfWh2XEpUqa7QUkgeVlpI8fJaQvjQ75TcciSQfn+5c+sMHDJBjHtxymIpncOgLGz41w19ufNRPFYeRZmmdRTGgLFtt70W1HVhsj2dwu/Q9auIXcDvraiulzmeaRYeCe3Nm0l7cYCQ3JMd4SoWiyWC6gswAF3GV8s3Dqnr77SmdMxfTLRkmGro+LMZ3UdfS2AaFHkdCOT6kr/rXO8P6l9EZokFVi61t8SkEvuSdSqx7m6lmSG0r4QT5jVbS00lwXs2ms5YQsHZVd9QMUCcCjUTO6YeQaKq3/omhGRc8v37hMsbst6X48hAiv97BWoenuCVaDMjL55DcFIXWIb7zDfWU97AgqtbJwpR+IarEVJtDvL6DWbGg6OiSRnCUO93tQOI/Cmr2D1myhmS2s16RFIVODgNvXtxfTId7b3XnBFHtF+V6j9ut5YYrwCprfQK9ndS6VJANK20q4CFOSJGNwZO98= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001)(579004)(559001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 6jIU/ZfCc/3kfOflmYyIOl6z5jefCHeI0D8X5v5NoIQxz9vXsK9mjgrt9IvPy7SJ2hsfz7hK3skj+FpK4MT5gKM0k7InkI1lYwQDgYl6mKRw3H1sNXDZEOHucGuj2auz6n0VbjxWOMquOZECwl59BYRTzq6VFawiGwJguNruT7tiWx4om9CR/ngUDkFfmu9bu/uLz6wjThFXJNzdgWDCk7sf2Zwoh8a56jdDZzYqa0vStONWfATZWPF57F3AU9JNmucnanaJe3lSeFT8FGgNeVKO/PeQfY/29m4CazT4BEIW9FF4WlePP5O3Rq9Tu7U2vwufK77Sloc0aWT7wmC9Ye6unXsz6ulpyotmt4pl6IecVuYQVYFxXNRbYUNdVK9WJTUFNcMPwNo0xaaY860hZNqln0vZtY5QRZuImoGb1j7Ry6AoAuj4P/YFLNC5EJyt0Qrg27VX5LGo8dk3YOWvfIBvTeyeteLPGrzV4aq5XPHWTewdXl1nUnohVJxroQo96iu/nnt7qqLop/d9NKG9A/vo1rjcz3PnDQ312u7MSvdKiuzn/+pOrINwIESwawGjjMD+5n2QU/KbU9e3qSmWaVQfu03v33ah/MW6O1uoMJ49aWzR03QjDU8UWvvnkYHqecxXklb+NVIFCq/5LagcsVJOaLdXWDEpSoOzbec3R7CWMhKaywq3eMOP+2kkfwutdGc33QUeE+sCDtMU49awEVU+H8Dh+eAJDm2NMSuXs2raNT+CpwHIcBVQ3+5bEfcfIMheyIB0rlxJhVEP1EzsnuaQ7k01yvShzgOFzwrIZZzmtE5ZzMl7dJvaTBDPWyrsbtDIaA9KBTS0daE8PkAlEpPoPziGLmndFvAzTZXulpcDNTeeNYZMfuhdzxYyeEsSjYdR/QOyifGJ9OeNy0Y3CRhP4cwLIipl+BLeBFY6dJooQarRUE/7bf6Mf0G5XisQ3j2/xVYRZD1Mg56pgN1oD/8t+adctBmljLqPsd5GD+OPNKHZ3nvUvW/EBLj0bwy6866D8fcA3xVBl2/xSNrrozDmtsBOYFhVN5xFb1uU9KcDsv9XJPcOXjqygqVdSEE9YphKXiBjidsf3BzxAvnkYh9qMaQuCgLim9Q/pp1czv1LeSRIWNqIMg89kr6con3EgSKW4wMeCr9zZO6pJbEwXtN0PwThls0I1c2XsP8XCDzbSVqVD1IuL9aN9JjxxL5auEyw3SRCH4Kdk4729HjOq5gj+2ih4pHvW89itHJwOxgW+AvP4EgQR/TltEi2xRnoNMmN8z6HzAn1cmODcrckkomZAaNdWIV2VRppnKO0JK0aSmfzR+cPI6T+a/NHl1n/1Y/MGU8ICKZBHlDV9PIFkpfy33Iwo1u+ZU7Se16ctGVHqamrArqKoWkNvsJE5yoqioOWydmWz+mi8qamZ9YlRCCPTUiKUUeuoP6/SK17FnfQfyslCfBZ1CnXGI7okd/iRkoTzFi7pRoCHnt+RpVDyTwLRv9rqBvZ7t3U68VXluA60sxyqw0I9bODKuCs0fzOO94D1Gn1hjwXHEgAyVH8pmFb/Iz3Ut4HSJQODU8tG0ycqLDqcCqTnnPfH+Bz6CeeSzEfCPgKPAD0PHXIiDT/YPQrOfRKlFSIG+GtMKVFNF7llWSbxU27XDJ8ydBoder7zpQvfQ1U/7olelt5Rov/mai5ppnM8DnGVPBoXndm9n5TTVTBYHBLJqkPyGids5YyJo1RwnNDja3cbqU859fuvrMIWRrVewQoOh/0IJ6y2+E= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: f11bf062-e223-4200-a3c3-08da3d79f51e X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:44.1776 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: tTJRVPkKc0rQVaFd0HDt1/0CW9dpMK6UuWZ+OHPp2NKUb++j3jGTVWBkZnbPX1wjssrA8hxd+NBMNwUItH69Xw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rx.c | 1845 +++++++++++++++++++++++++ 1 file changed, 1845 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rx.c diff --git a/drivers/net/wireless/celeno/cl8k/rx.c b/drivers/net/wireless/celeno/cl8k/rx.c new file mode 100644 index 000000000000..b10c9b80fc06 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rx.c @@ -0,0 +1,1845 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include + +#include "tx.h" +#include "stats.h" +#include "rates.h" +#include "vns.h" +#include "dfs.h" +#include "recovery.h" +#include "def.h" +#include "mac80211.h" +#include "reg/reg_defs.h" +#include "key.h" +#include "utils.h" +#include "radio.h" +#include "vif.h" +#include "rx.h" + +/* Must correspond to FW definition of MM_SEC_DEFAULT_KEY_COUNT */ +#define MM_SEC_DEFAULT_KEY_COUNT 64 + +#define VHT_MCS_MASK 0x0F +#define VHT_MCS_OFT 0 + +/* Number of entries in HW legacy rate conversion table */ +#define LEGACY_RATE_MAX 16 +#define KSR_MGTK_BCAST_OFFSET 31 +#define KSR_BLOCK_SIZE 4 + +static const s8 legacy_rates_lut[LEGACY_RATE_MAX] = { + 0, /* 0: 1 Mbps */ + 1, /* 1: 2 Mbps */ + 2, /* 2: 5.5 Mbps */ + 3, /* 3: 11 Mbps */ + -1, /* 4: Invalid */ + -1, /* 5: Invalid */ + -1, /* 6: Invalid */ + -1, /* 7: Invalid */ + 10, /* 8: 48 Mbps */ + 8, /* 9: 24 Mbps */ + 6, /* 10: 12 Mbps */ + 4, /* 11: 6 Mbps */ + 11, /* 12: 54 Mbps */ + 9, /* 13: 36 Mbps */ + 7, /* 14: 18 Mbps */ + 5 /* 15: 9 Mbps */ +}; + +/* + * rx_skb_cnt is an atomic counter that tracks the total number of skbs in + * the entire host. + * The counter is incremented when skb is allocated, and freed when the skb + * is freed (=destructor function called). + * Therefore the counter is global (and not part of cl_hw or cl_chip). + * + * rx_skb_max is the configured to: + * max(chip0->conf->ci_rx_skb_max, chip1->conf->ci_rx_skb_max) + */ +static atomic_t rx_skb_cnt = ATOMIC_INIT(0); +static u32 rx_skb_max; + +static void cl_rx_skb_destructor(struct sk_buff *skb) +{ + atomic_dec(&rx_skb_cnt); +} + +static void cl_rx_skb_success(struct cl_vif *cl_vif, struct ieee80211_hdr *hdr, + u32 rx_packets, u32 rx_bytes) +{ + if (cl_vif) { + u8 ac = cl_rx_get_skb_ac(hdr); + + cl_vif->trfc_cntrs[ac].rx_packets += rx_packets; + cl_vif->trfc_cntrs[ac].rx_bytes += rx_bytes; + } +} + +static DEFINE_PER_CPU(struct tasklet_struct, rx_remote_tasklet_mac[TCV_TOTAL]); + +static call_single_data_t csd_rx_remote_cpu_mac[TCV_TOTAL]; +static void cl_rx_remote_cpu_mac(struct cl_hw *cl_hw) +{ + int cpu = cl_hw->conf->ci_rx_remote_cpu_mac; + struct tasklet_struct *t = csd_rx_remote_cpu_mac[cl_hw->idx].info; + + if (!test_bit(TASKLET_STATE_SCHED, &t->state)) + smp_call_function_single_async(cpu, &csd_rx_remote_cpu_mac[cl_hw->idx]); +} + +static int cl_rx_check_err(struct cl_hw *cl_hw, struct sk_buff *skb, struct hw_rxhdr *rxhdr) +{ + u32 status; + + if (rxhdr->frm_successful_rx) + return 0; + + /* The status field is in offset of 14 u32's */ + status = *((u32 *)rxhdr + 14); + + /* Ignore phy errors and do not drop the packet */ + if (rxhdr->phy_err) { + cl_hw->radio_stats[CL_RADIO_PHY_ERROR]++; + cl_dbg_warn(cl_hw, "phy_err (status 0x%x)\n", status); + return 0; + } + + /* From this point and on, drop the erroneous packets */ + if (rxhdr->fcs_err) { + cl_hw->radio_stats[CL_RADIO_FCS_ERROR]++; + cl_dbg_err(cl_hw, "fcs_err (status 0x%x)\n", status); + } + + if (rxhdr->rx_fifo_oflow) { + cl_hw->radio_stats[CL_RADIO_RX_FIFO_OVERFLOW]++; + cl_dbg_err(cl_hw, "rx_fifo_oflow (status 0x%x)\n", status); + } + + if (rxhdr->undef_err) { + cl_hw->radio_stats[CL_RADIO_UNDEFINED_ERROR]++; + cl_dbg_err(cl_hw, "undef_err (status 0x%x)\n", status); + } + + if (rxhdr->addr_mismatch) { + cl_hw->radio_stats[CL_RADIO_ADDRESS_MISMATCH]++; + cl_dbg_err(cl_hw, "addr_mismatch (status 0x%x)\n", status); + } + + if (rxhdr->amsdu_present && rxhdr->msdu_cnt > 1) + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, RX_AMSDU_ERR_NOT_SUCCESS); + + cl_hw->rx_info.pkt_drop_not_success++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); + + return -EBADMSG; +} + +static u8 chnl_bw_to_rate_info_bw[CHNL_BW_MAX] = { + [CHNL_BW_20] = RATE_INFO_BW_20, + [CHNL_BW_40] = RATE_INFO_BW_40, + [CHNL_BW_80] = RATE_INFO_BW_80, + [CHNL_BW_160] = RATE_INFO_BW_160, +}; + +static u8 chnl_bw_factor[CHNL_BW_MAX] = { + [CHNL_BW_20] = 0, + [CHNL_BW_40] = 3, + [CHNL_BW_80] = 6, + [CHNL_BW_160] = 9, +}; + +static int cl_rx_fill_status(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb, + struct hw_rxhdr *rxhdr, u8 *encrypt_len) +{ + s8 rssi[MAX_ANTENNAS] = RX_HDR_RSSI(rxhdr); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + u8 tid = ieee80211_get_tid(hdr); + + memset(status, 0, sizeof(struct ieee80211_rx_status)); + + status->mactime = ((u64)le32_to_cpu((rxhdr->tsf_hi)) << 32) | le32_to_cpu(rxhdr->tsf_lo); + status->flag |= RX_FLAG_MACTIME_END; + + if (cl_sta && cl_sta->tid_agg_rx[tid]) + status->flag |= RX_FLAG_DUP_VALIDATED; + + status->antenna = rxhdr->antenna_set; + status->band = cl_band_from_fw_idx(rxhdr->phy_band); + + if (rxhdr->format_mod >= FORMATMOD_HE_SU) { + status->encoding = RX_ENC_HE; + status->rate_idx = (rxhdr->mcs & VHT_MCS_MASK) >> VHT_MCS_OFT; + status->nss = rxhdr->n_sts + 1; + + /* he_gi expectes to get values according to enum nl80211_he_gi */ + status->he_gi = cl_convert_gi_format_wrs_to_fw(WRS_MODE_HE, rxhdr->gi_type); + } else if (rxhdr->format_mod == FORMATMOD_VHT) { + status->encoding = RX_ENC_VHT; + status->rate_idx = (rxhdr->mcs & VHT_MCS_MASK) >> VHT_MCS_OFT; + status->nss = rxhdr->n_sts + 1; + + if (rxhdr->gi_type) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + } else if (rxhdr->format_mod == FORMATMOD_HT_GF) { + status->encoding = RX_ENC_HT; + status->enc_flags |= RX_ENC_FLAG_HT_GF; + status->rate_idx = rxhdr->mcs; + + if (rxhdr->gi_type) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + } else if (rxhdr->format_mod == FORMATMOD_HT_MF) { + status->encoding = RX_ENC_HT; + status->rate_idx = rxhdr->mcs; + + if (rxhdr->gi_type) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + } else { + if (legacy_rates_lut[rxhdr->leg_rate] != -1) + status->rate_idx = legacy_rates_lut[rxhdr->leg_rate]; + if (status->band != NL80211_BAND_2GHZ) + status->rate_idx -= RATE_CTRL_OFFSET_OFDM; + if (!rxhdr->pre_type) + status->enc_flags |= RX_ENC_FLAG_SHORTPRE; + } + + if (rxhdr->aggregation) { + status->flag |= RX_FLAG_AMPDU_DETAILS; + status->ampdu_reference = rxhdr->ampdu_cnt; + } + + /* + * Set bw field + */ + if (rxhdr->ru_type) { + status->bw = RATE_INFO_BW_HE_RU; + + if (rxhdr->ru_type == CL_MU_OFDMA_RU_TYPE_26) + cl_rssi_bw_adjust(cl_hw, rxhdr, -9); + else if (rxhdr->ru_type == CL_MU_OFDMA_RU_TYPE_52) + cl_rssi_bw_adjust(cl_hw, rxhdr, -6); + else if (rxhdr->ru_type == CL_MU_OFDMA_RU_TYPE_106) + cl_rssi_bw_adjust(cl_hw, rxhdr, -3); + + status->he_ru = cl_ru_type_to_nl80211_he_ru_alloc(rxhdr->ru_type); + } else { + u8 factor = chnl_bw_factor[rxhdr->ch_bw]; + + status->bw = chnl_bw_to_rate_info_bw[rxhdr->ch_bw]; + cl_rssi_bw_adjust(cl_hw, rxhdr, factor); + } + + /* + * TODO: check if when a frame is received on 40MHz or more bandwidth, + * we need to take the center1_freq instead of the prim20_freq + */ + status->freq = Q2_TO_FREQ(rxhdr->phy_prim20_freq); + + status->signal = cl_rssi_calc_equivalent(cl_hw, rssi); + + switch (rxhdr->decr_status) { + case CL_RX_HDR_DECR_UNENC: + if (!ieee80211_has_protected(hdr->frame_control)) + break; + + cl_dbg_warn(cl_hw, "Protected frame unencrypted\n"); + cl_hw->rx_info.pkt_drop_unencrypted++; + if (rxhdr->amsdu_present && rxhdr->msdu_cnt > 1) + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, + RX_AMSDU_ERR_UNENCRYPTED); + return -EBADMSG; + case CL_RX_HDR_DECR_ICVFAIL: + case CL_RX_HDR_DECR_AMSDUDISCARD: + case CL_RX_HDR_DECR_NULLKEY: + case CL_RX_HDR_DECR_CCMPFAIL: + cl_dbg_warn(cl_hw, "Decryption failed (%u)\n", rxhdr->decr_status); + cl_hw->rx_info.pkt_drop_decrypt_fail++; + *encrypt_len = 0; + if (rxhdr->amsdu_present && rxhdr->msdu_cnt > 1) + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, RX_AMSDU_ERR_DECRYPT_FAIL); + return -EBADMSG; + case CL_RX_HDR_DECR_WEPSUCCESS: + case CL_RX_HDR_DECR_TKIPSUCCESS: + *encrypt_len = IEEE80211_WEP_ICV_LEN; + status->flag |= (RX_FLAG_DECRYPTED | RX_FLAG_ICV_STRIPPED); + break; + case CL_RX_HDR_DECR_CCMPSUCCESS: + *encrypt_len = IEEE80211_CCMP_HDR_LEN; + status->flag |= (RX_FLAG_DECRYPTED | RX_FLAG_MIC_STRIPPED); + break; + } + + return 0; +} + +static void cl_rx_handle_mesh_reconnect(struct cl_hw *cl_hw, + struct ieee80211_mgmt *mgmt, struct cl_sta *cl_sta) +{ + struct ieee80211_sta *sta = cl_sta->sta; + struct cl_tx_queue *tx_queue; + u8 action_code = mgmt->u.action.u.self_prot.action_code; + u8 i; + + if (action_code == WLAN_SP_MESH_PEERING_CONFIRM) { + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + tx_queue = cl_sta->agg_tx_queues[i]; + + if (tx_queue) + ieee80211_stop_tx_ba_session(sta, i); + } + } +} + +static void cl_rx_action_frame_handler(struct cl_hw *cl_hw, struct cl_ieee80211_mgmt *mgmt, + int len, struct cl_sta *cl_sta) +{ + /* Verify action code is present */ + if (len < IEEE80211_MIN_ACTION_SIZE + 1) + return; + + switch (mgmt->u.action.category) { + case WLAN_CATEGORY_WNM: + break; + case WLAN_CATEGORY_SELF_PROTECTED: + if (cl_sta && cl_sta->cl_vif->vif->type == NL80211_IFTYPE_MESH_POINT) + cl_rx_handle_mesh_reconnect(cl_hw, (struct ieee80211_mgmt *)mgmt, cl_sta); + break; + default: + break; + } +} + +static struct ieee80211_he_6ghz_oper * +cl_rx_get_he_6ghz_oper(const struct ieee80211_he_operation *he_oper) +{ + const u8 *ret = (void *)&he_oper->optional; + u32 he_oper_params; + + he_oper_params = le32_to_cpu(he_oper->he_oper_params); + + if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)) + return NULL; + if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO) + ret += 3; + if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) + ret++; + + return (void *)ret; +} + +static void +cl_rx_check_he_minrate_change(struct cl_sta *cl_sta, + const struct ieee80211_he_operation *he_oper) +{ + struct ieee80211_he_6ghz_oper * + he_6ghz_oper = cl_rx_get_he_6ghz_oper(he_oper); + + if (!he_6ghz_oper) + return; + + if (he_6ghz_oper->minrate != cl_sta->wrs_sta.he_minrate) + cl_wrs_api_he_minrate_changed(cl_sta, he_6ghz_oper->minrate); +} + +static void cl_rx_handle_beacon(struct cl_hw *cl_hw, + struct sk_buff *skb, + struct cl_sta *cl_sta) +{ + struct ieee802_11_elems elems; + struct cl_vif *cl_vif = cl_sta->cl_vif; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + size_t baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); + struct ieee80211_bss_conf *bss_conf = &cl_vif->vif->bss_conf; + + if (cl_vif->vif->type != NL80211_IFTYPE_STATION) + return; + + cl_ieee802_11_parse_elems(mgmt->u.beacon.variable, skb->len - baselen, &elems); + + if (!elems.parse_error && elems.he_operation && bss_conf->he_support) + cl_rx_check_he_minrate_change(cl_sta, elems.he_operation); +} + +static bool cl_rx_mgmt_check(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_vif *cl_vif, struct cl_sta *cl_sta, + struct hw_rxhdr *rxhdr) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + __le16 fc = mgmt->frame_control; + + if (!ieee80211_is_mgmt(fc)) + return true; + + if (cl_sta) { + if (ieee80211_is_beacon(fc)) + cl_rx_handle_beacon(cl_hw, skb, cl_sta); + else if (ieee80211_is_action(fc)) + cl_rx_action_frame_handler(cl_hw, (struct cl_ieee80211_mgmt *)mgmt, + skb->len, cl_sta); + } else { + s8 rssi[MAX_ANTENNAS] = RX_HDR_RSSI(rxhdr); + + cl_vns_mgmt_handler(cl_hw, mgmt->sa, rssi); + + if (ieee80211_is_assoc_req(fc) || ieee80211_is_assoc_resp(fc)) { + cl_rssi_assoc_handle(cl_hw, mgmt->sa, rxhdr); + return true; + } + } + + return true; +} + +static void cl_rx_data_check(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_sta *cl_sta, u32 packet_len, struct hw_rxhdr *rxhdr) +{ + if (cl_sta) { + cl_traffic_rx_handler(cl_hw, cl_sta, packet_len); + + if (!rxhdr->aggregation || (rxhdr->aggregation && rxhdr->mpdu_cnt == 0)) + cl_motion_sense_rssi_data(cl_hw, cl_sta, rxhdr); + } +} + +static bool cl_rx_skb_done(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_sta *cl_sta, struct hw_rxhdr *rxhdr) +{ + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + struct cl_vif *cl_vif = NULL; + + /* Update trigger base statistics */ + cl_fw_dbg_trigger_based_update(cl_hw, rxhdr, hdr); + cl_fw_dbg_trigger_based_sta_update(cl_hw, rxhdr, hdr); + + if (cl_sta) { + cl_vif = cl_sta->cl_vif; + skb->dev = cl_vif->dev; + + cl_stats_update_rx_rate(cl_hw, cl_sta, rxhdr); + + if (!rxhdr->aggregation || (rxhdr->aggregation && rxhdr->mpdu_cnt == 0)) + cl_rssi_rx_handler(cl_hw, cl_sta, rxhdr, status->signal); + } else { + cl_vif = cl_vif_get_by_mac(cl_hw, hdr->addr3); + skb->dev = cl_vif ? cl_vif->dev : NULL; + + if (cl_hw_is_prod_or_listener(cl_hw)) + cl_stats_update_rx_rate_production(cl_hw, rxhdr); + } + + /* DATA */ + if (ieee80211_is_data(fc)) { + cl_wrs_update_rx_rate(cl_hw, cl_sta, rxhdr); + cl_rx_data_check(cl_hw, skb, cl_sta, skb->len, rxhdr); + goto out; + } + + /* MGMT/CTL */ + if (cl_sta) + cl_motion_sense_rssi_mgmt_ctl(cl_hw, cl_sta, rxhdr); + + /* MGMT */ + if (!cl_rx_mgmt_check(cl_hw, skb, cl_vif, cl_sta, rxhdr)) + return false; + +out: + if (rx_skb_max && + atomic_read(&rx_skb_cnt) >= rx_skb_max) { + cl_hw->rx_info.pkt_drop_host_limit++; + cl_rx_skb_drop(cl_hw, skb, 1); + kfree_skb(skb); + return false; + } + + cl_rx_skb_success(cl_vif, hdr, 1, skb->len); + + return true; +} + +static void cl_rx_pass_to_mac(struct cl_hw *cl_hw, + struct ieee80211_sta *sta, + struct sk_buff_head *frames) +{ + if (cl_hw->conf->ci_rx_remote_cpu_mac == -1) { + struct sk_buff *skb = NULL; + + while ((skb = __skb_dequeue(frames))) + ieee80211_rx_napi(cl_hw->hw, sta, skb, NULL); + } else { + struct sk_buff_head *rx_remote_queue_mac = &cl_hw->rx_remote_queue_mac; + + spin_lock(&rx_remote_queue_mac->lock); + skb_queue_splice_tail_init(frames, rx_remote_queue_mac); + spin_unlock(&rx_remote_queue_mac->lock); + + cl_rx_remote_cpu_mac(cl_hw); + } +} + +static void cl_rx_amsdu_done_reorder(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff_head *frames) +{ + struct sk_buff *skb = NULL; + struct sk_buff_head reorder_buf; + + /* Init the reorder buffer */ + __skb_queue_head_init(&reorder_buf); + + while ((skb = __skb_dequeue(frames))) + cl_rx_reorder_ampdu(cl_hw, cl_sta, skb, &reorder_buf); + + if (!skb_queue_empty(&reorder_buf)) + cl_rx_pass_to_mac(cl_hw, cl_sta->sta, &reorder_buf); +} + +static void cl_rx_amsdu_done(struct cl_hw *cl_hw, struct cl_amsdu_rx_state *amsdu_rx_state) +{ + struct sk_buff_head *frames = &amsdu_rx_state->frames; + struct sk_buff *skb = __skb_peek(frames); + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct cl_sta *cl_sta; + struct cl_vif *cl_vif; + struct hw_rxhdr *rxhdr = amsdu_rx_state->rxhdr; + u32 packet_len = amsdu_rx_state->packet_len; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_sta *sta; + + if (cl_rx_amsdu_check_aggregation_attack(amsdu_rx_state)) { + cl_hw->rx_info.pkt_drop_amsdu_inj_attack += amsdu_rx_state->msdu_cnt; + __skb_queue_purge(frames); + return; + } + + /* START - cl_sta protected block */ + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, amsdu_rx_state->sta_idx); + + if (!cl_sta) { + cl_sta_unlock(cl_hw); + cl_hw->rx_info.pkt_drop_sta_null += amsdu_rx_state->msdu_cnt; + __skb_queue_purge(frames); + return; + } + + sta = cl_sta->sta; + cl_vif = cl_sta->cl_vif; + skb->dev = cl_vif->dev; + + cl_rx_data_check(cl_hw, skb, cl_sta, packet_len, rxhdr); + cl_stats_update_rx_rate(cl_hw, cl_sta, rxhdr); + cl_wrs_update_rx_rate(cl_hw, cl_sta, rxhdr); + + if (!rxhdr->aggregation || (rxhdr->aggregation && rxhdr->mpdu_cnt == 0)) + cl_rssi_rx_handler(cl_hw, cl_sta, rxhdr, status->signal); + + cl_sta_unlock(cl_hw); + /* END - cl_sta protected block */ + + if (rx_skb_max && + (atomic_read(&rx_skb_cnt) + amsdu_rx_state->msdu_cnt) >= rx_skb_max) { + cl_hw->rx_info.pkt_drop_host_limit += amsdu_rx_state->msdu_cnt; + cl_rx_skb_drop(cl_hw, skb, amsdu_rx_state->msdu_cnt); + __skb_queue_purge(frames); + return; + } + + cl_rx_skb_success(cl_vif, hdr, rxhdr->msdu_cnt, packet_len); + + if (cl_sta->tid_agg_rx[amsdu_rx_state->tid]) + cl_rx_amsdu_done_reorder(cl_hw, cl_sta, frames); + else + cl_rx_pass_to_mac(cl_hw, sta, frames); +} + +static void cl_rx_invalid_tailroom(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr, + struct sk_buff *skb, u32 len) +{ + cl_dbg_err(cl_hw, "Invalid RX header length - tailroom=%d, len=%u\n", + skb_tailroom(skb), len); + + if (rxhdr->amsdu_present && rxhdr->msdu_cnt > 1) + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, RX_AMSDU_ERR_INVALID_TAILROOM); + + cl_hw->rx_info.pkt_drop_tailroom_error++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +static void cl_rx_invalid_pattern(struct cl_hw *cl_hw, struct sk_buff *skb, u32 pattern) +{ + cl_dbg_err(cl_hw, "WRONG PATTERN - 0x%x\n", pattern); + cl_hw->rx_info.pkt_drop_wrong_pattern++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +static int cl_rx_get_sta_idx(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr) +{ + int sta_idx = rxhdr->key_sram_index - MM_SEC_DEFAULT_KEY_COUNT; + u8 vif_type; + + if (sta_idx < 0) { + vif_type = cl_hw_get_iface_conf(cl_hw); + if (vif_type == CL_IFCONF_MESH_AP || vif_type == CL_IFCONF_MESH_ONLY) { + sta_idx += KSR_MGTK_BCAST_OFFSET; + sta_idx /= KSR_BLOCK_SIZE; + } + } + + if (sta_idx >= 0 && sta_idx < CL_MAX_NUM_STA) + return sta_idx; + + cl_dbg_err(cl_hw, "invalid sta_idx %d, key_sram_index=%d\n", + sta_idx, rxhdr->key_sram_index); + + return -EINVAL; +} + +static void cl_rx_handle_first_amsdu(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_amsdu_rx_state *amsdu_rx_state, + struct hw_rxhdr *rxhdr, u8 sta_idx, u8 tid, u8 encrypt_len) +{ + /* + * First MSDU recived frame: + * ------------------------------------------ + * || WLAN_HDR || MSDU HDR || MSDU PAYLOAD || + * ------------------------------------------ + */ + cl_rx_amsdu_stats(cl_hw, rxhdr->msdu_cnt); + + if (rxhdr->corrupted_amsdu) { + cl_rx_amsdu_first_corrupted(cl_hw, skb, rxhdr); + } else { + cl_rx_amsdu_first(cl_hw, skb, rxhdr, sta_idx, tid, encrypt_len); + + /* If there are more MSDU's, hold on with the update + * to the upper layer until A-MSDU is complete + */ + if (amsdu_rx_state->msdu_remaining_cnt == 0) + cl_rx_amsdu_done(cl_hw, amsdu_rx_state); + } +} + +static void cl_rx_handle_sub_amsdu(struct cl_hw *cl_hw, struct sk_buff *skb, + struct cl_amsdu_rx_state *amsdu_rx_state) +{ + /* Update the remaining MSDU counter */ + amsdu_rx_state->msdu_remaining_cnt--; + + /* Free MSDU with error */ + if (amsdu_rx_state->amsdu_error) { + cl_rx_amsdu_sub_error(cl_hw, skb); + return; + } + + /* Add the sub-MSDU to the existing ones */ + if (!cl_rx_amsdu_sub(cl_hw, skb)) + return; + + /* This is the last MSDU, A-MSDU is complete, push to upper layer */ + if (amsdu_rx_state->msdu_remaining_cnt == 0) + cl_rx_amsdu_done(cl_hw, amsdu_rx_state); +} + +static void cl_rx_handle_ps(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + struct ieee80211_sta *sta = cl_sta->sta; + bool is_ps; + __le16 fc = hdr->frame_control; + + if (ieee80211_is_pspoll(fc) || + ieee80211_has_morefrags(fc) || + !(ieee80211_is_mgmt(fc) || + ieee80211_is_data(fc))) + return; + + is_ps = ieee80211_has_pm(hdr->frame_control); + + cl_sta_ps_notify(cl_hw, cl_sta, is_ps); + ieee80211_sta_ps_transition(sta, is_ps); +} + +static void cl_rx_shift_rxhdr_rssi_values(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr) +{ + /* Fill in the rxhdr rssi "holes" so that values will start from rssi1 */ + switch (cl_hw->first_riu_chain) { + case 1: + rxhdr->rssi1 = rxhdr->rssi2; + rxhdr->rssi2 = rxhdr->rssi3; + rxhdr->rssi3 = rxhdr->rssi4; + rxhdr->rssi4 = rxhdr->rssi5; + rxhdr->rssi5 = rxhdr->rssi6; + break; + case 2: + rxhdr->rssi1 = rxhdr->rssi3; + rxhdr->rssi2 = rxhdr->rssi4; + rxhdr->rssi3 = rxhdr->rssi5; + rxhdr->rssi4 = rxhdr->rssi6; + break; + case 3: + rxhdr->rssi1 = rxhdr->rssi4; + rxhdr->rssi2 = rxhdr->rssi5; + rxhdr->rssi3 = rxhdr->rssi6; + break; + case 4: + rxhdr->rssi1 = rxhdr->rssi5; + rxhdr->rssi2 = rxhdr->rssi6; + break; + case 5: + rxhdr->rssi1 = rxhdr->rssi6; + break; + default: + break; + } +} + +static void cl_rx_handle_skb(struct cl_hw *cl_hw, struct sk_buff *skb) +{ + u8 encrypt_len = 0; + u8 tid = 0; + u32 mpdu_offset = 0; + u32 len = 0; + int sta_idx = -1; + bool skb_done = false; + struct cl_sta *cl_sta = NULL; + struct ieee80211_sta *sta = NULL; + struct hw_rxhdr *rxhdr = NULL; + struct cl_tid_ampdu_rx *tid_agg_rx = NULL; + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + s8 remote_cpu_mac = cl_hw->conf->ci_rx_remote_cpu_mac; + + if (amsdu_rx_state->msdu_remaining_cnt > 0) { + cl_rx_handle_sub_amsdu(cl_hw, skb, amsdu_rx_state); + return; + } + + rxhdr = (struct hw_rxhdr *)skb->data; + mpdu_offset = sizeof(struct hw_rxhdr); + + if (rxhdr->rx_padding_done) + mpdu_offset += CL_PADDING_IN_BYTES; + + /* Pull the HW RX header */ + skb_reserve(skb, mpdu_offset); + + /* + * Sanity check - the embedded layer is responsible to validate the pattern correctness. + * If pattern is invalid then it is likely that the embedded layer did some thing wrong. + */ + if (le32_to_cpu(rxhdr->pattern) != IPC_RX_DMA_OVER_PATTERN) { + cl_rx_invalid_pattern(cl_hw, skb, le32_to_cpu(rxhdr->pattern)); + return; + } + + if (cl_rx_check_err(cl_hw, skb, rxhdr)) + return; + + /* Convert gi from firmware format to driver format */ + rxhdr->gi_type = cl_convert_gi_format_fw_to_wrs(rxhdr->format_mod, rxhdr->gi_type); + + if (cl_hw->first_riu_chain > 0) + cl_rx_shift_rxhdr_rssi_values(cl_hw, rxhdr); + + if (cl_hw->rssi_simulate) + cl_rssi_simulate(cl_hw, rxhdr); + + if (rxhdr->key_sram_v) + sta_idx = cl_rx_get_sta_idx(cl_hw, rxhdr); + + cl_sta_lock(cl_hw); + + if (sta_idx != -1) { + cl_sta = cl_sta_get(cl_hw, sta_idx); + + if (cl_sta) { + sta = cl_sta->sta; + + if (cl_hw->conf->ci_fast_rx_en) { + tid = ieee80211_get_tid((struct ieee80211_hdr *)skb->data); + tid_agg_rx = cl_sta->tid_agg_rx[tid]; + cl_rx_handle_ps(cl_hw, cl_sta, skb); + } + + /* Store the pointer to sta in the skb->sk field */ + if (remote_cpu_mac != -1) + skb->sk = (struct sock *)sta; + } + } + + if (unlikely(cl_rx_fill_status(cl_hw, cl_sta, skb, rxhdr, &encrypt_len))) { + cl_sta_unlock(cl_hw); + cl_rx_skb_error(cl_hw); + kfree_skb(skb); + return; + } + + /* Is A-MSDU frame? */ + if (rxhdr->amsdu_present) { + cl_rx_handle_first_amsdu(cl_hw, skb, amsdu_rx_state, rxhdr, sta_idx, + tid, encrypt_len); + cl_sta_unlock(cl_hw); + return; + } + + len = rxhdr->len; + + if (skb_tailroom(skb) >= len) { + /* Push the WLAN HDR + MDPU payload to the skb data */ + skb_put(skb, len); + cl_hw->rx_info.non_amsdu++; + } else { + cl_sta_unlock(cl_hw); + cl_rx_invalid_tailroom(cl_hw, rxhdr, skb, len); + return; + } + + skb_done = cl_rx_skb_done(cl_hw, skb, cl_sta, rxhdr); + + cl_sta_unlock(cl_hw); + + if (!skb_done) + return; + + if (tid_agg_rx) { + struct sk_buff_head reorder_buf; + + /* Init the reorder buffer */ + __skb_queue_head_init(&reorder_buf); + cl_rx_reorder_ampdu(cl_hw, cl_sta, skb, &reorder_buf); + + if (!skb_queue_empty(&reorder_buf)) + cl_rx_pass_to_mac(cl_hw, sta, &reorder_buf); + } else { + if (cl_key_handle_pn_validation(cl_hw, skb, cl_sta) == CL_PN_VALID_STATE_FAILED) { + kfree_skb(skb); + return; + } + + if (remote_cpu_mac == -1) { + ieee80211_rx_napi(cl_hw->hw, sta, skb, NULL); + } else { + skb_queue_tail(&cl_hw->rx_remote_queue_mac, skb); + cl_rx_remote_cpu_mac(cl_hw); + } + } +} + +static bool cl_is_rx_allowed(struct cl_hw *cl_hw) +{ + return !(cl_radio_is_off(cl_hw) || + !test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags) || + cl_recovery_in_progress(cl_hw)); +} + +static void cl_rx_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct sk_buff *skb = NULL; + u16 pkt_cnt = 0; + + if (unlikely(!cl_is_rx_allowed(cl_hw))) + return; + + while ((skb = skb_dequeue(&cl_hw->rx_skb_queue))) { + cl_rx_handle_skb(cl_hw, skb); + + if (++pkt_cnt > cl_hw->conf->ce_rx_pkts_budget) { + if (cl_hw->chip->conf->ci_rx_resched_tasklet) + tasklet_schedule(&cl_hw->rx_resched_tasklet); + else + tasklet_schedule(&cl_hw->rx_tasklet); + + cl_hw->rx_info.exceed_pkt_budget++; + return; + } + } +} + +static void cl_rx_resched_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + + tasklet_schedule(&cl_hw->rx_tasklet); +} + +static void cl_rx_remote_tasklet_mac(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct sk_buff *skb = NULL; + struct ieee80211_sta *sta; + + if (unlikely(!cl_is_rx_allowed(cl_hw))) + return; + + cl_rx_remote_cpu_info(cl_hw); + + while ((skb = skb_dequeue(&cl_hw->rx_remote_queue_mac))) { + /* + * Get sta pointer from skb->sk (stored their in cl_rx_remote_cpu_mac) + * and reset skb->sk. + */ + sta = (struct ieee80211_sta *)skb->sk; + skb->sk = NULL; + + ieee80211_rx_napi(cl_hw->hw, sta, skb, NULL); + } +} + +void cl_rx_init(struct cl_hw *cl_hw) +{ + s8 cpu_mac = cl_hw->conf->ci_rx_remote_cpu_mac; + + /* Set rx_skb_max to be the maximum of ci_rx_skb_max configured for each chip */ + rx_skb_max = max(cl_hw->chip->conf->ci_rx_skb_max, rx_skb_max); + + skb_queue_head_init(&cl_hw->rx_remote_queue_mac); + skb_queue_head_init(&cl_hw->rx_skb_queue); + __skb_queue_head_init(&cl_hw->amsdu_rx_state.frames); + + tasklet_init(&cl_hw->rx_tasklet, cl_rx_tasklet, (unsigned long)cl_hw); + tasklet_init(&cl_hw->rx_resched_tasklet, cl_rx_resched_tasklet, (unsigned long)cl_hw); + + if (cpu_mac >= 0) { + struct tasklet_struct *t = &per_cpu(rx_remote_tasklet_mac[cl_hw->idx], cpu_mac); + + tasklet_init(t, + cl_rx_remote_tasklet_mac, + (unsigned long)cl_hw); + + csd_rx_remote_cpu_mac[cl_hw->idx].func = cl_rx_remote_tasklet_sched; + csd_rx_remote_cpu_mac[cl_hw->idx].info = t; + } + cl_rx_pci_init(cl_hw); +} + +void cl_rx_off(struct cl_hw *cl_hw) +{ + s8 cpu_mac = cl_hw->conf->ci_rx_remote_cpu_mac; + + if (cpu_mac >= 0) + tasklet_kill(&per_cpu(rx_remote_tasklet_mac[cl_hw->idx], cpu_mac)); + + tasklet_kill(&cl_hw->rx_tasklet); + tasklet_kill(&cl_hw->rx_resched_tasklet); + + skb_queue_purge(&cl_hw->rx_remote_queue_mac); + skb_queue_purge(&cl_hw->rx_skb_queue); + + cl_rx_amsdu_reset(cl_hw); + cl_rx_pci_deinit(cl_hw); +} + +void cl_rx_remote_tasklet_sched(void *t) +{ + tasklet_schedule((struct tasklet_struct *)t); +} + +void cl_rx_remote_cpu_info(struct cl_hw *cl_hw) +{ + u32 processor_id = smp_processor_id(); + + if (processor_id < CPU_MAX_NUM) + cl_hw->rx_info.remote_cpu[processor_id]++; +} + +void cl_rx_push_queue(struct cl_hw *cl_hw, struct sk_buff *skb) +{ + skb_queue_tail(&cl_hw->rx_skb_queue, skb); + tasklet_schedule(&cl_hw->rx_tasklet); +} + +void cl_rx_skb_alloc_handler(struct sk_buff *skb) +{ + skb->destructor = cl_rx_skb_destructor; + atomic_inc(&rx_skb_cnt); +} + +void cl_rx_skb_error(struct cl_hw *cl_hw) +{ + /* + * When there is an error with the received packet we can't + * know the interface and the AC. + * So just use the first interface and BE. + */ + struct cl_vif *cl_vif = cl_vif_get_first(cl_hw); + + if (!cl_vif) { + cl_dbg_err(cl_hw, "Couldn't find vif\n"); + return; + } + + cl_vif->trfc_cntrs[AC_BE].rx_errors++; +} + +void cl_rx_skb_drop(struct cl_hw *cl_hw, struct sk_buff *skb, u8 cnt) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct cl_vif *cl_vif = cl_vif_get_by_mac(cl_hw, hdr->addr3); + + if (cl_vif) { + u8 ac = cl_rx_get_skb_ac(hdr); + + cl_vif->trfc_cntrs[ac].rx_dropped += cnt; + } +} + +void cl_rx_post_recovery(struct cl_hw *cl_hw) +{ + if (!skb_queue_empty(&cl_hw->rx_skb_queue)) + tasklet_schedule(&cl_hw->rx_tasklet); + + if (!skb_queue_empty(&cl_hw->rx_remote_queue_mac)) + tasklet_schedule(&per_cpu(rx_remote_tasklet_mac[cl_hw->idx], + cl_hw->conf->ci_rx_remote_cpu_mac)); +} + +u8 cl_rx_get_skb_ac(struct ieee80211_hdr *hdr) +{ + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qos_ctl = ieee80211_get_qos_ctl(hdr); + u8 tid = *qos_ctl & IEEE80211_QOS_CTL_TAG1D_MASK; + return tid_to_ac[tid]; + } + + return AC_BE; +} + +bool cl_rx_process_in_irq(struct cl_hw *cl_hw) +{ + struct cl_ipc_ring_indices *indices = cl_hw->ipc_env->ring_indices_elem->indices; + u32 read_idx = le32_to_cpu(indices->rxdesc_read_idx[CL_RX_BUF_RXM]); + u32 write_idx = le32_to_cpu(indices->rxdesc_write_idx[CL_RX_BUF_RXM]); + u32 free_buffers = read_idx - write_idx; + + if (free_buffers < (IPC_RXBUF_CNT_RXM / 2)) { + cl_hw->rx_info.buffer_process_irq++; + return true; + } + + cl_hw->rx_info.buffer_process_tasklet++; + return false; +} + +static bool cl_agg_rx_report_is_status_valid(u8 status) +{ + if (status == MM_AGG_RX_REPORT_STAT_OK || + status == MM_AGG_RX_REPORT_STAT_COLISION_WITH_COUNTER) + return true; + + return false; +} + +static void sync_rx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct cl_wrs_info *wrs_info, + struct cl_wrs_params *wrs_params, u8 bw, u8 nss, u8 mcs, u8 gi) +{ + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + + if (bw == rate_params->bw && + nss == rate_params->nss && + mcs == rate_params->mcs && + gi == rate_params->gi) { + cl_wrs_api_rate_sync(cl_hw, cl_sta, wrs_params); + + wrs_info->synced = true; + wrs_info->quick_rate_check = true; + wrs_info->quick_rate_agg_cntr = 0; + wrs_info->quick_rate_pkt_cntr = 0; + } else { + wrs_info->sync_attempts++; + } +} + +void cl_agg_rx_report_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 sta_loc, + struct mm_agg_rx_ind *agg_report) +{ + struct cl_wrs_info *wrs_info = NULL; + struct cl_wrs_params *wrs_params = cl_sta->wrs_sta.rx_params; + u16 success_cnt = le16_to_cpu(agg_report->correct_received_mpdu_count[sta_loc]); + u16 data_rate; + u8 nss = agg_report->nss_per_user[sta_loc]; + u8 mcs = agg_report->mcs_rate[sta_loc]; + u8 gi = CL_TF_GI_LTF_TO_GI(agg_report->gi_ltf); + u8 bw; + + if (!wrs_params || + !cl_agg_rx_report_is_status_valid(agg_report->status[sta_loc])) + return; + + wrs_info = &cl_sta->wrs_info_rx; + + { + u8 ru_type = cl_ru_alloc_to_ru_type(agg_report->ru_allocation[sta_loc]); + + bw = cl_mu_ofdma_grp_convert_ru_type_to_bw(cl_hw, ru_type); + } + + /* WRS sync mechanism */ + if (!wrs_info->synced) + sync_rx_rate(cl_hw, cl_sta, wrs_info, wrs_params, bw, nss, mcs, gi); + + data_rate = cl_data_rates_get_x10(WRS_MODE_HE, bw, nss, mcs, gi); + + wrs_info->success += success_cnt; + wrs_info->fail += (le16_to_cpu(agg_report->incorrect_received_mpdu_count[sta_loc]) + + le16_to_cpu(agg_report->incorrect_delimiter_count[sta_loc])); + wrs_info->epr_acc += ((u64)success_cnt * data_rate); +} + +struct msduhdr { + u8 dest[ETH_ALEN]; + u8 source[ETH_ALEN]; + __be16 len; +} __packed; + +static void cl_rx_set_flag_amsdu_more(struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + + rx_status->flag |= RX_FLAG_AMSDU_MORE; +} + +static void cl_rx_clear_flag_amsdu_more(struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + + rx_status->flag &= ~RX_FLAG_AMSDU_MORE; +} + +static void cl_rx_add_80211_hdr(struct cl_amsdu_rx_state *amsdu_rx_state, + struct sk_buff *skb, struct sk_buff *first_skb) +{ + /* Copy the 802.11 header of the first skb */ + struct ieee80211_hdr *hdr_first = (struct ieee80211_hdr *)(first_skb->data); + u32 hdrlen_first = ieee80211_hdrlen(hdr_first->frame_control); + u32 total_bytes = hdrlen_first + amsdu_rx_state->encrypt_len; + + skb_push(skb, total_bytes); + memcpy(skb->data, first_skb->data, total_bytes); +} + +static void cl_rx_copy_status(struct cl_amsdu_rx_state *amsdu_rx_state, + struct sk_buff *skb, struct sk_buff *first_skb) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_rx_status *rx_status_first = IEEE80211_SKB_RXCB(first_skb); + + /* Copy rx_status from the first skb */ + memcpy(rx_status, rx_status_first, sizeof(struct ieee80211_rx_status)); + + /* If it is the last sub-frame clear RX_FLAG_AMSDU_MORE */ + if (amsdu_rx_state->msdu_remaining_cnt == 0) + rx_status->flag &= ~RX_FLAG_AMSDU_MORE; +} + +static void cl_rx_amsdu_set_state(struct cl_hw *cl_hw, struct sk_buff *skb, struct hw_rxhdr *rxhdr, + u8 sta_idx, u8 tid, u32 packet_len, u8 encrypt_len) +{ + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + + amsdu_rx_state->msdu_cnt = rxhdr->msdu_cnt; + amsdu_rx_state->msdu_remaining_cnt = rxhdr->msdu_cnt - 1; + amsdu_rx_state->msdu_dma_align = rxhdr->msdu_dma_align; + amsdu_rx_state->amsdu_error = 0; + amsdu_rx_state->encrypt_len = encrypt_len; + amsdu_rx_state->packet_len = packet_len; + amsdu_rx_state->rxhdr = rxhdr; + amsdu_rx_state->first_skb = skb; + amsdu_rx_state->sta_idx = sta_idx; + amsdu_rx_state->tid = tid; + + __skb_queue_head(&cl_hw->amsdu_rx_state.frames, skb); +} + +static void cl_rx_amsdu_first_length_error(struct cl_hw *cl_hw, struct sk_buff *skb, + struct hw_rxhdr *rxhdr, u32 len) +{ + cl_dbg_err(cl_hw, "RX-AMSDU length error (1/%u) - tailroom=%d, len=%u\n", + rxhdr->msdu_cnt, skb_tailroom(skb), len); + + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, RX_AMSDU_ERR_LENGTH); + + cl_hw->rx_info.pkt_drop_amsdu_len_error++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +static void cl_rx_amsdu_sub_length_error(struct cl_hw *cl_hw, struct sk_buff *skb, u32 len) +{ + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + struct sk_buff *skb_tail; + u8 sub_cnt = amsdu_rx_state->msdu_cnt - amsdu_rx_state->msdu_remaining_cnt; + + cl_dbg_err(cl_hw, "RX-AMSDU length error (%u/%u) - tailroom=%d, len=%u\n", + sub_cnt, amsdu_rx_state->msdu_cnt, skb_tailroom(skb), len); + + /* All remaining skbs in the AMSDU will be treated as errors */ + amsdu_rx_state->amsdu_error = RX_AMSDU_ERR_LENGTH; + + /* Clear RX_FLAG_AMSDU_MORE in the last success skb that was received */ + skb_tail = skb_peek_tail(&amsdu_rx_state->frames); + cl_rx_clear_flag_amsdu_more(skb_tail); + + cl_hw->rx_info.pkt_drop_sub_amsdu_len_error++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +static bool cl_rx_amsdu_is_frame_aggregation_attack(struct ieee80211_hdr *hdr, + const struct msduhdr *msdu_hdr) +{ + __le16 fc; + int to_ds; + int from_ds; + + fc = hdr->frame_control; + to_ds = ieee80211_has_tods(fc); + from_ds = ieee80211_has_fromds(fc); + + if (to_ds && memcmp(hdr->addr2, msdu_hdr->source, ETH_ALEN)) + return true; + + if (from_ds && memcmp(hdr->addr1, msdu_hdr->dest, ETH_ALEN) && + !(is_multicast_ether_addr(hdr->addr3))) + return true; + + return false; +} + +void cl_rx_amsdu_first(struct cl_hw *cl_hw, struct sk_buff *skb, + struct hw_rxhdr *rxhdr, u8 sta_idx, u8 tid, u8 encrypt_len) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u32 hdr_len = ieee80211_hdrlen(hdr->frame_control); + struct msduhdr *msdu_hdr = (struct msduhdr *)(skb->data + hdr_len + encrypt_len); + u32 packet_len = hdr_len + encrypt_len + sizeof(struct msduhdr) + ntohs(msdu_hdr->len); + + if (skb_tailroom(skb) < packet_len) { + cl_rx_amsdu_first_length_error(cl_hw, skb, rxhdr, packet_len); + return; + } + + /* Put the WLAN header + MSDU header + payload in the skb data */ + skb_put(skb, packet_len); + + cl_rx_amsdu_set_state(cl_hw, skb, rxhdr, sta_idx, tid, packet_len, encrypt_len); + + /* Must be called after cl_rx_amsdu_set_state() */ + if (cl_hw->amsdu_rx_state.msdu_remaining_cnt > 0) + cl_rx_set_flag_amsdu_more(skb); +} + +bool cl_rx_amsdu_sub(struct cl_hw *cl_hw, struct sk_buff *skb) +{ + /* + * ---------------------------------------------------------- + * | DMA padding 4 byte alignment | MSDU HDR | MSDU PAYLOAD | + * --------------------------------------------------------- + */ + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + struct sk_buff *first_skb = amsdu_rx_state->first_skb; + struct msduhdr *msdu_hdr; + u32 packet_len; + + /* + * Push the dma alignment to the reserved area, so that skb->data will + * point to the MSDU header + */ + skb_reserve(skb, amsdu_rx_state->msdu_dma_align); + + msdu_hdr = (struct msduhdr *)(skb->data); + packet_len = sizeof(struct msduhdr) + ntohs(msdu_hdr->len); + + if (skb_tailroom(skb) < packet_len) { + cl_rx_amsdu_sub_length_error(cl_hw, skb, packet_len); + return false; + } + + /* Put the MSDU HDR + MSDU PAYLOAD into the skb data area */ + skb_put(skb, packet_len); + + amsdu_rx_state->packet_len += packet_len; + + cl_rx_add_80211_hdr(amsdu_rx_state, skb, first_skb); + cl_rx_copy_status(amsdu_rx_state, skb, first_skb); + + /* Store the pointer to sta in the skb->sk field */ + skb->sk = first_skb->sk; + + __skb_queue_tail(&amsdu_rx_state->frames, skb); + + return true; +} + +bool cl_rx_amsdu_check_aggregation_attack(struct cl_amsdu_rx_state *amsdu_rx_state) +{ + u32 hdrlen = 0; + struct sk_buff_head *frames = &amsdu_rx_state->frames; + struct hw_rxhdr *rxhdr = amsdu_rx_state->rxhdr; + struct ieee80211_hdr *hdr = NULL; + struct msduhdr *msdu_hdr = NULL; + struct sk_buff *skb = NULL; + + /* Validate encryption info - forbid A-MSDU on pre-HT connections */ + switch (rxhdr->decr_status) { + case CL_RX_HDR_DECR_ICVFAIL: + case CL_RX_HDR_DECR_WEPSUCCESS: + case CL_RX_HDR_DECR_TKIPSUCCESS: + return true; + default: + break; + } + + skb_queue_walk(frames, skb) { + hdr = (struct ieee80211_hdr *)(skb->data); + hdrlen = ieee80211_hdrlen(hdr->frame_control); + msdu_hdr = (struct msduhdr *)(skb->data + hdrlen + amsdu_rx_state->encrypt_len); + if (cl_rx_amsdu_is_frame_aggregation_attack(hdr, msdu_hdr)) + return true; + } + + return false; +} + +void cl_rx_amsdu_first_corrupted(struct cl_hw *cl_hw, struct sk_buff *skb, + struct hw_rxhdr *rxhdr) +{ + struct ieee80211_hdr *mac_hdr = (struct ieee80211_hdr *)(skb->data); + + cl_dbg_verbose(cl_hw, "Corrupted RX-AMSDU (1/%u), dest_addr=%pM\n", + rxhdr->msdu_cnt, mac_hdr->addr1); + + cl_rx_amsdu_set_state_error(cl_hw, rxhdr, RX_AMSDU_ERR_CORRUPTED); + + cl_hw->rx_info.pkt_drop_amsdu_corrupted++; + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +void cl_rx_amsdu_sub_error(struct cl_hw *cl_hw, struct sk_buff *skb) +{ + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + u8 sub_cnt = amsdu_rx_state->msdu_cnt - amsdu_rx_state->msdu_remaining_cnt; + + if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_CORRUPTED) { + cl_hw->rx_info.pkt_drop_sub_amsdu_corrupted++; + + cl_dbg_verbose(cl_hw, "Corrupted RX-AMSDU (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } else if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_LENGTH) { + cl_hw->rx_info.pkt_drop_sub_amsdu_len_error++; + + cl_dbg_verbose(cl_hw, "RX-AMSDU length error (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } else if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_NOT_SUCCESS) { + cl_hw->rx_info.pkt_drop_sub_amsdu_not_success++; + + cl_dbg_verbose(cl_hw, "RX-AMSDU not success (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } else if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_UNENCRYPTED) { + cl_hw->rx_info.pkt_drop_sub_amsdu_unencrypted++; + + cl_dbg_verbose(cl_hw, "Protected frame unencrypted (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } else if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_DECRYPT_FAIL) { + cl_hw->rx_info.pkt_drop_sub_amsdu_decrypt_fail++; + + cl_dbg_verbose(cl_hw, "Decryption failed (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } else if (amsdu_rx_state->amsdu_error & RX_AMSDU_ERR_INVALID_TAILROOM) { + cl_hw->rx_info.pkt_drop_sub_amsdu_tailroom_error++; + + cl_dbg_verbose(cl_hw, "Invalid tailroom (%u/%u)\n", + sub_cnt, amsdu_rx_state->msdu_cnt); + } + + cl_rx_skb_error(cl_hw); + kfree_skb(skb); +} + +void cl_rx_amsdu_set_state_error(struct cl_hw *cl_hw, + struct hw_rxhdr *rxhdr, + enum rx_amsdu_error err) +{ + struct cl_amsdu_rx_state *amsdu_rx_state = &cl_hw->amsdu_rx_state; + + amsdu_rx_state->msdu_cnt = rxhdr->msdu_cnt; + amsdu_rx_state->msdu_remaining_cnt = rxhdr->msdu_cnt - 1; + amsdu_rx_state->amsdu_error = err; +} + +void cl_rx_amsdu_reset(struct cl_hw *cl_hw) +{ + /* Free pending frames */ + __skb_queue_purge(&cl_hw->amsdu_rx_state.frames); + + /* Reset RX A-MSDU state */ + memset(&cl_hw->amsdu_rx_state, 0, sizeof(struct cl_amsdu_rx_state)); + + __skb_queue_head_init(&cl_hw->amsdu_rx_state.frames); +} + +void cl_rx_amsdu_stats(struct cl_hw *cl_hw, u8 msdu_cnt) +{ + /* + * Update A-MSDU statistics + * msdu_cnt 1 - 128 is mapped to 0 - 127. + */ + if (msdu_cnt <= RX_MAX_MSDU_IN_AMSDU) + cl_hw->rx_info.amsdu_cnt[msdu_cnt - 1]++; + else + cl_dbg_err(cl_hw, "Invalid msdu_cnt [%u]\n", msdu_cnt); +} + +/* Only ieee80211_hw_set() is defined in mac80211.h */ +static inline void _ieee80211_hw_clear(struct ieee80211_hw *hw, + enum ieee80211_hw_flags flg) +{ + return __clear_bit(flg, hw->flags); +} + +#define ieee80211_hw_clear(hw, flg) _ieee80211_hw_clear(hw, IEEE80211_HW_##flg) + +void cl_rx_amsdu_hw_en(struct ieee80211_hw *hw, bool rxamsdu_en) +{ + if (rxamsdu_en) + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + else + ieee80211_hw_clear(hw, SUPPORTS_AMSDU_IN_AMPDU); +} + +u32 cl_rx_filter_update_flags(struct cl_hw *cl_hw, u32 filter) +{ + u32 rx_filter = 0; + + if (filter & FIF_ALLMULTI) + rx_filter |= RX_CNTRL_ACCEPT_MULTICAST_BIT; + + if (filter & (FIF_FCSFAIL | FIF_PLCPFAIL)) + rx_filter |= RX_CNTRL_ACCEPT_ERROR_FRAMES_BIT; + + if (filter & FIF_BCN_PRBRESP_PROMISC) + rx_filter |= RX_CNTRL_ACCEPT_OTHER_BSSID_BIT; + + if (filter & FIF_CONTROL) + rx_filter |= RX_CNTRL_ACCEPT_OTHER_CNTRL_FRAMES_BIT | + RX_CNTRL_ACCEPT_CF_END_BIT | + RX_CNTRL_ACCEPT_ACK_BIT | + RX_CNTRL_ACCEPT_CTS_BIT | + RX_CNTRL_ACCEPT_RTS_BIT | + RX_CNTRL_ACCEPT_BA_BIT | RX_CNTRL_ACCEPT_BAR_BIT; + + if (filter & FIF_OTHER_BSS) + rx_filter |= RX_CNTRL_ACCEPT_OTHER_BSSID_BIT; + + if (filter & FIF_PSPOLL) + rx_filter |= RX_CNTRL_ACCEPT_PS_POLL_BIT; + + if (filter & FIF_PROBE_REQ) + rx_filter |= RX_CNTRL_ACCEPT_PROBE_REQ_BIT; + + /* Add the filter flags that are set by default and cannot be changed here */ + rx_filter |= CL_MAC80211_NOT_CHANGEABLE; + + if (ieee80211_hw_check(cl_hw->hw, AMPDU_AGGREGATION)) + rx_filter |= RX_CNTRL_ACCEPT_BA_BIT; + + /* + * work around for HW bug (AD 14672) + * In order for the response frames to BAR and RTS be with correct + * power they should always be accepted and found in the KSR + */ + rx_filter |= RX_CNTRL_ACCEPT_BAR_BIT | RX_CNTRL_ACCEPT_RTS_BIT; + + return rx_filter; +} + +static u32 cl_filter_get_flags(struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + return sdata->local->filter_flags; +} + +void cl_rx_filter_restore_flags(struct cl_hw *cl_hw) +{ + struct net_device *dev = cl_vif_get_first_net_device(cl_hw); + u32 filter = 0; + + if (!dev) + return; + + filter = cl_filter_get_flags(dev); + cl_dbg_verbose(cl_hw, "Restoring filter flags to 0x%x\n", filter); + cl_msg_tx_set_filter(cl_hw, filter, false); +} + +void cl_rx_filter_set_promiscuous(struct cl_hw *cl_hw) +{ + u32 filter = ~(FIF_FCSFAIL | FIF_PLCPFAIL | (1 << 31)); + + cl_dbg_verbose(cl_hw, "set promiscuous mode 0x%x\n", filter); + cl_msg_tx_set_filter(cl_hw, filter, false); +} + +#define REORDER_BUF_TIMEOUT (HZ / 10) +#define REORDER_BUF_TIMEOUT_MS jiffies_to_msecs(REORDER_BUF_TIMEOUT + 1) + +static bool cl_rx_reorder_ready(struct cl_tid_ampdu_rx *tid_agg_rx, u8 index) +{ + struct sk_buff_head *frames = &tid_agg_rx->reorder_buf[index]; + struct sk_buff *tail = skb_peek_tail(frames); + struct ieee80211_rx_status *status; + + if (tid_agg_rx->reorder_buf_filtered & BIT_ULL(index)) + return true; + + if (!tail) + return false; + + status = IEEE80211_SKB_RXCB(tail); + + if (status->flag & RX_FLAG_AMSDU_MORE) + return false; + + return true; +} + +static void cl_rx_release_reorder_frame(struct cl_tid_ampdu_rx *tid_agg_rx, int index, + struct sk_buff_head *frames) +{ + struct cl_hw *cl_hw = tid_agg_rx->cl_hw; + struct sk_buff_head *skb_list = &tid_agg_rx->reorder_buf[index]; + struct sk_buff *skb; + struct ieee80211_rx_status *status = NULL; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(tid_agg_rx->sta); + int pn_state = CL_PN_VALID_STATE_FAILED; + + lockdep_assert_held(&tid_agg_rx->reorder_lock); + + if (skb_queue_empty(skb_list)) + goto no_frame; + + tid_agg_rx->stored_mpdu_num--; + + if (!cl_rx_reorder_ready(tid_agg_rx, index)) { + __skb_queue_purge(skb_list); + goto no_frame; + } + + /* For NON AMSDU - Single skb in skb_list + * For AMSDU - Validate first skb and set PN flag for rest. + */ + skb = skb_peek(skb_list); + pn_state = cl_key_handle_pn_validation(cl_hw, skb, cl_sta); + if (pn_state == CL_PN_VALID_STATE_FAILED) { + __skb_queue_purge(skb_list); + goto no_frame; + } + + while ((skb = __skb_dequeue(skb_list))) { + if (pn_state == CL_PN_VALID_STATE_SUCCESS) { + status = IEEE80211_SKB_RXCB(skb); + status->flag |= RX_FLAG_PN_VALIDATED; + } + __skb_queue_tail(frames, skb); + } + +no_frame: + tid_agg_rx->reorder_buf_filtered &= ~BIT_ULL(index); + tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num); +} + +static void cl_rx_release_reorder_frames(struct cl_tid_ampdu_rx *tid_agg_rx, + u16 head_seq_num, + struct sk_buff_head *frames) +{ + int index; + + lockdep_assert_held(&tid_agg_rx->reorder_lock); + + while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) { + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + cl_rx_release_reorder_frame(tid_agg_rx, index, frames); + } +} + +static void cl_reorder_release(struct cl_tid_ampdu_rx *tid_agg_rx, struct sk_buff_head *frames) +{ + u8 index, i, j; + + lockdep_assert_held(&tid_agg_rx->reorder_lock); + + /* Release buffer until next hole */ + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + if (!cl_rx_reorder_ready(tid_agg_rx, index) && tid_agg_rx->stored_mpdu_num) { + u8 skipped = 1; + + for (j = (index + 1) % tid_agg_rx->buf_size; j != index; + j = (j + 1) % tid_agg_rx->buf_size) { + if (!cl_rx_reorder_ready(tid_agg_rx, j)) { + skipped++; + continue; + } + if (skipped && + !time_after(jiffies, tid_agg_rx->reorder_time[j] + + REORDER_BUF_TIMEOUT)) + goto set_release_timer; + + /* Incomplete A-MSDUs */ + for (i = (index + 1) % tid_agg_rx->buf_size; i != j; + i = (i + 1) % tid_agg_rx->buf_size) { + __skb_queue_purge(&tid_agg_rx->reorder_buf[i]); + } + + cl_rx_release_reorder_frame(tid_agg_rx, j, frames); + + tid_agg_rx->head_seq_num = + (tid_agg_rx->head_seq_num + + skipped) & IEEE80211_SN_MASK; + skipped = 0; + } + } else { + while (cl_rx_reorder_ready(tid_agg_rx, index)) { + cl_rx_release_reorder_frame(tid_agg_rx, index, frames); + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + } + } + + if (tid_agg_rx->stored_mpdu_num) { + j = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + index = j; + for (; j != (index - 1) % tid_agg_rx->buf_size; + j = (j + 1) % tid_agg_rx->buf_size) { + if (cl_rx_reorder_ready(tid_agg_rx, j)) + break; + } + + set_release_timer: + if (!tid_agg_rx->removed) + mod_timer(&tid_agg_rx->reorder_timer, tid_agg_rx->reorder_time[j] + + msecs_to_jiffies(REORDER_BUF_TIMEOUT_MS)); + } else { + del_timer(&tid_agg_rx->reorder_timer); + } +} + +static void cl_rx_reorder_release_timeout(struct timer_list *t) +{ + struct cl_tid_ampdu_rx *tid_agg_rx = from_timer(tid_agg_rx, t, reorder_timer); + struct sk_buff *skb = NULL; + struct cl_hw *cl_hw = NULL; + struct ieee80211_sta *sta = NULL; + struct sk_buff_head buffer; + + if (!tid_agg_rx) + return; + + __skb_queue_head_init(&buffer); + + spin_lock(&tid_agg_rx->reorder_lock); + + cl_hw = tid_agg_rx->cl_hw; + sta = tid_agg_rx->sta; + cl_reorder_release(tid_agg_rx, &buffer); + + spin_unlock(&tid_agg_rx->reorder_lock); + + while (!skb_queue_empty(&buffer)) { + skb = __skb_dequeue(&buffer); + ieee80211_rx_napi(cl_hw->hw, sta, skb, NULL); + } +} + +static bool cl_rx_manage_reorder_buf(struct cl_tid_ampdu_rx *tid_agg_rx, + struct sk_buff *skb, + struct sk_buff_head *ordered_mpdu) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + u16 sc = le16_to_cpu(hdr->seq_ctrl); + u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; + u16 head_seq_num, buf_size; + u8 index; + bool ret = true; + + if (unlikely(tid_agg_rx->auto_seq)) { + tid_agg_rx->auto_seq = false; + tid_agg_rx->ssn = mpdu_seq_num; + tid_agg_rx->head_seq_num = mpdu_seq_num; + } + + buf_size = tid_agg_rx->buf_size; + head_seq_num = tid_agg_rx->head_seq_num; + + /* Current SN is smaller than the SSN */ + if (unlikely(!tid_agg_rx->started)) { + if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) { + ret = false; + goto out; + } + tid_agg_rx->started = true; + } + + /* Out of date sequence number */ + if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) { + dev_kfree_skb(skb); + goto out; + } + + /* SN exceeds buffer window */ + if (!ieee80211_sn_less(mpdu_seq_num, head_seq_num + buf_size)) { + head_seq_num = ieee80211_sn_inc(ieee80211_sn_sub(mpdu_seq_num, buf_size)); + cl_rx_release_reorder_frames(tid_agg_rx, head_seq_num, ordered_mpdu); + } + + index = mpdu_seq_num % tid_agg_rx->buf_size; + + /* Frame already stored */ + if (cl_rx_reorder_ready(tid_agg_rx, index)) { + dev_kfree_skb(skb); + goto out; + } + + if (mpdu_seq_num == tid_agg_rx->head_seq_num && + tid_agg_rx->stored_mpdu_num == 0) { + if (!(status->flag & RX_FLAG_AMSDU_MORE)) { + tid_agg_rx->head_seq_num = + ieee80211_sn_inc(tid_agg_rx->head_seq_num); + } + ret = false; + goto out; + } + + /* Insert frame into reorder buffer */ + __skb_queue_tail(&tid_agg_rx->reorder_buf[index], skb); + if (!(status->flag & RX_FLAG_AMSDU_MORE)) { + tid_agg_rx->reorder_time[index] = jiffies; + tid_agg_rx->stored_mpdu_num++; + cl_reorder_release(tid_agg_rx, ordered_mpdu); + } + + out: + return ret; +} + +void cl_rx_reorder_ampdu(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, struct sk_buff_head *ordered_mpdu) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct cl_tid_ampdu_rx *tid_agg_rx; + u8 tid, ack_policy; + + if (!cl_sta) + return; + + ack_policy = *ieee80211_get_qos_ctl(hdr) & + IEEE80211_QOS_CTL_ACK_POLICY_MASK; + tid = ieee80211_get_tid(hdr); + + tid_agg_rx = cl_sta->tid_agg_rx[tid]; + if (!tid_agg_rx) + return; + + spin_lock(&tid_agg_rx->reorder_lock); + if (!ieee80211_is_data_qos(hdr->frame_control) || + is_multicast_ether_addr(hdr->addr1)) + goto dont_reorder; + + if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) + goto dont_reorder; + + if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK && + ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) + goto dont_reorder; + + /* Ignore EAPOL frames */ + if (cl_is_eapol(skb)) + goto dont_reorder; + + if (cl_rx_manage_reorder_buf(tid_agg_rx, skb, ordered_mpdu)) { + spin_unlock(&tid_agg_rx->reorder_lock); + return; + } + + dont_reorder: + spin_unlock(&tid_agg_rx->reorder_lock); + + if (cl_key_handle_pn_validation(cl_hw, skb, cl_sta) == CL_PN_VALID_STATE_FAILED) { + dev_kfree_skb(skb); + return; + } + + __skb_queue_tail(ordered_mpdu, skb); +} + +void cl_rx_reorder_close(struct cl_sta *cl_sta, u8 tid) +{ + struct cl_tid_ampdu_rx *tid_agg_rx = cl_sta->tid_agg_rx[tid]; + u16 i; + + spin_lock_bh(&tid_agg_rx->reorder_lock); + tid_agg_rx->removed = true; + spin_unlock_bh(&tid_agg_rx->reorder_lock); + + del_timer_sync(&tid_agg_rx->reorder_timer); + + spin_lock_bh(&tid_agg_rx->reorder_lock); + for (i = 0; i < tid_agg_rx->buf_size; i++) + __skb_queue_purge(&tid_agg_rx->reorder_buf[i]); + + kfree(tid_agg_rx->reorder_buf); + kfree(tid_agg_rx->reorder_time); + cl_sta->tid_agg_rx[tid] = NULL; + + spin_unlock_bh(&tid_agg_rx->reorder_lock); + kfree(tid_agg_rx); +} + +void cl_rx_reorder_init(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 tid, u16 buf_size) +{ + struct cl_tid_ampdu_rx *tid_agg_rx; + u16 i; + + tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL); + if (!tid_agg_rx) + return; + + spin_lock_init(&tid_agg_rx->reorder_lock); + + timer_setup(&tid_agg_rx->reorder_timer, cl_rx_reorder_release_timeout, 0); + + tid_agg_rx->reorder_buf = + kcalloc(buf_size, sizeof(struct sk_buff_head), GFP_KERNEL); + tid_agg_rx->reorder_time = + kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL); + if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) { + pr_err("Allocation failed!\n"); + kfree(tid_agg_rx->reorder_buf); + kfree(tid_agg_rx->reorder_time); + return; + } + + for (i = 0; i < buf_size; i++) + __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]); + + tid_agg_rx->ssn = 0; + tid_agg_rx->head_seq_num = 0; + tid_agg_rx->buf_size = buf_size; + tid_agg_rx->stored_mpdu_num = 0; + tid_agg_rx->auto_seq = 0; + tid_agg_rx->started = false; + tid_agg_rx->reorder_buf_filtered = 0; + tid_agg_rx->tid = tid; + tid_agg_rx->sta = cl_sta->sta; + tid_agg_rx->cl_hw = cl_hw; + cl_sta->tid_agg_rx[tid] = tid_agg_rx; +} From patchwork Tue May 24 11:34:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576841 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 99A23C4321E for ; Tue, 24 May 2022 11:40:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236932AbiEXLk3 (ORCPT ); Tue, 24 May 2022 07:40:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236922AbiEXLk0 (ORCPT ); Tue, 24 May 2022 07:40:26 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60067.outbound.protection.outlook.com [40.107.6.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 057B74130C for ; Tue, 24 May 2022 04:39:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WkvXtl00D4nYTv5V0FTZ4Pv+ovMQWGTUgcNAcFLGLq0jaCOP4uElkPM4elF5XJ4eqr7/+rvQwfmfA1/6KRehvwy5d4f681Qr09K2zsFvLVFAiDkAc2djOmq+ox/hlm2HgTcQflsG/qTQ2KBGejkNYJxSzEaYaNGTO2MgEbUO86vBltRnSxpMMCFT48b0dj2m0gJmUiMngbailkgwsL1RRIaApn0D/JNd2aTwSqEoSYHn3o8Knu3/P8JehKaEHiNZVZ5ynNbKlfUucv3HYt8+bj4wzF4i3sOhWoUxN8uxR4XBAvT+PiiiwzrpqKNv7Hn9qhMqrhiXSgau56093O6Dig== 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=zDhmt51XVQj8SzfSkcyrHoAiahElyAD4CWoy9Z+j9js=; b=BPkEPC+IK1X8t8DNGNg408yYZ/R6d8QB55hxe5H4hV5enM47RbWyzcK1BeIRsUBfmwFtujY7dk3+JV1QWIh6rvDg8wOGEj76xcH5fR0KH0W6PPuVx0YM88Fuk9aSqpAC8BwmS4UQwOYzEcky+UKd3xyY3Wl7jE63d7Jbkx9Ipyasiw0Wkp0XMd0orHjn5tmnNYlYsUTa6Ubqth89gjhEAXYyBtN+Ui3GxW9W53PKdI7OD/DXM8unMevHeBIFLGmPsZmjrxqOA5M12iMnufp0oAClCAhH8qtUFy7/rAHGrWvei5uEzUu0KXuZDMO8/C+3GI2sbjKvqgM2CBeyCD+Y3Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zDhmt51XVQj8SzfSkcyrHoAiahElyAD4CWoy9Z+j9js=; b=Ta5XAcudP4cZwbITdQIsKMm+QdsF/vmuWq8C1mp6hV/GWZ1pkifhL9jN6vz9WlKWHBwUAie3KsNwUJt2DEva80GEk7tdHakt64WK4SWUApd/iq3J41AywbSDr/YTefgfKQL06wVgJY6cbQW7BIswiBv2SYKS1I08JzO93sAvWrI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:26 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:25 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 69/96] cl8k: add rx.h Date: Tue, 24 May 2022 14:34:35 +0300 Message-Id: <20220524113502.1094459-70-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d26175c0-189a-43ba-8c4d-08da3d79f5b9 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LY9KPkxmoHfRv8vjtYZRo0sWoJ317xATXs8Z35KnokwpuaoblelAQa+eGjmu2NdX2sJRCXiEjnr3446T4Y/5VGvfBxKqoQL6OPAPU4ND895gk/R8jYyOiv/P7yc4xv1zg2X00UnJ5ujwD3CgsupvQzPj+Gv1HjJANuOqq9I+mUQzO2f2MfzrGadiHwoUOR9BE8eeRmmJHpaWO+j3zeCRETzzvEX0Xac8ZEaiz9bH0PCa0WuOa4DQG3V8b+BaL/RJOfvYlj6Bu8Y2cRg4yff24wcoq4G6mIsxhZ0JDaFL0jfH5xaaF2vyXjB4JDkNuSdbZ7yN0HBRaVYg5T8Li7euQJ9VAH3BljON/vh3epLRo7Pu1t3xHQaSgOhh9Gi1GCRLLlr5xjOEYuo44UMOQa79N+noCI+8KH3oFZgTptyFzr5Y/EDIgVlzvwFAJeCKJpaM0IIcST3FiQO04I4fJHZcvKrm/4s5qUT5UeRfiYvq1n1vPam4mjUI7ID8TqvSpHxZkNWo+FRhrIo8lCaj6YIRXmIXkcIlobDxnDqBsf7u3aEjlgl9PkDk84/zl6e+01WEAUGtv4WVJMOYjTu7GcpDnt4L49EdME4di/51KicVeU3BZAUFU/XwmGdTuKSu0KI0pHQ16J4SWlAo83cid4fvnqrTHAHtTY3BUUSdL5wtfRR+FFqJjXOjRMhdNAIRYnU28kdEemlC8nfQtIoQZJoH6yZw370wr1PE54VnZFknO00= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: v4Xwkz8qVxEhUMXxxyMl2QqrarMrDzDMJMVqz7ybheViGj+ppnPN2f1BS39McrjbqHgZWXV7BqEJAnEGgNbJ1rJC78L17k57Pi7FVAWTqbLvLYbXK+CGAXJFIF7jOVDDcc5ak8/tYxeNcD+I3vhJuG+ziFeEWCtw0xaJybI5whPOKZy7H/bV0ylBSvUHiIfYWOMMgnCHZ6zFJscKJ2ZnXRN1bO8Lki63kwV29O4gaTWxH72TpbwfLx6OLZDp9dozkLE9IYsOgklH3st1ZsWbX3r8aVJLa3waaz9z46jiUCaIvKT1YwDQlY3M4ea/ktmdBkiRmW+jy6Zpq5p0E7CwRMJMqZOoGWa/672ps91rOCy7JDJ3Tz8kAwvlG5RtPdOun3M2FH41yeotTo8iQp7fV7fBwcbKjJVFOMUNwD737pmdS2QKgo/RLCBI4xnUuxjlRqJJyNaxBBma8tA2+vceiZRSYKZmrMHxupIKl1twl8+mqyWR7QGqq6AIZahmEu4ADX+4IHaN4QM9pKqDKjjvjCK9OqstVe+f+XGLAkvaqElv/OWKIFtXpW3QeqNXqA+f/DS639Z1rlzE8XTDaOFWPlkYGyoTQzMiMl79C8luvxcU/6k2uWdX4UjWgTk1kSQ/e6dVQB3YqpPYJnvfAzfdnYc8aaAhfDX/yr3b95YYvyEV+srovzF3HUd/tQHPOtuwTEyyaL0TXQiL03Nk7UKDww1UsGYG/9kG1csiCd8545a8xYCZnXFHOPbu3swDrQVFZFXIMI1JN2uXuy/vqBr5JBd85j8Jek1SAnzW0OMzLid844gYCiwxWtPABjbW3CwW3SzvLwFShCC4dfkUFVQeUCzAnzJYW5tOorV4OWjFDdqd15ITCDPTE6lCTl4ZnNnat27f4ohEIm3uAxnwWOpH54cf9cPwOTSM/saVw0v5G0rvYru2HMICBpwEcAnYEF9cszwsbgylelIIuAgBhA10gt3hNXvibcGTwLh9V0N4MxLZUlucEfyJkkms/QAauCZ4gOR3UAxxGqNgUHfW32zKT+j/HGSGbB/D7p3myMcmkmmRFgHzX2Ec0R9xHugyq3xZMSjmrJnuVefgITOEURyjyNPr90AfBsDiKpBa6w7cuvu6GwVPbsXWY1Zl/uTQPGHUQatjx+BPHLbsfZ8pLiT4xDyf4UbWbltR4Fm/wIaM5pWbrNIihlrI+pIUBcNtM0/JRA8nvb7x2iSLo8Zrw8YIaGGIreRA9FfXCG8PM2wvsMI4LAA3t8rME10uH5zEnPa/b/bL1OSGj8gDqubZ6c1sjX8UEFPxh1EF4IBXMDk497x9CxCw899/+wQlaoEcXe4ju+GRuzUx39oLMTdBqbnXAWImg4U6JRdJL4gyqU1/udw/5plFd2wooSdDhsZMWeRkJr4ravUf7BY42qHslTEBF0S1gvbE0vHnvJeLPZSzKghOUSH/3sx1kll0EsOXHeyugBuzzLUXH5Y/CxiIwMB6ldp3p+zYVILDVDWdLWTpBi6ylsE91HyxoxE5v57gikgXq1uVzexUgJPxvvVkKq5PieUpqh3vHj5u/wD70z5Cd/xj8p46gEfKRJ24zKqA1+lMiIP8rwAo/Slz0Y/Iet20ScJ7DYsxHAx+IdEZStZihCqHmROd7qXyd/E0QZ/viDAIIvLFBRoge4hWS3I00PDizCELaaLNTpQ6Y58CVkAdnDbCiFGykFnaAMSfPrQW/s7O+tY5597GQgfIRPbNVxY1enzPcJvTLr2+lum6szZ4xa8= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d26175c0-189a-43ba-8c4d-08da3d79f5b9 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:45.0993 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: p+SieZDgJ+ddWBUBYGGiizvgcVV4Th7YK+6/FZJkSYGG29zdnA3hoii5aaNhUUVRGiSMTryEnJZn041JeGZxSw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/rx.h | 505 ++++++++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/rx.h diff --git a/drivers/net/wireless/celeno/cl8k/rx.h b/drivers/net/wireless/celeno/cl8k/rx.h new file mode 100644 index 000000000000..f460c3c37475 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/rx.h @@ -0,0 +1,505 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_RX_H +#define CL_RX_H + +#include +#include + +#include "ipc_shared.h" + +/* Decryption status subfields */ +enum cl_rx_hdr_decr { + CL_RX_HDR_DECR_UNENC, + CL_RX_HDR_DECR_ICVFAIL, + CL_RX_HDR_DECR_CCMPFAIL, + CL_RX_HDR_DECR_AMSDUDISCARD, + CL_RX_HDR_DECR_NULLKEY, + CL_RX_HDR_DECR_WEPSUCCESS, + CL_RX_HDR_DECR_TKIPSUCCESS, + CL_RX_HDR_DECR_CCMPSUCCESS +}; + +#define CL_PADDING_IN_BYTES 2 + +struct hw_rxhdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 msdu_cnt : 8, /* [7:0] */ + corrupted_amsdu : 1, /* [8] */ + reserved : 1, /* [9] */ + msdu_dma_align : 2, /* [11:10] */ + amsdu_error_code : 4, /* [15:12] */ + reserved_2 :16; /* [31:16] */ +#else + u32 reserved_2 :16, /* [15:0] */ + amsdu_error_code : 4, /* [19:16] */ + msdu_dma_align : 2, /* [21:20] */ + reserved : 1, /* [22] */ + corrupted_amsdu : 1, /* [23] */ + msdu_cnt : 8; /* [31:24] */ +#endif + /* Total length for the MPDU transfer */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 len :14, /* [13:0] */ + ampdu_cnt : 2, /* [15:14] */ + rx_padding_done : 1, /* [16] */ + rx_class_rule_res : 7, /* [23:17] */ + /* AMPDU Status Information */ + mpdu_cnt : 8; /* [31:24] */ +#else + u32 mpdu_cnt : 8, /* [7:0] */ + rx_class_rule_res : 7, /* [14:8] */ + rx_padding_done : 1, /* [15] */ + ampdu_cnt : 2, /* [17:16] */ + len :14; /* [31:18] */ +#endif + + /* TSF Low */ + __le32 tsf_lo; + /* TSF High */ + __le32 tsf_hi; + + /* Receive Vector 1a */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 leg_length :12, /* [11:0] */ + leg_rate : 4, /* [15:12] */ + ht_length_l :16; /* [31:16] */ +#else + u32 ht_length_l :16, /* [15:0] */ + leg_rate :4, /* [19:16] */ + leg_length :12; /* [31:20] */ +#endif + + /* Receive Vector 1b */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 ht_length_h : 8, /* [7:0] */ + mcs : 7, /* [14:8] */ + pre_type : 1, /* [15] */ + format_mod : 4, /* [19:16] */ + reserved_1b : 1, /* [20] */ + n_sts : 3, /* [23:21] */ + lsig_valid : 1, /* [24] */ + sounding : 1, /* [25] */ + num_extn_ss : 2, /* [27:26] */ + aggregation : 1, /* [28] */ + fec_coding : 1, /* [29] */ + dyn_bw : 1, /* [30] */ + doze_not_allowed : 1; /* [31] */ +#else + u32 doze_not_allowed : 1, /* [0] */ + dyn_bw : 1, /* [1] */ + fec_coding : 1, /* [2] */ + aggregation : 1, /* [3] */ + num_extn_ss : 2, /* [5:4] */ + sounding : 1, /* [6] */ + lsig_valid : 1, /* [7] */ + n_sts : 3, /* [10:8] */ + reserved_1b : 1, /* [11] */ + format_mod : 4, /* [15:12] */ + pre_type : 1, /* [16] */ + mcs : 7, /* [23:17] */ + ht_length_h : 8; /* [31:24] */ +#endif + + /* Receive Vector 1c */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 sn : 4, /* [3:0] */ + warn_1c : 1, /* [4] */ + stbc : 2, /* [6:5] */ + smoothing : 1, /* [7] */ + partial_aid : 9, /* [16:8] */ + group_id : 6, /* [22:17] */ + reserved_1c : 1, /* [23] */ + rssi1 : 8; /* [31:24] */ +#else + u32 rssi1 : 8, /* [7:0] */ + reserved_1c : 1, /* [8] */ + group_id : 6, /* [14:9] */ + partial_aid : 9, /* [23:15] */ + smoothing : 1, /* [24] */ + stbc : 2, /* [26:25] */ + warn_1c : 1, /* [27] */ + sn : 4; /* [31:28] */ +#endif + + /* Receive Vector 1d */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + s32 rssi2 : 8, /* [7:0] */ + rssi3 : 8, /* [15:8] */ + rssi4 : 8, /* [23:16] */ + rx_chains : 8; /* [31:24] */ +#else + s32 rx_chains : 8, /* [7:0] */ + rssi4 : 8, /* [15:8] */ + rssi3 : 8, /* [23:16] */ + rssi2 : 8; /* [31:24] */ +#endif + + /* Receive Vector 1e */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 txop_duration : 7, /* [6:0] */ + beam_change : 1, /* [7] */ + mcs_sig_b : 3, /* [10:8] */ + dcm : 1, /* [11] */ + dcm_sig_b : 1, /* [12] */ + beamformed : 1, /* [13] */ + ltf_type : 2, /* [15:14] */ + ru_band : 1, /* [16] */ + ru_type : 3, /* [19:17] */ + ru_index : 6, /* [25:20] */ + pe_duration : 3, /* [28:26] */ + ch_bw : 2, /* [30:29] */ + reserved_1e : 1; /* [31] */ +#else + u32 reserved_1e : 1, /* [0] */ + ch_bw : 2, /* [2:1] */ + pe_duration : 3, /* [5:3] */ + ru_index : 6, /* [11:6] */ + ru_type : 3, /* [14:12] */ + ru_band : 1, /* [15] */ + ltf_type : 2, /* [17:16] */ + beamformed : 1, /* [18] */ + dcm_sig_b : 1, /* [19] */ + dcm : 1, /* [20] */ + mcs_sig_b : 3, /* [23:21] */ + beam_change : 1, /* [24] */ + txop_duration : 7; /* [31:25] */ +#endif + + /* Receive Vector 1f */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 spatial_reuse : 16, /* [15:0] */ + service : 16; /* [31:16] */ +#else + u32 service : 16, /* [15:0] */ + spatial_reuse : 16; /* [31:16] */ +#endif + + /* Receive Vector 1g */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 bss_color : 6, /* [5:0] */ + gi_type : 2, /* [7:6] */ + antenna_set : 16, /* [23:8] */ + rssi5 : 8; /* [31:24] */ +#else + u32 rssi5 : 8, /* [7:0] */ + antenna_set : 16, /* [23:8] */ + gi_type : 2, /* [25:24] */ + bss_color : 6; /* [31:26] */ +#endif + + /* Receive Vector 1h */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + s32 rssi6 : 8, /* [7:0] */ + rssi7 : 8, /* [15:8] */ + rssi8 : 8, /* [23:16] */ + future_1 : 8; /* [31:24] */ +#else + s32 future_1 : 8, /* [7:0] */ + rssi8 : 8, /* [15:8] */ + rssi7 : 8, /* [23:16] */ + rssi6 : 8; /* [31:24] */ +#endif + + /* Receive Vector 2a */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 rcpi : 8, /* [7:0] */ + evm1 : 8, /* [15:8] */ + evm2 : 8, /* [23:16] */ + evm3 : 8; /* [31:24] */ +#else + u32 evm3 : 8, /* [7:0] */ + evm2 : 8, /* [15:8] */ + evm1 : 8, /* [23:16] */ + rcpi : 8; /* [31:24] */ +#endif + + /* Receive Vector 2b */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 evm4 : 8, /* [7:0] */ + warn_2b : 1, /* [8] */ + reserved2b_1 : 7, /* [15:9] */ + reserved2b_2 : 8, /* [23:16] */ + reserved2b_3 : 8; /* [31:24] */ +#else + u32 reserved2b_3 : 8, /* [7:0] */ + reserved2b_2 : 8, /* [15:8] */ + reserved2b_1 : 7, /* [22:16] */ + warn_2b : 1, /* [23] */ + evm4 : 8; /* [31:24] */ +#endif + + /* Status **/ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 rx_vect2_valid : 1, /* [0] */ + resp_frame : 1, /* [1] */ + decr_status : 3, /* [4:2] */ + rx_fifo_oflow : 1, /* [5] */ + undef_err : 1, /* [6] */ + phy_err : 1, /* [7] */ + fcs_err : 1, /* [8] */ + addr_mismatch : 1, /* [9] */ + ga_frame : 1, /* [10] */ + first_qos_data : 1, /* [11] */ + amsdu_present : 1, /* [12] */ + frm_successful_rx : 1, /* [13] */ + desc_done_rx : 1, /* [14] */ + desc_spare : 1, /* [15] */ + key_sram_index : 9, /* [24:16] */ + key_sram_v : 1, /* [25] */ + type : 2, /* [27:26] */ + subtype : 4; /* [31:28] */ +#else + u32 subtype : 4, /* [3:0] */ + type : 2, /* [5:4] */ + key_sram_v : 1, /* [6] */ + key_sram_index : 9, /* [15:7] */ + desc_spare : 1, /* [16] */ + desc_done_rx : 1, /* [17] */ + frm_successful_rx : 1, /* [18] */ + amsdu_present : 1, /* [19] */ + first_qos_data : 1, /* [20] */ + ga_frame : 1, /* [21] */ + addr_mismatch : 1, /* [22] */ + fcs_err : 1, /* [23] */ + phy_err : 1, /* [24] */ + undef_err : 1, /* [25] */ + rx_fifo_oflow : 1, /* [26] */ + decr_status : 3, /* [29:27] */ + resp_frame : 1, /* [30] */ + rx_vect2_valid : 1; /* [31] */ +#endif + + /* PHY channel information 1 */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 phy_band : 8, /* [7:0] */ + phy_channel_type : 8, /* [15:8] */ + phy_prim20_freq : 16; /* [31:16] */ +#else + u32 phy_prim20_freq : 16, /* [15:0] */ + phy_channel_type : 8, /* [23:16] */ + phy_band : 8; /* [31:24] */ +#endif + + /* PHY channel information 2 */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 phy_center1_freq : 16, /* [15:0] */ + phy_center2_freq : 16; /* [31:16] */ +#else + u32 phy_center2_freq : 16, /* [15:0] */ + phy_center1_freq : 16; /* [31:16] */ +#endif + + /* Patten **/ + __le32 pattern; +}; + +enum cl_radio_stats { + CL_RADIO_FCS_ERROR = 0, + CL_RADIO_PHY_ERROR, + CL_RADIO_RX_FIFO_OVERFLOW, + CL_RADIO_ADDRESS_MISMATCH, + CL_RADIO_UNDEFINED_ERROR, + CL_RADIO_ERRORS_MAX +}; + +struct cl_rx_path_info { + u32 rx_desc[CL_RX_BUF_MAX]; + u32 netif_rx; + u32 elem_alloc_fail; + u32 skb_null; + u32 pkt_drop_amsdu_corrupted; + u32 pkt_drop_sub_amsdu_corrupted; + u32 pkt_drop_amsdu_len_error; + u32 pkt_drop_sub_amsdu_len_error; + u32 pkt_drop_wrong_pattern; + u32 pkt_drop_not_success; + u32 pkt_drop_sub_amsdu_not_success; + u32 pkt_drop_unencrypted; + u32 pkt_drop_sub_amsdu_unencrypted; + u32 pkt_drop_decrypt_fail; + u32 pkt_drop_sub_amsdu_decrypt_fail; + u32 pkt_drop_tailroom_error; + u32 pkt_drop_sub_amsdu_tailroom_error; + u32 pkt_drop_amsdu_inj_attack; + u32 pkt_drop_sta_null; + u32 pkt_drop_host_limit; + u32 pkt_drop_invalid_pn; + u32 remote_cpu[CPU_MAX_NUM]; + u32 exceed_pkt_budget; + u32 pkt_handle_bucket_rxm[IPC_RXBUF_NUM_BUCKETS_RXM]; + u32 pkt_handle_bucket_fw[IPC_RXBUF_NUM_BUCKETS_FW]; + u32 amsdu_cnt[RX_MAX_MSDU_IN_AMSDU]; + u32 non_amsdu; + u32 buffer_process_irq; + u32 buffer_process_tasklet; +}; + +struct cl_hw; +struct cl_vif; +struct cl_sta; +struct mm_agg_rx_ind; + +void cl_rx_init(struct cl_hw *cl_hw); +void cl_rx_off(struct cl_hw *cl_hw); +void cl_rx_remote_tasklet_sched(void *t); +void cl_rx_remote_cpu_info(struct cl_hw *cl_hw); +void cl_rx_push_queue(struct cl_hw *cl_hw, struct sk_buff *skb); +void cl_rx_skb_alloc_handler(struct sk_buff *skb); +void cl_rx_skb_error(struct cl_hw *cl_hw); +void cl_rx_skb_drop(struct cl_hw *cl_hw, struct sk_buff *skb, u8 cnt); +void cl_rx_post_recovery(struct cl_hw *cl_hw); +void cl_rx_finish(struct cl_hw *cl_hw, struct sk_buff *skb, struct ieee80211_sta *sta); +u8 cl_rx_get_skb_ac(struct ieee80211_hdr *hdr); +bool cl_rx_process_in_irq(struct cl_hw *cl_hw); +void cl_agg_rx_report_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 sta_loc, + struct mm_agg_rx_ind *agg_report); + +enum rx_amsdu_error { + RX_AMSDU_ERR_CORRUPTED = 0x1, + RX_AMSDU_ERR_LENGTH = 0x2, + RX_AMSDU_ERR_NOT_SUCCESS = 0x4, + RX_AMSDU_ERR_UNENCRYPTED = 0x8, + RX_AMSDU_ERR_DECRYPT_FAIL = 0x10, + RX_AMSDU_ERR_INVALID_TAILROOM = 0x20, +}; + +struct cl_amsdu_rx_state { + u8 msdu_cnt; + u8 msdu_remaining_cnt; + /* + * MSDU padding - all MSDU pkt within A-MSDU are 4byte aligned (this + * value holds the alignment value) + * According to ieee80211 spec all MSDU share the same alignment + */ + u8 msdu_dma_align; + u8 amsdu_error; + u8 encrypt_len; + u8 sta_idx; + u8 tid; + u32 packet_len; + struct hw_rxhdr *rxhdr; + struct sk_buff *first_skb; + struct sk_buff_head frames; +}; + +void cl_rx_amsdu_first(struct cl_hw *cl_hw, struct sk_buff *skb, struct hw_rxhdr *rxhdr, + u8 sta_idx, u8 tid, u8 encrypt_len); +bool cl_rx_amsdu_sub(struct cl_hw *cl_hw, struct sk_buff *skb); +bool cl_rx_amsdu_check_aggregation_attack(struct cl_amsdu_rx_state *amsdu_rx_state); +void cl_rx_amsdu_first_corrupted(struct cl_hw *cl_hw, struct sk_buff *skb, + struct hw_rxhdr *rxhdr); +void cl_rx_amsdu_sub_error(struct cl_hw *cl_hw, struct sk_buff *skb); +void cl_rx_amsdu_set_state_error(struct cl_hw *cl_hw, + struct hw_rxhdr *rxhdr, + enum rx_amsdu_error err); +void cl_rx_amsdu_reset(struct cl_hw *cl_hw); +void cl_rx_amsdu_stats(struct cl_hw *cl_hw, u8 msdu_cnt); +void cl_rx_amsdu_hw_en(struct ieee80211_hw *hw, bool rxamsdu_en); + +/* Field definitions */ +#define RX_CNTRL_EN_DUPLICATE_DETECTION_BIT ((u32)0x80000000) +#define RX_CNTRL_EN_DUPLICATE_DETECTION_POS 31 +#define RX_CNTRL_ACCEPT_UNKNOWN_BIT ((u32)0x40000000) +#define RX_CNTRL_ACCEPT_UNKNOWN_POS 30 +#define RX_CNTRL_ACCEPT_OTHER_DATA_FRAMES_BIT ((u32)0x20000000) +#define RX_CNTRL_ACCEPT_OTHER_DATA_FRAMES_POS 29 +#define RX_CNTRL_ACCEPT_QO_S_NULL_BIT ((u32)0x10000000) +#define RX_CNTRL_ACCEPT_QO_S_NULL_POS 28 +#define RX_CNTRL_ACCEPT_QCFWO_DATA_BIT ((u32)0x08000000) +#define RX_CNTRL_ACCEPT_QCFWO_DATA_POS 27 +#define RX_CNTRL_ACCEPT_Q_DATA_BIT ((u32)0x04000000) +#define RX_CNTRL_ACCEPT_Q_DATA_POS 26 +#define RX_CNTRL_ACCEPT_CFWO_DATA_BIT ((u32)0x02000000) +#define RX_CNTRL_ACCEPT_CFWO_DATA_POS 25 +#define RX_CNTRL_ACCEPT_DATA_BIT ((u32)0x01000000) +#define RX_CNTRL_ACCEPT_DATA_POS 24 +#define RX_CNTRL_ACCEPT_OTHER_CNTRL_FRAMES_BIT ((u32)0x00800000) +#define RX_CNTRL_ACCEPT_OTHER_CNTRL_FRAMES_POS 23 +#define RX_CNTRL_ACCEPT_CF_END_BIT ((u32)0x00400000) +#define RX_CNTRL_ACCEPT_CF_END_POS 22 +#define RX_CNTRL_ACCEPT_ACK_BIT ((u32)0x00200000) +#define RX_CNTRL_ACCEPT_ACK_POS 21 +#define RX_CNTRL_ACCEPT_CTS_BIT ((u32)0x00100000) +#define RX_CNTRL_ACCEPT_CTS_POS 20 +#define RX_CNTRL_ACCEPT_RTS_BIT ((u32)0x00080000) +#define RX_CNTRL_ACCEPT_RTS_POS 19 +#define RX_CNTRL_ACCEPT_PS_POLL_BIT ((u32)0x00040000) +#define RX_CNTRL_ACCEPT_PS_POLL_POS 18 +#define RX_CNTRL_ACCEPT_BA_BIT ((u32)0x00020000) +#define RX_CNTRL_ACCEPT_BA_POS 17 +#define RX_CNTRL_ACCEPT_BAR_BIT ((u32)0x00010000) +#define RX_CNTRL_ACCEPT_BAR_POS 16 +#define RX_CNTRL_ACCEPT_OTHER_MGMT_FRAMES_BIT ((u32)0x00008000) +#define RX_CNTRL_ACCEPT_OTHER_MGMT_FRAMES_POS 15 +#define RX_CNTRL_ACCEPT_ALL_BEACON_BIT ((u32)0x00002000) +#define RX_CNTRL_ACCEPT_ALL_BEACON_POS 13 +#define RX_CNTRL_ACCEPT_NOT_EXPECTED_BA_BIT ((u32)0x00001000) +#define RX_CNTRL_ACCEPT_NOT_EXPECTED_BA_POS 12 +#define RX_CNTRL_ACCEPT_DECRYPT_ERROR_FRAMES_BIT ((u32)0x00000800) +#define RX_CNTRL_ACCEPT_DECRYPT_ERROR_FRAMES_POS 11 +#define RX_CNTRL_ACCEPT_BEACON_BIT ((u32)0x00000400) +#define RX_CNTRL_ACCEPT_BEACON_POS 10 +#define RX_CNTRL_ACCEPT_PROBE_RESP_BIT ((u32)0x00000200) +#define RX_CNTRL_ACCEPT_PROBE_RESP_POS 9 +#define RX_CNTRL_ACCEPT_PROBE_REQ_BIT ((u32)0x00000100) +#define RX_CNTRL_ACCEPT_PROBE_REQ_POS 8 +#define RX_CNTRL_ACCEPT_MY_UNICAST_BIT ((u32)0x00000080) +#define RX_CNTRL_ACCEPT_MY_UNICAST_POS 7 +#define RX_CNTRL_ACCEPT_UNICAST_BIT ((u32)0x00000040) +#define RX_CNTRL_ACCEPT_UNICAST_POS 6 +#define RX_CNTRL_ACCEPT_ERROR_FRAMES_BIT ((u32)0x00000020) +#define RX_CNTRL_ACCEPT_ERROR_FRAMES_POS 5 +#define RX_CNTRL_ACCEPT_OTHER_BSSID_BIT ((u32)0x00000010) +#define RX_CNTRL_ACCEPT_OTHER_BSSID_POS 4 +#define RX_CNTRL_ACCEPT_BROADCAST_BIT ((u32)0x00000008) +#define RX_CNTRL_ACCEPT_BROADCAST_POS 3 +#define RX_CNTRL_ACCEPT_MULTICAST_BIT ((u32)0x00000004) +#define RX_CNTRL_ACCEPT_MULTICAST_POS 2 +#define RX_CNTRL_DONT_DECRYPT_BIT ((u32)0x00000002) +#define RX_CNTRL_DONT_DECRYPT_POS 1 +#define RX_CNTRL_EXC_UNENCRYPTED_BIT ((u32)0x00000001) +#define RX_CNTRL_EXC_UNENCRYPTED_POS 0 + +/* Default MAC Rx filters that cannot be changed by mac80211 */ +#define CL_MAC80211_NOT_CHANGEABLE ( \ + RX_CNTRL_ACCEPT_QO_S_NULL_BIT | \ + RX_CNTRL_ACCEPT_Q_DATA_BIT | \ + RX_CNTRL_ACCEPT_DATA_BIT | \ + RX_CNTRL_ACCEPT_OTHER_MGMT_FRAMES_BIT | \ + RX_CNTRL_ACCEPT_MY_UNICAST_BIT | \ + RX_CNTRL_ACCEPT_BROADCAST_BIT | \ + RX_CNTRL_ACCEPT_BEACON_BIT | \ + RX_CNTRL_ACCEPT_PROBE_RESP_BIT \ + ) + +u32 cl_rx_filter_update_flags(struct cl_hw *cl_hw, u32 filter); +void cl_rx_filter_restore_flags(struct cl_hw *cl_hw); +void cl_rx_filter_set_promiscuous(struct cl_hw *cl_hw); + +struct cl_tid_ampdu_rx { + spinlock_t reorder_lock; + u64 reorder_buf_filtered; + struct sk_buff_head *reorder_buf; + unsigned long *reorder_time; + struct ieee80211_sta *sta; + struct timer_list reorder_timer; + struct cl_hw *cl_hw; + u16 head_seq_num; + u16 stored_mpdu_num; + u16 ssn; + u16 buf_size; + u16 timeout; + u8 tid; + u8 auto_seq:1, + removed:1, + started:1; +}; + +void cl_rx_reorder_ampdu(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, struct sk_buff_head *ordered_mpdu); +void cl_rx_reorder_close(struct cl_sta *cl_sta, u8 tid); +void cl_rx_reorder_init(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 tid, u16 buf_size); + +#endif /* CL_RX_H */ From patchwork Tue May 24 11:34:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575958 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 C80F7C433FE for ; Tue, 24 May 2022 11:40:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236949AbiEXLkp (ORCPT ); Tue, 24 May 2022 07:40:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236105AbiEXLkl (ORCPT ); Tue, 24 May 2022 07:40:41 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60044.outbound.protection.outlook.com [40.107.6.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C56652E53 for ; Tue, 24 May 2022 04:39:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eo0EvKniGP4CGTQHW2wtoRhO0Jnk93X7d85BlomoAPXOs16Fq4lu547w+naWjUm1QHRb9wcRINxYXbnIGsbjv0cBSelyz2jVxf7asrVecjg4Vt0tFznDpcGuiMkR8mQIIYWJgEiZPxlXgXjU5tUGWb5F2CxTaZ6s8kswrs2uAenrZVD1knbBS39sJom5w5u/vYYost4CGP0YJUkBvDTUP6KVHid0e1EKNg+weENDV6uTax3R4IUlw+JBRc1MTtSZmO3Aj42Er0t6oKY3jFHEk0SOhrrBlnfRVOv0MNHe4YLMb0sJuIFbksW2nOLfF3tWnLoHqykYivjXE42wJX024g== 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=1NKkNFUnzF4NBOR/kll86ViWsMGlbf5FYlK9A+AVYl0=; b=GyqMQuge2uTtmNV6gLBD90F9AvrnyVdWvGRqyGPv4+oBjaRMa1iyT6n2tMHU3RqMTXiO3ZZq2In88bN2n44DowN5T74RdkwxVrevaZVhRLcHJUnG01pmjq67ABpeVt5HmNRDIc2P3c5kWfV28okxYOK23iC+jrv79n3rYQ82xlEM0VFP0sSHI6QmU249vML0LEH0jK854Gfbnf2L6APdwctWonXuoCCUkli9O9iMeKm2+YnNgcfWwOE2rI4SeuI70qNIESTlvctl5P9hK38//BRu5K0Hquo0vJK8DG9TJudUD23l2S2AuY0zD3l9+0Cp2ORDTEwB/BkoaT5Uir+VMg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1NKkNFUnzF4NBOR/kll86ViWsMGlbf5FYlK9A+AVYl0=; b=AneTBnVw4DBov0k78wMCWJ8cJ0iSzxkth19wexQs6MplMJeGFAT+2nRV73HS0837kyV6uJlUoF6E5hW8zEycPextGGRr+G+VCUwa0Q5FDV0hxz9ZlcuViDGA2YLYDKe9f01jbnzbwKX61NP1ajGFC+C5as13/124cQhD3CaVt1s= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:26 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:26 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 70/96] cl8k: add scan.c Date: Tue, 24 May 2022 14:34:36 +0300 Message-Id: <20220524113502.1094459-71-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 553d6de1-df54-4ee7-b1f3-08da3d79f654 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: QOxkJSLcbLocB9PEZcQ4R4l9y6jjtKIONRIiWp7dejMKKsz2ayh7kLaskpNjrkZKkzTIbF98htNvI2x0gyYiFDwZvla2NGdkRg8UaRqYMX4GOrcSzJYyWQjixdmc3TwR9oe4vktUL0hg+fxEABsEYhLUgrmQQ8RRHpt7TcCnI9hLErLWc7B+TBNLCPOnck7eyAZC7FUvhiYNES4GI4LI7e7KoFeQ4Kkd+OeyCclgZHua8yzUIEQu4WjuCxGUiFx305Qxo/A8NVGActDoCKwxUV6FTAlbCbv0Hqjd8yc/1MXOQIdj1lWHZ8yo5rxEa1LU/iwauz2tMjaRZpDuDZFxn+/ubNbZ4RQbc6PPh25IEROSO0qQ/0GHcIjk9eEj+QEwpdO/hUklhCYpD1TzAzWRAyfmrd4Vot6VIBdaESI8pVaSP3Kgqgfzlu3EjGdHRapsbh3CulWc2y0v8zoQlBd0uxqyK7xiUnBfVpMGumfVtK8heJXEX8542J7pyTSA4dysWXgpz0A8JahhmTKHd77E6l1kjw4QXuMB9Nu+8O6NcHDCtCjVcna2R3yQBNGI/aaeN56a1xGfoCFHYX3lE/SzXBZOT8GUfCn541KmuBOL65itb5uvs+Wqu3Zv7kvAiS8xUYp4T7X54zRnVoSy7g2BCYBPnbFjpNtHJkR8ERfFA1BDAbPxbb+QT68MiJUzCcJdKh9RY2bv9nzf1uB9q98Xl9xhabX1OdUlU54IJUvvnXQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(45080400002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: hYMa5CzzcReSszsFsUuiCELcjttVbRGPrVEywnSya/ajoeyYA37WefJ2lP/gRuUTBfPCY3xAxG/cCPbQikrGSbZWIc8j12F7T9p5LjyFuFOxVZnhZ5ITVD1CRhdzqqs5V/GGK9Fn/T7HnSnXF/F/UO52EGOOWm8wB17LxipjDwTwG1V9IRsBoE0FNaf1pLN2NaU5g+1s/hlZwa4SK6LgAJujsHhVARKQPyPRkoSOdjreJ22IxC0o2m9EU/xDyto/eHd7RTUp2cQhezExD9PQUc3L8u66Hn5/qAaO7MF4fFtEQI2Q40pnSmAC0yJxWIFSkt83xpRjgLT7gF6HxQwNKqT1uuuOKscPmmTNmbLfB/QnDVczJz/CHvQkjPkSeOrapFNotXx1wXiU0cqXeS0OQ5m1I+vvkJbiBj0mAwkTe0UU5fMT8gI9GHsqk/DIanYCUUHECFWIqW1eO4fbiGpdco6h5gSSn2oTaogaoBTd2yncJ2Ng0jFTh7Cg5/ApxPsuWoIzPgMrmBOz35jHDwOZ1No70G0hk/DF7zq4rquJ4QF43PLDHfavd8IyOyBsVqj6hCgZXNwJXRK2dGPFeuoTeHmvnqr3zQ2+mXL9oHMG4HPEEmZYyP6aKoCdk1oHLc9Znd6oyi4981yFbnF16ZOPINr3kPCVn06eYhGhH6KMKtK6RnvC8Hv9meT1NcIxxeco6x435aBtCOTf04JcwHbT3XULIDnEj0XoFAx6chUHXz2TPjtIBarP9E5/tDKVYDlAvTRJkvIBReW4AP3StPV8zZKU7TVws9x1eCFJ6Ts/VY0vpmPFcFO59ET6bqYL8WhUVC/G1x4gPDJurI5P56+To/Ivm1Rf+P/yovJE3+HjycVOqgSJnRyi8hfI7rhCscbNH35Woc4I0OLCfpkrOGTujbcVNU6fed2TfcfrptfXNuii7lc8h0ZxVCqAXHa66NfYdNERhMMQMxuLSFYJPzJm30d8gM36WtWMATXF4rrTMyII68kFgPKtK9tycJM82bnh+bf9SBH38ZSTMT3sogUicOkXUiULyKXwKoyNRvBQ/FT0SCxqvIMDh9TmmYTNa+lNx9c+rwBtZvQPom+1QNX2oVdXj8HZ2PGEm0eDSOC1x/H6BNFIdXiegDZci1wvLrpYuWPlXtzkrAT5OlJAvPopTNUAWkIjn58aDHfL+jJx4BP4apbe/6j67z6KYmZN/pQF98WT+DkKMflNOlXD3A4co5TGBEDTglieWIYQ4TSY0yqTryRclJ8cQ1kAd9atEhLO3PfDlgGkFWkWmynC8bPnI1FBRvEYov52poH5bvnxZQJZVQ8e1BcDetw8Zs5x9d5kdsAR3C2Sc0sRN1B44GodJ+mEaNO9H2MNKZuQgnVQD5sKf7FKHc6S43fiyL6j+GHBC60Zky3ENkDwArJAO9um/3vFQPEO97SNc+z8IpGm8rOIK+lYcr/cpryAdFBjn0Wu8vDcjJ41KibjWgjQ9/0hoInWWrl7kdnLKzMpGyPs4KcIk+Wlv9p//bFYz/YjlZsMcnpXBtqmPxSR1B/km3A1OiVYVcvlwl8vliKy6xJliLeHf9ePPVUxyvXNAAFY70/dELrLeJcg1ezBQQv7aoULKTiUIXdxuB03kaTF3vJi+XkYznIpq4xRCW8owZsL/54JSQa42mIiai+cWPelz1tw7K+dVWaLLozu/pKXYN5UQ76CFx0jxcg0sh/sWqOdNNYyZrRRktmkdRn1MHHrx817heoqx+WjSGuYwIpOVYwkdG4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 553d6de1-df54-4ee7-b1f3-08da3d79f654 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:46.0679 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: oleXYSTvYSojiks2TgKTFZfmxhjnzzsh/d7kImlzd9El5k7xkszFNhkbVp/CzD9PjeCCAOJWbSf1pix6hSxPWA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/scan.c | 392 ++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/scan.c diff --git a/drivers/net/wireless/celeno/cl8k/scan.c b/drivers/net/wireless/celeno/cl8k/scan.c new file mode 100644 index 000000000000..10076d93620e --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/scan.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include +#include +#include + +#include "channel.h" +#include "chip.h" +#include "calib.h" +#include "debug.h" +#include "rates.h" +#include "vif.h" +#include "hw.h" +#include "scan.h" + +#define CL_MIN_SCAN_TIME_MS 50 +#define CL_MIN_WAIT_TIME_MS 20 + +static const char SCANNER_KTHREAD_NAME[] = "cl_scanner_kthread"; + +int cl_scan_channel_switch(struct cl_hw *cl_hw, u8 channel, u8 bw, + bool allow_recalib) +{ + struct cl_vif *cl_vif = cl_vif_get_first(cl_hw); + struct cfg80211_chan_def *chandef = NULL; + struct cfg80211_chan_def local_chandef; + struct ieee80211_channel *chan = NULL; + u16 freq = ieee80211_channel_to_frequency(channel, cl_hw->nl_band); + int ret = 0; + + if (!cl_vif) { + ret = -EINVAL; + goto exit; + } + + chandef = &cl_vif->vif->bss_conf.chandef; + local_chandef = *chandef; + + chan = ieee80211_get_channel(cl_hw->hw->wiphy, freq); + if (!chan) { + cl_dbg_err(cl_hw, "Channel %u wasn't found!\n", channel); + ret = -EINVAL; + goto exit; + } + + local_chandef.chan = chan; + if (cl_chandef_calc(cl_hw, channel, bw, + &local_chandef.width, + &local_chandef.chan->center_freq, + &local_chandef.center_freq1)) { + cl_dbg_err(cl_hw, "Failed to extract chandef data for ch:%d\n", + channel); + ret = -EINVAL; + goto exit; + } + + *chandef = local_chandef; + cl_hw->hw->conf.chandef = local_chandef; + + if (cl_hw->chip->conf->ce_calib_runtime_en && allow_recalib) + ret = cl_calib_runtime_and_switch_channel(cl_hw, channel, bw, + freq, + chandef->center_freq1); + else + ret = cl_msg_tx_set_channel(cl_hw, channel, bw, freq, + chandef->center_freq1, + CL_CALIB_PARAMS_DEFAULT_STRUCT); +exit: + return ret; +} + +static int cl_scan_channel(struct cl_chan_scanner *scanner, u8 ch_idx) +{ + u8 main_channel; + enum cl_channel_bw main_bw; + s32 res = 0; + bool is_off_channel; + u64 scan_time_jiffies; + + /* + * 1. Save current channel + * 2. Disable tx + * 3. jump to new channel + * 4. Enable promiscious + * 5. Enable BSS collection + * 6. Reset stats counters + * 7. Sleep for scan_time + * 8. Calculate stats + * 9. Disable promiscious + * 10. Disable BSS collection + * 11. Switch to current channel + * 12. Enable tx + **/ + + cl_dbg_trace(scanner->cl_hw, "Starting scan on channel %u, scan time %u(ms)\n", + scanner->channels[ch_idx].channel, scanner->scan_time); + + /* Save current channel */ + res = mutex_lock_interruptible(&scanner->cl_hw->set_channel_mutex); + if (res != 0) + return res; + main_channel = scanner->cl_hw->channel; + main_bw = scanner->cl_hw->bw; + mutex_unlock(&scanner->cl_hw->set_channel_mutex); + + cl_dbg_trace(scanner->cl_hw, "Main channel is %u with bw %u\n", + main_channel, main_bw); + + is_off_channel = (scanner->channels[ch_idx].channel != main_channel) || + (scanner->channels[ch_idx].scan_bw != main_bw); + + /* Jump to new channel */ + if (is_off_channel) { + /* Disable tx */ + cl_tx_en(scanner->cl_hw, CL_TX_EN_SCAN, false); + + res = cl_scan_channel_switch(scanner->cl_hw, + scanner->channels[ch_idx].channel, + scanner->channels[ch_idx].scan_bw, + false); + if (res) { + cl_dbg_err(scanner->cl_hw, + "Channel switch failed: ch - %u, bw - %u, err - %d\n", + scanner->channels[ch_idx].channel, + scanner->channels[ch_idx].scan_bw, res); + goto enable_tx; + } + } else { + cl_dbg_trace(scanner->cl_hw, "Scan on main channel %u\n", main_channel); + } + + /* Enable promiscious mode */ + cl_rx_filter_set_promiscuous(scanner->cl_hw); + + /* Reset channel stats */ + cl_get_initial_channel_stats(scanner->cl_hw, &scanner->channels[ch_idx]); + + /* Sleep for scan time */ + scan_time_jiffies = msecs_to_jiffies(scanner->scan_time); + res = wait_for_completion_interruptible_timeout(&scanner->abort_completion, + scan_time_jiffies); + if (res > 0) { + cl_dbg_err(scanner->cl_hw, "Scan on channel %u, bw %u, idx %u was aborted\n", + scanner->channels[ch_idx].channel, + scanner->channels[ch_idx].scan_bw, ch_idx); + res = 0; + } + + /* Calculate stats */ + cl_get_final_channel_stats(scanner->cl_hw, &scanner->channels[ch_idx]); + + /* Disable promiscious */ + cl_rx_filter_restore_flags(scanner->cl_hw); + + if (is_off_channel) { + res = cl_scan_channel_switch(scanner->cl_hw, main_channel, main_bw, false); + if (res) + cl_dbg_err(scanner->cl_hw, + "Switching to main ch %u, bw %u failed, err - %d\n", + main_channel, main_bw, res); +enable_tx: + /* Enable tx */ + cl_tx_en(scanner->cl_hw, CL_TX_EN_SCAN, true); + } + + cl_dbg_trace(scanner->cl_hw, "Scan on channel %u finished, actual scan_time is %u ms\n", + scanner->channels[ch_idx].channel, scanner->channels[ch_idx].scan_time_ms); + + return res; +} + +static s32 cl_run_off_channel_scan(struct cl_chan_scanner *scanner) +{ + u8 i = 0, scanned_channels = 0; + s32 ret = 0; + + for (i = 0; i < scanner->channels_num && !scanner->scan_aborted; ++i) { + if (!scanner->channels[i].scan_enabled) + continue; + + scanner->curr_ch_idx = i; + ret = cl_scan_channel(scanner, i); + if (ret) + cl_dbg_err(scanner->cl_hw, "scan failed, err - %d, channel - %u\n", + ret, scanner->channels[i].channel); + + if (scanner->scan_aborted) + break; + + cl_dbg_trace(scanner->cl_hw, "Scan on chan %u finished, waiting for time %u\n", + scanner->channels[i].channel, scanner->wait_time); + + ++scanned_channels; + if (scanned_channels != scanner->scan_channels_num) { + u64 wait_time_jiffies; + + wait_time_jiffies = msecs_to_jiffies(scanner->wait_time); + ret = wait_for_completion_interruptible_timeout(&scanner->abort_completion, + wait_time_jiffies); + if (ret > 0) { + cl_dbg_err(scanner->cl_hw, "Off-channel scan was aborted\n"); + ret = 0; + } + } + } + + if (scanner->completion_cb) + scanner->completion_cb(scanner->cl_hw, scanner->completion_arg); + + cl_dbg_info(scanner->cl_hw, "Off-channel scan on %u channels finished\n", + scanner->scan_channels_num); + + return ret; +} + +static s32 cl_off_channel_scan_thread_fn(void *args) +{ + struct cl_chan_scanner *scanner = args; + + while (!kthread_should_stop()) { + if (atomic_read(&scanner->scan_thread_busy)) { + cl_run_off_channel_scan(scanner); + atomic_set(&scanner->scan_thread_busy, 0); + wake_up_interruptible(&scanner->wq); + } + + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + + return 0; +} + +static bool cl_is_scan_available(struct cl_chan_scanner *scanner) +{ + if (atomic_cmpxchg(&scanner->scan_thread_busy, 0, 1) == 1) { + cl_dbg_warn(scanner->cl_hw, "Off-channel scan is already in progress\n"); + return false; + } + + return true; +} + +static enum cl_channel_bw cl_scanner_fix_input_bw(struct cl_chan_scanner *scanner, u8 bw) +{ + return (bw >= CHNL_BW_MAX) ? scanner->cl_hw->bw : bw; +} + +static void cl_scanner_disable_everywhere(struct cl_chan_scanner *scanner) +{ + u8 j; + + for (j = 0; j < scanner->channels_num; ++j) + scanner->channels[j].scan_enabled = false; +} + +s32 cl_trigger_off_channel_scan(struct cl_chan_scanner *scanner, u32 scan_time, u32 wait_time, + const u8 *channels, enum cl_channel_bw scan_bw, u8 channels_num, + void (*completion_cb)(struct cl_hw *cl_hw, void *arg), + void *completion_arg) +{ + u8 i, j; + + if (!channels || scan_bw > CHNL_BW_MAX) + return -EINVAL; + + if (!scanner->scans_enabled) + return 0; + + if (channels_num > scanner->channels_num) { + cl_dbg_err(scanner->cl_hw, "channels num %u is invalid, max is %u\n", + channels_num, scanner->channels_num); + return -ERANGE; + } + + if (!cl_is_scan_available(scanner)) + return -EBUSY; + + scanner->completion_arg = completion_arg; + scanner->completion_cb = completion_cb; + scanner->scan_time = max_t(u32, scan_time, CL_MIN_SCAN_TIME_MS); + scanner->wait_time = max_t(u32, wait_time, CL_MIN_WAIT_TIME_MS); + scanner->scan_bw = cl_scanner_fix_input_bw(scanner, scan_bw); + scanner->scan_aborted = false; + + cl_scanner_disable_everywhere(scanner); + + scanner->scan_channels_num = 0; + for (j = 0; j < scanner->channels_num; ++j) { + for (i = 0; i < channels_num; ++i) { + if (channels[i] != scanner->channels[j].channel) + continue; + + if (!cl_chan_info_get(scanner->cl_hw, scanner->channels[j].channel, + scanner->scan_bw)) { + cl_dbg_warn(scanner->cl_hw, "channel %u with bw %u is disabled\n", + scanner->channels[j].channel, scanner->scan_bw); + continue; + } + + scanner->channels[j].scan_enabled = true; + ++scanner->scan_channels_num; + } + } + + reinit_completion(&scanner->abort_completion); + + wake_up_process(scanner->scan_thread); + + return 0; +} + +void cl_abort_scan(struct cl_chan_scanner *scanner) +{ + scanner->scan_aborted = true; + complete(&scanner->abort_completion); + cl_dbg_info(scanner->cl_hw, "Off-channel scan was aborted\n"); +} + +bool cl_is_scan_in_progress(const struct cl_chan_scanner *scanner) +{ + return atomic_read(&scanner->scan_thread_busy); +} + +int cl_scanner_init(struct cl_hw *cl_hw) +{ + u8 i, j; + s32 ret = 0; + u32 channels_num; + struct cl_chan_scanner *scanner; + + cl_hw->scanner = vzalloc(sizeof(*cl_hw->scanner)); + if (!cl_hw->scanner) + return -ENOMEM; + + scanner = cl_hw->scanner; + init_completion(&scanner->abort_completion); + + scanner->cl_hw = cl_hw; + scanner->scans_enabled = true; + + channels_num = cl_channel_num(scanner->cl_hw); + for (i = 0, j = 0; i < channels_num; ++i) { + u32 freq; + + freq = cl_channel_idx_to_freq(cl_hw, i); + if (!ieee80211_get_channel(cl_hw->hw->wiphy, freq)) + continue; + + ret = cl_init_channel_stats(scanner->cl_hw, &scanner->channels[j], freq); + if (ret) + return ret; + + cl_dbg_trace(scanner->cl_hw, "Stats for channel %u at index %u initialized\n", + scanner->channels[j].channel, j); + ++j; + } + + scanner->channels_num = j; + + atomic_set(&scanner->scan_thread_busy, 0); + init_waitqueue_head(&scanner->wq); + + scanner->scan_thread = kthread_run(cl_off_channel_scan_thread_fn, + scanner, SCANNER_KTHREAD_NAME); + if (IS_ERR(scanner->scan_thread)) { + cl_dbg_err(scanner->cl_hw, "unable to create kthread %s, err - %ld\n", + SCANNER_KTHREAD_NAME, PTR_ERR(scanner->scan_thread)); + return PTR_ERR(scanner->scan_thread); + } + cl_dbg_trace(scanner->cl_hw, "%s kthread was created, pid - %u\n", + SCANNER_KTHREAD_NAME, scanner->scan_thread->pid); + + return ret; +} + +void cl_scanner_deinit(struct cl_hw *cl_hw) +{ + struct cl_chan_scanner *scanner = cl_hw->scanner; + + if (!scanner->scans_enabled) + goto out; + + if (scanner->scan_thread) + kthread_stop(scanner->scan_thread); + + out: + vfree(cl_hw->scanner); + cl_hw->scanner = NULL; +} From patchwork Tue May 24 11:34:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575948 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 244A3C433EF for ; Tue, 24 May 2022 11:41:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236958AbiEXLky (ORCPT ); Tue, 24 May 2022 07:40:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236709AbiEXLkr (ORCPT ); Tue, 24 May 2022 07:40:47 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60065.outbound.protection.outlook.com [40.107.6.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04F0392D2F for ; Tue, 24 May 2022 04:40:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IsGGd41TT1QJWhFRwAc9LyLutlu4zfD5o/LpjlXaD6g9OrJa1U7Dyc4OOBA/XxvfnUw/J3RuicVoqbQ6pKnImI6SUJ+ERIppphOMZmeyqsvHj+LUZcduoZXAQSzSCewoXfjFYKqgmwUXD3p348MMwRGqVwNPxSCk5WuAABM+DV4Qh+NhqKx88z7Au8dvk1fvxLapVYdqs+fyBns/be9PI8zmpymxdx3yEDXUpSsIEh6YOGm9Htn0n8fpRDChj9OQwZI7vqRonOS8RYsU3mkmw3iDEGrFZ7I6n7BOf7bEdkyHbEf4oQW6MiYZZb8wn14vE+g+5+QQYGfLSCC5sYAOJg== 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=kWenKMz6sRkGRCEeZNuLRQX0Fpm7HBuV/91nSZIKfWw=; b=mKnSMZGlnLJ6WNOJb08BMLalh59Ab5rjhk96eEhMUQRKpLSCKAMDO/mrJgELZb+oTtNbgVXV0wBUMXnxCN1x0p82F82LhWTXSFWu1KdQBBMuEjUrq45PG4cAlUPl8ZKeqx8Y2J2suMa8WkHednC7XvePe1JlsxM0L7ZkU20SUgYZOmwn/KmAIXj9VtJ7LMb2x8FKfPun0E2Tk7FygwWPoSF6I5jQ2xa+xMg1eKXK+K26BBFMDUWPJgJEGYrek751SYu4Tr6YOvd03bHToRGlIfzbNSqkem8PrnNH2OWPac/IdRzWvI978FFe9H4Qi4nPrej6FV6jTVWG/eQ8a9av+w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=kWenKMz6sRkGRCEeZNuLRQX0Fpm7HBuV/91nSZIKfWw=; b=bIkn91i3CQecEZO1je+cFWiTps0KBt+0f8Ac1dgoxN1HT8MVh3JGbatyRi5po39SBErYJuYRnRhDvTMMibwidjbtar+s5gAaOqSv8hARiFKXUvWU68/xSw9Os711FNum5jQLtkDyBLlgXSyIivGF9sn4vwkYtDMBFjFIiitjE+o= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:26 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:26 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 71/96] cl8k: add scan.h Date: Tue, 24 May 2022 14:34:37 +0300 Message-Id: <20220524113502.1094459-72-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 60798ae7-bd04-43ff-8132-08da3d79f6c9 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: H3Mrl0lwAYie4ueynuHLOZZ5W/ARjWESB3Ttux524C7MkE787W+fbj6r+faN7jFs7SbfLRjhSgz/OV4iZP144gG5o35aH9V3sTKx1nA0ExIiqD6dhM5ao4VVWHmDBYBO/oVro6exp0cyvAnQxONT+Qb+ywoxL2wBf8aZOjtifY1KuwqUNbNLdfu+/vvpD96FF3EZe5p/HDA2P1K0cexK+gBufboLOfdNwulOrIwpisVWusJLgkIfLZkONzkUVUpOxiC8SFXZ1KSrBd0aFwl9B1uQGz2gcjC4/EHaFC/36FzNIZ92zEejo2WOvkA2udiicWtkNRzlpqJqATUh+kxvLYhBlodukNikllNVXEh2MvJfYFWz/fA3TcXHGAn/WmK27BfeKqE5UQAqC1n2kxwQquauWuk7yTQgbcAi5sJ0AGaebPiijOQ7/DEOuc45Gmea41sWAbKK2zM7sHtQvDEZ5KJ07TE3dA/kcRZUkuxqKPI1S1xYvT5XGSsTAUYEiVolxcEjaZXSOLU4BMIAQ8tvxb5Gm5Nd2tax1i4zNMTp3jGovZNQE/qlOFp4WmsZ+sXGzsKNsSW1iwClomso9ffYNiUaRXdzc4LAa7sGhB3lGmtfaPiogwy5Pe8C5cy43Jhaq6VAofJFoGmvhrSZ0zLOHMGA1o32SFc9+5im8EHH1M8P9tZvyUWBJfXKsedDF0D2lZMNLMErst5XR6ujL8gE01KdvydreRBxXIlBgDwOkLg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: IWKTP5y9Y2kMOCADCPCk+U23k/V0swE3ZEzr7nBonhCfsavll/a7xRFCz8IheD6wLKkHMpEOz2lPv4Ocy718nQZpXX0iqoYiP7nLxuKdQaTVZgXU3vqLpCt6/JrNJ0GaUF+5vIOpPYlWRwTWPBvWynkvUwPobfONLbZX1bmz/wIkYKL8v3o/JLfoOS0shfSOebA55+dqjX/N+4rz3xyoGWkcH2BiQU/cqkY4w//DgqBcet+7Hm8e+LPtfHO+6jvie3wGsptr5NU9WzUqqxSeokOy0rIRhKQm4ECr70La+2WxjLts7zem5KqHyR/OP2UgRKh/viGn5otrRSNBfoYO99mO+FiDiFRKflt89l9ADH87VWBYlJXuy2OJxzXZDUlsMSxcj3wRiyS3nsvziAmvBgztZDFMzPV0wbid7PjSovT/Mo3vzTPB9/d/qPDxvHe5d2+G9L3gJvIM3tC9Zd/PQvWdHji4pOWoQLl5TxcEeLTWFZptMyNG6y9OwgWHkgQqizv3qAX9MBQkC7R9Si0h0Gf5IqhIoI+g1O9l5rH749xTm7Q35Pr3jHnROOLFY4v02ulLJldFgxzISu2OMaVMMCNK5QbRQk+QFrZpoyDog/UXPYiF62DNLbqwHSAQ1TwBzNtNJRmYmOPJQHeoHwDcNPmCaEbBjDp4DKBZpRmew0dEaRsuQL8MakRWjA7dc6UbaNw5qK2VUPHURX8m25oGZk1NF1dHhQPp2YZZFJOIyXnHmDBUzzj5dEPD271Wc0XmfTmEQLHbDtVJAKEKmt5wx37qQski4V2hDMxdJa96zBfMSguR3xCN8jygXFkQoLnhAlCbMU7A7KzajevavH8LCIUivTCQM8g5+P1DJ23dNArc0/7IC9uBsH1Hv2QxlJKhhJ2d8O/xloIdockm0himmX0+7y4Sf2gX2S2C78CNeH8CzewuyX+zBEwstWZuigAJ+xfhcO2yR9EFDjqFLTl6SP6DS2RsbOGzHT21Lgj9JgdofbAlNxL5xkdfI3BAa5UjUUagQMP0Wgdp/Qv1UmgfVIIRUgsLssV+fhDJyRt90bHZ7CkpQZa1bz78LUC4J8F4Bnlz54dSJ/MUZ+RFcqCDccK5jSLxkaV/ZlZPmzE0HWnzTNQW/h1dnuNZyUOLh1xB+ySOn7EW/rs01r+7+hpJ3zu4oeadeAudMz+typsUkUIbX2SmAQ4ZORG/ARtntQ3KVZ/ezY9By65Jo6rarO/kMHgdrByPAIQnA2vb7W9+bTU4oyZ58L5F5UORT50WokHqlUSdCaiKJMmn7X643yQEJWFT77pfvzAbb17SGEIG8poWA85UNjGNZwusnkdsgO5oHSBFf65ETJZwrLe+FGDxv9qkTEMf3mWjtauhRLhYZvZ4sWRh5NnWAEYe5dW5Egyt8INOSkNg7Ooxgwn6KsuNx1Ag9L1O1VveRADUfUIrwPLJEOrGnP0dU26rP9goRvgFVlxkz1wLxvtcPSGBw4kDTX44oUHfaWJGMOJBfFyfYA4tS3wKIzZXXfkBILbjWta+XnUwDEy9F8wXOeE74Xc2ff0AjLzhLn7pgykjQmS2+gFdx2HPhsl5f4ErmdSzibgvBqTrSHpTCn9k5wUmpvvQTKFvhzSqsjUMHGBmfL+5XTjKGCcx5SBIWOgVo/1kyj/OP6S3LA5vMFoL3eBvFR5Df0DQU1JWlpSSrQws67przyNcBfzv2PBDOK7DpZVigFSmMR/888d2j/ogot+gbeQw7eJZDr6eOKAacig/k6+yvsc= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 60798ae7-bd04-43ff-8132-08da3d79f6c9 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:46.8490 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: G17TUoo5T0Wmea2qOJXGO4Lf4LPeesVpWCd0C/9C100HEhv7vzPzerdC3oyMElux1LREJKa3REg2UdXbD+fo3A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/scan.h | 53 +++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/scan.h diff --git a/drivers/net/wireless/celeno/cl8k/scan.h b/drivers/net/wireless/celeno/cl8k/scan.h new file mode 100644 index 000000000000..857e1cfc1745 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/scan.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_SCAN_H +#define CL_SCAN_H + +#include +#include +#include +#include +#include + +#include "channel.h" + +struct cl_chan_scanner { + struct cl_channel_stats channels[MAX_CHANNELS]; + enum cl_channel_bw scan_bw; + u8 channels_num; + u8 scan_channels_num; + u8 curr_ch_idx; + + struct task_struct *scan_thread; + atomic_t scan_thread_busy; + + u32 scan_time; + u32 wait_time; + + bool scans_enabled; + bool scan_aborted; + struct completion abort_completion; + + u8 prescan_bw; + u32 prescan_channel; + + wait_queue_head_t wq; + struct cl_hw *cl_hw; + + void (*completion_cb)(struct cl_hw *cl_hw, void *arg); + void *completion_arg; +}; + +/* Use CHNL scan_bw =_BW_MAX to perform scan on current bandwidth */ +s32 cl_trigger_off_channel_scan(struct cl_chan_scanner *scanner, u32 scan_time, u32 wait_time, + const u8 *channels, enum cl_channel_bw scan_bw, u8 channels_num, + void (*completion_cb)(struct cl_hw *cl_hw, void *arg), + void *completion_arg); +void cl_abort_scan(struct cl_chan_scanner *scanner); +int cl_scanner_init(struct cl_hw *cl_hw); +void cl_scanner_deinit(struct cl_hw *cl_hw); +int cl_scan_channel_switch(struct cl_hw *cl_hw, u8 channel, u8 bw, bool allow_recalib); +bool cl_is_scan_in_progress(const struct cl_chan_scanner *scanner); + +#endif /* CL_SCAN_H */ From patchwork Tue May 24 11:34:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575952 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 5C414C433F5 for ; Tue, 24 May 2022 11:41:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237006AbiEXLlb (ORCPT ); Tue, 24 May 2022 07:41:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236972AbiEXLl2 (ORCPT ); Tue, 24 May 2022 07:41:28 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60065.outbound.protection.outlook.com [40.107.6.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0EC738CCC5 for ; Tue, 24 May 2022 04:40:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=i7ahLqdzrCRhMHmOh0i9h8/a32QwBubFxbOJNnHwW5YvwdAw4XSHe/4nv3DCPKtpyLlI+l4NF1qjWv3TErJqNZkAF9R9jILLG9ZFZawzyOCu5nnmX3Y1tcDtqRQ+oTvWNzHQ/bm4BYT7x0AS8E+bvgKWKrvqMdl99E3PqBcWwmvGvdWK7KJXeJEf7+wMlV3WKp/tJHSZ8Nqh9Ue83u1S3vIxHw7uw+mhTeO3pgi6PQVZMWTTnJ5GBOhii2Do5P7BkXYB6IYVrA2BCmTkubuChRJuROPUCUxwAN6gIWwPSDhR9hJ7g6E/GSqTqh2TwxNrAQhTSkvOk5rH2J+yq4LWuA== 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=+9NC1fx3Hc0lj16PXDrj6GUYe3Ky/0eBFlqVCFY52KM=; b=ThOurIE8gCxn6JsALGxxI35qQZBDcrvJJNkJbL1O83MkvxkycryRyYOhTIITOKfFS1dlySSkgInqRmNFZYdAOUF9OBYRCWwDzkSAcB5DjaqdJH0f9o+BTanWpumrhX8zjR5OW3yrPdS/2lPTIdmmSCtNVRiaHRTaFCPdnBO/wzlh1bu/8KQ+0GF7Am6IATxG/IppbCF8fXtFF/Enur3iDZlvdXd/KQ1Cwex5y/uoIDdFT0wP0BM2Lz6yUn6RgxcvHjiTYLGGEwLBDQyBHXs3fb7iQmdqatJLLMlRGYWeJKCHoVb/ru+xhs1u9RhCswfyDNTxkocm15mtaSOa55ncWQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+9NC1fx3Hc0lj16PXDrj6GUYe3Ky/0eBFlqVCFY52KM=; b=mMlx5klFj4OHyn4qxioN5eonECurI2K37SBarbyUwwwvqXUnAAWbe+LRbw9T5VlaEUGMvl7hAPJCpcUb9B70LNvH4OZRsoSqlHbZb4kmNvS4KOWsEGDZbTIbMWy6bnAkqtjkfBXe9k/YMDyzTG4EYlyODZG3uu/LgrkucYbP5DI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:26 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:26 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 72/96] cl8k: add sounding.c Date: Tue, 24 May 2022 14:34:38 +0300 Message-Id: <20220524113502.1094459-73-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 21fe8d8c-2a17-4acf-f5e3-08da3d79f734 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LKvPqdaz3+aJVYPHGr2KBj8RmHGucTpXZEPMFf7zBbbk8vZ/UafVJCzMUG7d5iipdEby8bHvi2Pf3k+9TFU7zaYBTg8u1aifICTdUsnEGjrEnvsBMaWUmunBwOxyyWYtrtiLgMFKORmsuw3HjkIeIv0qcJkH1PeC1GCYS19UEuw/w1LmhrSuTKoMFIu+zPwvR/m2zRvKGxbsLXuiwIOI0Bj1/mxmE9rgo5Lu9yuCu4lNFIGwOEcrEbGS/ifSvIVWOgc9dz3Xtl2JSl47n4+5pzSC9NkB0f5Uv0yCJOgK+cD2DrFe8al7LN+PCCzEiwklNy3DL95bHTOd8gl52cCZPrdLE6iWGZSbK6dAuzpwHTc6oHbkMSby7/3Nxxmq5p6l+WBzLt0g3bHMXOL/GILihsgo3YZOu53XOEXisIanuqQi1hTzN2pusVZdMy1Oh99hZlPNuu4MH/8seOVzBh+xspSmduLBX/pvPfDbdoNLo31rXkm77HZGUhy90kpcNc+b/VXKLEAJ+k/969f5lmWlXuRAxO5OIQwDBkg4bsCFVGlMcVEBS26sqxAxOIiQ84zTRvy/27jz6yd8MvP4/z03G+Dxd+NY7hCN89/U7kKbXWEQDLO6wv3M5qN/INlDlZWyvesfBjJzQkGLqLD5hUCHCU4ob+g9ZJeTeCvqi7/ajieDFrh+x9KAOJSt7eXo/BDbGkJGDfwzTtdS6ulMnnKg58D5Xtx3vsJPdYNZQiwLzy0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: aVBNCkkuOz496PBXGN58uuVKdBHNeByoXEZrucflM6C4eQTPTHKV2ySjYNvwIeWcNz4XU41gE4UMW3fV7faKKOIOGQh0WtgKIEEoYOoEaAp87g2mwhi6l7Buwr0kmr5PrRGyZ5LIFpREexAu/CLJGRbipr2nJMhWd54yDXFKNrb4Xolp4Sa5qW1FYEXFszZbigWWCyBH76lGrWhVNhH/kzBb+EyJ4M5luYvn6pLu74TA27AIrmIcqesIA4NSp9rvG5tiFhaduhJCcxY0fcZTVjAUFrYWLLiV7bzN4rg8XmQ+ZPSTRfIeWGQZFi16AiY3vrQkDaQaasc/Kh2cML9izQ2ZF4x8wecNh0qTK7HlGNkGJ0XZ/4zWMvffSd8clsLIaisYm6aHI89LaSjVSJExGYgENRUDOPQe7vZ8JCM1eoKfQRkQ4EoyVO5Mz6aBgn0dHDcNTyTIY7yzOrZxlRRW+SkyLyR5LbE8Qp06qLZjhRreZNpZNres3Eb90UrjTwxQpT2gEdOdpj0JtL/Du43Ncx1g1YUY8s2tklhDa6942Tixqxx8L5OOpqdPc3MdYKYvKQvl1rlovo5WyjkkayCqQ6Rt5Tdj4hgFBr/lvPR/fw5xIVKY4MZJn1XppUogwnLIOIEMHl8HtDq06GiGOFRMQfwioQMxaHifVCN5VyBXZfcho2Uz0+BJtaKTZPhjeVzW/yigKhGTV+m8mDsODO5pdKF9qR0gcdc+1m8pjOzvRKJrVzktSACh9ndpWzgFerX8SR+7vVwacXqLyIn6QP3cmmBZAVjHzsYbhHFr1QJMGDOsanUXnAYLa73OCp6MJ91lZErT9kvC9lH/aDxlp9193oW4X2CEMn5ic7QK22ZYosKnyxgtZo5VGp1ayrGBCmXznlASoPb5MWCtFM0z/+pGCXF6QJ7l2TlTHkITZFZoN8coV+AlmEd+vPJFwe5yTVCP+uNzF79aH1O5tAal6hTVz5ecCduHmb1r30inPV1fNiD4rcr1pxw+CiW/qVlBvhEmfO4O5dWlxweKFGNzBGFzK9q6C2WNg3D+LzTXzXQgre/xjvxmg1uRjttYXogEyAHkjNML50CaBNuJEMtTbx/qXPSsbJdVnWFPPILKWrbEUo75OrggC5+bGFOilpXbtXFWNffZFg0XmN/x6VihpL5OW/5l5Cb8XTvj9v9ZJdJd7Ip7SNKzDm/r6xwdnrI+9N5FK545hOXHvKc/iVogZd6yYmEYCq2+HxuAY0cTgdd1lhctRDfEh9xz/EVbi2uu/lczgtTLaINTYCxEZiNo3q/yYELIi27G5dl1spEG69mDpntP2f1kG4EIJjLfx94YVTnhn8xjE7yCE39t15oK1CILew4QsyLqcb4NgvreHlIlc4yNZ7TQXQ15lvG6OL7BpT2TTvV02HpfMlG9SHzJuyvPX4BxJPEjw7Z7ptnkDh53LksHPt8cZPlWmTKKS9VamYiYlCLdXaldBc3adbRwGji/SdvOls9kImJbHp2Wrfg5/whOF7znoR9SEG1s2yDgjjG2RziUQRqgBnnefnHpxP9WKYbqBWAOnLSRdN5NkJcF9/syHP10U+gjSXUhz6GHDH7z5ZxFOPvEAFz/40+YV1Fvp8ZHoTXNBgeY1R5Rb8fY6k7e+z9xzht4W8rwpg6fLB2JFjm+0R8gBSc2ga5/NDNbXTtVCPKm7WhL/euP+Gccpenjm9/M3SmyfJ2hRTq2IfHR6Uwuq2iTggUdEGFEdoMBnDsBXi6/1/3MwBgowS6r20I= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 21fe8d8c-2a17-4acf-f5e3-08da3d79f734 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:47.6157 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: h0rHukkdPJbZT5llP9wKIcJqId4CuHqWkkJ7tLXBqJra5rtddiZ5nK8titsBUzEFfjzVk77XYWs8GevvATzFOQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/sounding.c | 1121 +++++++++++++++++++ 1 file changed, 1121 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/sounding.c diff --git a/drivers/net/wireless/celeno/cl8k/sounding.c b/drivers/net/wireless/celeno/cl8k/sounding.c new file mode 100644 index 000000000000..09d43a01bb70 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/sounding.c @@ -0,0 +1,1121 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "debug.h" +#include "bf.h" +#include "chip.h" +#include "utils.h" +#include "recovery.h" +#include "debug.h" +#include "hw.h" +#include "sounding.h" + +#define DBG_PREFIX_MAX_LENGTH 64 +#define sounding_pr(level, format, ...) \ + do { \ + if ((level) <= cl_hw->sounding.dbg_level) { \ + char __dbg_prefix[DBG_PREFIX_MAX_LENGTH] = {0}; \ + if ((level) >= DBG_LVL_TRACE) \ + snprintf(__dbg_prefix, DBG_PREFIX_MAX_LENGTH, "[%s][%d]", \ + __func__, __LINE__); \ + pr_debug("%s [Sounding] " format, __dbg_prefix, ##__VA_ARGS__); \ + } \ + } while (0) + +#define sounding_pr_verbose(...) sounding_pr(DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define sounding_pr_err(...) sounding_pr(DBG_LVL_ERROR, ##__VA_ARGS__) +#define sounding_pr_warn(...) sounding_pr(DBG_LVL_WARNING, ##__VA_ARGS__) +#define sounding_pr_trace(...) sounding_pr(DBG_LVL_TRACE, ##__VA_ARGS__) +#define sounding_pr_info(...) sounding_pr(DBG_LVL_INFO, ##__VA_ARGS__) + +#define CL_SOUNDING_ALL_STA 0xff +#define CL_SOUNDING_LIFETIME_MAX 4095 +#define CL_SOUNDING_LIFETIME_FACTOR 5 +#define CL_SOUNDING_V_MATRIX_PADDING 32 +#define CL_V_MATRIX_MAC_OVERHEAD 41 +#define CL_Q_MATRIX_BITMAP_MASK 0xf + +enum cl_sounding_feedback_type { + CL_SOUNDING_FEEDBACK_TYPE_SU = 0, + CL_SOUNDING_FEEDBACK_TYPE_MU, +}; + +enum cl_sounding_ng { + CL_SOUNDING_NG_4 = 0, + CL_SOUNDING_NG_16, + CL_SOUNDING_NG_MAX +}; + +struct sounding_work_data { + struct work_struct work; + struct cl_hw *cl_hw; + bool start; + bool is_recovery; + struct cl_sounding_info *elem; /* For stop and recovery cases */ + enum sounding_type sounding_type; + u8 gid; + u8 sta_num; + u8 bw; + u8 q_matrix_bitmap; + u8 sta_indices[CL_MU_MAX_STA_PER_GROUP]; +}; + +static u16 ng_bw_to_nsc[CL_SOUNDING_NG_MAX][CHNL_BW_MAX_HE] = { + {64, 128, 256, 512}, + {32, 32, 64, 128} +}; + +static int cl_sounding_check_response(struct cl_hw *cl_hw, u8 param_err) +{ + int ret = -1; + + switch (param_err) { + case CL_SOUNDING_RSP_OK: + sounding_pr_trace("param OK!\n"); + ret = 0; + break; + case CL_SOUNDING_RSP_ERR_RLIMIT: + sounding_pr_err("error, resource limit reached\n"); + break; + case CL_SOUNDING_RSP_ERR_BW: + sounding_pr_err("error, unsupported BW tx requested\n"); + break; + case CL_SOUNDING_RSP_ERR_NSS: + sounding_pr_err("error, unsupported ndp NSS tx requested\n"); + break; + case CL_SOUNDING_RSP_ERR_INTERVAL: + sounding_pr_err("error, interval value is invalid\n"); + break; + case CL_SOUNDING_RSP_ERR_ALREADY: + sounding_pr_err("error, station already associated/disassociated with sounding\n"); + break; + case CL_SOUNDING_RSP_ERR_STA: + sounding_pr_err("error, station is inactive/active\n"); + break; + case CL_SOUNDING_RSP_ERR_TYPE: + sounding_pr_err("error, invalid sounding type\n"); + break; + default: + sounding_pr_err("error status unknown, BUG\n"); + break; + } + + return ret; +} + +static u32 cl_sounding_get_lifetime(struct cl_hw *cl_hw, u32 interval) +{ + u32 lifetime = (interval * CL_SOUNDING_LIFETIME_FACTOR) >> 1; + + if (lifetime > CL_SOUNDING_LIFETIME_MAX) { + sounding_pr_err("lifetime (%u) exceeds 4095\n", lifetime); + lifetime = CL_SOUNDING_LIFETIME_MAX; + } + + return lifetime; +} + +static bool cl_sounding_is_sta_ng_16_capable(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + bool mu_cap) +{ + struct ieee80211_sta_he_cap *he_cap = &cl_sta->sta->he_cap; + + if (he_cap->has_he) { + if (mu_cap) + return (he_cap->he_cap_elem.phy_cap_info[5] & + IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK); + else + return (he_cap->he_cap_elem.phy_cap_info[5] & + IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK); + } + + return false; +} + +static bool cl_sounding_is_sta_codebook_size_75_capable(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct ieee80211_sta_he_cap *he_cap = &cl_sta->sta->he_cap; + + if (he_cap->has_he) + return (he_cap->he_cap_elem.phy_cap_info[6] & + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU); + + return false; +} + +static void cl_sounding_extract_ng_cb_size(struct cl_hw *cl_hw, u8 fb_type_ng_cb_size, + enum cl_sounding_ng *ng, u8 *phi_psi_sum) +{ + enum cl_sounding_feedback_type fb_type = + SOUNDING_FEEDBACK_TYPE_VAL(fb_type_ng_cb_size); + u8 cb_size = SOUNDING_CODEBOOK_SIZE_VAL(fb_type_ng_cb_size); + + *ng = SOUNDING_NG_VAL(fb_type_ng_cb_size); + + switch (fb_type) { + case CL_SOUNDING_FEEDBACK_TYPE_SU: + *phi_psi_sum = (cb_size ? 10 : 6); + break; + case CL_SOUNDING_FEEDBACK_TYPE_MU: + *phi_psi_sum = (cb_size ? 16 : 12); + break; + default: + sounding_pr_err("Invalid feedback_type %d\n", fb_type); + break; + } +} + +static u32 cl_sounding_get_v_matrix_size(struct cl_hw *cl_hw, u8 sta_idx, u8 bw, u8 nc, u8 nr, + u8 fb_type_ng_cb_size) +{ + enum cl_sounding_ng ng = 0; + u8 phi_psi_sum = 0; + u8 nsc; + u32 v_size; + + cl_sounding_extract_ng_cb_size(cl_hw, fb_type_ng_cb_size, &ng, &phi_psi_sum); + nsc = ng_bw_to_nsc[ng][bw]; + + /* NC and NR should start from 1 and not 0 for the below calculation */ + nc++; + nr++; + + /* v_size = [8*41 + 8*nc + (phi + psi)/2 * nsc*(nc * (2*nr-nc-1))] / 8 + extra padding */ + v_size = CL_V_MATRIX_MAC_OVERHEAD + nc + + ((phi_psi_sum * nsc * nc * (2 * nr - nc - 1)) >> 4) + + CL_SOUNDING_V_MATRIX_PADDING; + + sounding_pr_info("sta %u, nc %u, nr %u, ng %d, phi_psi_sum %u, nsc %u, v_size %u\n", + sta_idx, nc, nr, ng, phi_psi_sum, nsc, v_size); + + return v_size; +} + +static u32 cl_sounding_get_v_matrices_data_size(struct cl_hw *cl_hw, + struct sounding_info_per_sta *info_per_sta, + u8 sta_num, u8 bw, u8 nr) +{ + u8 i; + u32 v_size = 0; + + for (i = 0; i < sta_num; i++) + v_size += cl_sounding_get_v_matrix_size(cl_hw, info_per_sta[i].sta_idx, + bw, info_per_sta[i].nc, + nr, info_per_sta[i].fb_type_ng_cb_size); + + sounding_pr_info("v_matrices data size %u, sta_num %u\n", v_size, sta_num); + + return v_size; +} + +static u32 cl_sounding_get_q_matrix_size(struct cl_hw *cl_hw, + const struct sounding_info_per_sta *info_per_sta, + u8 sta_num, u8 bw, u8 nr) +{ + u8 i; + u8 nc = 0; + enum cl_sounding_ng ng = 0; + u8 nsc, phi_psi_sum = 0; + u32 q_size = 0; + + /* + * NC and NR should start from 1 and not 0 for the below calculation + * In MU-MIMO case, when sta_num > 1, we should take the sum of all nc's + */ + for (i = 0; i < sta_num; i++) + nc += info_per_sta[i].nc + 1; + + nr++; + + cl_sounding_extract_ng_cb_size(cl_hw, info_per_sta[0].fb_type_ng_cb_size, &ng, + &phi_psi_sum); + nsc = ng_bw_to_nsc[ng][bw]; + q_size = (nr * nc * nsc) << 2; + + sounding_pr_info("q_matrix size %u, sta_num %u\n", q_size, sta_num); + + return q_size; +} + +static u32 cl_sounding_get_required_xmem_size(struct cl_hw *cl_hw, + const struct mm_sounding_req *sounding_req, + const struct sounding_info_per_sta *info_per_sta) +{ + u8 i; + u8 sta_num = sounding_req->sta_num; + u8 q_matrix_bitmap = sounding_req->q_matrix_bitmap; + u8 bw = sounding_req->req_txbw; + u8 nr = sounding_req->ndp_nsts; + u32 total_size = 0; + + /* + * In case of MU sounding only one Q matrix is generated. + * Otherwise, the number of Q matrices equals to te number of stations + */ + if (sta_num > 1 && + sounding_req->sounding_type != SOUNDING_TYPE_HE_MU && + sounding_req->sounding_type != SOUNDING_TYPE_VHT_MU) + for (i = 0; i < sta_num; i++) + total_size += + cl_sounding_get_q_matrix_size(cl_hw, &info_per_sta[i], 1, bw, nr); + else + total_size = + cl_sounding_get_q_matrix_size(cl_hw, info_per_sta, sta_num, bw, nr); + + /* + * If additional SU Q matrices should be generated - consider them also when calculating + * the required XMEM space + */ + if (q_matrix_bitmap) { + for (i = 0; i < CL_MU_MIMO_MAX_STA_PER_GRP; i++) + if (q_matrix_bitmap & BIT(i)) + total_size += + cl_sounding_get_q_matrix_size(cl_hw, &info_per_sta[i], 1, bw, nr); + } + + return total_size; +} + +static bool cl_sounding_is_enough_xmem_space(struct cl_hw *cl_hw, + const struct mm_sounding_req *sounding_req, + const struct sounding_info_per_sta *info_per_sta, + u32 *required_size) +{ + struct cl_xmem *xmem_db = &cl_hw->chip->xmem_db; + u32 req_mem = cl_sounding_get_required_xmem_size(cl_hw, sounding_req, info_per_sta); + + if (required_size) + *required_size = req_mem; + + return ((xmem_db->size - xmem_db->total_used) >= req_mem); +} + +static void cl_sounding_fill_info_per_sta(struct cl_hw *cl_hw, u8 sounding_type, u8 bw, u8 sta_num, + struct cl_sta **cl_sta_arr, + struct sounding_info_per_sta *info_per_sta, + u8 *n_sts) +{ + u8 i; + u8 min_sts = cl_hw->num_antennas; + struct cl_sta *cl_sta = NULL; + u8 mu_fb_type_ng_cb_size = FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_9_7; + u8 curr_fb_type_ng_cb_size; + bool should_update_fb_type_ng_cb_size = false; + + for (i = 0; i < sta_num; i++) { + cl_sta = cl_sta_arr[i]; + + if (!cl_sta) + continue; + + info_per_sta[i].sta_idx = cl_sta->sta_idx; + info_per_sta[i].nc = cl_sta->bf_db.nc; + + min_sts = min(min_sts, cl_sta->bf_db.beamformee_sts); + + switch (sounding_type) { + case SOUNDING_TYPE_HE_CQI: + case SOUNDING_TYPE_HE_SU: + case SOUNDING_TYPE_VHT_SU: + case SOUNDING_TYPE_VHT_MU: + info_per_sta[i].fb_type_ng_cb_size = + FEEDBACK_TYPE_SU_NG_4_CODEBOOK_SIZE_4_2; + break; + case SOUNDING_TYPE_HE_SU_TB: + info_per_sta[i].fb_type_ng_cb_size = + FEEDBACK_TYPE_SU_NG_4_CODEBOOK_SIZE_6_4; + break; + case SOUNDING_TYPE_HE_CQI_TB: + info_per_sta[i].fb_type_ng_cb_size = + FEEDBACK_TYPE_CQI_TB; + break; + case SOUNDING_TYPE_HE_MU: + if (bw == CHNL_BW_160 && + info_per_sta[i].nc >= WRS_SS_3 && + min_sts == MAX_ANTENNAS) { + should_update_fb_type_ng_cb_size = true; + + if (cl_sounding_is_sta_codebook_size_75_capable(cl_hw, cl_sta)) { + curr_fb_type_ng_cb_size = + FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_7_5; + } else if (cl_sounding_is_sta_ng_16_capable(cl_hw, cl_sta, true)) { + curr_fb_type_ng_cb_size = + FEEDBACK_TYPE_MU_NG_16_CODEBOOK_SIZE_9_7; + } else { + curr_fb_type_ng_cb_size = + FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_9_7; + mu_fb_type_ng_cb_size = + FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_9_7; + min_sts--; + } + + if ((SOUNDING_NG_VAL(curr_fb_type_ng_cb_size) > + SOUNDING_NG_VAL(mu_fb_type_ng_cb_size)) || + (SOUNDING_CODEBOOK_SIZE_VAL(curr_fb_type_ng_cb_size) < + SOUNDING_CODEBOOK_SIZE_VAL(mu_fb_type_ng_cb_size))) + mu_fb_type_ng_cb_size = curr_fb_type_ng_cb_size; + } + + info_per_sta[i].fb_type_ng_cb_size = mu_fb_type_ng_cb_size; + break; + default: + sounding_pr_trace("Invalid sounding type %u\n", sounding_type); + break; + } + } + + *n_sts = min_sts; + + if (should_update_fb_type_ng_cb_size) + for (i = 0; i < sta_num; i++) + info_per_sta[i].fb_type_ng_cb_size = mu_fb_type_ng_cb_size; +} + +static struct cl_sounding_info *cl_sounding_elem_alloc(struct cl_hw *cl_hw, u32 v_mat_len) +{ + struct cl_sounding_info *elem = NULL; + dma_addr_t phys_dma_addr; + struct v_matrix_header *buf = NULL; + + elem = kzalloc(sizeof(*elem), GFP_KERNEL); + + if (!elem) { + CL_DBG(cl_hw, DBG_LVL_ERROR, "kzalloc failed\n"); + return NULL; + } + + buf = dma_alloc_coherent(cl_hw->chip->dev, v_mat_len, &phys_dma_addr, GFP_KERNEL); + + if (!buf) { + CL_DBG(cl_hw, DBG_LVL_ERROR, "dma_alloc_coherent failed. size=%u\n", v_mat_len); + kfree(elem); + return NULL; + } + + elem->v_matrices_data = buf; + elem->v_matrices_dma_addr = phys_dma_addr; + elem->v_matrices_data_len = v_mat_len; + + return elem; +} + +static void cl_sounding_elem_free(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + struct v_matrix_header *v_data = elem->v_matrices_data; + + if (v_data) { + dma_free_coherent(cl_hw->chip->dev, elem->v_matrices_data_len, (void *)v_data, + elem->v_matrices_dma_addr); + } else { + sounding_pr_err("%s: v_matrices_data is NULL for sid %u\n", + __func__, elem->sounding_id); + } + + elem->v_matrices_data = NULL; + kfree(elem); +} + +static void cl_sounding_req_success(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + cl_bf_sounding_req_success(cl_hw, elem); +} + +static void cl_sounding_req_failure(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + cl_bf_sounding_req_failure(cl_hw, elem); +} + +static void cl_sounding_increase_num_profiles(struct cl_hw *cl_hw, u8 sounding_type, u8 sta_num) +{ + if (SOUNDING_TYPE_IS_CQI(sounding_type)) + cl_hw->sounding.cqi_profiles += sta_num; + else + cl_hw->sounding.active_profiles += sta_num; +} + +static void cl_sounding_decrease_num_profiles(struct cl_hw *cl_hw, u8 sounding_type, u8 sta_num) +{ + if (SOUNDING_TYPE_IS_CQI(sounding_type)) + cl_hw->sounding.cqi_profiles -= sta_num; + else + cl_hw->sounding.active_profiles -= sta_num; +} + +static void _cl_sounding_add(struct cl_hw *cl_hw, struct cl_sounding_info *elem, u8 sounding_id, + u32 req_xmem) +{ + write_lock_bh(&cl_hw->sounding.list_lock); + elem->sounding_id = sounding_id; + elem->xmem_space = req_xmem; + cl_hw->chip->xmem_db.total_used += req_xmem; + cl_hw->sounding.num_soundings++; + list_add_tail(&elem->list, &cl_hw->sounding.head); + cl_sounding_increase_num_profiles(cl_hw, elem->type, elem->sta_num); + write_unlock_bh(&cl_hw->sounding.list_lock); +} + +static void cl_sounding_remove_from_list(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + /* Remove the sounding sequence from the list and update the XMEM and profile counters */ + write_lock_bh(&cl_hw->sounding.list_lock); + list_del(&elem->list); + cl_hw->chip->xmem_db.total_used -= elem->xmem_space; + cl_hw->sounding.num_soundings--; + cl_sounding_decrease_num_profiles(cl_hw, elem->type, elem->sta_num); + write_unlock_bh(&cl_hw->sounding.list_lock); +} + +static void cl_sounding_remove_recovery(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + u8 i; + + cl_sounding_remove_from_list(cl_hw, elem); + + { + /* Set invalid sid for all STAs related to this sounding sequence */ + for (i = 0; i < elem->sta_num; i++) { + struct cl_sta *cl_sta = elem->su_cl_sta_arr[i]; + + if (cl_sta) + cl_sta->su_sid = INVALID_SID; + } + } + + /* Free the deleted sounding element */ + cl_sounding_elem_free(cl_hw, elem); +} + +static void cl_sounding_start_handler(struct cl_hw *cl_hw, struct sounding_work_data *data) +{ + struct mm_sounding_req sounding_req; + struct mm_sounding_cfm *cfm = NULL; + int ret = 0; + u32 len = 0; + u32 req_xmem = 0; + struct cl_sounding_info *elem = NULL; + u8 sounding_type = data->sounding_type; + u8 bw = data->bw; + u8 i, sta_num = 0; + u8 q_matrix_bitmap = data->q_matrix_bitmap; + u8 min_nsts = 0; + struct cl_sta *cl_sta_arr[CL_MU_MAX_STA_PER_GROUP] = {NULL}; + + cl_sta_lock_bh(cl_hw); + + for (i = 0; i < data->sta_num; i++) { + u8 sta_idx = data->sta_indices[i]; + struct cl_sta *cl_sta; + + cl_sta = cl_sta_get(cl_hw, sta_idx); + + if (!cl_sta) + continue; + + cl_sta_arr[sta_num] = cl_sta; + sta_num++; + } + + if (!sta_num) { + cl_sta_unlock_bh(cl_hw); + sounding_pr_err("%s: No STA found!\n", __func__); + return; + } + + q_matrix_bitmap &= CL_Q_MATRIX_BITMAP_MASK; + + /* Configure sounding request parameters */ + sounding_req.start = true; + sounding_req.sounding_type = sounding_type; + sounding_req.req_txbw = bw; + sounding_req.sta_num = sta_num; + sounding_req.interval = cl_sounding_get_interval(cl_hw); + sounding_req.lifetime = cl_sounding_get_lifetime(cl_hw, sounding_req.interval); + sounding_req.q_matrix_bitmap = q_matrix_bitmap; + cl_sounding_fill_info_per_sta(cl_hw, sounding_type, bw, sta_num, cl_sta_arr, + sounding_req.info_per_sta, &min_nsts); + cl_sta_unlock_bh(cl_hw); + + sounding_req.ndp_nsts = min_nsts; + + if (data->is_recovery) { + elem = data->elem; + } else { + /* + * Check if there is enough XMEM space. + * Should be called after filling sounding req struct + */ + if (!cl_sounding_is_enough_xmem_space(cl_hw, &sounding_req, + sounding_req.info_per_sta, &req_xmem)) { + sounding_pr_err("There is not enough space in XMEM!\n"); + return; + } + + /* Should be called after filling info per STA */ + len = cl_sounding_get_v_matrices_data_size(cl_hw, sounding_req.info_per_sta, + sta_num, bw, min_nsts); + elem = cl_sounding_elem_alloc(cl_hw, len); + + if (!elem) + return; + + elem->type = sounding_type; + elem->bw = bw; + elem->sta_num = sta_num; + elem->q_matrix_bitmap = q_matrix_bitmap; + + if (data->gid) + elem->gid = data->gid; + else + memcpy(elem->su_cl_sta_arr, cl_sta_arr, + sta_num * sizeof(cl_sta_arr[0])); + } + + sounding_req.host_address = cpu_to_le32(elem->v_matrices_dma_addr); + + /* Print request parameters */ + sounding_pr_trace("Request: start=%u, bfr_lifetime=%u, interval=%u, " + "req_txbw=%u, ndp_nsts=%u, sounding_type=%u\n", + sounding_req.start, + sounding_req.lifetime, + sounding_req.interval, + sounding_req.req_txbw, + sounding_req.ndp_nsts, + sounding_req.sounding_type); + + /* Send message to firmware */ + ret = cl_msg_tx_sounding(cl_hw, &sounding_req); + + /* Check firmware response */ + cfm = cl_hw->msg_cfm_params[MM_SOUNDING_CFM]; + if (ret == 0 && cfm) { + ret = cl_sounding_check_response(cl_hw, cfm->param_err); + + if (ret == 0) { + if (!data->is_recovery) + _cl_sounding_add(cl_hw, elem, cfm->sounding_id, req_xmem); + + cl_sounding_req_success(cl_hw, elem); + + sounding_pr_trace("Sounding %u was enabled successfully\n", + cfm->sounding_id); + } else { + cl_sounding_req_failure(cl_hw, elem); + + if (data->is_recovery) + cl_sounding_remove_recovery(cl_hw, elem); + } + } else { + sounding_pr_err("%s: failed to send message (%d)\n", __func__, ret); + cl_sounding_req_failure(cl_hw, elem); + + if (data->is_recovery) + cl_sounding_remove_recovery(cl_hw, elem); + else + cl_sounding_elem_free(cl_hw, elem); + } + + /* Free message confirmation */ + cl_msg_tx_free_cfm_params(cl_hw, MM_SOUNDING_CFM); +} + +static void _cl_sounding_remove(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + u8 i; + struct sounding_work_data data = { + .cl_hw = cl_hw, + .bw = elem->bw, + .start = true, + .is_recovery = false, + .sta_num = 0 + }; + + cl_sounding_remove_from_list(cl_hw, elem); + + /* Update invalid sid for all STAs related to this sounding sequence. + * Also start sounding for STAs that didn't request to stop sounding. + */ + + for (i = 0; i < elem->sta_num; i++) { + struct cl_sta *cl_sta = elem->su_cl_sta_arr[i]; + + if (!cl_sta) + continue; + + cl_sta->su_sid = INVALID_SID; + + /* After stopping the multi STA sounding - check if a new sounding is needed */ + if (elem->sounding_restart_required) { + if (!cl_sta->bf_db.sounding_remove_required) { + data.sta_indices[data.sta_num] = cl_sta->sta_idx; + data.sta_num++; + } else { + cl_sta->bf_db.sounding_remove_required = false; + } + } + } + + /* Start a new sounding for the remaining stations only when needed */ + if (data.sta_num) { + /* Determine new sounding type */ + if (SOUNDING_TYPE_IS_CQI(elem->type)) { + if (data.sta_num > 1) + data.sounding_type = elem->type; + else + data.sounding_type = SOUNDING_TYPE_HE_CQI; + } else if (SOUNDING_TYPE_IS_VHT(elem->type)) { + data.sounding_type = SOUNDING_TYPE_VHT_SU; + } else { + if (data.sta_num > 1) + data.sounding_type = SOUNDING_TYPE_HE_SU_TB; + else + data.sounding_type = SOUNDING_TYPE_HE_SU; + } + + cl_sounding_start_handler(cl_hw, &data); + } + + /* Free the deleted sounding element */ + cl_sounding_elem_free(cl_hw, elem); +} + +static void cl_sounding_stop_handler(struct cl_hw *cl_hw, struct cl_sounding_info *elem) +{ + struct mm_sounding_req sounding_req; + int ret = 0; + + if (!elem) { + sounding_pr_err("elem is NULL!!\n"); + return; + } + + /* Configure sounding request parameters */ + sounding_req.start = false; + sounding_req.sounding_type = elem->type; + sounding_req.sid = elem->sounding_id; + + /* Print request parameters */ + sounding_pr_trace("Delete request: sid=%u, sounding_type=%u\n", + elem->sounding_id, elem->type); + + /* Send message to firmware */ + ret = cl_msg_tx_sounding(cl_hw, &sounding_req); + + /* Check firmware response */ + if (ret) + sounding_pr_err("%s: failed to send message (%d)\n", __func__, ret); + else + /* Free message confirmation */ + cl_msg_tx_free_cfm_params(cl_hw, MM_SOUNDING_CFM); + + /* Remove the sounding sequence from the list and update the used XMEM counter. + * Notice that elem is freed and shouldn't be accessed after the call to this function. + */ + _cl_sounding_remove(cl_hw, elem); +} + +static void cl_sounding_handler_send_request(struct work_struct *work) +{ + struct sounding_work_data *data = (struct sounding_work_data *)work; + struct cl_hw *cl_hw = data->cl_hw; + + if (data->start) { + cl_sounding_start_handler(cl_hw, data); + } else { + u8 sid; + + { + u8 sta_idx = data->sta_indices[0]; + struct cl_sta *cl_sta; + + cl_sta_lock_bh(cl_hw); + cl_sta = cl_sta_get(cl_hw, sta_idx); + sid = cl_sta ? cl_sta->su_sid : U8_MAX; + cl_sta_unlock_bh(cl_hw); + } + + if (data->elem) + cl_sounding_stop_handler(cl_hw, data->elem); + else + cl_sounding_stop_by_sid(cl_hw, sid, false); + } + + kfree(data); +} + +static u16 cl_sounding_calc_interval(struct cl_hw *cl_hw, u8 active_profiles) +{ + /* Sounding interval = min interval + [(active_profiles - 1) / STA step] * interval step */ + + u16 *coefs = cl_hw->conf->ce_sounding_interval_coefs; + u16 min_interval = coefs[SOUNDING_INTERVAL_COEF_MIN_INTERVAL]; + u16 max_interval = coefs[SOUNDING_INTERVAL_COEF_MAX_INTERVAL]; + u8 sta_step = coefs[SOUNDING_INTERVAL_COEF_STA_STEP]; + u8 interval_step = coefs[SOUNDING_INTERVAL_COEF_INTERVAL_STEP]; + u16 ret = min_interval; + + if (active_profiles <= sta_step) + return ret; + + active_profiles--; + ret += (active_profiles / sta_step) * interval_step; + + return min(ret, max_interval); +} + +static void cl_sounding_handler_change_interval(struct work_struct *work) +{ + struct sounding_work_data *data = (struct sounding_work_data *)work; + struct cl_hw *cl_hw = data->cl_hw; + struct mm_sounding_interval_cfm *sounding_interval_cfm = NULL; + int ret = 0; + /* Configure sounding request parameters */ + u16 interval = cl_sounding_get_interval(cl_hw); + u16 lifetime = cl_sounding_get_lifetime(cl_hw, interval); + + sounding_pr_trace("Sounding interval request: sta_idx=%d, interval=%u, " + "lifetime=%u, sounding_type=%u\n", + CL_SOUNDING_ALL_STA, interval, lifetime, data->sounding_type); + + /* Start/Stop synchronize sounding request periodically */ + ret = cl_msg_tx_sounding_interval(cl_hw, interval, lifetime, data->sounding_type, + CL_SOUNDING_ALL_STA); + sounding_interval_cfm = cl_hw->msg_cfm_params[MM_SOUNDING_INTERVAL_CFM]; + if (ret == 0 && sounding_interval_cfm) + cl_sounding_check_response(cl_hw, sounding_interval_cfm->param_err); + else + sounding_pr_err("%s: failed to send message (%d)\n", __func__, ret); + + cl_msg_tx_free_cfm_params(cl_hw, MM_SOUNDING_INTERVAL_CFM); + kfree(data); +} + +static void cl_sounding_recovery_reset(struct cl_hw *cl_hw) +{ + struct cl_sounding_db *sounding_db = &cl_hw->sounding; + + memset(sounding_db->active_profiles_prev, 0, sizeof(u8) * CL_SOUNDING_STABILITY_TIME); + sounding_db->active_profiles_idx = 0; + cl_sta_loop(cl_hw, cl_bf_reset_sounding_ind); +} + +void cl_sounding_init(struct cl_hw *cl_hw) +{ + struct cl_sounding_db *sounding_db = &cl_hw->sounding; + + memset(sounding_db, 0, sizeof(*sounding_db)); + sounding_db->sounding_wq = create_workqueue("cl_sounding_wq"); + sounding_db->current_interval = + cl_hw->conf->ce_sounding_interval_coefs[SOUNDING_INTERVAL_COEF_MIN_INTERVAL]; + sounding_db->dbg_level = 1; + cl_hw->chip->xmem_db.size = XMEM_SIZE; + INIT_LIST_HEAD(&sounding_db->head); + rwlock_init(&sounding_db->list_lock); +} + +void cl_sounding_close(struct cl_hw *cl_hw) +{ + struct cl_sounding_info *elem, *tmp; + + if (cl_hw->sounding.sounding_wq) + destroy_workqueue(cl_hw->sounding.sounding_wq); + + list_for_each_entry_safe(elem, tmp, &cl_hw->sounding.head, list) { + /* Don't try to start a new sounding sequence after stopping this one */ + elem->sounding_restart_required = false; + cl_sounding_stop_handler(cl_hw, elem); + } +} + +struct cl_sounding_info *cl_sounding_get_elem(struct cl_hw *cl_hw, u8 sounding_id) +{ + struct cl_sounding_info *elem = NULL; + + read_lock_bh(&cl_hw->sounding.list_lock); + + list_for_each_entry(elem, &cl_hw->sounding.head, list) { + if (elem->sounding_id == sounding_id) { + read_unlock_bh(&cl_hw->sounding.list_lock); + return elem; + } + } + + read_unlock_bh(&cl_hw->sounding.list_lock); + + return NULL; +} + +void cl_sounding_send_request(struct cl_hw *cl_hw, struct cl_sta **cl_sta_arr, + u8 sta_num, bool enable, u8 sounding_type, u8 bw, + void *mu_grp, + u8 q_matrix_bitmap, struct cl_sounding_info *recovery_elem) +{ + struct sounding_work_data *data; + struct cl_sounding_info *elem = NULL; + u8 i; + struct cl_sta *cl_sta = NULL; + bool background = (preempt_count() != 0); + + if (cl_band_is_24g(cl_hw) && SOUNDING_TYPE_IS_VHT(sounding_type)) { + sounding_pr_err("A VHT sounding type (%u) is not supported in 2.4g band\n", + sounding_type); + return; + } + + /* + * When Multiple STAs are members of a single sounding process, that is about to be stopped, + * we want to schedule the stopping work only once and possibly start another sounding + * sequence for STAs that still want to use it. + */ + if (enable) + goto next; + + cl_sta = cl_sta_arr[0]; + if (cl_sta) { + u8 sid = cl_sta->su_sid; + + if (sid != INVALID_SID) { + elem = cl_sounding_get_elem(cl_hw, sid); + + if (!elem) { + sounding_pr_trace("Sounding %u not found\n", sid); + return; + } + + cl_sta->bf_db.sounding_remove_required = true; + + if (elem->sounding_restart_required) + return; + elem->sounding_restart_required = true; + } + } + +next: + /* data will be freed in work handler */ + data = kzalloc(sizeof(*data), GFP_ATOMIC); + + if (!data) + return; + + data->cl_hw = cl_hw; + data->start = enable; + data->sounding_type = sounding_type; + data->bw = bw; + data->is_recovery = cl_recovery_in_progress(cl_hw); + data->elem = recovery_elem ? recovery_elem : elem; + + /* Fill cl_sta_arr */ + { + for (i = 0; i < sta_num; i++) + data->sta_indices[i] = cl_sta_arr[i]->sta_idx; + + data->sta_num = sta_num; + } + + if (background) { + INIT_WORK(&data->work, cl_sounding_handler_send_request); + queue_work(cl_hw->sounding.sounding_wq, &data->work); + } else { + cl_sounding_handler_send_request((struct work_struct *)data); + } +} + +static void cl_sounding_change_interval(struct cl_hw *cl_hw, u8 sounding_type) +{ + /* Data will be freed in work handler */ + struct sounding_work_data *data = kzalloc(sizeof(*data), GFP_ATOMIC); + + if (!data) + return; + + INIT_WORK(&data->work, cl_sounding_handler_change_interval); + data->cl_hw = cl_hw; + data->sounding_type = sounding_type; + queue_work(cl_hw->sounding.sounding_wq, &data->work); +} + +void cl_sounding_stop_by_sid(struct cl_hw *cl_hw, u8 sid, bool sounding_restart_check) +{ + struct cl_sounding_info *elem = cl_sounding_get_elem(cl_hw, sid); + + if (!elem) { + sounding_pr_trace("Sounding with id %u not found or is in the middle of removal\n", + sid); + return; + } + + elem->sounding_restart_required = sounding_restart_check; + cl_sounding_stop_handler(cl_hw, elem); +} + +void cl_sounding_maintenance(struct cl_hw *cl_hw) +{ + /* + * Change sounding_index accoording to number of active_profiles. + * sounding_index is modified only if number of active_profiles is stable for 5 seconds. + * + * Examples: + * e.g #1: active_profiles=2, active_profiles_prev=3,3,3,3,3 - stabilised on 3 + * e.g #3: active_profiles=2, active_profiles_prev=1,1,1,1,1 - stabilised on 1 + * e.g #2: active_profiles=5, active_profiles_prev=6,7,7,6,6 - stabilised on 6 + * e.g #4: active_profiles=5, active_profiles_prev=4,3,3,2,4 - stabilised on 4 + */ + + int i = 0; + u8 active_profiles_min = 255; + u8 active_profiles_max = 0; + u8 active_profiles = cl_hw->sounding.last_conf_active_profiles; + u8 active_profiles_new = 0; + u16 interval; + u16 interval_new; + + /* Add to last 5 sec buffer */ + cl_hw->sounding.active_profiles_prev[cl_hw->sounding.active_profiles_idx] = + cl_hw->sounding.active_profiles; + + /* Increase cyclic index */ + cl_hw->sounding.active_profiles_idx++; + if (cl_hw->sounding.active_profiles_idx == CL_SOUNDING_STABILITY_TIME) + cl_hw->sounding.active_profiles_idx = 0; + + /* Find active_profiles min/max in last 5 seconds */ + for (i = 0; i < CL_SOUNDING_STABILITY_TIME; i++) { + if (cl_hw->sounding.active_profiles_prev[i] < active_profiles_min) + active_profiles_min = cl_hw->sounding.active_profiles_prev[i]; + + if (cl_hw->sounding.active_profiles_prev[i] > active_profiles_max) + active_profiles_max = cl_hw->sounding.active_profiles_prev[i]; + } + + if (active_profiles < active_profiles_min) + active_profiles_new = active_profiles_min; + else if (active_profiles > active_profiles_max) + active_profiles_new = active_profiles_max; + else /* Active_profiles in last 5 seconds did not change or is not stable */ + return; + + interval = cl_sounding_calc_interval(cl_hw, active_profiles); + interval_new = cl_sounding_calc_interval(cl_hw, active_profiles_new); + + /* Check if sounding interval changed */ + if (interval != interval_new) { + cl_hw->sounding.last_conf_active_profiles = active_profiles_new; + cl_hw->sounding.current_interval = interval_new; + cl_sounding_change_interval(cl_hw, SOUNDING_TYPE_MAX); + sounding_pr_trace("Interval: current = %u, new = %u\n", + interval, interval_new); + } +} + +u16 cl_sounding_get_interval(struct cl_hw *cl_hw) +{ + return cl_hw->sounding.current_interval; +} + +static void cl_sounding_indication_pr(struct cl_hw *cl_hw, + struct mm_sounding_ind *ind, + struct v_matrix_header *v_matrix, + u8 *avg_snr) +{ + sounding_pr_info("Sounding indication: nc index = %u, BFR BW = %u, " + "SNR1 = %u, SNR2 = %u, SNR3 = %u, SNR4 = %u, SNR5 = %u, SNR6 = %u," + "feedback type = %u, sta index = %u\n", + v_matrix->nc_index, v_matrix->bw, + avg_snr[0], avg_snr[1], avg_snr[2], avg_snr[3], avg_snr[4], + avg_snr[5], ind->sounding_type, ind->sta_idx); +} + +static void cl_sounding_indication_su(struct cl_hw *cl_hw, + struct mm_sounding_ind *ind, + struct cl_sounding_info *sounding_elem) +{ + struct cl_sta *cl_sta; + struct v_matrix_header *v_matrix = NULL; + u8 *avg_snr = NULL; + bool pairing = false; + + v_matrix = sounding_elem->v_matrices_data + ind->v_matrix_offset[0]; + avg_snr = (u8 *)v_matrix + v_matrix->padding; + + cl_sta_lock(cl_hw); + cl_sta = cl_sta_get(cl_hw, ind->sta_idx); + + if (cl_sta) { + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + /* Update Nc for the current STA */ + bf_db->nc = v_matrix->nc_index; + bf_db->sounding_indications++; + + if (bf_db->sounding_indications == 1) { + /* + * After getting first indication disable the timer and set the BF + * bit in the firmware rate flags. + */ + del_timer(&bf_db->timer); + cl_bf_update_rate(cl_hw, cl_sta); + pairing = true; + } + } + + cl_sta_unlock(cl_hw); + + /* Send a msg to fw to pair the STA with sounding ID */ + if (pairing) + cl_msg_tx_sounding_pairing(cl_hw, ind->sid, ind->sounding_type, 0, ind->sta_idx); + + cl_sounding_indication_pr(cl_hw, ind, v_matrix, avg_snr); +} + +void cl_sounding_indication(struct cl_hw *cl_hw, struct mm_sounding_ind *ind) +{ + struct cl_sounding_info *sounding_elem = NULL; + + sounding_elem = cl_sounding_get_elem(cl_hw, ind->sid); + + if (!sounding_elem) { + sounding_pr_err("[%s]: sounding id %u not found!\n", __func__, ind->sid); + return; + } + + switch (ind->sounding_type) { + case SOUNDING_TYPE_HE_SU: + case SOUNDING_TYPE_HE_SU_TB: + case SOUNDING_TYPE_VHT_SU: + case SOUNDING_TYPE_HE_CQI: + case SOUNDING_TYPE_HE_CQI_TB: + break; + default: + sounding_pr_err("[%s]: Invalid sounding type %u\n", __func__, + ind->sounding_type); + return; + } + + cl_sounding_indication_su(cl_hw, ind, sounding_elem); +} + +void cl_sounding_recovery(struct cl_hw *cl_hw) +{ + /* + * After recovery process we need to update sounding requests and + * sounding interval in firmware + */ + struct cl_sounding_info *elem; + + /* No sounding is active */ + if (!cl_hw->sounding.num_soundings) + return; + + /* Reset sounding parameters */ + cl_sounding_recovery_reset(cl_hw); + + /* + * Go over all clients that had sounding before recovery, + * and send a new sounding request to firmware. + */ + + sounding_pr_trace("Start sounding recovery\n"); + + list_for_each_entry(elem, &cl_hw->sounding.head, list) + cl_bf_sounding_start(cl_hw, elem->type, elem->su_cl_sta_arr, elem->sta_num, elem); +} + From patchwork Tue May 24 11:34:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575955 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 1421BC433F5 for ; Tue, 24 May 2022 11:41:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236952AbiEXLlV (ORCPT ); Tue, 24 May 2022 07:41:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237015AbiEXLlH (ORCPT ); Tue, 24 May 2022 07:41:07 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60044.outbound.protection.outlook.com [40.107.6.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28949939C1 for ; Tue, 24 May 2022 04:40:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ghZ9jkrAttnyJ0br6pxC6SsCLMbRsDBFCQjKO/QlIAQOznhLmCTa9kkfxoK50KoeL1MrQ+Ij6rmkoUyAyxkf6RtsX7Nb5UbKDiMrdUEkXpYhWmRwRRLtGb09kN7C0EOupHrNFJT5W1JEOpduQ3p66aMj5UA3RMrezp4ZOk1UUNaG9TtVTyR4HxlZl8F/A+jTfYqjUlZIPNsjzHNIs2QS0Kq7T423YX2Gt9Wko2M9hetq5CopLCjQQQkYVZfK5j6T96e82v/QQU5iRZVM+M34TtlNu3Wqe6KFZ7uLb6OReuNXLMJ4+OWEa4HQB8/ep1KlyHaS5or0TzGfSBYU3MreuQ== 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=ezFzTKm+SPHZR3WunxeWCl5uQoANH8wfRCQqI6VTySY=; b=Ksx4GWAcVP2nIeAx2oCw29pGVtrP/YztsfAXOsc14+matp1vd0kmTk3f4flZxW9htj57FjL/rpaJm8WNuvWQFpYsLcp4sjP1DH7dXFqq+NJ5+B164iUPD1rQR6I7hShrEaW6BqNeU5weNs856dDr/fPNF/f51SiepK4z0bgK142rhhvrj872U1FuMJUiK+CPhbCCvLW7wwW4q8Olm6JNhyoMariXZ14t0n/qtchJRAp6oGFbJuBTMiZCdzZhjQnFUOXetRmd1/us4gisHU0OkLkzW5ZFrHoxro6K0dJuyf0wEZfN+wZqdl7OxIIOj8Zbmej0i+rOgcjEo6abnykiMA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ezFzTKm+SPHZR3WunxeWCl5uQoANH8wfRCQqI6VTySY=; b=FLWuPfo8w44k+TpTwSps1tvE//CZE/1Ywrz+x8Ur6P53q50O4bHpCfbzGIlZyGsvsg0oBmqdjLXFPvkYodOK9VIjclD4go58LcKZNAWH/K18YS8LBik29tDjigiBV+IxVDJ7AyOx+GTs9RkocHK0SwKbkjFlK9MgkElccwZrTFs= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:27 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:26 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 73/96] cl8k: add sounding.h Date: Tue, 24 May 2022 14:34:39 +0300 Message-Id: <20220524113502.1094459-74-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6d9a4160-b921-452a-b44a-08da3d79f7c1 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 24UNXHCUQFfbO2asd8ZpYEvahFrXkkPzqdAFjNQD16oYO7ylOsUbQd4/iRZ6EFx2L+g03xQlkyS50aqDlFTGUhzau3n8USFIZHNv1iFZwUeowty3ktHGQfVpOGpDiCOKw1DWfXv2h9WuKUpLby1dG2UyEj6Dx8+DG9LWbNGWSvR30/BLATRiXsZvzcIlsn1e8gYuCvTfZoUWz01QMQaLRixVWmyvTs/HUClFo9HW5J2MfdocaQSLYEJknkfAoo8ozSAkLYrLRqX6+heNEkMb0HBAfNK77KxIQxv9Z7hxQwAhdnqOXVA5h1Be9rulylaqNrWo7+7GIAVA0db9NSPgc2URj0de1Eb6mNqYAzyTSgzwPneO9AixjDtFoNX9B1xKIZmeSeOw89DAGWgeBUnvr90H60oD3vIwWiEZfJ4XT1cs75XuUSWOk73HG2IcoJd+Z1WlQhYZO2UPkrjVfRkkcWVvSRfKK9fmzs9RRCp0V/pdaMBvYGZ5Toiw0pTkHX+TF8srX+/arQbUpWqX/RRIQt2jnrpxBqXNi0gQLVvt1/5s7z5p3LmYTctpNp9MbwxB6uNJ9LOLIyGnVYU8ebEe1TR9/mopo7IL2+hGtCDFH2UpH3dQX3o73pLI6YORirGzRsyan9NUPNJ5wvUha2KVNeSpYYZ6D2pTi5xBf/ZgENK4i2kve+ovhM4kR6biB4eBVs4AwHdIBlUq5lfOrtf5Kz1E0U716PQxGWWpryEIFCw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: k+oqY7q4Z2+GsYGXDnuLIDr5Tk1/qzrzLEqfhPwo3UnE1G9GYYZa+NxwBoa23Qn4GXnDG36N3an2BxDWp3a/lKtWmS+JOFWkq8fqwgMjwZjduUuXiDSRTHNT/9gF0MZ/ojiCPuKhFf3pl3tNfD9OlAIWT6vgtsu8a6eO/LA0HCWmS7r1J5UJO8hRSHA5lvO7kTrDO82AwwERnolk1bpNuRu+Obo9dDYFZmDb1Cae7JR2J682W44aw8u5IBQ3RlsDuUBopSP+yCw9w2vl8hPfs6KitxcLBqC+i7btDd7JPDFc7K2yyLLLRK0S5UEDMJ4OgmRKS4TiIcthCZ+phrP6iN7QuO3PRcaTKh0fIRJejOw693YBCr2eukSoFPloclW9jc/cX8oRN5XaIrYG2XYs42A5ZoQ1yeNRdTLduUaHnkCBBdiosHtHYIMAZB+mA7BERQKZKtnVjOejjAIM7zO4E22iW40HAzROpq4ceNRFlgKSJlZepR2YBbqAcFk4LmI8bypWU1W5F+75nihe4qoQZcIKCwlDWmaZ+74iG6lvljSKSOuh+lEavCT3jR4xGuLMMUxPljzNAqWpbdeqqxIjj8sl/lILC9SedKFeeiCeGI83E84DaDf9EZwxcNTNbpEhNgOpg8IwbotWbKTO1WEyKMNC572gfp9ZxCPAhv1mogQy0XwsF91HK2d/5Ty4/GlyDWAEDRhD1SRP0a6iNI1u7QxW35QjnI9NRGZ14yVP+IHRfvFbTMQaufHyzH2lyoUqxrDtC0dBZJQKGHFJc2EXQDC1WXABg4hL0gkP6ZR2o9QMYq0R950gEt1SIkM+Gz+IOsxdp/hui3/jFKwBvVAPTLN3wP3p4vKhCADj8BJ8+o1SX7xQ35Oy7BSG5l3WU+jCzgeWa82l5jFX4xhbfrJeNdBsW1Iuv9i8zv0UyW6bDRT2d8zvtSa2s0EUlRS1CY5VOSIi77byXGxNYrU2BC5DRRyA5oG/idHNsNZQLiNQKrr7K2R6ieuCVxWUQy3oOBnSfz4rsSupJ+HoXpNoV+faznXubiQwa4/S4LjCLat5AKg5e2eLEz/taBsoIIflmoAvVtDfTqRfRcXAOU8bzn1TrhDcj7C2gSFyRO97gJoIl7uACEoK3aJ/XJbi0Kc0nWXxc8zoRpbu2+MSTHwgWdatdSzLeEXTILHzxG9KDFUaw10hIpVpRlipmnhn4rl47Adj/05RP6l1fplSJYXNQPPGDZBysvG+OJiEUXULMpbsfwkB/B8ozehcyq9eQMi8c7vtCyYRWmOB86PIGV/dZZiNXiGDQWNVaZxdNtbWZqW6vwLCy1a93xdOR9IOa82PSD6gs3aoIb2axr91cN7SAB5wqGvIYg8vbtXP2uRmXEI6a7zLq3udvodzB7NYhGoSPBaygN6HI+wLx1MK4qTxrXoVebL6m1EEsAyCpC4kF1YaElZLeQk6QNbaH7NBof8uCecSxyfP+wDghWrC/Y+0uWI4683uyu/7xQ/JnR2JZ91L9lbAK/rscV5wHptiPYWsEVJImFt28fdsqKjJRKjFzaNNJJLf0FDJoByq2UAkQuiMvbaXXjQ7dsFwygGIYrOa5la1lz/W4z1It9zaiuu9HuFy9DljzOlRBcAcgixJYeLxDunNDjNv7Vst2b/oYAdD9X5ZCRDWW61K0PI2Nh78R7c8+anT6DKSWeo+G0hspKFx9Id/F21BHfPwiUBl7+pZrKd4uOiI5M7olxVlf2CQXwe7yI6kAL23xgPbZVqIgAUuGJs= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6d9a4160-b921-452a-b44a-08da3d79f7c1 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:48.4756 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 23c8jKV1RE7PAX7J/iG+goBaOlzJMyGrHBjeDEbNBeLlV7B40gn7YxOWdMAZ8fIeyfjp6LlYegKHSCCrh3OmKg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/sounding.h | 151 ++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/sounding.h diff --git a/drivers/net/wireless/celeno/cl8k/sounding.h b/drivers/net/wireless/celeno/cl8k/sounding.h new file mode 100644 index 000000000000..abdf834150f9 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/sounding.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_SOUNDING_H +#define CL_SOUNDING_H + +#include + +#include "fw.h" + +#define SOUNDING_ENABLE true +#define SOUNDING_DISABLE false +#define INVALID_SID 0xff +#define XMEM_SIZE (0x180 << 10) /* 384KB */ +#define CL_SOUNDING_STABILITY_TIME 5 +#define CL_SOUNDING_FACTOR 10 + +#define SOUNDING_FEEDBACK_TYPE_SHIFT 2 +#define SOUNDING_FEEDBACK_TYPE_MASK (BIT(SOUNDING_FEEDBACK_TYPE_SHIFT)) +#define SOUNDING_NG_SHIFT 1 +#define SOUNDING_NG_MASK (BIT(SOUNDING_NG_SHIFT)) +#define SOUNDING_MU_CODEBOOK_SIZE_SHIFT 0 +#define SOUNDING_MU_CODEBOOK_SIZE_MASK (BIT(SOUNDING_MU_CODEBOOK_SIZE_SHIFT)) +#define SOUNDING_FEEDBACK_TYPE_VAL(fb_type_ng_cb_size) (((fb_type_ng_cb_size) & \ + SOUNDING_FEEDBACK_TYPE_MASK) >> \ + SOUNDING_FEEDBACK_TYPE_SHIFT) +#define SOUNDING_NG_VAL(fb_type_ng_cb_size) (((fb_type_ng_cb_size) & \ + SOUNDING_NG_MASK) >> SOUNDING_NG_SHIFT) +#define SOUNDING_CODEBOOK_SIZE_VAL(fb_type_ng_cb_size) (((fb_type_ng_cb_size) & \ + SOUNDING_MU_CODEBOOK_SIZE_MASK) >> \ + SOUNDING_MU_CODEBOOK_SIZE_SHIFT) + +#define SOUNDING_TYPE_IS_VHT(type) ((type) == SOUNDING_TYPE_VHT_SU || \ + (type) == SOUNDING_TYPE_VHT_MU) +#define SOUNDING_TYPE_IS_CQI(type) ((type) == SOUNDING_TYPE_HE_CQI || \ + (type) == SOUNDING_TYPE_HE_CQI_TB) + +enum fb_type_ng_cb_size { + FEEDBACK_TYPE_SU_NG_4_CODEBOOK_SIZE_4_2 = 0x0, + FEEDBACK_TYPE_SU_NG_4_CODEBOOK_SIZE_6_4, + FEEDBACK_TYPE_SU_NG_16_CODEBOOK_SIZE_4_2, + FEEDBACK_TYPE_SU_NG_16_CODEBOOK_SIZE_6_4, + FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_7_5, + FEEDBACK_TYPE_MU_NG_4_CODEBOOK_SIZE_9_7, + FEEDBACK_TYPE_CQI_TB, + FEEDBACK_TYPE_MU_NG_16_CODEBOOK_SIZE_9_7, +}; + +enum cl_sounding_response { + CL_SOUNDING_RSP_OK = 0, + + CL_SOUNDING_RSP_ERR_RLIMIT, + CL_SOUNDING_RSP_ERR_BW, + CL_SOUNDING_RSP_ERR_NSS, + CL_SOUNDING_RSP_ERR_INTERVAL, + CL_SOUNDING_RSP_ERR_ALREADY, + CL_SOUNDING_RSP_ERR_STA, + CL_SOUNDING_RSP_ERR_TYPE, +}; + +enum sounding_type { + SOUNDING_TYPE_HE_SU = 0, + SOUNDING_TYPE_HE_SU_TB, + SOUNDING_TYPE_VHT_SU, + SOUNDING_TYPE_HE_CQI, + SOUNDING_TYPE_HE_CQI_TB, + SOUNDING_TYPE_HE_MU, + SOUNDING_TYPE_VHT_MU, + + SOUNDING_TYPE_MAX +}; + +enum sounding_interval_coef { + SOUNDING_INTERVAL_COEF_MIN_INTERVAL = 0, + SOUNDING_INTERVAL_COEF_STA_STEP, + SOUNDING_INTERVAL_COEF_INTERVAL_STEP, + SOUNDING_INTERVAL_COEF_MAX_INTERVAL, + SOUNDING_INTERVAL_COEF_MAX +}; + +struct v_matrix_header { + u32 format : 2, + rsv1 : 30; + u32 bw : 2, + nr_index : 3, + nc_index : 3, + rsv2 : 24; + u32 grouping : 4, + rsv3 : 28; + u32 feedback_type : 1, + codebook_info : 3, + rsv4 : 28; + u32 ru_start_idx : 7, + rsv5 : 25; + u32 ru_end_idx : 7, + rsv6 : 25; + u32 padding : 6, + rsv7 : 26; + u32 rsv8; +}; + +struct cl_sounding_info { + enum sounding_type type; + u8 sounding_id; + struct v_matrix_header *v_matrices_data; + u32 v_matrices_data_len; + u32 v_matrices_dma_addr; + u8 gid; + u8 bw; + u8 sta_num; + u8 q_matrix_bitmap; + struct cl_sta *su_cl_sta_arr[CL_MU_MAX_STA_PER_GROUP]; + u32 xmem_space; + bool sounding_restart_required; + struct list_head list; +}; + +struct cl_sounding_db { + struct workqueue_struct *sounding_wq; + u8 num_soundings; + u8 cqi_profiles; /* Num of STAs with CQI active sounding */ + u8 active_profiles; /* Num of STAs with non-CQI active sounding */ + u8 active_profiles_prev[CL_SOUNDING_STABILITY_TIME]; + u8 active_profiles_idx; + u8 dbg_level; + u8 current_interval; + u8 last_conf_active_profiles; + rwlock_t list_lock; + struct list_head head; +}; + +struct cl_xmem { + u32 total_used; + u32 size; +}; + +void cl_sounding_init(struct cl_hw *cl_hw); +void cl_sounding_close(struct cl_hw *cl_hw); +void cl_sounding_send_request(struct cl_hw *cl_hw, struct cl_sta **cl_sta_arr, + u8 sta_num, bool enable, u8 sounding_type, u8 bw, + void *mu_grp, + u8 q_matrix_bitmap, struct cl_sounding_info *recovery_elem); +void cl_sounding_switch_profile(struct cl_hw *cl_hw, u8 sta_idx_en, u8 sta_idx_dis); +void cl_sounding_stop_by_sid(struct cl_hw *cl_hw, u8 sid, bool sounding_restart_check); +void cl_sounding_maintenance(struct cl_hw *cl_hw); +u16 cl_sounding_get_interval(struct cl_hw *cl_hw); +void cl_sounding_recovery(struct cl_hw *cl_hw); +struct cl_sounding_info *cl_sounding_get_elem(struct cl_hw *cl_hw, u8 sounding_id); +void cl_sounding_indication(struct cl_hw *cl_hw, struct mm_sounding_ind *ind); + +#endif /* CL_SOUNDING_H */ From patchwork Tue May 24 11:34:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575951 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 14300C433F5 for ; Tue, 24 May 2022 11:41:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235724AbiEXLln (ORCPT ); Tue, 24 May 2022 07:41:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237004AbiEXLlg (ORCPT ); Tue, 24 May 2022 07:41:36 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60067.outbound.protection.outlook.com [40.107.6.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB024915BB for ; Tue, 24 May 2022 04:40:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kU6GZZ4tP21xZHfCImAmk6FGWXVfqww6OJrTgkB6NDrw8uRH7fxl0yGztTlvqDxahqQz9RA7BPWo62cTm6s+FIvoBC9i2A2ZaFfpzqvJw+IKircfm/68FTFXkSifqkF7aA5wv6OUs99yx2R12Lb/3iJMCD/BH2O/kn00uVDvW5r0p7eI7JYLJlEuxiMuCDqLC7BKRdJt8EzaUMpy/fgHM0KxsjK8Y5UTUB34h4dIQtbUPxIkwIMrOhN7FodL+ksraOrz3eHIhSpB6S1IFq+XQ87wBr+JtAdxviBeHMvom5RJmDYJrxzt1GM3XgECxoggkXSWhIFkuPXnB2bx1ZTHKA== 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=1JM4onuLiLGB7asJfwptj2ATnylJ+NbnJA+JvJV1v1c=; b=AaP+Q2CG9DS3699/muQPDq1nJYOVpkUaLIGRSWiFTR6eaMRv2MyIPbkPj+O3YRkaOsz42jPzHCSylwLx9Big1wA7bd4K+ixpqCxVB9YhPka0pNVaEksj2MXMMcneAn8YJ2XQZqsAvSJ1aNQm9AL5ukf2tcobemSstWSqbR3MQY4cXXZafNLW5LyqwzzgitNFshf8MGVe76B3s1RIdX/W1JHxuzA0TAJxulOgrFsqrroB2NJ6Im+G1HxiiI8Op8e5j3IopmavO7W9MQ5WMjlD//PJsQPTnfFp2oxOyfnYaDzwjqjpM+KrzwJhret8xsFM7BtZNwM+xIWOOFetwoCG1A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1JM4onuLiLGB7asJfwptj2ATnylJ+NbnJA+JvJV1v1c=; b=Yp/bjNLr2yA7L24a1TrNzPi+ULQzAPeB3wV1VXjPBGiEkKAFP19SGopZ7kFiRiielE0lqeI86kMFChY5AnImaU80sA9+eGFAZs4tzCij84cgYldMe4/PsnNP8T7j3eyLbbPUarTtYL3k9bGEc2hUw+aBpb72naHPRptWWkjKmxc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:27 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:27 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 74/96] cl8k: add sta.c Date: Tue, 24 May 2022 14:34:40 +0300 Message-Id: <20220524113502.1094459-75-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e6d73d93-0093-40b1-44ba-08da3d79f82a X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: EVXl/wgYqPlpALlw/gvksicvQFyYGL+1n5hkTttMq+YUbCE2MRM9j/QFUHh7QPZ6Vx6bSsb1brLY3uw81gWs81KY75qeHYRSkw9fH3qE53YPdZh1M/93UIq1dbFK2pWMkr54BSmxbPdSYsDXIw8GBXCZEjK2IwV0Ma9srIWSWjI811jwITGH3HQFAgHTQjFJPCRNL1THL6je0Lotu1xhi3C9WEkDYvrLGamjG1AdnPywCmD48A7dzl8QfTeSvV6g1iUxCAH463eFOX1TEtR1bjNYyAflG3gAfpeyCbC9vm2Sigs7T5Vujv3U/p7vheJ1TL3f9PNem7v5yaL3pyVNhJpJ8OtIlvbc64NYhsaJndvEXqKbrt9NyQ8vcujWWwo0gnpiZNJOvLO93JvLUHq1FrNTXWBZWx0ftRUhnDLSZPbJETIw3VzyE2U6F/J/Vq92ebQsyCrBK30tQhuRZBaoOG0/Gjsv2fWL9e04PzVGMRJ0Pls5sRFM5nT6CXu7s05vYplT5zww6kgE1PCp7Oncy1fn8siA0wQBVnM80lJ835bYLPtJAh9jZflHOI4BsNYHR9dEyDzVKo5epGcxPkcCz9R0N/W3QK/NiHSHwS4n/xm2/n61IMG888o1t7BaanKmyDl1fRE459gR8RoIMrNUJK7kuyLjbP9qJNqFAwgsrZGKnRI0COZXXZOV3TWN/H5bw2pBqJo2XsnLwG6QCvAv97nAeqbp7Iyv/3ki3yKboyI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(30864003)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: CUwExySzDcH77f6WdpXa//8hT7E1wA2vbVwYrLUxGhdebeSSBwum7qhho1SqtBHARxSuRhPFcoanHDkDIdLc7Qp5B/uHGJXwnNdAtRhrEeGFTnEfje/YglYGOJ7Ew/Ygwc4WI4Qe9+Rz5XINgTZ2bb0MHQWg97IgCefl3l9Omoyd/DmrnvD8v1nap3mDRU59MY/fmJC4WFOvMRhMr7b6Z/yNk1m1WedpWFb1vAfspSYbsdjkyX+aqZfNBA9zzTqSvaMXMQwkw4CeBSkRtngF6pVBYhg+kGGFaRH+5EyoWWrgb3LBxI6jNVwbQhuoylKE+Vh6PMrZPkO3Vc7cQu7i+gligz0Zv3AGyXIt6lqOZ+BEoJhWGFZjUvFcAtlk2YBqNFn72k3sW5abmuWZUIgcMTo61YNmQNymqaeZf1iMlrhy8IMZg3P3I05wRKhWoTNLInHGgqo90aTTQDbaeLz2KJHw5+cLmlhiVhCw3JNBEuYXxQc1S037a+016If+Z+G31r0XxPwd5gw3FlVrLieXUUf2O5YS+E0n1A0Z1QDOLauAgOij2OeJLcNgsnIZSXw2cFw5gwWUODV+zhSixwaicQD/28kKeplZNvXhcjkayTpURmYUaHILhHyWLoSwBZZehBtmSXK6ddofAI19nX/CWblWjG6pFttRQoxaCmDsh9mzBPvmp3Q/qYxGpfvJAhcKgJfeiFQykXdWyH1TE+PuAUnx+FGPbFY/bb0YvbrSTD1bPNOUagPYAi0wvhRcJnA0YNq2XrX2DgIB1wKMFIS0VbTieZoepq0qTEB4pN6YqqRDbheQO50bmYoIC4+aX+NRqqNfvrg//0D1uRMnJ5hv4yVLzpyhYHPP73cayHeKcxFgRw+IBA/ZYzjvy26cJnHsLQ88KlJUKPuLjVooyrSqd51pJu7m4+hBdzuyRT5EEloWE9lTaDTD6H2FHtIPcFKXxZhNS9eJvzNnpSCworYX/EiN9yyY3XqoUfVz1GirJ3MPf+RhlYeY3zKuCFlea3lAjIAJWgWW4cq1Yztr4iP/SAv/w0/cR4m02NQuDC1gFFUmX9UV0ZiGXsz7DrLbeNOsAEz/4WVoTp7q3coC1XhS220XtayDJWbol2hDYew2Aq1lslksa8a21icBZ/6SKD440gflbUcXe4gIHsiNbxU6WJNx9I9yTf/Za62X9E4Y6cZerz5/J7hivPvHvhvGqnpMuYfwBQbgjVyMWUJGAnkbjP+FgezSirL9py+I6XEBqso8l0Xtr4SJAhq+K5+bXVN+9bhMj70HuWN5jQxJx1MLv5V+1wD235/E++1PWUrxCgOZfwYGaVUyE/GwgUJfYkAx0kPznHPctoQGF0VMommKXOsbmQJEwcqh32f6Up7SNJBoimzyHs/bZTCbXDUm225CZNW/3V2Q7srCCAvcSVPd/QZ+3xvWuCOJ54R6CpUTSoKeAPSgZf4bqYw1uA8MGA5CHkeNXhMdTfJfBPg2JEgH/Dp1UqunTXj79VMyoQs3uPZLAdDq/4SBxdYm+jlgT9MckI2BMVdo5d6Sd8N5qnTD0feoNpztdw/5lUzpDNH5ivDQb5oV8z6e3AMe1m/yPVabepUwGjI/5/54+r7p0iXOU7+fxQo5A61LE9lTJSyPghy7PJ9b44iWuAr6vxyR2H3h5y48+oBIu/2OrEZcwx6jn066OZftQwbh0wVxpa+kIVAoVIdw++ivBiji3LeA1EUITZWab+Oq9F45CR1oHWvdr0Rb8kAfcg5v20CjVL4vaOM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: e6d73d93-0093-40b1-44ba-08da3d79f82a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:49.1778 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: MrF/NPNvcT8zVFiJedunRuowTJi4uhCvJOc6IvhUAmISRG3LAWlFZjZqAe6OpXryXb7ABeycASKSUB+u9NBOFg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/sta.c | 507 +++++++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/sta.c diff --git a/drivers/net/wireless/celeno/cl8k/sta.c b/drivers/net/wireless/celeno/cl8k/sta.c new file mode 100644 index 000000000000..26c280b05266 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/sta.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "chip.h" +#include "phy.h" +#include "bf.h" +#include "vns.h" +#include "tx.h" +#include "radio.h" +#include "motion_sense.h" +#include "mac_addr.h" +#include "recovery.h" +#include "dfs.h" +#include "stats.h" +#include "utils.h" +#include "sta.h" + +void cl_sta_init(struct cl_hw *cl_hw) +{ + u32 i; + + rwlock_init(&cl_hw->cl_sta_db.lock); + INIT_LIST_HEAD(&cl_hw->cl_sta_db.head); + + for (i = 0; i < CL_STA_HASH_SIZE; i++) + INIT_LIST_HEAD(&cl_hw->cl_sta_db.hash[i]); +} + +void cl_sta_init_sta(struct cl_hw *cl_hw, struct ieee80211_sta *sta) +{ + if (!cl_recovery_in_progress(cl_hw)) { + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + /* Reset all cl_sta strcture */ + memset(cl_sta, 0, sizeof(struct cl_sta)); + cl_sta->sta = sta; + /* + * Set sta_idx to 0xFF since FW expects this value as long as + * the STA is not fully connected + */ + cl_sta->sta_idx = STA_IDX_INVALID; + } +} + +static void cl_sta_add_to_lut(struct cl_hw *cl_hw, struct cl_vif *cl_vif, struct cl_sta *cl_sta) +{ + write_lock_bh(&cl_hw->cl_sta_db.lock); + + cl_hw->cl_sta_db.num++; + cl_vif->num_sta++; + cl_hw->cl_sta_db.lut[cl_sta->sta_idx] = cl_sta; + + /* Done here inside the lock because it allocates cl_stats */ + cl_stats_sta_add(cl_hw, cl_sta); + + write_unlock_bh(&cl_hw->cl_sta_db.lock); + + cl_dbg_verbose(cl_hw, "mac=%pM, sta_idx=%u, vif_index=%u\n", + cl_sta->addr, cl_sta->sta_idx, cl_sta->cl_vif->vif_index); +} + +static void cl_sta_add_to_list(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + u8 hash_idx = CL_STA_HASH_IDX(cl_sta->addr[5]); + + write_lock_bh(&cl_hw->cl_sta_db.lock); + + /* Add to hash table */ + list_add(&cl_sta->list_hash, &cl_hw->cl_sta_db.hash[hash_idx]); + + /* Make sure that cl_sta's are stored in the list according to their sta_idx. */ + if (list_empty(&cl_hw->cl_sta_db.head)) { + list_add(&cl_sta->list, &cl_hw->cl_sta_db.head); + } else if (list_is_singular(&cl_hw->cl_sta_db.head)) { + struct cl_sta *cl_sta_singular = + list_first_entry(&cl_hw->cl_sta_db.head, struct cl_sta, list); + + if (cl_sta_singular->sta_idx < cl_sta->sta_idx) + list_add_tail(&cl_sta->list, &cl_hw->cl_sta_db.head); + else + list_add(&cl_sta->list, &cl_hw->cl_sta_db.head); + } else { + struct cl_sta *cl_sta_last = + list_last_entry(&cl_hw->cl_sta_db.head, struct cl_sta, list); + + if (cl_sta->sta_idx > cl_sta_last->sta_idx) { + list_add_tail(&cl_sta->list, &cl_hw->cl_sta_db.head); + } else { + struct cl_sta *cl_sta_next = NULL; + struct cl_sta *cl_sta_prev = NULL; + + list_for_each_entry(cl_sta_next, &cl_hw->cl_sta_db.head, list) { + if (cl_sta_next->sta_idx < cl_sta->sta_idx) + continue; + + cl_sta_prev = list_prev_entry(cl_sta_next, list); + __list_add(&cl_sta->list, &cl_sta_prev->list, &cl_sta_next->list); + break; + } + } + } + + write_unlock_bh(&cl_hw->cl_sta_db.lock); + + cl_sta->add_complete = true; +} + +static void cl_connection_data_add(struct cl_vif *cl_vif) +{ + struct cl_connection_data *conn_data = cl_vif->conn_data; + + if (cl_vif->num_sta > conn_data->max_client) { + conn_data->max_client = cl_vif->num_sta; + conn_data->max_client_timestamp = ktime_get_real_seconds(); + } + + if (cl_vif->num_sta == conn_data->watermark_threshold) + conn_data->watermark_reached_cnt++; +} + +static void cl_connection_data_remove(struct cl_vif *cl_vif) +{ + struct cl_connection_data *conn_data = cl_vif->conn_data; + + if (cl_vif->num_sta == conn_data->watermark_threshold) + conn_data->watermark_reached_cnt++; +} + +static void _cl_sta_add(struct cl_hw *cl_hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + /* !!! Must be first !!! */ + cl_sta_add_to_lut(cl_hw, cl_vif, cl_sta); + + cl_baw_init(cl_sta); + cl_txq_sta_add(cl_hw, cl_sta); + cl_vns_sta_add(cl_hw, cl_sta); + cl_connection_data_add(cl_vif); + + /* + * Add rssi of association request to rssi pool + * Make sure to call it before cl_wrs_api_sta_add() + */ + cl_rssi_assoc_find(cl_hw, cl_sta, cl_hw->cl_sta_db.num); + + cl_motion_sense_sta_add(cl_hw, cl_sta); + cl_bf_sta_add(cl_hw, cl_sta, sta); + cl_wrs_api_sta_add(cl_hw, sta); + cl_wrs_api_set_smps_mode(cl_hw, sta, sta->bandwidth); +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + /* Should be called after cl_wrs_api_sta_add() */ + cl_dyn_mcast_rate_update_upon_assoc(cl_hw, cl_sta->wrs_sta.mode, + cl_hw->cl_sta_db.num); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_update_upon_assoc(cl_hw, + cl_sta->wrs_sta.tx_su_params.rate_params.mcs, + cl_hw->cl_sta_db.num); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + + /* !!! Must be last !!! */ + cl_sta_add_to_list(cl_hw, cl_sta); +} + +/* + * Parse the ampdu density to retrieve the value in usec, according to + * the values defined in ieee80211.h + */ +static u8 cl_sta_density2usec(u8 ampdu_density) +{ + switch (ampdu_density) { + case IEEE80211_HT_MPDU_DENSITY_NONE: + return 0; + /* 1 microsecond is our granularity */ + case IEEE80211_HT_MPDU_DENSITY_0_25: + case IEEE80211_HT_MPDU_DENSITY_0_5: + case IEEE80211_HT_MPDU_DENSITY_1: + return 1; + case IEEE80211_HT_MPDU_DENSITY_2: + return 2; + case IEEE80211_HT_MPDU_DENSITY_4: + return 4; + case IEEE80211_HT_MPDU_DENSITY_8: + return 8; + case IEEE80211_HT_MPDU_DENSITY_16: + return 16; + default: + return 0; + } +} + +static void cl_sta_set_min_spacing(struct cl_hw *cl_hw, + struct ieee80211_sta *sta) +{ + bool is_6g = cl_band_is_6g(cl_hw); + u8 sta_min_spacing = 0; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + + if (is_6g) + sta_min_spacing = + cl_sta_density2usec(le16_get_bits(sta->he_6ghz_capa.capa, + IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START)); + else if (sta->ht_cap.ht_supported) + sta_min_spacing = + cl_sta_density2usec(sta->ht_cap.ampdu_density); + else + cl_dbg_err(cl_hw, "HT is not supported - cannot set sta_min_spacing\n"); + + cl_sta->ampdu_min_spacing = + max(cl_sta_density2usec(IEEE80211_HT_MPDU_DENSITY_1), sta_min_spacing); +} + +u32 cl_sta_num(struct cl_hw *cl_hw) +{ + u32 num = 0; + + read_lock(&cl_hw->cl_sta_db.lock); + num = cl_hw->cl_sta_db.num; + read_unlock(&cl_hw->cl_sta_db.lock); + + return num; +} + +u32 cl_sta_num_bh(struct cl_hw *cl_hw) +{ + u32 num = 0; + + read_lock_bh(&cl_hw->cl_sta_db.lock); + num = cl_hw->cl_sta_db.num; + read_unlock_bh(&cl_hw->cl_sta_db.lock); + + return num; +} + +struct cl_sta *cl_sta_get(struct cl_hw *cl_hw, u8 sta_idx) +{ + if (sta_idx < CL_MAX_NUM_STA) + return cl_hw->cl_sta_db.lut[sta_idx]; + + return NULL; +} + +struct cl_sta *cl_sta_get_by_addr(struct cl_hw *cl_hw, u8 *addr) +{ + struct cl_sta *cl_sta = NULL; + u8 hash_idx = CL_STA_HASH_IDX(addr[5]); + + if (is_multicast_ether_addr(addr)) + return NULL; + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.hash[hash_idx], list_hash) + if (cl_mac_addr_compare(cl_sta->addr, addr)) + return cl_sta; + + return NULL; +} + +void cl_sta_loop(struct cl_hw *cl_hw, sta_callback callback) +{ + struct cl_sta *cl_sta = NULL; + + /* Go over all stations */ + read_lock(&cl_hw->cl_sta_db.lock); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) + callback(cl_hw, cl_sta); + + read_unlock(&cl_hw->cl_sta_db.lock); +} + +void cl_sta_loop_bh(struct cl_hw *cl_hw, sta_callback callback) +{ + struct cl_sta *cl_sta = NULL; + + /* Go over all stations - use bottom-half lock */ + read_lock_bh(&cl_hw->cl_sta_db.lock); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) + callback(cl_hw, cl_sta); + + read_unlock_bh(&cl_hw->cl_sta_db.lock); +} + +static int cl_sta_add_to_firmware(struct cl_hw *cl_hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + struct mm_sta_add_cfm *sta_add_cfm; + int error = 0; + u8 recovery_sta_idx = 0; + u32 rate_ctrl_info = 0; + + if (cl_recovery_in_progress(cl_hw)) { + struct cl_wrs_rate_params *rate_params = &cl_sta->wrs_sta.tx_su_params.rate_params; + + /* + * If station is added to firmware during recovery, the driver passes to firmware + * the station index to be used instead of firmware selecting a free index + */ + recovery_sta_idx = cl_sta->sta_idx; + + /* Keep current rate value */ + rate_ctrl_info = cl_rate_ctrl_generate(cl_hw, cl_sta, rate_params->mode, + rate_params->bw, rate_params->nss, + rate_params->mcs, rate_params->gi, + false, false); + } else { + bool is_cck = cl_band_is_24g(cl_hw) && cl_hw_mode_is_b_or_bg(cl_hw); + u8 mode = is_cck ? WRS_MODE_CCK : WRS_MODE_OFDM; + + /* + * Not in recovery: + * firmware will set sta_idx and will return in confirmation message + */ + recovery_sta_idx = STA_IDX_INVALID; + + /* Default rate value */ + rate_ctrl_info = cl_rate_ctrl_generate(cl_hw, cl_sta, mode, + 0, 0, 0, 0, false, false); + } + + /* Must be called before cl_msg_tx_sta_add() */ + cl_sta_set_min_spacing(cl_hw, sta); + + /* Send message to firmware */ + error = cl_msg_tx_sta_add(cl_hw, sta, cl_vif, recovery_sta_idx, rate_ctrl_info); + if (error) + return error; + + sta_add_cfm = (struct mm_sta_add_cfm *)(cl_hw->msg_cfm_params[MM_STA_ADD_CFM]); + if (!sta_add_cfm) + return -ENOMSG; + + if (sta_add_cfm->status != 0) { + cl_dbg_verbose(cl_hw, "Status Error (%u)\n", sta_add_cfm->status); + cl_msg_tx_free_cfm_params(cl_hw, MM_STA_ADD_CFM); + return -EIO; + } + + /* Save the index retrieved from firmware */ + cl_sta->sta_idx = sta_add_cfm->sta_idx; + + /* Release cfm msg */ + cl_msg_tx_free_cfm_params(cl_hw, MM_STA_ADD_CFM); + + return 0; +} + +int cl_sta_add(struct cl_hw *cl_hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + int error = 0; + + if (cl_radio_is_going_down(cl_hw)) + return -EPERM; + + if (vif->type == NL80211_IFTYPE_MESH_POINT && + cl_vif->num_sta >= CL_MAX_NUM_MESH_POINT) + return -EPERM; + + cl_sta->cl_vif = cl_vif; + cl_mac_addr_copy(cl_sta->addr, sta->addr); + + error = cl_sta_add_to_firmware(cl_hw, vif, sta); + if (error) + return error; + + if (!cl_recovery_in_progress(cl_hw)) + if (vif->type != NL80211_IFTYPE_STATION || + cl_hw->chip->conf->ce_production_mode) + _cl_sta_add(cl_hw, vif, sta); + + if (vif->type == NL80211_IFTYPE_MESH_POINT && cl_vif->num_sta == 1) + set_bit(CL_DEV_MESH_AP, &cl_hw->drv_flags); + + return 0; +} + +void cl_sta_mgd_add(struct cl_hw *cl_hw, struct cl_vif *cl_vif, struct ieee80211_sta *sta) +{ + /* Should be called in station mode */ + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + + /* !!! Must be first !!! */ + cl_sta_add_to_lut(cl_hw, cl_vif, cl_sta); + + cl_baw_init(cl_sta); + cl_txq_sta_add(cl_hw, cl_sta); + cl_vns_sta_add(cl_hw, cl_sta); + + /* + * Add rssi of association response to rssi pool + * Make sure to call it before cl_wrs_api_sta_add() + */ + cl_rssi_assoc_find(cl_hw, cl_sta, cl_hw->cl_sta_db.num); + + cl_connection_data_add(cl_vif); + + /* In station mode we assume that the AP we connect to is static */ + cl_motion_sense_sta_add(cl_hw, cl_sta); + cl_bf_sta_add(cl_hw, cl_sta, sta); + cl_wrs_api_sta_add(cl_hw, sta); +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + /* Should be called after cl_wrs_api_sta_add() */ + cl_dyn_mcast_rate_update_upon_assoc(cl_hw, cl_sta->wrs_sta.mode, + cl_hw->cl_sta_db.num); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_update_upon_assoc(cl_hw, + cl_sta->wrs_sta.tx_su_params.rate_params.mcs, + cl_hw->cl_sta_db.num); + +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + /* !!! Must be last !!! */ + cl_sta_add_to_list(cl_hw, cl_sta); +} + +static void _cl_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + write_lock_bh(&cl_hw->cl_sta_db.lock); + + list_del(&cl_sta->list); + list_del(&cl_sta->list_hash); + + cl_hw->cl_sta_db.lut[cl_sta->sta_idx] = NULL; + cl_hw->cl_sta_db.num--; + cl_sta->cl_vif->num_sta--; + + cl_dbg_verbose(cl_hw, "mac=%pM, sta_idx=%u, vif_index=%u\n", + cl_sta->addr, cl_sta->sta_idx, cl_sta->cl_vif->vif_index); + + write_unlock_bh(&cl_hw->cl_sta_db.lock); +} + +void cl_sta_remove(struct cl_hw *cl_hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct cl_vif *cl_vif = (struct cl_vif *)vif->drv_priv; + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + u8 sta_idx = cl_sta->sta_idx; + + cl_sta->remove_start = true; + + /* !!! Must be first - remove from list and LUT !!! */ + _cl_sta_remove(cl_hw, cl_sta); + + cl_traffic_sta_remove(cl_hw, cl_sta); + cl_bf_sta_remove(cl_hw, cl_sta); + cl_connection_data_remove(cl_vif); +#ifdef CONFIG_CL8K_DYN_MCAST_RATE + cl_dyn_mcast_rate_update_upon_disassoc(cl_hw, + cl_sta->wrs_sta.mode, + cl_hw->cl_sta_db.num); +#endif /* CONFIG_CL8K_DYN_MCAST_RATE */ +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + cl_dyn_bcast_rate_update_upon_disassoc(cl_hw, + cl_sta->wrs_sta.tx_su_params.rate_params.mcs, + cl_hw->cl_sta_db.num); +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + cl_wrs_api_sta_remove(cl_hw, cl_sta); + cl_stats_sta_remove(cl_hw, cl_sta); + + /* + * TX stop flow: + * 1) Flush TX queues + * 2) Poll confirmation queue and clear enhanced TIM + * 3) Send MM_STA_DEL_REQ message to firmware + * 4) Flush confirmation queue + * 5) Reset write index + */ + + cl_txq_flush_sta(cl_hw, cl_sta); + cl_single_cfm_poll_empty_sta(cl_hw, sta_idx); + cl_txq_sta_remove(cl_hw, sta_idx); + + if (cl_vif->vif->type == NL80211_IFTYPE_MESH_POINT && + cl_vif->num_sta == 0) { + clear_bit(CL_DEV_MESH_AP, &cl_hw->drv_flags); + } + + cl_single_cfm_flush_sta(cl_hw, sta_idx); + + cl_msg_tx_sta_del(cl_hw, sta_idx); + + if (cl_vif->num_sta == 0) + cl_radio_off_wake_up(cl_hw); +} + +void cl_sta_ps_notify(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool is_ps) +{ + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + /* + * PS-Poll & UAPSD are handled by FW, by setting + * WLAN_STA_SP we ensure mac80211 does not re-handle. + * flag is unset at ieee80211_sta_ps_deliver_wakeup + */ + if (is_ps) + set_sta_flag(stainfo, WLAN_STA_SP); + + cl_stats_update_ps(cl_hw, cl_sta, is_ps); +} + From patchwork Tue May 24 11:34:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576832 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 12190C433EF for ; Tue, 24 May 2022 11:41:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236968AbiEXLlp (ORCPT ); Tue, 24 May 2022 07:41:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236994AbiEXLlj (ORCPT ); Tue, 24 May 2022 07:41:39 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60044.outbound.protection.outlook.com [40.107.6.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AEB9DBE8 for ; Tue, 24 May 2022 04:41:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mW7q++whO27S+UNdFQ682IU3M9CvhkwmqmXRfZQ8qg2A1tBl/Y4iSXRPSfrrxUPE2O6V6HITGn8D2jVlUqRaRwj3HLlSbQfgMcXik614y+Zmf8Q9MQnOd6pIY3S6cu0q76yYetcZBdlLXN7uvNwdQNwgK86XfLcFBOlkzGQUQ5YxR04/aR7CxppJs1DReqbNcku2Ov/UnCS4gnXyPt7FkK4xSGkF86WvLF8M7Y34poA9hO/hB9GIAwshjto6HVowJVmkyV5v8rvI602GwZkcqyxylgnHGGnmhEQoCcYy9uStNKcfexdjjARtG94vSt5ONZQ1teuMmFkV/n8hJVwS1Q== 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=sdqqG26dssxH+NjXK6D8Jiyj+M5focrYOsTHZ92RRO0=; b=nKZXjkg1Ai0fdtnjxPuw0GE+F+q1iL/xroh0anQYkU6ZBkpC2YczIqy1aC9DgOva0GTLDdAOtUnGX8Ep+gb3lweKfcn4ksZynzXXMvKezIQ7kHDMc9KlZdHU1XTLzg6SeqdacRtb4kIH4D9kkRyQXEHVqC4km4QIZ6mNiyJNFnz9rOioEKe+5SVD/JMPkWBoWFbjjdVf45cZ03/78W3SZ+3AHXDuiU6+Zzp3kOCXHcbH8EQumfTZ80qkoqbC/nJAH5tqM5zDe/kg1w3KCPg3QtIVuYBNh19cK9R4ylgWriHuwcJ9ukFlhh1SDHJYJFi36nCWy8LJvYE4zYB2l92Ujg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=sdqqG26dssxH+NjXK6D8Jiyj+M5focrYOsTHZ92RRO0=; b=Jws/eTMzkPt4CakjxEsLcCxa8cVuGMiLlITb55wcRCoYgs7od2xAjE3st68irzkKq1Vec8GQQLtkAFVi5e2dY6GuJmxttocpcc+cnEH38zz6WzclTMcTOnJISGNXqNw9EuX/Cbdrl9GbeM3j3IpRH/P+5crNSVrjgeajtpsbquw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by AM8P192MB0915.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:1ed::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5293.13; Tue, 24 May 2022 11:39:27 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:27 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 75/96] cl8k: add sta.h Date: Tue, 24 May 2022 14:34:41 +0300 Message-Id: <20220524113502.1094459-76-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 81f910f5-b922-4792-ba72-08da3d79f895 X-MS-TrafficTypeDiagnostic: AM8P192MB0915:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: WA8vAtq5JgfXY4MMQeyO2/ebhCbTpgLWdOqIESVKXonJxeBGFsAM8Rmq9CKrTp5yA0PWKfVcgtQeBci0lq20VkEgTgeectTMF5CFcHxR4USIT/4yTfhxHQVOHZ9bu2npk7dXGB8d7zHTsvu3WLYFQHwybmcplloKo56SKH1jCe1hCbzQoDmNnaxeNlic6jFElDFalRcCwsLzp/geKlTvj0Yw4xxj8HJg5VKKalvp/9H0DXjlTVYR/ngYltijKsXYADzhCf28X7ei67z3EeqVRT/hxBB6U8NvtTfpgnRLP2eC8W+7LRlBCvStsw6oD+L+4SXktgRLz1Jtxe5D1XneWaF59HzGJ9YRRokpQS0fadJm6Lr1p1Myjga1mCPGnJ1sdQiF1YGXVj9KfGEcPjxRs0MwQ80YsXVznK9863lQ3getN++lK7t/37TUpJB1M3b6q+8KTa34jBUUHkzcdqZZw3J+gL0qbcFhw9pV6lPnA8UDPxceQ5Lf5AGDK3TTTMgwmAb0qUiq1q0O66l9x5ffqDk0Dy2P3rE+fFh8KO0KGMC1tq8eLvOkLBdgUiPKiJwSdrQudAK66ze2zugnrJfOnESoOpzZdycTm7yW1lDmT2pRqBuGWbj/5SnZAxmROvgo9NHaXcV3K8rIq0PJ09Rp+CmWJcIp1bOkYZxy3P0iZD8JBEQBx+cf0+oYa7fZFwp2WE6uTczsjtJVhIsvGhgCT7FQhPkRj6RNJi4lRsqK2r0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(136003)(366004)(396003)(376002)(346002)(39850400004)(83380400001)(54906003)(186003)(36756003)(107886003)(2906002)(2616005)(1076003)(6916009)(41300700001)(66946007)(8936002)(6666004)(9686003)(66476007)(26005)(86362001)(66556008)(5660300002)(6512007)(4326008)(38350700002)(316002)(6506007)(52116002)(8676002)(6486002)(38100700002)(508600001)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: lNfcHJpsfyLRLRXogVVyVPRpAzG0H87ptVEefTCVm4WNdogwd3iWKfzan5B54EFsqfdRWq0nq3IdCN7ZhxKBwH7qWncV5ffRvKGiffe5IzT1OtvkreLFm5JfhVWXXUDpk2ztjNUevlpISyjrlFk0z/YQPODwkBr9St8QyAbDjHIwg3G8uOKEm9kRP3uKivh+mRpU+G/9IOpOZJp8a8EmcMbotsDyugd1WsME66mHHh3FXpPcFB9RGI3Aby5e8AfRKMnwfg1yEfZKjb1enmb1hBRW9dQrdYisRZKsU8FaY+kRdU6l1Y3PEaRnVU1SeyNW6x0D7IARu7FR0VWLPxq1rEY7oWh4N4gBVUgNJGmgYNBqt/z6kN+hbYDyEImAXivCv7osIIQJh7QS1GHaBXuMZ33M1Q+ic0jHbqK8iVaK4D1WMqF8YssceOc8YFNlVtrq7HAnE+vRV7ifiFU2R+VPDBzlqGW4hvvHuYpPRgRHPVA+Vep7Bhfl4wAyZ5H3DUB85FbGYrD42O9M5cwpoZ5CvgEOOya383A4PS9vRfJ5571LRge6xknYAjus5KxsvA3Pr7GoAN/1TpREk8jeuKUIUdDZTeSK9+AwGh91Yhw1UHNLzgduJo7nvmxjE42W9V2EENEZnfUV1rpCtERpDlKcWr3QpUWs39sF5IXcA7rJe0CI6cVUEYLDM81aNpQutcXXGfL6rOkJphsSlpk7CqkIeWD3mvpLVgQ39w7ZEn9hmrrwLaNUUMRDCqtu57wZUwCLucYn/Y/WcvWvCpoXtuZjXm51qvb95mf8IKLVzNCJlZbW2RXRbm58cRqnT8cZSk5a/SNW2xOhkPZTMH9deyu4uNsXD/tTXAK9lqKcgt40rELSlMCCS2zWLgahWX7R8o3UyG5au5B0K4SZWfr51mcPpst+eDB0DK/IKcEHreBcgsozkAf4dxEunvluiwJjPU/o/a8d5BKte901MF9PEmPzqqIb3B8jy7Uhox+ZfdoO3zE3EMmevLozmX8VM6gfYhxFC69GOyPKgXCWMafdFYHSBG1Fh0dTM1StTHI27xqG2GRSDtRNedtTCsDP3CEnlkWtB1kVnR/NQ0kFmKC/Wu7NROaXvDuvmvLkfNuP6pvQvKPsCXbn3y3U8YlLPCwhmLJ261fXGWjv+k56wu6PYdqmOwjmAP+PgtJL3EXYM4afVl+ONxckRN62hjpA9AJDNOJ7IfFuhGYOMZqU/zAWBBfIBPfl9KxQabCOS+wrTLizhEYzYr4NowccIxyfYoo9Q6C9JCKt4neBjVgBt0/xN3amJrI4EMgY1/sZY0h18uDdZqV4OfYgdaKMm0Es4G8y7ED61itEIlku80eAlxubfDb1aBl7G9nFSNJLqy7uIk3v+mqFyQWyvnTYyVLAuByGxTLLnpG9QisJ5tuSV/Bn3V8v8i4EprpFffFsJqCcYd4dpXvQlfXKeZ/DdxRB6uWQauOAsQB3ISsodfIh+BMHpQrNEBOLXo4vZRv6CXwcy1rYz1DVSx2Sp2rK8yNs9l0S1mheFFk2ydf+zlJhHw9JqA2EC4k2J1YG7pb7E+oVTTRhYQdg0NZGosm56vOgAXYnhRG5vnbV8MtQFiTvB7gjIlocxPt10VUA4Pjacy5DxAwZyumyVfD5DQW47lNXtkdE//sdpL7po3D5J/K1HCOuJGN5QZpHGtic4YMe0HDLQ4o3Qp+ReOEBaH8JCuL05C7ODiEK4RKSJsm/IR1iCcgBECojSwCEGoJB7zrbRli0USA0vsQ= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 81f910f5-b922-4792-ba72-08da3d79f895 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:49.8808 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0s3pTD7PeyYhlIQ2WqqnIUt2c1a+jqsDKMENekriw4F+jn96xeFf3UigxVi2sIpvXBmqCmbNJ0gIIyEf2yXr6w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P192MB0915 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/sta.h | 99 ++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/sta.h diff --git a/drivers/net/wireless/celeno/cl8k/sta.h b/drivers/net/wireless/celeno/cl8k/sta.h new file mode 100644 index 000000000000..f3c6bc743b96 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/sta.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_STA_H +#define CL_STA_H + +#include "sta_info.h" +#include "mac80211.h" +#include "rates.h" +#include "motion_sense.h" +#include "tx.h" +#include "traffic.h" +#include "bf.h" +#include "vns.h" + +#define IEEE80211_STA_TO_CL_STA(sta) ((struct cl_sta *)(sta)->drv_priv) +#define IEEE80211_STA_TO_STAINFO(ieee80211_sta) (container_of(ieee80211_sta, struct sta_info, sta)) + +#define CL_MAX_NUM_MESH_POINT 8 + +/* + * Structure used to save information relative to the managed stations. + * Will be used as the 'drv_priv' field of the "struct ieee80211_sta" structure. + */ +struct cl_sta { + struct list_head list; + struct list_head list_hash; + u8 sta_idx; + u8 su_sid; + bool key_disable; + u8 addr[ETH_ALEN]; + struct cl_baw baws[IEEE80211_NUM_TIDS]; + struct cl_amsdu_ctrl amsdu_anchor[IEEE80211_NUM_TIDS]; + struct cl_tx_queue *agg_tx_queues[IEEE80211_NUM_TIDS]; + u8 rx_pn[IEEE80211_NUM_TIDS][IEEE80211_CCMP_PN_LEN]; + struct cl_vif *cl_vif; + struct ieee80211_sta *sta; + struct ieee80211_key_conf *key_conf; + struct cl_bf_sta_db bf_db; + struct cl_stats *stats; + s32 alpha_rssi; + bool manual_alpha_rssi; + s8 last_rssi[MAX_ANTENNAS]; + u8 ampdu_min_spacing; + struct cl_traffic_sta traffic_db[TRAFFIC_DIRECTION_MAX]; + struct cl_traffic_mon traffic_mon[CL_TRFC_MON_PROT_MAX][CL_TRFC_MON_DIR_MAX]; + struct cl_vns_sta_db vns_db; + u32 retry_count; + u32 data_pending[AC_MAX]; + struct cl_wrs_info wrs_info_tx_su; + struct cl_wrs_info wrs_info_tx_mu_mimo; + struct cl_wrs_info wrs_info_rx; + struct cl_wrs_rssi wrs_rssi; + bool add_complete; + bool remove_start; + struct cl_wrs_sta wrs_sta; + struct cl_motion_sense motion_sense; + union cl_rate_ctrl_info_he rate_ctrl_he; + bool tf_support_dis; + struct cl_tid_ampdu_rx *tid_agg_rx[IEEE80211_NUM_TIDS]; + u64 tx_bytes; + u64 rx_bytes; + bool stop_tx; + bool pause_tx; + +}; + +#define CL_STA_HASH_SIZE (CL_MAX_NUM_STA / 2) +#define CL_STA_HASH_MASK (CL_STA_HASH_SIZE - 1) +#define CL_STA_HASH_IDX(x) ((x) & CL_STA_HASH_MASK) + +struct cl_sta_db { + struct list_head head; + struct cl_sta *lut[CL_MAX_NUM_STA]; + struct list_head hash[CL_STA_HASH_SIZE]; + rwlock_t lock; + u32 num; +}; + +typedef void (*sta_callback)(struct cl_hw *, struct cl_sta *); + +/* These functions take the lock inside */ +u32 cl_sta_num(struct cl_hw *cl_hw); +u32 cl_sta_num_bh(struct cl_hw *cl_hw); + +/* Must take lock before calling these functions */ +struct cl_sta *cl_sta_get(struct cl_hw *cl_hw, u8 sta_idx); +struct cl_sta *cl_sta_get_by_addr(struct cl_hw *cl_hw, u8 *addr); + +void cl_sta_init(struct cl_hw *cl_hw); +void cl_sta_loop(struct cl_hw *cl_hw, sta_callback callback); +void cl_sta_loop_bh(struct cl_hw *cl_hw, sta_callback callback); +void cl_sta_init_sta(struct cl_hw *cl_hw, struct ieee80211_sta *sta); +int cl_sta_add(struct cl_hw *cl_hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +void cl_sta_mgd_add(struct cl_hw *cl_hw, struct cl_vif *cl_vif, struct ieee80211_sta *sta); +void cl_sta_remove(struct cl_hw *cl_hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +void cl_sta_ps_notify(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool is_ps); + +#endif /* CL_STA_H */ From patchwork Tue May 24 11:34:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575964 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 EBEF9C433EF for ; Tue, 24 May 2022 11:40:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236865AbiEXLkB (ORCPT ); Tue, 24 May 2022 07:40:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236875AbiEXLj5 (ORCPT ); Tue, 24 May 2022 07:39:57 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2071.outbound.protection.outlook.com [40.107.20.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42D7791550 for ; Tue, 24 May 2022 04:39:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IVT0B+CQqEzKsIfpsxf4PYEWy49ZtTNEzAMGGId0cZfnM+Pc0ulACtpFHPPBaWmIN7WrhwJSJtiM1Yt+fon+c19/ZeWdB+PxEB9Qti3lEhfsxIUC2DelRb+yir/ZuvPNCs5boPpYXkk6b+dDAqXSC1iduXoLaCMm2oaGTri+6wcPaoF1xQfx8+FE2CDJf/H3KbCMGnM9Vd6FXOgm6lsuEx8Y/EbE2wzb4+Hx3E3OgDctCYDeOhi5vbyxIoSns/vP5N3wPC8nfD++N8jQgNlNY81x/iKNHZiGnfWpH3nVyRNb7GtaNZShX6RheVemWvaP8KshQGbbqzRNf6PKX1MDaw== 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=ucTvL73BxGU3jwDbQm7KMzdaWcUR66LqkJX67jbRs6E=; b=IvEg2vnj4DRzQGLIgEMyQmmF0jkBRRb20LF2T0RIlwaNF5MvhCNROa5eonqVB9Ha7+w7pNlCQXc3mJXT/rTWYuQ/kDwdwvjynr+0F9hyDH41p5K/rKWKgSp2UQM4ENeDPndnCQq4LKS6u2Wm7CCBkkgt7B2+gtApbRE7Ej+WGeBiEtvc+/i38sPdpXH7lRhUyygsea5vZybK3cjdLj3jxbBvc3KRuNGlcdc7Ng8h/gnJ0ps8j98+Lg4FEY7w64CQRlqM8/6u8+C5B1/rDW6Y5dJcP5HLh8zqC1ya5HHgcxH+c1SfBgKNFX5p4PAapnXIEM8O6RYi3R4AVYHCZRz/+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ucTvL73BxGU3jwDbQm7KMzdaWcUR66LqkJX67jbRs6E=; b=RkaNVLV+rFQvOK/127rZ01gexe5vGasNBmt5lFtCRxYPggvhim0KQiu+v5qUdNUbB2qkWkWELFgjb0ngDFp9WoNiX8ZzcJZKYGx587e2sa6AV60nup9OIDryr0mith9x59EgQowuP7xTPU+AFkE49jXqbwZI9pxNaCInk3YProU= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:27 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:27 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 76/96] cl8k: add stats.c Date: Tue, 24 May 2022 14:34:42 +0300 Message-Id: <20220524113502.1094459-77-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b6b1bf08-8085-4f3b-6153-08da3d79f903 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: cXIB0EY0g5AI1ykespUgkVJEg5q/yPjXBIQYPoQrpYMnXl0l9nS8KvdKbMIc0fMSIE2i1loCJjHo7nMEZ1ZTsn9DloQVOpnY29KIkJfdtqYVaqNzkgrx9/H9YLPBpZcdshju3mUciKHmZre1egk9USFTL8nRDcEd8IXhoSNEGlwhwFTdpL1JubLiI/MWVFlSCFElUYslRYKy5ZsErSzwd5V14TFVu6K0Yf5eHBwhuaMgBTuljlw9ZgsGw8be4GtgAzAYzFKLsK3NlqoXzLlWOByvISV+ScoHhOFnXVu+SW3bh0WUGqiynbLvsCwiF+Xk0YrCMCA66r6Gp/bL+sadrxDHi9To0+7ARUoJOq2QZuUFtLx+ygfFadbBgUAmViXf30QCXrOzOG/wdalvQ2yuFnXINBu+v/KcLKQuQruxgZ4JOsN+LT3dxONKX8wi0h8yjG96orLMF+PpSAwUGBVB23FBF9/HYb4LFz6PvuRYVyK0RIVu+a9nqLslV5ZpDG+NmwXFd+j6QwUmRE0QRYaFSqbGrbjKp/kL6VvVUhQcmgP4lBd2h+9s+trm0DL+bIu3bgzX7LMay1+hBB+tfTW7g1UmEDJqJNG6/i80fS5Fy7cILo/D0ET7BLS3NHNi5ESgCB7oGoQdNZR1pvYPywMpO87uQYZ2VzXBQMGZRoWglXrjFRayWOjI/DF/0JGwNrjR4hYWK51RjaQ5S1Ibq1BgGreLns9S9pknrsNEnITChpU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: YW8FiAqDtU1Z/zojI1k/8wf01HAEEmrGWlEU7Ab5iZoLqK/VPU/qhMsmvAc+WUOMxqb6EapBrj1026q+XE9tRL/BlphkF3b+VEdnq1e5slj7dFLzY7vmoT2J+qt0LZhiiP2UdYDeF5UM+B75jbehHnEnGf1z4vhFzk2mLtlq3wVUxSgp834FKZykkrVRmqHDHOwK2nHDvLX/zAGs6Hv4qIKpxd1OR5frLPYeXPmHvf41pRA+Fjc7DUkMWOsxRvb02wKIZhA5E/1dAK0zZFGfdM9qLxCXgKGOiQKrgLBqiRegyMaHeIrsAX++ia0+kr8z9TKJc0R1UWRodhhx+onDCO17mFMzmil86i6/50TIeduC1DVReazJkrwSBCmykMGQkIKDVDX/CznQykRGdXzFJNMYxLpR7nIU2Qc3bYYrrm0g1Wj3kizKfaNEw3t+L38BBmQpB344wcWG6MoKdR3LQZYEte/4fqxyzx0HSIxQadOjrQKhh374++xofI12+4uRrTbadhJGGyZWaOFjmbjWg7Jc6EPK2JLdOpvR7NjAH0ur9e14fGMeDn8Ra4DtC9ROdOyMzJ38IZ+ryDnR0xSL6pYAUKhJ86YRMnqZtASxpqNz0b3cH3/y6fBTSduWLB7YKNIAHtwRlC2CnjtvFXtzOMi2oMiCBHG74baa96bosNdTU57rT11pHGueonbaC+hbV/zL8LRAT7kw6CT/unI5R1Rab2wo9N8u8wqs3td4n2z2JPJO8XiRe5e+Ulwd04NEnkhzCOLfmISnbW11Mthr3u8leXbdS1ZDWl+Rm4dQcNhINmBd+/dljxXPSm5rYr5SiTCP4Lf44Q6dnK/B3oPtQhzXu8RLjhPkGs55+zwiP7JMyasmupLBmTyw7+9TVptYjwTvlYn9fKwwNsvdlcKjewTr1m6IP2siOl6ZKFVUGTD5J8+WjDMjFmR+oT2yU5VGugKc3IBaVMa6yLfY4UsV+RMUWU4Lgkw7layWsOun1iLuCGLiOz2pkat3xiP47/FlYNEKlzeflv7VgDDUdiGtce/HQNcFBjwqk9i7zv5AYPHzS2Q2PGfKcHIYALyBJ9t1D53CnfXL8hDWG3Qo18d05+gc/R5c7OBm9RERWaSL0sbgO+fm+9pslIczuQD1b5nNHt0HBRdWZXEVqMR1V/fuJkot7h505AjvuCf8vgsbGxVfBi+6O7BRO01ZhUr98rbbo37/ag7eQ/YC0oPRT7adGj3DWn5VphRPDVa8V1oTAEJTPC/2zLvudwrXkfpXVFQiFwZoz6pO8I/rATzPKR9zs4RkBiXDrelKfH0lntEVol1iNL6Tl+RO6ywtVnj8tNIcpdOXbnbqgxwZa1eOusViHG3qzI3daqzDmdxu5plZ/0pLrXJAbBynSgEEeJkJX0OFfesmqc7pQfNpU/rDaNvT4hqS1S0064r+wmlscMUOueaeRI0AN6JDnk0JbPj0BDC9nR+OG0oHpcT/NFieRowcb9vzI2jaOf4GhM5kXrxD35SNBU8gMPovEz5oqz1XGmpe2f0R6sQTraoVcxjS1Yn1l7JSjX+IVIfBiwyzKFQH81/aq/G/V4rrSFUC/y8dkk+mx2dhzl4pHzRgzun4mBQQfYpkMXx4B5s8TxqkGXZRuxh4qB70GqDY6PRDSFnNdsTRNh4yLWy1iEnEfAg3M0cw2ed5cgkZ/4kct+LXUOkPe2402rGfeW3k3ZEgLZkkKnZhhCN5sk05uglUD+wzKpzOKVdYOlqlZ15CrZVctVb3/3c= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: b6b1bf08-8085-4f3b-6153-08da3d79f903 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:50.5852 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Qqp7MWf63nb6WDPMSosjxVqwl2e4mlVu/4S1klqBTW6Cdo6o5oy0z3Re9ZQNf1rJZWDoAMwJjRgC+39VR9aryw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/stats.c | 438 +++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/stats.c diff --git a/drivers/net/wireless/celeno/cl8k/stats.c b/drivers/net/wireless/celeno/cl8k/stats.c new file mode 100644 index 000000000000..c526199513f4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/stats.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "reg/reg_access.h" +#include "sta.h" +#include "utils.h" +#include "reg/reg_defs.h" +#include "rates.h" +#include "debug.h" +#include "tx.h" +#include "vif.h" +#include "stats.h" + +static void cll_stats_config_ps(struct cl_sta *cl_sta) +{ + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(cl_sta->sta); + + cl_sta->stats->ps.timestamp_sleep = jiffies; + cl_sta->stats->ps.is_ps = test_sta_flag(stainfo, WLAN_STA_PS_STA); +} + +static void cl_stats_free(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + kfree(cl_sta->stats); + cl_sta->stats = NULL; +} + +static void cl_stats_disable(struct cl_hw *cl_hw) +{ + pr_debug("Statistics disabled\n"); + cl_hw->conf->ci_stats_en = false; + cl_sta_loop(cl_hw, cl_stats_free); + + if (cl_hw_is_prod_or_listener(cl_hw)) { + kfree(cl_hw->rx_stats); + cl_hw->rx_stats = NULL; + } +} + +static void _cl_stats_update_tx(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report) +{ + struct cl_stats *stats = cl_sta->stats; + struct cl_tx_cntrs *cntrs; + union cl_rate_ctrl_info rate_ctrl_info = { + .word = le32_to_cpu(agg_report->rate_cntrl_info)}; + u8 bw, nss, mcs, gi, bf; + + switch (rate_ctrl_info.field.format_mod) { + case WRS_MODE_HE: + nss = (rate_ctrl_info.field.mcs_index >> 4); + mcs = (rate_ctrl_info.field.mcs_index & 0xF); + gi = rate_ctrl_info.field.gi; + + { + bw = rate_ctrl_info.field.bw; + bf = agg_report->bf; + + cntrs = &stats->tx.he[bw][nss][mcs][gi][bf]; + } + break; + case WRS_MODE_VHT: + bw = rate_ctrl_info.field.bw; + nss = (rate_ctrl_info.field.mcs_index >> 4); + mcs = (rate_ctrl_info.field.mcs_index & 0xF); + gi = rate_ctrl_info.field.gi; + bf = agg_report->bf; + + cntrs = &stats->tx.vht[bw][nss][mcs][gi][bf]; + break; + case WRS_MODE_HT: + bw = rate_ctrl_info.field.bw; + nss = (rate_ctrl_info.field.mcs_index >> 3); + mcs = (rate_ctrl_info.field.mcs_index & 0x7); + gi = rate_ctrl_info.field.gi; + cntrs = &stats->tx.ht[bw][nss][mcs][gi]; + break; + case WRS_MODE_OFDM: + mcs = rate_ctrl_info.field.mcs_index - RATE_CTRL_OFFSET_OFDM; + cntrs = &stats->tx.ofdm[mcs]; + break; + case WRS_MODE_CCK: + mcs = rate_ctrl_info.field.mcs_index; + cntrs = &stats->tx.cck[mcs]; + break; + default: + return; + } + + cntrs->success += agg_report->success; + cntrs->fail += agg_report->fail; + stats->tx.packet_success += agg_report->success; + stats->tx.packet_fail += agg_report->fail; +} + +static void _cl_stats_update_rx_rate(struct cl_hw *cl_hw, struct cl_rx_stats *rx_stats, + struct hw_rxhdr *rxhdr) +{ + u8 bw, nss, mcs, gi; + + switch (rxhdr->format_mod) { + case FORMATMOD_HE_TRIG: + nss = rxhdr->n_sts & 0x3; + mcs = min_t(u8, rxhdr->mcs, WRS_MCS_MAX_HE); + gi = min_t(u8, rxhdr->gi_type, WRS_GI_MAX_HE); + rx_stats->he_trig[rxhdr->ch_bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_HE_TRIG; + break; + case FORMATMOD_HE_EXT: + nss = rxhdr->n_sts & 0x3; + mcs = min_t(u8, rxhdr->mcs, WRS_MCS_MAX_HE); + gi = min_t(u8, rxhdr->gi_type, WRS_GI_MAX_HE); + rx_stats->he_ext[rxhdr->ch_bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_HE_EXT; + break; + case FORMATMOD_HE_MU: + nss = rxhdr->n_sts & 0x3; + mcs = min_t(u8, rxhdr->mcs, WRS_MCS_MAX_HE); + gi = min_t(u8, rxhdr->gi_type, WRS_GI_MAX_HE); + rx_stats->he_mu[rxhdr->ch_bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_HE_MU; + break; + case FORMATMOD_HE_SU: + nss = rxhdr->n_sts & 0x3; + mcs = min_t(u8, rxhdr->mcs, WRS_MCS_MAX_HE); + gi = min_t(u8, rxhdr->gi_type, WRS_GI_MAX_HE); + rx_stats->he_su[rxhdr->ch_bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_HE_SU; + break; + case FORMATMOD_VHT: + nss = rxhdr->n_sts & 0x3; + mcs = min_t(u8, rxhdr->mcs, WRS_MCS_MAX_VHT); + gi = rxhdr->gi_type & 0x1; + rx_stats->vht[rxhdr->ch_bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_VHT; + break; + case FORMATMOD_HT_MF: + case FORMATMOD_HT_GF: + bw = rxhdr->ch_bw & 0x1; + nss = (rxhdr->mcs >> 3) & 0x3; + mcs = rxhdr->mcs & 0x7; + gi = rxhdr->gi_type & 0x1; + rx_stats->ht[bw][nss][mcs][gi] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_HT; + break; + case FORMATMOD_NON_HT: + if (rxhdr->mcs >= RATE_CTRL_OFFSET_OFDM) { + mcs = (rxhdr->mcs - RATE_CTRL_OFFSET_OFDM) & 0x7; + rx_stats->ofdm[mcs] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_OFDM; + } else if (cl_band_is_24g(cl_hw)) { + mcs = rxhdr->mcs & 0x3; + rx_stats->cck[mcs] += rxhdr->frm_successful_rx; + rx_stats->flag |= RX_STATS_CCK; + } + break; + } + + rx_stats->packet_success += rxhdr->frm_successful_rx; +} + +void cl_stats_init(struct cl_hw *cl_hw) +{ + spin_lock_init(&cl_hw->lock_stats); + + if (cl_hw->conf->ci_stats_en && cl_hw_is_prod_or_listener(cl_hw)) { + cl_hw->rx_stats = kzalloc(sizeof(*cl_hw->rx_stats), GFP_ATOMIC); + + if (!cl_hw->rx_stats) + cl_hw->conf->ci_stats_en = false; + } +} + +void cl_stats_deinit(struct cl_hw *cl_hw) +{ + spin_lock_bh(&cl_hw->lock_stats); + + if (cl_hw->conf->ci_stats_en && (cl_hw_is_prod_or_listener(cl_hw))) { + cl_hw->conf->ci_stats_en = false; + + kfree(cl_hw->rx_stats); + cl_hw->rx_stats = NULL; + } + + spin_unlock_bh(&cl_hw->lock_stats); +} + +void cl_stats_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + /* + * If allocation failed disable ci_stats_en + * and free the memory of all other stations + */ + bool disable = false; + + if (cl_hw->conf->ci_stats_en) { + /* + * Take regular lock and not BH, + * because cl_sta_add_to_lut() already disables BH + */ + spin_lock(&cl_hw->lock_stats); + + cl_sta->stats = kzalloc(sizeof(*cl_sta->stats), GFP_ATOMIC); + + if (cl_sta->stats) + cll_stats_config_ps(cl_sta); + else + disable = true; + + spin_unlock(&cl_hw->lock_stats); + } + + if (disable && cl_hw->conf->ci_stats_en) { + spin_lock_bh(&cl_hw->lock_stats); + cl_stats_disable(cl_hw); + spin_unlock_bh(&cl_hw->lock_stats); + } +} + +void cl_stats_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock_bh(&cl_hw->lock_stats); + + cl_stats_free(cl_hw, cl_sta); + + spin_unlock_bh(&cl_hw->lock_stats); +} + +void cl_stats_update_tx_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report) +{ + struct cl_stats *stats = cl_sta->stats; + + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock(&cl_hw->lock_stats); + + stats->tx.agg_cntr++; + stats->tx.fail_cntr += agg_report->fail; + _cl_stats_update_tx(cl_hw, cl_sta, agg_report); + + spin_unlock(&cl_hw->lock_stats); +} + +void cl_stats_update_tx_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report) +{ + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock(&cl_hw->lock_stats); + + cl_sta->stats->tx.fail_cntr += agg_report->fail; + _cl_stats_update_tx(cl_hw, cl_sta, agg_report); + + spin_unlock(&cl_hw->lock_stats); +} + +void cl_stats_update_rx_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + s8 rssi[MAX_ANTENNAS]) +{ + int i; + s8 rx_rssi; + + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock_bh(&cl_hw->lock_stats); + + for (i = 0; i < cl_hw->num_antennas; i++) { + rx_rssi = rssi[i] * -1; + + if (rx_rssi >= 0 && rx_rssi < RSSI_ARR_SIZE) + cl_sta->stats->rssi[rx_rssi][i]++; + } + + spin_unlock_bh(&cl_hw->lock_stats); +} + +void cl_stats_update_rx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct hw_rxhdr *rxhdr) +{ + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock(&cl_hw->lock_stats); + + _cl_stats_update_rx_rate(cl_hw, &cl_sta->stats->rx, rxhdr); + cl_sta->stats->fec_coding[rxhdr->fec_coding]++; + + spin_unlock(&cl_hw->lock_stats); +} + +void cl_stats_update_rx_rate_production(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr) +{ + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock(&cl_hw->lock_stats); + + _cl_stats_update_rx_rate(cl_hw, cl_hw->rx_stats, rxhdr); + + spin_unlock(&cl_hw->lock_stats); +} + +void cl_stats_update_ps(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool is_ps) +{ + struct cl_ps_stats *ps; + + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock_bh(&cl_hw->lock_stats); + + ps = &cl_sta->stats->ps; + + if (ps->is_ps == is_ps) + goto out; + + ps->is_ps = is_ps; + + if (is_ps) { + ps->timestamp_sleep = jiffies; + } else { + unsigned long sleep_time = jiffies_to_msecs(jiffies - ps->timestamp_sleep); + + if (sleep_time <= 50) + ps->period[PS_PERIOD_50MS]++; + else if (sleep_time <= 100) + ps->period[PS_PERIOD_100MS]++; + else if (sleep_time <= 250) + ps->period[PS_PERIOD_250MS]++; + else if (sleep_time <= 500) + ps->period[PS_PERIOD_500MS]++; + else if (sleep_time <= 750) + ps->period[PS_PERIOD_750MS]++; + else if (sleep_time <= 1000) + ps->period[PS_PERIOD_1000MS]++; + else if (sleep_time <= 2000) + ps->period[PS_PERIOD_2000MS]++; + else if (sleep_time <= 5000) + ps->period[PS_PERIOD_5000MS]++; + else if (sleep_time <= 10000) + ps->period[PS_PERIOD_10000MS]++; + else + ps->period[PS_PERIOD_ABOVE]++; + } + +out: + spin_unlock_bh(&cl_hw->lock_stats); +} + +int cl_stats_get_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_stats *stats = NULL; + u32 i = 0, j = 0; + u64 total_rssi = 0; + s8 avg_signal = 0; + + if (!cl_hw->conf->ci_stats_en) + return 0; + + u64 avg_rssi[MAX_ANTENNAS] = {0}; + u64 sum_rssi[MAX_ANTENNAS] = {0}; + + spin_lock_bh(&cl_hw->lock_stats); + + stats = cl_sta->stats; + + if (!stats) + goto out; + + for (i = 0; i < RSSI_ARR_SIZE; i++) { + total_rssi = 0; + + for (j = 0; j < cl_hw->num_antennas; j++) { + sum_rssi[j] += stats->rssi[i][j]; + avg_rssi[j] += i * stats->rssi[i][j]; + } + } + + for (j = 0; j < cl_hw->num_antennas; j++) + if (sum_rssi[j]) + avg_rssi[j] = div64_u64(avg_rssi[j], sum_rssi[j]); + + for (j = 0; j < cl_hw->num_antennas; j++) + total_rssi += avg_rssi[j]; + + avg_signal = -div64_u64(total_rssi, cl_hw->num_antennas); +out: + spin_unlock_bh(&cl_hw->lock_stats); + + return avg_signal; +} + +void cl_stats_get_tx(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + u64 *total_tx_success, u64 *total_tx_fail) +{ + if (!cl_hw->conf->ci_stats_en) + return; + + spin_lock_bh(&cl_hw->lock_stats); + + if (!cl_sta->stats) + goto out; + + *total_tx_success = cl_sta->stats->tx.packet_success; + *total_tx_fail = cl_sta->stats->tx.packet_fail; + +out: + spin_unlock_bh(&cl_hw->lock_stats); +} + +u64 cl_stats_get_rx(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + u64 total_rx_packets = 0; + + if (!cl_hw->conf->ci_stats_en) + return 0; + + spin_lock_bh(&cl_hw->lock_stats); + + if (!cl_sta->stats) + goto out; + + total_rx_packets = cl_sta->stats->rx.packet_success; + +out: + spin_unlock_bh(&cl_hw->lock_stats); + + return total_rx_packets; +} + From patchwork Tue May 24 11:34:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576847 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 773D1C433EF for ; Tue, 24 May 2022 11:39:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236869AbiEXLjy (ORCPT ); Tue, 24 May 2022 07:39:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236870AbiEXLjx (ORCPT ); Tue, 24 May 2022 07:39:53 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2088.outbound.protection.outlook.com [40.107.20.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B509792D05 for ; Tue, 24 May 2022 04:39:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LWTpbQv5pe9mtuMCi0QiSsB+99jnWNXrBv8pbFCik0+NMY842FXHjETLPl4f8Hv7JXB9sc6USzQoL3/nUtL8VK2mmA3qqNWi3jO5ova4PbXg5XUq1IOiHVVXdWyf+sPzn/wW7nxalnLXpNelrmvEXTl9uMYyfxpKCemD7z/73mlI/A9ejuMRWQDYzKPuONmiOnoRUqJFkCtjtkifDtjRO8r/RIU+P9klDclN+n5bVSg633x3FvavWBGqb4bPOLN7bzwIuw73ECEceM8SGkSE6/uysWPvxlfEqUklVP+Ay4QqEh0yoQSP+mbPx82WRmxhoPx5dfJvGUuWQlb3zbVQ5w== 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=1QMp427PszoGDOKJWlCbEEHJoWVoA48pzfD1C6lCKNk=; b=aqE2x4tVRLG16zNaWOr8oUzlsZI08gKXcqsPAkBbFgwh/EjzVqhsu/7gJFYTL/VAHa8SGSTFHATFsMiwgoiXvjPY87SQsUTAARobZ5FLTwdJbh83PTNkmsDI/eXDWgxvbP+u3j8BXSAiyF64uTc8+CciJ3OVqZ85jw9zjUJH8SoDDBUSbqik8HCTc7dp90pw2ive6aDD73pb63OB04SAmtvPJYQqKxdRZK+//xrhK5tvnGpFz1DMeKfpQ/cl7m32f2wllYylkjB7fuAC/iBWh1jrE+4pmzWcQ/itSJFu6O75yT4OOFWd9GRMgFrpYSTL7BYE1waGx53yPMCdsfPeAQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1QMp427PszoGDOKJWlCbEEHJoWVoA48pzfD1C6lCKNk=; b=TmLh1+dsuMSTqLk3JI1uxEbIYz5WOiqrktOF/hbcWsiKFijCelm2BosqFhhYdZJ4xjwAFwXVLbNyMKSKMahQ46IaeLIhrSXGNJpfRcAMDnXP0eQxn9AuAOtmJbZflYSZ/7ruBuubv5qmq2uchzW6KtgWwa9ZCAOdNyQ0P2RHUxo= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:28 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:28 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 77/96] cl8k: add stats.h Date: Tue, 24 May 2022 14:34:43 +0300 Message-Id: <20220524113502.1094459-78-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 78a1538a-0bbe-478e-a99f-08da3d79f98b X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ceDYCliiYMwD4+YvDLZD4WKnE5eTRIEuciXvMl2jBj4ndwU9bk6dweJFKsgN3wRHFkBKaD5MXAC978/wfUKdCBlor9Jy5Q2MkrV3XxHtGE8i/Vf9Ar7jkyCDUoTrKpWyst06ojd4RCn87vKo32OnHwsKxnvdOrqJxcAYasH62Cd42/j4y5px/b9itijFMacbAb+S3CeIs9EGUytzwZjIx4yHu+KtIs20Gz0HzsA+gwVCsw2BDoIaT+4EnxyLkjgoDSw6R2r2xEdWCp1H72UidwrHx17Tou21WBeq2bCMf1/SrDWPrWOy/sadInxei2BVc8WfWwpo1S62j0QbJNIy/EQSGXPrB1IyZDtB52mKal9q+cJV5sgedEpfx6hijQvxM2+1WnEkrgNJha4PlrFAJ4XM5aZiEQHqLKGEIx2qW6GcL50g2+MYtdVv0jMlTxMg/drgQ+OExz+lzYNpXgVqS/84mc9VzNeAr1po/JCJI0kltJruSk/yEeh6FYdSuRdoDh2cTxYnSrZEm9C+ItUY1g/UIoGuy7WZXqADuYabaAV6qS9rWfZ1RjDjvEl5Dr9n/Ruf6AX2qCJHg1FORwQIFtU0j1dzvOiCKVhXdaBXa3lVtXdvNSY+RC1wMJ5tMzrcRK/RX6Jeh36PdnUWBpmv4YNNKbf6ZMBJb2Te/v+P+sYMKfUUAbDyU+rVGckryy48SKkzybl6eFlcwifuVdnW/TWP+6DZs44SzPz7hWKUlxw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Uc9BXoNzBr66O890ubizoxFmiYFR8/uf0KohNyjOGUAZCweKpgOJ5B1DUUjtz4Q0CjrQaF/Rzoy9BsS5NrppiLna+hAzJ/BA94iFbzDIIEo1IqUlOn528LueXto1yOoZqnqzMixUp5HukOeCgkJhR0N2bkucZ4LycSFProjpWYf82aF6HAWY+YA9W0/Xoxp798yYH1Utwgk3qB3wmAxebk6TjZyg9sMFUEKkcl77BoRyxXX+5P2wFeRdWP2Ln3BM+AIRTj79csSme7+mHABX+fZhLuhOR2iRpKyQlzZX2tfMtKORc11R2hAA/Q3/iawG7ZVwZ3fsCRYFn03ZLsXO6LPzqPNnkvb4hoZysGx1lbzFOQz3rUT/C7ZH6b2fK9dhg7JG1C78Ea58yVSPd93RmPQdsA74F2UYAH0MNxbDow+YotW2Iw2XLBZW3cFCcO8xNMt2U/H5V8TjPSV8gP80Wo/gkddzt+TaEnaEoAZXpec9Sw3WM1w0soOceN90TPT38d+3Q4O3/S4GNcwKu3m13s40BWEzFhVh+DTQV5I9chNm1RfZUaOmcR3VdX7tkkQNjXNyU85ZzDBznm9W+ommSzGqCDCEPlWhxUH1fHoHbQKGa3lAqtxg1jyxlsXdSvBcPmoqQuWK/4A2CEBJuHhT3gbUPplXX6KmoOfb0dsFeJlRMhis4TmLNZ6U9mqukVMUedCjyHjWGCDueZFHiq5Ec1jlyK4mSuiO49RssXR3etzPY9cCPftBvANkRPSjvlhBIAlAEjcAizDM/Ct5TNnppMKmYfAVZs1jHJRJz9AgaQ0g4KhZoo/ZFvYdJVdO0m68lFtTF9y+iSU1UYpv6A478wGW4GDIJuS18W/YcnTamPINlETdYlutiwlwz3LFYLAVYzhptrXdOTkQnBPr8l6+CmfZWBoOBWFJzwusEoJoR823XqReV6uyaMER1IkbbTvhKghJ8wN6AH8ojkDj5WfIdawZyzWeXcMFmB1ycQf2RxY5W7G7X5ZeUDFQ/3+23dLwO6V+Axixp6+y0L6kH3IMBR9OJD5CqoofquL+J+2Xsv1auTWFAgkf+wsjOV5QzZ/xGKfDbzzeDNALlUY763PNujQVXnIe/A3K9XX7p+L2F4OndXSikaYtWhn27HhoYSKq8HV9swzFhNmpp7igJBcBWDVS5DkaomYZQuQmgy9t0WYM+AtHYd6790xIADE4SiJ6vCf4Z/0QqDmx7n8ofnZJtEEE3EOhsje9sVLVHCVZo0+Jv1P/nYJpZUDX+re60I22Eo6+5uMU7J6fYKpfit9V59AKrOvea2mpRgB9vBhjnltc9udYmGkIKe4hGzZsuu+MK/cINpAV5BQn5CMkEzpUNNIrHYBvDWEwm8COf4qAH9nGnMLMvEmOfaR0+7WJSYpSqHFrQLfDpu0iFMTrGqtxr+P5qHEY/PdxzrCmsXAq5YKeOe2XQZuUIvVfl8eL7z0lfjqILY/KbWKh0ZmlyxRDPJVwBDak9PNFBbE0nz/FSlbYbUDirg1CpryGanaa+KIqMo1eAZeDosvLg30b7MegtnKVwiHL0rXd2+YxTP/XOhg9z1KdkYT7cPnhllkztvi/EwZNh8ZlxVJfRof1HluVTj07o56BeDeBfZFPmbPlzs+Gm0ayLRs3osdbGIGe+7F3oVlyZeSqWu1WLT/J3QvAsOfe9Cnwi8qVlq86T26tmHFurpRt/0V+o3dFffeozNoLYQqazoPG6is7ODQteKzOV6k7LNhcWRK3h67j16kXQ20= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 78a1538a-0bbe-478e-a99f-08da3d79f98b X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:51.4925 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 74y5lPh9EvFKLVtMO4c+N3b/LAVfHPtExmy8Y/zzP1EhfRAa9rPbdJevvztiG+jmacdl1WUOS1ZrJwpVT0V4Cg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/stats.h | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/stats.h diff --git a/drivers/net/wireless/celeno/cl8k/stats.h b/drivers/net/wireless/celeno/cl8k/stats.h new file mode 100644 index 000000000000..480c00b395f1 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/stats.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_STATS_H +#define CL_STATS_H + +#include "wrs.h" + +enum cl_rx_stats_flag { + RX_STATS_CCK = 0x01, + RX_STATS_OFDM = 0x02, + RX_STATS_HT = 0x04, + RX_STATS_VHT = 0x08, + RX_STATS_HE_SU = 0x10, + RX_STATS_HE_MU = 0x20, + RX_STATS_HE_EXT = 0x40, + RX_STATS_HE_TRIG = 0x80, +}; + +struct cl_rx_stats { + u32 he_trig[CHNL_BW_MAX_HE][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; + u32 he_ext[CHNL_BW_MAX_HE][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; + u32 he_mu[CHNL_BW_MAX_HE][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; + u32 he_su[CHNL_BW_MAX_HE][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; + u32 vht[CHNL_BW_MAX_VHT][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT]; + u32 ht[CHNL_BW_MAX_HT][WRS_SS_MAX][WRS_MCS_MAX_HT][WRS_GI_MAX_HT]; + u32 ofdm[WRS_MCS_MAX_OFDM]; + u32 cck[WRS_MCS_MAX_CCK]; + u8 flag; + u64 packet_success; +}; + +#define RSSI_ARR_SIZE 128 +#define BF_IDX_MAX 2 + +struct cl_tx_cntrs { + u32 success; + u32 fail; +}; + +struct cl_tx_stats { + struct cl_tx_cntrs he[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX][WRS_GI_MAX][BF_IDX_MAX]; + struct cl_tx_cntrs + vht[CHNL_BW_MAX_VHT][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT][BF_IDX_MAX]; + struct cl_tx_cntrs ht[CHNL_BW_MAX_HT][WRS_SS_MAX][WRS_MCS_MAX_HT][WRS_GI_MAX_HT]; + struct cl_tx_cntrs ofdm[WRS_MCS_MAX_OFDM]; + struct cl_tx_cntrs cck[WRS_MCS_MAX_CCK]; + u32 agg_cntr; + u32 fail_cntr; + u64 packet_success; + u64 packet_fail; +}; + +enum cl_ps_period { + PS_PERIOD_50MS, + PS_PERIOD_100MS, + PS_PERIOD_250MS, + PS_PERIOD_500MS, + PS_PERIOD_750MS, + PS_PERIOD_1000MS, + PS_PERIOD_2000MS, + PS_PERIOD_5000MS, + PS_PERIOD_10000MS, + PS_PERIOD_ABOVE, + + PS_PERIOD_MAX +}; + +struct cl_ps_stats { + bool is_ps; + unsigned long timestamp_sleep; + u32 period[PS_PERIOD_MAX]; +}; + +enum cl_fec_coding { + CL_FEC_CODING_BCC, + CL_FEC_CODING_LDPC, + CL_FEC_CODING_MAX +}; + +struct cl_stats { + struct cl_tx_stats tx; + struct cl_rx_stats rx; + u32 rssi[RSSI_ARR_SIZE][MAX_ANTENNAS]; + u32 fec_coding[CL_FEC_CODING_MAX]; + struct cl_ps_stats ps; +}; + +struct cl_vif; + +void cl_stats_init(struct cl_hw *cl_hw); +void cl_stats_deinit(struct cl_hw *cl_hw); +void cl_stats_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_stats_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_stats_update_tx_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report); +void cl_stats_update_tx_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report); +void cl_stats_update_rx_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]); +void cl_stats_update_rx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct hw_rxhdr *rxhdr); +void cl_stats_update_rx_rate_production(struct cl_hw *cl_hw, struct hw_rxhdr *rxhdr); +void cl_stats_update_ps(struct cl_hw *cl_hw, struct cl_sta *cl_sta, bool is_ps); +void cl_stats_get_tx(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + u64 *total_success, u64 *total_fail); +u64 cl_stats_get_rx(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +int cl_stats_get_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta); + +#endif /* CL_STATS_H */ From patchwork Tue May 24 11:34:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575959 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 2E451C433EF for ; Tue, 24 May 2022 11:40:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236935AbiEXLka (ORCPT ); Tue, 24 May 2022 07:40:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236105AbiEXLk1 (ORCPT ); Tue, 24 May 2022 07:40:27 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2088.outbound.protection.outlook.com [40.107.20.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BC7A8DDC7 for ; Tue, 24 May 2022 04:39:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n74o+2dNyF9phE9J673q+zk3OfJQuC6YqEt1q5YmIuHQ3lJUYDnuOXIaygcYC9lIBt5Qcve9UWBjksTp1nkGuKLv4rEtDXhDqmSlghnXdGAdUifvj1/VjB4bfNZIzbMQYPYdfUp6NvUuLA2dvdVGb+4J4yWhlWfBsu5Yn2uAFB77HkZSGYDAG7nSWRm5lxIHNvYs+Atfb1XE/AZ1NeqVjEmUTlgUcIQ7ASzdyvL7WnXk9gmmPBCnPqeEvtnlgcFgBui5udZjxvdGLyDMTOoAObnSjneStBqGLqLGYLk2m0enQChWxbrjDg2IArl09U19EcDXYGJJUivCAfCmu9Us6A== 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=s9hpv4aDcmsApscyn6Y4MAEnUt5bAohDeoAFauk6axw=; b=LMLzU5SMUG+5JkqXLn32xBtBeU0VKRGpNugqYl9flE0/7jQmNG32RY9jfMahkWyUk0DmqDLFVAjW8s9huNgU70Wj8nkZ7yDDvZSduIyL3G9F83LB6vgIRKlviWI5WSGrjC+yfaqe0BdN3d8Yuq1kfR/SsQcC/Qmw99QIERpK0/a7xbqLcUriGT0nNyTw2Ow+F3LT316Ess9aN8X1wuZ/cuCIQt7JwGXhqBIFqpBriNYS1nvX02Ok6H/fM4KlJahfs2d2o0qSMQkGOZY5bGC4Ika1TdD/A938qjcFBddgHVosuJjNA8j2SbDDdM9lHLK8COEz4FjevoBHeVardulY4A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s9hpv4aDcmsApscyn6Y4MAEnUt5bAohDeoAFauk6axw=; b=n3d+RF6I1uBriEB8Y6bues9zBx0Sh6H3PVcPrgE6yecDCqGV6Cq8lsesjtL9foiQoUUmkJ3neTiJCEXt8kMzUKMcLHfQxGsJa/mjeMRaPmsM0dVnUgQojDmkZ8ZFwdLQaL3iGnaZKn0Ltqrw8P03PoBB1oFyxPoTaoWUo78QeQY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:28 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:28 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 78/96] cl8k: add tcv.c Date: Tue, 24 May 2022 14:34:44 +0300 Message-Id: <20220524113502.1094459-79-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e84ddf78-802a-4c57-b2c1-08da3d79f9fb X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ELKIofXPVk5lkIKICq1XAoppm7oKc58bG/cE7uLuxE6WIBxDKxGqV14Kb525ObLgCrT51eNbXdgVMmSdlkCN0oRn8y1o6cK7h4nOQyHk4gTE7vi6PATeC56MSh0542TKS29fQQt1p+uu+rMnFeIKZmHmsO0L4oFRlnr0UYBj9V1QWF6a9tugYUC+TdOvBuX39wgnzxsIOShHi8wZ16U7hHLwywPxSp61z5NvYgvmyFPxYQ03Z7yds7YwNSB2G39Bvw4wjG0r9abVl+k5aQ4Pp7hnMpfLqh67s9YJS0tg0YWpG3keCWvlmIDVVzPxb0msrgRr6TwcKHkNBemnzIW4TFwMxquCYYHNRuWB1MFU4nOj2iGJUQFgTB3fN73HLwYawocvU2syGjWSVV5eoHE30S75eXFvOOWquqV2OhXODRzE1Ys/nELCvYiT1QSAL+1T3ymhYL5eo8RsCRlac49bepgVrxjDQ7KCV4drsEYjByvnlsNdvAnA0cbyFv+qudmEZamWJEpbTdTVS+b1smBMuZFb6JMMj/XqDxLHg3dCUkeNOUA7UBBcQ/nMXLvmzA1ybtBEcWffFzHqo7g3nceMV/cut6d2znJD9XpL9pMPQqI4BpNDHnNtIa2WVq/55nfZ3+ZBq6RA5GZwzRRtjG3MMu1F04P7NSF5vyVrOCH6v4wZRsNSITXafbn649L5rdZnbPs114xWE0uqEwhNFd4Ds6x82UYGS/Z0E1hPoUZffz0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: QF29h8pB6RAXTEyBSW8mkaO/8wiOyhznmUNs3p61fqiHYkdiltTCC68nm8JEYef58uQ/Ol9VPnyyXfe96Fs95G3s39yTkXQtLTXvLvpXp3V+YEpTBZtZxp6ACTLdZjWPxlUGz3jf7oopWC/d1KMX3JVObxIuBHgFO2RI7Jwwer0OChgfwkk5DnmL3a0+bKnQx9N54+oPvui6Ct3Ids+4UvLeHT47tBoPyV3pQ2yaMMxc8fwrKU46ucxgICxK9zZ3G0+fV4Ap2kJMRYdsNhjbvJQiNwmXCp32MXEGty9qxMUZYLCbmiNNytpK7cClCxUgrTZFXBzn7iiO0SmwHt7NSlAEcRcV5Ilw6aUanlqO8s4BxXDdja4kZbAQJABeP1baFnqhKeNDJNRPgWc5FCB6IWVjO3cq1bKWfuSD5LX5AEiJqdOQ1IyL6GU5/mc/Z/DTTQQWP3vBMWObhMLbIdiPfc7XLqRCwlj3SnMC+hL/rlkPm8mBG3Jj6PgpHnRMQ1PAVMudWmYDIBznYmEzGnI+Vae2Tu3p6/LD+XxAImNVCHMIsvka/HdFVRxjDRKhEfLg6Jo7hwOvATqRpoznHr+mQ3/GFhoVvIagqcisYtI6sZxwlBGr7MxDXaUbfxpvNiCS3BQCBIuwmpsIxUUERg4PylL3YTHpf8z0yzNhuztND1ZA7pGt41PG25+rfp0KK4kTZXLqnblbv9GZb/lWQU8WxepRRRww6ElfTsXnEqcPxoiNpSvhq6p/nz7a6I1b6e6578cdKaSNFqyEb4GJwED363xcdetXX3O2EgX4HS1BnS//EaScPUmEVcFNcUJvJYZYOshfOXBwNJdbfl9zUwCZ8RWV5XFqaSXxKYVNB/wPROkrZSTpmNQBtng41x9VVK62SBv93H/pieLVTrhc2rIBZpObdJb31yhORpRziBLr/JrQKeSKDoDGs8pmlHig52F7OEJIUm20m3ZppMGmcbckDs+Yht5nAbMgrBxYqS2X02JnWYobHYXVMkNwGnADxhioPL4qxeseZgMYIY7QMiWiX2IFiNZVdYIJ/g1nw0HL8MOw0R87hlubvvPsotwiBn1JYkdzmczCz8I7l23YqkV3JRrNIPoT2Y68TdJZ0SC7ODLvpldPhFyWekcGQK34pGUxfymyVHkY7yiZvzldIywYZru3EJIH/VPdv3DhHcwIU1urlDbn7g6i1C4+lFJqGgVTDXHL0w6ECNybPrUDnX9ubpB0JJmsp3yjNPDoCZmpGYSwWAU2tGoO8rIk3mpRse+ymQ2BBWC9GzbaqOTd5Ry4rkSZZZ7sBYurWHtkEepHnZrdcH0UlW6t1a/5LfZh1kNkUtwuy+W+SZcPUiRgO35TXtnCfZ2MqXzKLpH4vRQ0Txco9aITCoJPAGutr2/OjnePj3s/BIPmZiykh57nZ18L1bOd7qls5aAOpwpwPFX53VnahPPwYDpQjLCpjbUijXH+xwcF0vMklEi8EppWgrd/gvuWk5jZo9j8WADAeADFfJn8fPFyva2KL+BzE3EX2uIqcC9612iWjEal0T9jfsM3B8LKRPayrs+WYcUbgGXlYNLsjtgioeUKlWCJCNXCf4DxsjYrt9f9ZzeUko2Nuxr71TJqUpUIyE9AbhENNRfv/n5KmHGOcjRFfNmVVYbcxyRj0D5UKl6jX5bgt7ZDMU6CTaLpZOfR8HBe5mpz7mKDzWsiKo3viS9E0jj13q1bVVXf37cKMQfyvFntKSZIvosP0zIVqoQUGRUkDOFR+wgkxVE= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: e84ddf78-802a-4c57-b2c1-08da3d79f9fb X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:52.2736 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: pspCXPTnzsg0AsgQI5UZ9ZQvssvq6O4H0So7vckhoFiTrMW3o/INo1P5hFYf/6BX+Aw8InXhdw9OFaW9KP6AQw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/tcv.c | 1259 ++++++++++++++++++++++++ 1 file changed, 1259 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/tcv.c diff --git a/drivers/net/wireless/celeno/cl8k/tcv.c b/drivers/net/wireless/celeno/cl8k/tcv.c new file mode 100644 index 000000000000..1a17c4f4445a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/tcv.c @@ -0,0 +1,1259 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include +#include + +#include "chip.h" +#include "recovery.h" +#include "vns.h" +#include "mac80211.h" +#include "config.h" +#include "rfic.h" +#include "e2p.h" +#include "hw.h" +#include "radio.h" +#include "utils.h" +#include "tcv.h" + +#define CL_TX_BCN_PENDING_CHAIN_MIN_TIME 10 /* Usec */ +#define CL_MAX_NUM_OF_RETRY 15 +#define INVALID_CALIB_RX_GAIN 0xff + +static struct cl_tcv_conf conf = { + .ce_debug_level = DBG_LVL_ERROR, + .ce_radio_on = true, + .ce_ps_ctrl_enabled = true, + .ci_ieee80211h = false, + .ci_max_bss_num = ARRAY_SIZE(((struct cl_hw *)0)->addresses), + .ci_short_guard_interval = 1, + .ci_max_mpdu_len = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991, + .ci_max_ampdu_len_exp = IEEE80211_VHT_MAX_AMPDU_1024K, + .ce_dsp_code = "fwC.hex", + .ce_dsp_data = "fwD.hex", + .ce_dsp_external_data = "fwD.ext.hex", + .ci_uapsd_en = true, + .ce_eirp_regulatory_op_en = true, + .ce_eirp_regulatory_prod_en = false, + .ci_agg_tx = true, + .ci_agg_rx = true, + .ce_txldpc_en = true, + .ci_ht_rxldpc_en = true, + .ci_vht_rxldpc_en = true, + .ci_he_rxldpc_en = true, + .ci_cs_required = false, + .ci_rx_sensitivity_prod = { + [0 ... MAX_ANTENNAS - 1] = -100, + }, + .ci_rx_sensitivity_op = { + [0 ... MAX_ANTENNAS - 1] = -100, + }, + .ci_min_he_en = false, + .ce_cck_tx_ant_mask = 0x1, + .ce_cck_rx_ant_mask = 0x1, + .ce_rx_nss = 4, + .ce_tx_nss = 4, + .ce_num_antennas = 4, + .ce_max_agg_size_tx = IEEE80211_MAX_AMPDU_BUF_HE, + .ce_max_agg_size_rx = IEEE80211_MAX_AMPDU_BUF_HE, + .ce_rxamsdu_en = true, + .ce_txamsdu_en = CL_AMSDU_TX_PAYLOAD_MAX, + .ci_tx_amsdu_min_data_rate = 26, /* 26Mbps (= BW 20, NSS 0, MCS 3, GI 0) */ + .ci_tx_sw_amsdu_max_packets = 0, + .ci_tx_packet_limit = 5000, + .ci_sw_txhdr_pool = 0, + .ci_amsdu_txhdr_pool = 0, + .ci_tx_queue_size_agg = 500, + .ci_tx_queue_size_single = 50, + .ci_tx_push_cntrs_stat_en = false, + .ci_traffic_mon_en = false, + .ci_ipc_rxbuf_size = { + [CL_RX_BUF_RXM] = IPC_RXBUF_SIZE, + [CL_RX_BUF_FW] = IPC_RXBUF_SIZE + }, + .ce_max_retry = 8, + .ce_short_retry_limit = 4, + .ce_long_retry_limit = 4, + .ci_assoc_auth_retry_limit = 0, + .ci_cap_bandwidth = CHNL_BW_MAX, + .ci_chandef_channel = INVALID_CHAN_IDX, + .ci_chandef_bandwidth = CHNL_BW_MAX, + .ci_cck_in_hw_mode = true, + .ce_temp_comp_slope = 8, + .ci_fw_dbg_severity = CL_MACFW_DBG_SEV_WARNING, + .ci_fw_dbg_module = 0x0FFFFF, + .ci_lcu_dbg_cfg_inx = 4, + .ci_dsp_lcu_mode = 0, + .ci_hal_idle_to = CL_DEFAULT_HAL_IDLE_TIMEOUT, + .ci_tx_ac0_to = CL_TX_DEFAULT_AC0_TIMEOUT, + .ci_tx_ac1_to = CL_TX_DEFAULT_AC1_TIMEOUT, + .ci_tx_ac2_to = CL_TX_DEFAULT_AC2_TIMEOUT, + .ci_tx_ac3_to = CL_TX_DEFAULT_AC3_TIMEOUT, + .ci_tx_bcn_to = CL_TX_DEFAULT_BCN_TIMEOUT, + .ce_hardware_power_table = {0}, + .ce_arr_gain = "0,3,4.75,6,7,7.75", + .ce_bf_gain_2_ant = "0", + .ce_bf_gain_3_ant = "0", + .ce_bf_gain_4_ant = "0", + .ce_bf_gain_5_ant = "0", + .ce_bf_gain_6_ant = "0", + .ce_ant_gain = "0", + .ce_ant_gain_36_64 = "0", + .ce_ant_gain_100_140 = "0", + .ce_ant_gain_149_165 = "0", + .ci_min_ant_pwr = "0", + .ci_bw_factor = "0,0,0,0", + .ce_mcast_rate = 0, + .ce_dyn_mcast_rate_en = false, + .ce_dyn_bcast_rate_en = false, + .ce_default_mcs_ofdm = 0, + .ce_default_mcs_cck = 0, + .ce_prot_log_nav_en = false, + .ce_prot_mode = TXL_PROT_RTS_FW, + .ce_prot_rate_format = 1, + .ce_prot_rate_mcs = 4, + .ce_prot_rate_pre_type = 0, + .ce_bw_signaling_mode = 0, + .ci_dyn_cts_sta_thr = 2, + .ci_vns_pwr_limit = 0, + .ci_vns_pwr_mode = VNS_MODE_ALL, + .ci_vns_rssi_auto_resp_thr = -40, + .ci_vns_rssi_thr = -40, + .ci_vns_rssi_hys = 3, + .ci_vns_maintenance_time = 2000, + .ce_bcn_tx_path_min_time = 1000, + .ci_backup_bcn_en = true, + .ce_tx_txop_cut_en = true, + .ci_bcns_flushed_cnt_thr = 3, + .ci_phy_err_prevents_phy_dump = false, + .ci_tx_rx_delay = 0, + .ci_fw_assert_time_diff_sec = 5, + .ci_fw_assert_storm_detect_thd = 10, + .ce_hw_assert_time_max = CL_HW_ASSERT_TIME_MAX, + .ce_bg_assert_print = 1, + .ce_fw_watchdog_mode = FW_WD_INTERNAL_RECOVERY, + .ce_fw_watchdog_limit_count = 5, + .ce_fw_watchdog_limit_time = 30 * 1000, /* Msecs */ + .ci_rx_remote_cpu_drv = -1, + .ci_rx_remote_cpu_mac = -1, + .ci_pending_queue_size = 500, + .ce_tx_power_control = 100, + .ce_acs_coex_en = false, + .ci_dfs_initial_gain = 77, + .ci_dfs_agc_cd_th = 48, + .ci_dfs_long_pulse_min = 100, + .ci_dfs_long_pulse_max = 5000, + .ce_dfs_tbl_overwrite = {0}, + /* 6G */ + .ce_ppmcs_offset_he_6g = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + [WRS_MCS_10] = 0, + [WRS_MCS_11] = 0, + }, + /* 5G */ + .ce_ppmcs_offset_he_36_64 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + [WRS_MCS_10] = 0, + [WRS_MCS_11] = 0, + }, + .ce_ppmcs_offset_he_100_140 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + [WRS_MCS_10] = 0, + [WRS_MCS_11] = 0, + }, + .ce_ppmcs_offset_he_149_165 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + [WRS_MCS_10] = 0, + [WRS_MCS_11] = 0, + }, + .ce_ppmcs_offset_ht_vht_36_64 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + }, + .ce_ppmcs_offset_ht_vht_100_140 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + }, + .ce_ppmcs_offset_ht_vht_149_165 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + }, + .ce_ppmcs_offset_ofdm_36_64 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + }, + .ce_ppmcs_offset_ofdm_100_140 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + }, + .ce_ppmcs_offset_ofdm_149_165 = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + }, + /* 24G */ + .ce_ppmcs_offset_he = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + [WRS_MCS_8] = 0, + [WRS_MCS_9] = 0, + [WRS_MCS_10] = 0, + [WRS_MCS_11] = 0, + }, + .ce_ppmcs_offset_ht = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + }, + .ce_ppmcs_offset_ofdm = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + [WRS_MCS_4] = 0, + [WRS_MCS_5] = 0, + [WRS_MCS_6] = 0, + [WRS_MCS_7] = 0, + }, + .ce_ppmcs_offset_cck = { + [WRS_MCS_0] = 0, + [WRS_MCS_1] = 0, + [WRS_MCS_2] = 0, + [WRS_MCS_3] = 0, + }, + .ce_ppbw_offset = { + [CHNL_BW_20] = 0, + [CHNL_BW_40] = 0, + [CHNL_BW_80] = 0, + [CHNL_BW_160] = 0, + }, + .ce_power_offset_prod_en = true, + .ci_bf_en = false, + .ci_bf_max_nss = 2, + .ce_sounding_interval_coefs = { + [SOUNDING_INTERVAL_COEF_MIN_INTERVAL] = 100, + [SOUNDING_INTERVAL_COEF_STA_STEP] = 4, + [SOUNDING_INTERVAL_COEF_INTERVAL_STEP] = 50, + [SOUNDING_INTERVAL_COEF_MAX_INTERVAL] = 500, + }, + .ci_rate_fallback = { + [CL_RATE_FALLBACK_COUNT_SU] = 4, + [CL_RATE_FALLBACK_COUNT_MU] = 2, + [CL_RATE_FALLBACK_RETRY_COUNT_THR] = 2, + [CL_RATE_FALLBACK_BA_PER_THR] = 25, + [CL_RATE_FALLBACK_BA_NOT_RECEIVED_THR] = 2, + [CL_RATE_FALLBACK_DISABLE_MCS] = 1 + }, + .ce_rx_pkts_budget = 512, + .ci_band_num = 5, + .ci_mult_ampdu_in_txop_en = false, + .ce_wmm_aifsn = { + [AC_BK] = 3, + [AC_BE] = 7, + [AC_VI] = 1, + [AC_VO] = 1 + }, + .ce_wmm_cwmin = { + [AC_BK] = 4, + [AC_BE] = 4, + [AC_VI] = 3, + [AC_VO] = 2 + }, + .ce_wmm_cwmax = { + [AC_BK] = 10, + [AC_BE] = 10, + [AC_VI] = 4, + [AC_VO] = 3 + }, + .ce_wmm_txop = { + [AC_BK] = 0, + [AC_BE] = 0, + [AC_VI] = 94, + [AC_VO] = 47 + }, + .ci_su_force_min_spacing = CL_TX_MPDU_SPACING_INVALID, + .ci_mu_force_min_spacing = CL_TX_MPDU_SPACING_INVALID, + .ci_tf_mac_pad_dur = 0, + .ci_cca_timeout = 300, + .ce_tx_ba_session_timeout = 30000, + .ci_motion_sense_en = true, + .ci_motion_sense_rssi_thr = 8, + .ci_wrs_max_bw = CHNL_BW_160, + .ci_wrs_min_bw = CHNL_BW_20, + .ci_wrs_fixed_rate = { + [WRS_FIXED_PARAM_MODE] = -1, + [WRS_FIXED_PARAM_BW] = -1, + [WRS_FIXED_PARAM_NSS] = -1, + [WRS_FIXED_PARAM_MCS] = -1, + [WRS_FIXED_PARAM_GI] = -1 + }, + .ce_he_mcs_nss_supp_tx = { + [WRS_SS_1 ... WRS_SS_4] = 11, + }, + .ce_he_mcs_nss_supp_rx = { + [WRS_SS_1 ... WRS_SS_4] = 11, + }, + .ce_vht_mcs_nss_supp_tx = { + [WRS_SS_1 ... WRS_SS_4] = 9, + }, + .ce_vht_mcs_nss_supp_rx = { + [WRS_SS_1 ... WRS_SS_4] = 9, + }, + .ci_pe_duration = U8_MAX, + .ci_pe_duration_bcast = PPE_16US, + .ci_gain_update_enable = 1, + .ci_mcs_sig_b = 0, + .ci_spp_ksr_value = 1, + .ci_rx_padding_en = false, + .ci_stats_en = false, + .ci_bar_disable = false, + .ci_ofdm_only = true, + .ci_hw_bsr = false, + .ci_drop_to_lower_bw = false, + .ci_force_icmp_single = false, + .ce_wrs_rx_en = false, + .ci_hr_factor = { + [CHNL_BW_20] = 2, + [CHNL_BW_40] = 2, + [CHNL_BW_80] = 2, + [CHNL_BW_160] = 1 + }, + .ci_csd_en = true, + .ci_signal_extension_en = false, + .ci_vht_cap_24g = false, + .ci_tx_digital_gain = 0x28282828, + .ci_tx_digital_gain_cck = 0x63636363, + .ci_ofdm_cck_power_offset = -13, + .ci_mac_clk_gating_en = true, + .ci_phy_clk_gating_en = true, + .ci_imaging_blocker = false, + .ci_sensing_ndp_tx_chain_mask = NDP_TX_PHY0, + .ci_sensing_ndp_tx_bw = CHNL_BW_MAX, + .ci_sensing_ndp_tx_format = FORMATMOD_NON_HT, + .ci_sensing_ndp_tx_num_ltf = LTF_X1, + .ci_calib_ant_tx = { + [0 ... MAX_ANTENNAS - 1] = U8_MAX, + }, + .ci_calib_ant_rx = { + [0 ... MAX_ANTENNAS - 1] = U8_MAX, + }, + .ci_cca_ed_rise_thr_dbm = -62, + .ci_cca_ed_fall_thr_dbm = -65, + .ci_cca_cs_en = 1, + .ci_cca_modem_en = 0xf, + .ci_cca_main_ant = 0, + .ci_cca_second_ant = 1, + .ci_cca_flag0_ctrl = 0x8, + .ci_cca_flag1_ctrl = 0x8, + .ci_cca_flag2_ctrl = 0x2, + .ci_cca_flag3_ctrl = 0xa, + .ci_cca_gi_rise_thr_dbm = -72, + .ci_cca_gi_fall_thr_dbm = -75, + .ci_cca_gi_pow_lim_dbm = -59, + .ci_cca_ed_en = 0x7ff, + .ci_cca_gi_en = 0, + .ci_rx_he_mu_ppdu = false, + .ci_fast_rx_en = true, + .ci_distance_auto_resp_all = 0, + .ci_distance_auto_resp_msta = 0, + .ci_fw_disable_recovery = false, + .ce_listener_en = 0, + .ci_tx_delay_tstamp_en = false, + .ci_calib_tx_init_tx_gain = { + [0 ... MAX_ANTENNAS - 1] = CALIB_TX_GAIN_DEFAULT, + }, + .ci_calib_tx_init_rx_gain = { + [0 ... MAX_ANTENNAS - 1] = INVALID_CALIB_RX_GAIN, + }, + .ci_calib_rx_init_tx_gain = { + [0 ... MAX_ANTENNAS - 1] = CALIB_TX_GAIN_DEFAULT, + }, + .ci_calib_rx_init_rx_gain = { + [0 ... MAX_ANTENNAS - 1] = INVALID_CALIB_RX_GAIN, + }, + .ci_calib_conf_rx_gain_upper_limit = INVALID_CALIB_RX_GAIN, + .ci_calib_conf_rx_gain_lower_limit = INVALID_CALIB_RX_GAIN, + .ci_calib_conf_tone_vector_20bw = {6, 10, 14, 18, 22, 24, 26, 27}, + .ci_calib_conf_tone_vector_40bw = {10, 18, 26, 34, 41, 48, 53, 58}, + .ci_calib_conf_tone_vector_80bw = {18, 34, 50, 66, 82, 98, 110, 122}, + .ci_calib_conf_tone_vector_160bw = {18, 34, 66, 98, 130, 164, 224, 250}, + .ci_calib_conf_gp_rad_trshld = GP_RAD_TRSHLD_DEFAULT, + .ci_calib_conf_ga_lin_upper_trshld = GA_LIN_UPPER_TRSHLD_DEFAULT, + .ci_calib_conf_ga_lin_lower_trshld = GA_LIN_LOWER_TRSHLD_DEFAULT, + .ci_calib_conf_singletons_num = SINGLETONS_NUM_DEFAULT, + .ci_calib_conf_rampup_time = RAMPUP_TIME, + .ci_calib_conf_lo_coarse_step = LO_COARSE_STEP, +#ifdef CONFIG_CL8K_EEPROM_STM24256 + .ci_calib_conf_lo_fine_step = LO_FINE_STEP, + .ci_calib_eeprom_channels_20mhz = {0}, + .ci_calib_eeprom_channels_40mhz = {0}, + .ci_calib_eeprom_channels_80mhz = {0}, + .ci_calib_eeprom_channels_160mhz = {0}, +#endif + .ci_mesh_basic_rates = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +static int cl_tcv_update_config(struct cl_hw *cl_hw, char *name, char *value) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + int ret = -ENOENT; + + do { + READ_S8(ce_debug_level); + READ_BOOL(ce_radio_on); + READ_BOOL(ce_ps_ctrl_enabled); + READ_BOOL(ci_ieee80211h); + READ_U8(ci_max_bss_num); + READ_U8(ci_short_guard_interval); + READ_U8(ci_max_mpdu_len); + READ_U8(ci_max_ampdu_len_exp); + READ_STR(ce_dsp_code); + READ_STR(ce_dsp_data); + READ_STR(ce_dsp_external_data); + READ_BOOL(ci_uapsd_en); + READ_BOOL(ce_eirp_regulatory_op_en); + READ_BOOL(ce_eirp_regulatory_prod_en); + READ_BOOL(ci_agg_tx); + READ_BOOL(ci_agg_rx); + READ_BOOL(ce_txldpc_en); + READ_BOOL(ci_ht_rxldpc_en); + READ_BOOL(ci_vht_rxldpc_en); + READ_BOOL(ci_he_rxldpc_en); + READ_BOOL(ci_cs_required); + READ_S8_ARR(ci_rx_sensitivity_prod, MAX_ANTENNAS); + READ_S8_ARR(ci_rx_sensitivity_op, MAX_ANTENNAS); + READ_BOOL(ci_min_he_en); + READ_U8(ce_cck_tx_ant_mask); + READ_U8(ce_cck_rx_ant_mask); + READ_U8(ce_rx_nss); + READ_U8(ce_tx_nss); + READ_U8(ce_num_antennas); + READ_U16(ce_max_agg_size_tx); + READ_U16(ce_max_agg_size_rx); + READ_BOOL(ce_rxamsdu_en); + READ_U8(ce_txamsdu_en); + READ_U16(ci_tx_amsdu_min_data_rate); + READ_U8(ci_tx_sw_amsdu_max_packets); + READ_U16(ci_tx_packet_limit); + READ_U16(ci_sw_txhdr_pool); + READ_U16(ci_amsdu_txhdr_pool); + READ_U16(ci_tx_queue_size_agg); + READ_U16(ci_tx_queue_size_single); + READ_BOOL(ci_tx_push_cntrs_stat_en); + READ_BOOL(ci_traffic_mon_en); + READ_U16_ARR(ci_ipc_rxbuf_size, CL_RX_BUF_MAX, true); + READ_U16(ce_max_retry); + READ_U8(ce_short_retry_limit); + READ_U8(ce_long_retry_limit); + READ_U8(ci_assoc_auth_retry_limit); + READ_U8(ci_cap_bandwidth); + READ_U32(ci_chandef_channel); + READ_U8(ci_chandef_bandwidth); + READ_BOOL(ci_cck_in_hw_mode); + READ_S8(ce_temp_comp_slope); + READ_U32(ci_fw_dbg_severity); + READ_U32(ci_fw_dbg_module); + READ_U8(ci_lcu_dbg_cfg_inx); + READ_U8(ci_dsp_lcu_mode); + READ_U32(ci_hal_idle_to); + READ_U32(ci_tx_ac0_to); + READ_U32(ci_tx_ac1_to); + READ_U32(ci_tx_ac2_to); + READ_U32(ci_tx_ac3_to); + READ_U32(ci_tx_bcn_to); + READ_STR(ce_hardware_power_table); + READ_STR(ce_arr_gain); + READ_STR(ce_bf_gain_2_ant); + READ_STR(ce_bf_gain_3_ant); + READ_STR(ce_bf_gain_4_ant); + READ_STR(ce_bf_gain_5_ant); + READ_STR(ce_bf_gain_6_ant); + READ_STR(ce_ant_gain); + READ_STR(ce_ant_gain_36_64); + READ_STR(ce_ant_gain_100_140); + READ_STR(ce_ant_gain_149_165); + READ_STR(ci_min_ant_pwr); + READ_STR(ci_bw_factor); + READ_U8(ce_mcast_rate); + READ_BOOL(ce_dyn_mcast_rate_en); + READ_BOOL(ce_dyn_bcast_rate_en); + READ_U8(ce_default_mcs_ofdm); + READ_U8(ce_default_mcs_cck); + READ_BOOL(ce_prot_log_nav_en); + READ_U8(ce_prot_mode); + READ_U8(ce_prot_rate_format); + READ_U8(ce_prot_rate_mcs); + READ_U8(ce_prot_rate_pre_type); + READ_U8(ce_bw_signaling_mode); + READ_U8(ci_dyn_cts_sta_thr); + READ_S8(ci_vns_pwr_limit); + READ_U8(ci_vns_pwr_mode); + READ_S8(ci_vns_rssi_auto_resp_thr); + READ_S8(ci_vns_rssi_thr); + READ_S8(ci_vns_rssi_hys); + READ_U16(ci_vns_maintenance_time); + READ_U16(ce_bcn_tx_path_min_time); + READ_BOOL(ci_backup_bcn_en); + READ_BOOL(ce_tx_txop_cut_en); + READ_U8(ci_bcns_flushed_cnt_thr); + READ_BOOL(ci_phy_err_prevents_phy_dump); + READ_U8(ci_tx_rx_delay); + READ_U8(ci_fw_assert_time_diff_sec); + READ_U8(ci_fw_assert_storm_detect_thd); + READ_U32(ce_hw_assert_time_max); + READ_U8(ce_bg_assert_print); + READ_U8(ce_fw_watchdog_mode); + READ_U8(ce_fw_watchdog_limit_count); + READ_U32(ce_fw_watchdog_limit_time); + READ_S8(ci_rx_remote_cpu_drv); + READ_S8(ci_rx_remote_cpu_mac); + READ_U16(ci_pending_queue_size); + READ_U8(ce_tx_power_control); + READ_BOOL(ce_acs_coex_en); + READ_U8(ci_dfs_initial_gain); + READ_U8(ci_dfs_agc_cd_th); + READ_U16(ci_dfs_long_pulse_min); + READ_U16(ci_dfs_long_pulse_max); + READ_STR(ce_dfs_tbl_overwrite); + READ_S8_ARR(ce_ppmcs_offset_he_6g, WRS_MCS_MAX_HE); + READ_S8_ARR(ce_ppmcs_offset_he_36_64, WRS_MCS_MAX_HE); + READ_S8_ARR(ce_ppmcs_offset_he_100_140, WRS_MCS_MAX_HE); + READ_S8_ARR(ce_ppmcs_offset_he_149_165, WRS_MCS_MAX_HE); + READ_S8_ARR(ce_ppmcs_offset_ht_vht_36_64, WRS_MCS_MAX_VHT); + READ_S8_ARR(ce_ppmcs_offset_ht_vht_100_140, WRS_MCS_MAX_VHT); + READ_S8_ARR(ce_ppmcs_offset_ht_vht_149_165, WRS_MCS_MAX_VHT); + READ_S8_ARR(ce_ppmcs_offset_ofdm_36_64, WRS_MCS_MAX_OFDM); + READ_S8_ARR(ce_ppmcs_offset_ofdm_100_140, WRS_MCS_MAX_OFDM); + READ_S8_ARR(ce_ppmcs_offset_ofdm_149_165, WRS_MCS_MAX_OFDM); + READ_S8_ARR(ce_ppmcs_offset_he, WRS_MCS_MAX_HE); + READ_S8_ARR(ce_ppmcs_offset_ht, WRS_MCS_MAX_HT); + READ_S8_ARR(ce_ppmcs_offset_ofdm, WRS_MCS_MAX_OFDM); + READ_S8_ARR(ce_ppmcs_offset_cck, WRS_MCS_MAX_CCK); + READ_S8_ARR(ce_ppbw_offset, CHNL_BW_MAX); + READ_BOOL(ce_power_offset_prod_en); + READ_BOOL(ci_bf_en); + READ_U8(ci_bf_max_nss); + READ_U16_ARR(ce_sounding_interval_coefs, SOUNDING_INTERVAL_COEF_MAX, true); + READ_U8_ARR(ci_rate_fallback, CL_RATE_FALLBACK_MAX, true); + READ_U16(ce_rx_pkts_budget); + READ_U8(ci_band_num); + READ_BOOL(ci_mult_ampdu_in_txop_en); + READ_U8_ARR(ce_wmm_aifsn, AC_MAX, true); + READ_U8_ARR(ce_wmm_cwmin, AC_MAX, true); + READ_U8_ARR(ce_wmm_cwmax, AC_MAX, true); + READ_U16_ARR(ce_wmm_txop, AC_MAX, true); + READ_U8(ci_su_force_min_spacing); + READ_U8(ci_mu_force_min_spacing); + READ_U8(ci_tf_mac_pad_dur); + READ_U32(ci_cca_timeout); + READ_U16(ce_tx_ba_session_timeout); + READ_BOOL(ci_motion_sense_en); + READ_S8(ci_motion_sense_rssi_thr); + READ_U8(ci_wrs_max_bw); + READ_U8(ci_wrs_min_bw); + READ_S8_ARR(ci_wrs_fixed_rate, WRS_FIXED_PARAM_MAX); + READ_U8_ARR(ce_he_mcs_nss_supp_tx, WRS_SS_MAX, true); + READ_U8_ARR(ce_he_mcs_nss_supp_rx, WRS_SS_MAX, true); + READ_U8_ARR(ce_vht_mcs_nss_supp_tx, WRS_SS_MAX, true); + READ_U8_ARR(ce_vht_mcs_nss_supp_rx, WRS_SS_MAX, true); + READ_U8(ci_pe_duration); + READ_U8(ci_pe_duration_bcast); + READ_U8(ci_gain_update_enable); + READ_U8(ci_mcs_sig_b); + READ_U8(ci_spp_ksr_value); + READ_BOOL(ci_rx_padding_en); + READ_BOOL(ci_stats_en); + READ_BOOL(ci_bar_disable); + READ_BOOL(ci_ofdm_only); + READ_BOOL(ci_hw_bsr); + READ_BOOL(ci_drop_to_lower_bw); + READ_BOOL(ci_force_icmp_single); + READ_BOOL(ci_csd_en); + READ_BOOL(ce_wrs_rx_en); + READ_U8_ARR(ci_hr_factor, CHNL_BW_MAX, true); + READ_BOOL(ci_signal_extension_en); + READ_BOOL(ci_vht_cap_24g); + READ_U32(ci_tx_digital_gain); + READ_U32(ci_tx_digital_gain_cck); + READ_S8(ci_ofdm_cck_power_offset); + READ_BOOL(ci_mac_clk_gating_en); + READ_BOOL(ci_phy_clk_gating_en); + READ_BOOL(ci_imaging_blocker); + READ_U8(ci_sensing_ndp_tx_chain_mask); + READ_U8(ci_sensing_ndp_tx_bw); + READ_U8(ci_sensing_ndp_tx_format); + READ_U8(ci_sensing_ndp_tx_num_ltf); + READ_U8_ARR(ci_calib_ant_tx, MAX_ANTENNAS, true); + READ_U8_ARR(ci_calib_ant_rx, MAX_ANTENNAS, true); + READ_S8(ci_cca_ed_rise_thr_dbm); + READ_S8(ci_cca_ed_fall_thr_dbm); + READ_U8(ci_cca_cs_en); + READ_U8(ci_cca_modem_en); + READ_U8(ci_cca_main_ant); + READ_U8(ci_cca_second_ant); + READ_U8(ci_cca_flag0_ctrl); + READ_U8(ci_cca_flag1_ctrl); + READ_U8(ci_cca_flag2_ctrl); + READ_U8(ci_cca_flag3_ctrl); + READ_S8(ci_cca_gi_rise_thr_dbm); + READ_S8(ci_cca_gi_fall_thr_dbm); + READ_S8(ci_cca_gi_pow_lim_dbm); + READ_U16(ci_cca_ed_en); + READ_U8(ci_cca_gi_en); + READ_BOOL(ci_rx_he_mu_ppdu); + READ_BOOL(ci_fast_rx_en); + READ_U8(ci_distance_auto_resp_all); + READ_U8(ci_distance_auto_resp_msta); + READ_BOOL(ci_fw_disable_recovery); + READ_BOOL(ce_listener_en); + READ_BOOL(ci_tx_delay_tstamp_en); + READ_U8_ARR(ci_calib_tx_init_tx_gain, MAX_ANTENNAS, true); + READ_U8_ARR(ci_calib_tx_init_rx_gain, MAX_ANTENNAS, true); + READ_U8_ARR(ci_calib_rx_init_tx_gain, MAX_ANTENNAS, true); + READ_U8_ARR(ci_calib_rx_init_rx_gain, MAX_ANTENNAS, true); + READ_U8(ci_calib_conf_rx_gain_upper_limit); + READ_U8(ci_calib_conf_rx_gain_lower_limit); + READ_U8_ARR(ci_calib_conf_tone_vector_20bw, IQ_NUM_TONES_REQ, true); + READ_U8_ARR(ci_calib_conf_tone_vector_40bw, IQ_NUM_TONES_REQ, true); + READ_U8_ARR(ci_calib_conf_tone_vector_80bw, IQ_NUM_TONES_REQ, true); + READ_U8_ARR(ci_calib_conf_tone_vector_160bw, IQ_NUM_TONES_REQ, true); + READ_U32(ci_calib_conf_gp_rad_trshld); + READ_U32(ci_calib_conf_ga_lin_upper_trshld); + READ_U32(ci_calib_conf_ga_lin_lower_trshld); + READ_U8(ci_calib_conf_singletons_num); + READ_U16(ci_calib_conf_rampup_time); + READ_U16(ci_calib_conf_lo_coarse_step); + READ_U16(ci_calib_conf_lo_fine_step); + +#ifdef CONFIG_CL8K_EEPROM_STM24256 + if (cl_hw_is_tcv0(cl_hw)) { + READ_U16_ARR(ci_calib_eeprom_channels_20mhz, + EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0, false); + READ_U16_ARR(ci_calib_eeprom_channels_40mhz, + EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0, false); + READ_U16_ARR(ci_calib_eeprom_channels_80mhz, + EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0, false); + READ_U16_ARR(ci_calib_eeprom_channels_160mhz, + EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV0, false); + } + if (cl_hw_is_tcv1(cl_hw)) { + READ_U16_ARR(ci_calib_eeprom_channels_20mhz, + EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV1, false); + READ_U16_ARR(ci_calib_eeprom_channels_40mhz, + EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV1, false); + READ_U16_ARR(ci_calib_eeprom_channels_80mhz, + EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV1, false); + READ_U16_ARR(ci_calib_eeprom_channels_160mhz, + EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV1, false); + } +#endif + READ_U16_ARR(ci_mesh_basic_rates, MESH_BASIC_RATE_MAX, false); + } while (0); + + if (ret == -ENOENT) { + if (cl_config_is_non_driver_param(name)) + ret = 0; + else + CL_DBG_ERROR(cl_hw, "No matching conf for nvram parameter %s\n", name); + } + + return ret; +} + +static int cl_tcv_set_all_params_from_buf(struct cl_hw *cl_hw, char *buf, size_t size) +{ + char *line = buf; + char name[MAX_PARAM_NAME_LENGTH]; + char value[STR_LEN_256B]; + char *begin; + char *end; + int ret = 0; + int name_length = 0; + int value_length = 0; + + while (line && strlen(line) && (line != (buf + size))) { + if ((*line == '#') || (*line == '\n')) { + /* Skip comment or blank line */ + line = strstr(line, "\n") + 1; + } else if (*line) { + begin = line; + end = strstr(begin, "="); + + if (!end) { + ret = -EBADMSG; + goto exit; + } + + end++; + name_length = end - begin; + value_length = strstr(end, "\n") - end + 1; + + if (name_length >= MAX_PARAM_NAME_LENGTH) { + cl_dbg_err(cl_hw, + "Name too long (%u)\n", name_length); + ret = -EBADMSG; + goto exit; + } + if (value_length >= STR_LEN_256B) { + cl_dbg_err(cl_hw, + "Value too long (%u)\n", value_length); + ret = -EBADMSG; + goto exit; + } + + snprintf(name, name_length, "%s", begin); + snprintf(value, value_length, "%s", end); + + ret = cl_tcv_update_config(cl_hw, name, value); + if (ret) + goto exit; + + line = strstr(line, "\n") + 1; + } + } + +exit: + + return ret; +} + +static bool cl_tcv_is_valid_min_spacing(u8 min_spacing) +{ + return ((min_spacing == 0) || + (min_spacing == 1) || + (min_spacing == 2) || + (min_spacing == 3) || + (min_spacing == 4) || + (min_spacing == 6) || + (min_spacing == 8) || + (min_spacing == 10) || + (min_spacing == 12) || + (min_spacing == 14) || + (min_spacing == 16) || + (min_spacing == 18) || + (min_spacing == 20) || + (min_spacing == 24) || + (min_spacing == CL_TX_MPDU_SPACING_INVALID)); +} + +static bool cl_tcv_is_valid_cca_config(struct cl_hw *cl_hw, struct cl_tcv_conf *conf) +{ + if (conf->ci_cca_ed_rise_thr_dbm <= conf->ci_cca_ed_fall_thr_dbm) { + CL_DBG_ERROR(cl_hw, "cca_ed_rise_thr_dbm (%u) <= cca_ed_fall_thr_dbm (%u)\n", + conf->ci_cca_ed_rise_thr_dbm, conf->ci_cca_ed_fall_thr_dbm); + return false; + } + + if (conf->ci_cca_gi_rise_thr_dbm <= conf->ci_cca_gi_fall_thr_dbm) { + CL_DBG_ERROR(cl_hw, "cca_gi_rise_thr_dbm (%u) <= cca_gi_fall_thr_dbm (%u)\n", + conf->ci_cca_gi_rise_thr_dbm, conf->ci_cca_gi_fall_thr_dbm); + return false; + } + + if (conf->ci_cca_gi_pow_lim_dbm <= conf->ci_cca_ed_rise_thr_dbm) { + CL_DBG_ERROR(cl_hw, "cca_gi_pow_lim_dbm (%u) <= cca_ed_rise_thr_dbm (%u)\n", + conf->ci_cca_gi_pow_lim_dbm, conf->ci_cca_ed_rise_thr_dbm); + return false; + } + + return true; +} + +static inline void cl_tcv_set_default_channel(u32 *channel, u32 value) +{ + if (*channel == INVALID_CHAN_IDX) + *channel = value; +} + +static inline void cl_tcv_set_default_bandwidth(u8 *bw, u8 value) +{ + if (*bw == CHNL_BW_MAX) + *bw = value; +} + +static inline bool cl_tcv_is_valid_bandwidth(u8 *bw, u8 max_value) +{ + return *bw <= max_value; +} + +static bool cl_tcv_is_valid_channeling_context(struct cl_hw *cl_hw) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + u32 dflt_channel = 1; + u8 bw_limit = CHNL_BW_20; + char *band_str = "?"; + + if (cl_band_is_24g(cl_hw)) { + dflt_channel = 1; + bw_limit = CHNL_BW_40; + band_str = "24g"; + } else if (cl_band_is_5g(cl_hw)) { + dflt_channel = 36; + bw_limit = CHNL_BW_160; + band_str = "5g"; + } else { + dflt_channel = 1; + bw_limit = CHNL_BW_160; + band_str = "6g"; + } + + cl_tcv_set_default_channel(&conf->ci_chandef_channel, dflt_channel); + cl_tcv_set_default_bandwidth(&conf->ci_chandef_bandwidth, bw_limit); + cl_tcv_set_default_bandwidth(&conf->ci_cap_bandwidth, bw_limit); + + /* Forcibly change BW limit for production mode in 24g */ + if (cl_band_is_24g(cl_hw) && cl_hw->chip->conf->ce_production_mode) + bw_limit = CHNL_BW_160; + + if (!cl_tcv_is_valid_bandwidth(&conf->ci_cap_bandwidth, bw_limit)) { + CL_DBG_ERROR(cl_hw, "Invalid channel bandwidth (%u) for %s\n", + conf->ci_cap_bandwidth, band_str); + return false; + } + + return true; +} + +static int cl_tcv_post_configuration(struct cl_hw *cl_hw, const char *buf) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + struct cl_chip *chip = cl_hw->chip; + + if (conf->ci_max_bss_num > ARRAY_SIZE(cl_hw->addresses)) { + CL_DBG_ERROR(cl_hw, "Invalid ci_max_bss_num (%u)\n", + conf->ci_max_bss_num); + return -EINVAL; + } + + /* Production mode */ + if (chip->conf->ce_production_mode) { + memcpy(cl_hw->rx_sensitivity, conf->ci_rx_sensitivity_prod, MAX_ANTENNAS); + conf->ce_prot_mode = 0; + /* Production is done in station mode */ + cl_hw_set_iface_conf(cl_hw, CL_IFCONF_STA); + + } else { + if (chip->conf->ci_phy_dev == PHY_DEV_LOOPBACK) { + s8 rx_sens_loopback[MAX_ANTENNAS] = {-96, -96, -96, -96, -96, -96}; + + memcpy(cl_hw->rx_sensitivity, rx_sens_loopback, MAX_ANTENNAS); + } else { + memcpy(cl_hw->rx_sensitivity, conf->ci_rx_sensitivity_op, MAX_ANTENNAS); + } + } + + if (cl_hw_set_antennas(cl_hw)) { + CL_DBG_ERROR(cl_hw, "hw set antennas failed!\n"); + return -EINVAL; + } + + if (!cl_tcv_is_valid_cca_config(cl_hw, conf)) + return -EINVAL; + + if (conf->ce_num_antennas) { + /* Validate: ce_num_antennas, ce_rx_nss, ce_tx_nss */ + if (conf->ce_num_antennas < MIN_ANTENNAS || + conf->ce_num_antennas > MAX_ANTENNAS) { + CL_DBG_ERROR(cl_hw, "Invalid ce_num_antennas (%u)\n", + conf->ce_num_antennas); + return -EINVAL; + } + + if (conf->ce_rx_nss < 1 || + conf->ce_rx_nss > WRS_SS_MAX || + conf->ce_rx_nss > conf->ce_num_antennas) { + CL_DBG_ERROR(cl_hw, "Invalid ce_rx_nss (%u)\n", conf->ce_rx_nss); + return -EINVAL; + } + + if (conf->ce_tx_nss < 1 || + conf->ce_tx_nss > WRS_SS_MAX || + conf->ce_tx_nss > conf->ce_num_antennas) { + CL_DBG_ERROR(cl_hw, "Invalid ce_tx_nss (%u)\n", conf->ce_tx_nss); + return -EINVAL; + } + + /* Validate: ce_cck_tx_ant_mask and ce_cck_rx_ant_mask */ + if (cl_band_is_24g(cl_hw)) { + u8 ant_shift = cl_hw_ant_shift(cl_hw); + u8 ant_bitmap = (((1 << conf->ce_num_antennas) - 1) << ant_shift); + u8 num_cck_ant_tx = hweight8(conf->ce_cck_tx_ant_mask); + u8 num_cck_ant_rx = hweight8(conf->ce_cck_rx_ant_mask); + + if ((ant_bitmap & conf->ce_cck_tx_ant_mask) != conf->ce_cck_tx_ant_mask) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_tx_ant_mask (0x%x), " + "does not match ce_num_antennas mask (0x%x)\n", + conf->ce_cck_tx_ant_mask, ant_bitmap); + return -EINVAL; + } + + if ((ant_bitmap & conf->ce_cck_rx_ant_mask) != conf->ce_cck_rx_ant_mask) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_rx_ant_mask (0x%x), " + "does not match ce_num_antennas mask (0x%x)\n", + conf->ce_cck_rx_ant_mask, ant_bitmap); + return -EINVAL; + } + + if (conf->ce_cck_tx_ant_mask == 0) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_tx_ant_mask, can't be 0x0\n"); + return -EINVAL; + } + + if (conf->ce_cck_rx_ant_mask == 0) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_rx_ant_mask, can't be 0x0\n"); + return -EINVAL; + } + + if (num_cck_ant_tx > MAX_ANTENNAS_CCK) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_tx_ant_mask (0x%x), " + "number of set bits exceeds %u\n", + num_cck_ant_tx, MAX_ANTENNAS_CCK); + return -EINVAL; + } + + if (num_cck_ant_rx > MAX_ANTENNAS_CCK) { + CL_DBG_ERROR(cl_hw, "Invalid ce_cck_rx_ant_mask (0x%x), " + "number of set bits exceeds %u\n", + num_cck_ant_rx, MAX_ANTENNAS_CCK); + return -EINVAL; + } + } + } + + if (conf->ce_prot_mode == TXL_PROT_RTS) { + CL_DBG_ERROR(cl_hw, "ce_prot_mode %u is not supported\n", TXL_PROT_RTS); + return -EINVAL; + } + + if (!cl_tcv_is_valid_channeling_context(cl_hw)) + return -EINVAL; + + if (cl_band_is_5g(cl_hw)) { + if (!conf->ci_ofdm_only) { + CL_DBG_ERROR(cl_hw, "ci_ofdm_only must be set to 1 for 5g band\n"); + return -EINVAL; + } + } + + /* Validate ce_bcn_tx_path_min_time */ + if (conf->ce_bcn_tx_path_min_time <= CL_TX_BCN_PENDING_CHAIN_MIN_TIME) { + CL_DBG_ERROR(cl_hw, "Invalid ce_bcn_tx_path_min_time (%u)\n", + conf->ce_bcn_tx_path_min_time); + return -EINVAL; + } + + if (conf->ci_tx_sw_amsdu_max_packets > MAX_TX_SW_AMSDU_PACKET) { + cl_dbg_err(cl_hw, "ERROR: Invalid ci_tx_sw_amsdu_max_packets (%u), set default (%u)\n", + conf->ci_tx_sw_amsdu_max_packets, MAX_TX_SW_AMSDU_PACKET); + + conf->ci_tx_sw_amsdu_max_packets = MAX_TX_SW_AMSDU_PACKET; + } + + if (conf->ce_tx_power_control > 100 || conf->ce_tx_power_control < 1) { + cl_dbg_err(cl_hw, "ERROR: Invalid ce_tx_power_control (%u), set default 100\n", + conf->ce_tx_power_control); + + conf->ce_tx_power_control = 100; + } + + if (conf->ce_max_retry > CL_MAX_NUM_OF_RETRY) { + cl_dbg_err(cl_hw, "ERROR: Invalid ce_max_retry (%u), set default to maximum (%u)\n", + conf->ce_max_retry, CL_MAX_NUM_OF_RETRY); + + conf->ce_max_retry = CL_MAX_NUM_OF_RETRY; + } + + if (!cl_tcv_is_valid_min_spacing(conf->ci_su_force_min_spacing)) { + cl_dbg_err(cl_hw, "ERROR: Invalid ci_su_force_min_spacing (%u), must be 0/1/2/3/4/6/8/10/12/14/16/18/20/24, set default %u\n", + conf->ci_su_force_min_spacing, CL_TX_MPDU_SPACING_INVALID); + + conf->ci_su_force_min_spacing = CL_TX_MPDU_SPACING_INVALID; + } + + if (!cl_tcv_is_valid_min_spacing(conf->ci_mu_force_min_spacing)) { + cl_dbg_err(cl_hw, "ERROR: Invalid ci_mu_force_min_spacing (%u), must be 0/1/2/3/4/6/8/10/12/14/16/18/20/24, set default %u\n", + conf->ci_mu_force_min_spacing, CL_TX_MPDU_SPACING_INVALID); + + conf->ci_mu_force_min_spacing = CL_TX_MPDU_SPACING_INVALID; + } + + if (conf->ci_max_mpdu_len != IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 && + conf->ci_max_mpdu_len != IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 && + conf->ci_max_mpdu_len != IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454) { + cl_dbg_err(cl_hw, "ERROR: Invalid 'ci_max_mpdu_len' (%u). Must be 0/1/2. Setting to 0\n", + conf->ci_max_mpdu_len); + + conf->ci_max_mpdu_len = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; + } + + if (cl_hw_is_tcv1(cl_hw) && cl_chip_is_both_enabled(chip)) { + /* Check that sum of ce_num_antennas in both TCV's is smaller than max_antennas */ + struct cl_hw *cl_hw_tcv0 = chip->cl_hw_tcv0; + u8 num_ant_tcv0 = cl_hw_tcv0->conf->ce_num_antennas; + u8 num_ant_tcv1 = conf->ce_num_antennas; + u8 total_ant = num_ant_tcv0 + num_ant_tcv1; + + if (total_ant > chip->max_antennas) { + CL_DBG_ERROR(cl_hw, + "Invalid ce_num_antennas tcv0=%u, tcv1=%u, total=%u, max=%u\n", + num_ant_tcv0, num_ant_tcv1, total_ant, chip->max_antennas); + return -1; + } + } + + if (cl_hw_is_prod_or_listener(cl_hw) && !conf->ce_power_offset_prod_en) { + cl_dbg_err(cl_hw, "Disable PPMCS/PPBW in production mode\n"); + + if (cl_band_is_6g(cl_hw)) { + memset(conf->ce_ppmcs_offset_he_6g, 0, + sizeof(conf->ce_ppmcs_offset_he_6g)); + } else if (cl_band_is_5g(cl_hw)) { + memset(conf->ce_ppmcs_offset_he_36_64, 0, + sizeof(conf->ce_ppmcs_offset_he_36_64)); + memset(conf->ce_ppmcs_offset_he_100_140, 0, + sizeof(conf->ce_ppmcs_offset_he_100_140)); + memset(conf->ce_ppmcs_offset_he_149_165, 0, + sizeof(conf->ce_ppmcs_offset_he_149_165)); + memset(conf->ce_ppmcs_offset_ht_vht_36_64, 0, + sizeof(conf->ce_ppmcs_offset_ht_vht_36_64)); + memset(conf->ce_ppmcs_offset_ht_vht_100_140, 0, + sizeof(conf->ce_ppmcs_offset_ht_vht_100_140)); + memset(conf->ce_ppmcs_offset_ht_vht_149_165, 0, + sizeof(conf->ce_ppmcs_offset_ht_vht_149_165)); + memset(conf->ce_ppmcs_offset_ofdm_36_64, 0, + sizeof(conf->ce_ppmcs_offset_ofdm_36_64)); + memset(conf->ce_ppmcs_offset_ofdm_100_140, 0, + sizeof(conf->ce_ppmcs_offset_ofdm_100_140)); + memset(conf->ce_ppmcs_offset_ofdm_149_165, 0, + sizeof(conf->ce_ppmcs_offset_ofdm_149_165)); + } else { + memset(conf->ce_ppmcs_offset_he, 0, sizeof(conf->ce_ppmcs_offset_he)); + memset(conf->ce_ppmcs_offset_ht, 0, sizeof(conf->ce_ppmcs_offset_ht)); + memset(conf->ce_ppmcs_offset_ofdm, 0, sizeof(conf->ce_ppmcs_offset_ofdm)); + memset(conf->ce_ppmcs_offset_cck, 0, sizeof(conf->ce_ppmcs_offset_cck)); + } + + memset(conf->ce_ppbw_offset, 0, sizeof(conf->ce_ppbw_offset)); + } + + if (!cl_band_is_24g(cl_hw) && cl_hw->conf->ci_signal_extension_en) { + cl_dbg_err(cl_hw, "ERROR: Invalid 'ci_signal_extension_en' (%u). Must be 0 for non 2.4Ghz band. Setting to 0\n", + conf->ce_dyn_mcast_rate_en); + + conf->ci_signal_extension_en = false; + } + + if (conf->ce_dyn_mcast_rate_en && cl_band_is_6g(cl_hw)) { + cl_dbg_err(cl_hw, "ERROR: Invalid 'ce_dyn_mcast_rate_en' (%u). Must be 0 on 6Ghz band. Setting to 0\n", + conf->ce_dyn_mcast_rate_en); + + conf->ce_dyn_mcast_rate_en = 0; + } + + if (conf->ce_dyn_bcast_rate_en && cl_band_is_6g(cl_hw)) { + cl_dbg_err(cl_hw, "ERROR: Invalid 'ce_dyn_bcast_rate_en' (%u). Must be 0 on 6Ghz band. Setting to 0\n", + conf->ce_dyn_bcast_rate_en); + + conf->ce_dyn_bcast_rate_en = 0; + } + + return 0; +} + +int cl_tcv_config_read(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + char *buf = NULL; + size_t size = 0; + int ret = 0; + char filename[CL_FILENAME_MAX] = {0}; + u8 tcv_idx = cl_hw->idx; + + snprintf(filename, sizeof(filename), "cl_tcv%u.dat", tcv_idx); + pr_debug("%s: %s\n", __func__, filename); + size = cl_file_open_and_read(chip, filename, &buf); + + if (!buf) { + pr_err("read %s failed !!!\n", filename); + return -ENODATA; + } + + ret = cl_tcv_set_all_params_from_buf(cl_hw, buf, size); + if (ret) { + kfree(buf); + return ret; + } + + ret = cl_tcv_post_configuration(cl_hw, NULL); + if (ret) { + kfree(buf); + return ret; + } + + kfree(buf); + + return ret; +} + +int cl_tcv_config_alloc(struct cl_hw *cl_hw) +{ + cl_hw->conf = kzalloc(sizeof(*cl_hw->conf), GFP_KERNEL); + + if (!cl_hw->conf) + return -ENOMEM; + + /* Copy default values */ + memcpy(cl_hw->conf, &conf, sizeof(struct cl_tcv_conf)); + + return 0; +} + +void cl_tcv_config_free(struct cl_hw *cl_hw) +{ + kfree(cl_hw->conf); + cl_hw->conf = NULL; +} + +void cl_tcv_config_validate_calib_params(struct cl_hw *cl_hw) +{ + struct cl_tcv_conf *conf = cl_hw->conf; + u8 chain = 0; + + if (cl_hw->chip->conf->ci_phy_dev == PHY_DEV_ATHOS) { + if (cl_hw->chip->rfic_version == ATHOS_B_VER) { + for (chain = 0; chain < MAX_ANTENNAS; chain++) { + if (conf->ci_calib_tx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_tx_init_rx_gain[chain] = + CALIB_RX_GAIN_DEFAULT_ATHOS_B; + if (conf->ci_calib_rx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_rx_init_rx_gain[chain] = + CALIB_RX_GAIN_DEFAULT_ATHOS_B; + } + + if (conf->ci_calib_conf_rx_gain_upper_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_upper_limit = + CALIB_RX_GAIN_UPPER_LIMIT_ATHOS_B; + if (conf->ci_calib_conf_rx_gain_lower_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_lower_limit = + CALIB_RX_GAIN_LOWER_LIMIT_ATHOS_B; + } else { + for (chain = 0; chain < MAX_ANTENNAS; chain++) { + if (conf->ci_calib_tx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_tx_init_rx_gain[chain] = + CALIB_RX_GAIN_DEFAULT_ATHOS; + if (conf->ci_calib_rx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_rx_init_rx_gain[chain] = + CALIB_RX_GAIN_DEFAULT_ATHOS; + } + + if (conf->ci_calib_conf_rx_gain_upper_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_upper_limit = + CALIB_RX_GAIN_UPPER_LIMIT_ATHOS; + if (conf->ci_calib_conf_rx_gain_lower_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_lower_limit = + CALIB_RX_GAIN_LOWER_LIMIT_ATHOS; + } + } else { + for (chain = 0; chain < MAX_ANTENNAS; chain++) { + if (conf->ci_calib_tx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_tx_init_rx_gain[chain] = CALIB_RX_GAIN_DEFAULT; + + if (conf->ci_calib_rx_init_rx_gain[chain] == INVALID_CALIB_RX_GAIN) + conf->ci_calib_rx_init_rx_gain[chain] = CALIB_RX_GAIN_DEFAULT; + } + + if (conf->ci_calib_conf_rx_gain_upper_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_upper_limit = CALIB_RX_GAIN_UPPER_LIMIT; + if (conf->ci_calib_conf_rx_gain_lower_limit == INVALID_CALIB_RX_GAIN) + conf->ci_calib_conf_rx_gain_lower_limit = CALIB_RX_GAIN_LOWER_LIMIT; + } +} From patchwork Tue May 24 11:34:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575962 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 5F3EDC433FE for ; Tue, 24 May 2022 11:40:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235061AbiEXLkH (ORCPT ); Tue, 24 May 2022 07:40:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236660AbiEXLkD (ORCPT ); Tue, 24 May 2022 07:40:03 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2059.outbound.protection.outlook.com [40.107.20.59]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 689F092D1D for ; Tue, 24 May 2022 04:39:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Gdl3UvNq2Asyk/2nKA2s2JUKhDjrMs5PE3u2ZDJtUIaHJu3738jzz4QjQ0ePYF6TbocMT7TgHHBBhIF4/T37OnT/iSzHedBmvE+g7V1beU6y3R636iOxPVvStrlIM13UbrcDWeFHaiHwM2kvltqIhkf5PxVjw/qM8xD5qyGEB7wQPT8Vrnmm6mhd9YxqDTVD+yEizyGnPWXVbX4jNYpZ5mH1fzVwO9/g4Wt7Tmm7YSAabLyhGxPGBQnKDB3G4JtkIViWAwTLuljIEalmWWIO2aOvnympCjssMPzSRi3LoAj1BSUyxhP5+0g8w6KbaiXhLKwG/Q+I6er8YPa0UdHC2Q== 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=9328ff3sTPhLBWkOiYeDjCXOhOes3Yr2nLyBjnHesnI=; b=F2XY+1q0YQA5/PmjzdtwZ7eysf0JrmPFluK4ai7zjrm/wykee5yBat/BvVBlEp9sN6qb2un0YYVxRDHdSsHx/DoTP6wva3hBqKhalTKD2Nogmmu05WahL9AsO1nJYiSYYPlOkYk51+zrI8QjeQxmcRnEF5L3AoHqymWkUtctMj/NGEg8k7r+AxVpt6HmjrThgVuAsDhKf3KtMRVwgiQEF53rncnrw6SPetGPT49OQxX6twQO3Djy4kegbcMSR/YOxyW4ttIhnQiOfoy5Ht8fVfW5uiAMsxidojXA0QBiKKDcRh6NgL6BqFGpfGm4IrzqoNlxLfZ4uTl89hY2dHFFAQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=9328ff3sTPhLBWkOiYeDjCXOhOes3Yr2nLyBjnHesnI=; b=CCa+5hUiyEV8uPWFJqAUHm3jQhF1qLJk6JU5AZ+E1xTxXiz/ah6jNPI3+WGoI32kB982vnATItLvNVRVKqsTg7/m218auua7CYnrwoOCecYl3KtXFFQ/CdE38BD4MIHqrUWZSaL6z5nCTxpEBU2ZmdjGGX1JipQXUtfbyXd+pUg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:29 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:29 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 79/96] cl8k: add tcv.h Date: Tue, 24 May 2022 14:34:45 +0300 Message-Id: <20220524113502.1094459-80-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 03743f81-66c1-4fd8-1e01-08da3d79fa6e X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TUfrqMs9VH9RPLePEqKDeCj9+SRD8EL/8vFuHvs8osKKa9QGsPhhwTdzmvCFusTJ8TrTd2A5/tzjFN76/8EFVIxR28LGfBIoApuhISXQVW5bMr2UJ/i/Gm1qdaVjw4UP3bgWT8a4OeBMabBbuZvvHm+WttLqfnvMlsjJYIkSRbG9+yvhfJmG2jU01RqEh3K4GrnY0rPQZMKMlCQ0w7EV/VFMgXq6pE3NGGtvm7AiP5PF3OzjtHUgOW8HMHBOsT9zqUNcPJJiQQc5Z822RF7/7jJP6lvM33wYJqK5JMZDx9l+5Vui9jRbZqhmmdycx7ebthQ3Bi/A3iqIX8ApyhwgQeTtyXNvTjWP/bSDSZxM5HBuxdf3ZDNGTzwvB7i8OkbnJ59nAquWnYodyCg2QaRlfQ6Zm/DjItKj65D9J3Sj55ongzJJKDlpxTeiz9tmdcNAzx4AEf4vNrKjHBhZnqnjvym4umoRJhyabfvLSnkF70lQH0x5ABteobTAISHFqNFOg5YRhOJsE0ZCmlbn3bDZNu7ZDOnezv23FBEOqKP7Y+VHFBLI03/bD8eFwK1XAcUS7c3y67I80s6Kr8qZUCK2HoPDh1bB+PUn/nVIwNuFjjsBMag6p+WKRgR9+RGZhol420FZRz1RRRsxaANKVyVe0gIylw4vKnPH4+79Dkbcbh0GpDALAirldxhwjhAQ0cMfJJ+xlfmMkzFr/5g5VL5s1D++N+ZX4UlcfLz+DsM1O24= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: E47eIdm9mHSz4xrzKB6ArshjEFDLS736Nk0jbAc0gMYwF6wNF5JthmXt0DohwlhyjsL+EjodTjaPiy33Qruz4RhLcDj/w2DkFUDu4zZknNyXfu6oAwG+3n7saObSOvrDK3saqdh8yHA4Y7+oGjI3dNgdh/IGRHjzCw9D6JTlIWhRt98guQ/kYlDshzZsHY5+uaFH6eN5vAdI5toIlwqBzpgb6uBD+kg3HJj93Fv8zOg2f0cMaqg0/IZlDhI7osycfm+Z2F/TpiyvXSxy1a2HU3PiJ/qv1PoIa27HPk+g3JH6wTQQt9fJqULyEZpovMH/30HvaZJokRYJmG9ywrD/TWaJL9S+UjXGXls+Uc6aElIf0S0G/h9lRfejTE9IkkXgWj+gUkg+nnFzcgDZvX2BcJUURb5ZV5/lt29A+2slSzbQbqcSfGhG+Rk50AOd9kLNELucXIr6cRK6peNk0es7o4uvDpGnrOAJ0j0iguENBJkA+P61NLk/6GTlcskTpGjQOQPMzowEkTCMckbeAM+2poHQSEScPGUP5zYuXVNv0uCC3nVY8maV1qp8ibhcKPzq0pyYJOTS7djmpLD5r5W+VmMVIqP8yChv5ksRpwPJPGSH5YQ5fQNyQ9Df/1TXc1ootFIH7qptff4Uh/cPZWLHIvmBVPWpfN+7wPCKcRHhePeL703wchNsfFy2ukv0GAbPF6Qi4xzV4Vaof/LpGtucvjAS9b3F9st1lgX9BQxVWMkrRiX7YTMPpmjnYyab2lpIzD3VhVb7JWHAgtzPMkxxQM60ED5Y0GiEnaFi+CcQrIlC+cWIt7zQV7StF4EryhUN5fgHCPYIHl/WFJSv+8xS1W8FFsxlSmuztKOp2qpG0NLTWqR/z+oZukZF55TWHi5EFfEb/JRH26N7Ca+h3RuxTR/gpwZ+F7Pg9puk3b18TAWrzXwfEEGRHR3iGTzunugXj9Kq681s8Hy+/cKHve03T6XYYjD9VLPTK8pq8E7SgbHqNOOcw3IxbO4TghmECtdn8PMdUGYs9X2RoyP/rPdwBvOjiclTPWzDw2MQBegGXWh427hSyey175EHqI/RM7A1tcOLViqt8JL/Ii3jD1C1l5PzhblrPvtY9ZFk8mi/WPPRVKLoyijS2F/ljCAgbjRU15S4dJW+R4MhfGQ1qcNmCfTulsAiJJUsdeN71My7eCAAykMwUAlbYMBOqCH1toL7TB1DDfUQENLwlzkRiGnsvPTUjnNHaS9gfhzowMo7pcWZIBu53ALx1401Lltq8lil3VLH65F/5PDx4iB2+lEaJcpRvJiZoVUT5ZYqV4VZva+N+b211D14I2g9QbmartMvnNeNKiE1EQRrqjZGxRN9dm+YkRV6PioWIxVf3T4mwLA+0TT+ixuj4XEUNEK+z1C9AsaMetHdGJymQmsZCmccLw2cY5QLGpXAtjc3gcN8xT+ICiq4AMi02fWQsbDaMAqNrmM0K438vyDpcI2LOXUxDKkEa+7oJtP5TCdwgkqYhZTjh4ky/1rkImQhVri6ymD+Q+UZk/aAvoQLagxAJFlW1dZ0ijg+JMM25Q50E8PGy+l/X9+0IkwGNR6CdC9nI35Svo8YfqlpwXT8QcNh4i/Ug+YAUHBEHk/1ss8PIEvQqeu4HbkQZQyj/9Qf/26emJWxH1/OUpP+mGVsf6VxBLsyO/hEVxD6gv5EUmNQvupOcy76gAwGg0UBhv00ZW5ZD+5vSxlxyH+Lt1GbkWGUZatOaGd1DVizlsT6Tltjvr9bdBs= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 03743f81-66c1-4fd8-1e01-08da3d79fa6e X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:52.9610 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: J87myJsEOHKR7Ne/3Prh4mHj7H73iob9JPWiE4rhlHxnCKbQE8/R67g9dF3sMazvK1UwoZ/AJ1flexYIn7hdwQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/tcv.h | 283 +++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/tcv.h diff --git a/drivers/net/wireless/celeno/cl8k/tcv.h b/drivers/net/wireless/celeno/cl8k/tcv.h new file mode 100644 index 000000000000..99cf0938c5c4 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/tcv.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_TCV_CONFIG_H +#define CL_TCV_CONFIG_H + +#include "def.h" +#include "ipc_shared.h" +#include "radio.h" +#include "sounding.h" +#include "eeprom.h" + +/** + * TCV (=Tranceiver) configuration, is related to the specific band on top + * of specific chipset. + */ +#define CL_DEFAULT_HAL_IDLE_TIMEOUT 16000 /* Idle request - 16ms */ +#define CL_TX_DEFAULT_AC0_TIMEOUT 500000 /* Background - 500ms */ +#define CL_TX_DEFAULT_AC1_TIMEOUT 300000 /* Best effort - 300ms */ +#define CL_TX_DEFAULT_AC2_TIMEOUT 200000 /* Video - 200ms */ +#define CL_TX_DEFAULT_AC3_TIMEOUT 200000 /* Voice - 200ms */ +#define CL_TX_DEFAULT_BCN_TIMEOUT 150000 /* Beacon - 150ms */ + +/* Minimal MPDU spacing we support in TX - correspond to FW NX_TX_MPDU_SPACING */ +#define CL_TX_MPDU_SPACING_INVALID 0xFF + +enum { + CL_RATE_FALLBACK_COUNT_SU, + CL_RATE_FALLBACK_COUNT_MU, + CL_RATE_FALLBACK_RETRY_COUNT_THR, + CL_RATE_FALLBACK_BA_PER_THR, + CL_RATE_FALLBACK_BA_NOT_RECEIVED_THR, + CL_RATE_FALLBACK_DISABLE_MCS, + + CL_RATE_FALLBACK_MAX, +}; + +struct cl_tcv_conf { + s8 ce_debug_level; + bool ce_radio_on; + bool ce_ps_ctrl_enabled; + bool ci_ieee80211h; + u8 ci_max_bss_num; + u8 ci_short_guard_interval; + u8 ci_max_mpdu_len; + u8 ci_max_ampdu_len_exp; + s8 ce_dsp_code[STR_LEN_32B]; + s8 ce_dsp_data[STR_LEN_32B]; + s8 ce_dsp_external_data[STR_LEN_32B]; + bool ci_uapsd_en; + bool ce_eirp_regulatory_op_en; + bool ce_eirp_regulatory_prod_en; + bool ci_agg_tx; + bool ci_agg_rx; + bool ce_txldpc_en; + bool ci_ht_rxldpc_en; + bool ci_vht_rxldpc_en; + bool ci_he_rxldpc_en; + bool ci_cs_required; + s8 ci_rx_sensitivity_prod[MAX_ANTENNAS]; + s8 ci_rx_sensitivity_op[MAX_ANTENNAS]; + bool ci_min_he_en; + u8 ce_cck_tx_ant_mask; + u8 ce_cck_rx_ant_mask; + u8 ce_rx_nss; + u8 ce_tx_nss; + u8 ce_num_antennas; + u16 ce_max_agg_size_tx; + u16 ce_max_agg_size_rx; + bool ce_rxamsdu_en; + u8 ce_txamsdu_en; + u16 ci_tx_amsdu_min_data_rate; + u8 ci_tx_sw_amsdu_max_packets; + u16 ci_tx_packet_limit; + u16 ci_sw_txhdr_pool; + u16 ci_amsdu_txhdr_pool; + u16 ci_tx_queue_size_agg; + u16 ci_tx_queue_size_single; + bool ci_tx_push_cntrs_stat_en; + bool ci_traffic_mon_en; + u16 ci_ipc_rxbuf_size[CL_RX_BUF_MAX]; + u16 ce_max_retry; + u8 ce_short_retry_limit; + u8 ce_long_retry_limit; + u8 ci_assoc_auth_retry_limit; + u8 ci_cap_bandwidth; + u32 ci_chandef_channel; + u8 ci_chandef_bandwidth; + bool ci_cck_in_hw_mode; + s8 ce_temp_comp_slope; + u32 ci_fw_dbg_severity; + u32 ci_fw_dbg_module; + u8 ci_lcu_dbg_cfg_inx; + u8 ci_dsp_lcu_mode; + u32 ci_hal_idle_to; + u32 ci_tx_ac0_to; + u32 ci_tx_ac1_to; + u32 ci_tx_ac2_to; + u32 ci_tx_ac3_to; + u32 ci_tx_bcn_to; + s8 ce_hardware_power_table[STR_LEN_256B]; + s8 ce_arr_gain[STR_LEN_32B]; + s8 ce_bf_gain_2_ant[STR_LEN_32B]; + s8 ce_bf_gain_3_ant[STR_LEN_32B]; + s8 ce_bf_gain_4_ant[STR_LEN_32B]; + s8 ce_bf_gain_5_ant[STR_LEN_32B]; + s8 ce_bf_gain_6_ant[STR_LEN_32B]; + s8 ce_ant_gain[STR_LEN_32B]; + s8 ce_ant_gain_36_64[STR_LEN_32B]; + s8 ce_ant_gain_100_140[STR_LEN_32B]; + s8 ce_ant_gain_149_165[STR_LEN_32B]; + s8 ci_min_ant_pwr[STR_LEN_32B]; + s8 ci_bw_factor[STR_LEN_32B]; + u8 ce_mcast_rate; + bool ce_dyn_mcast_rate_en; + bool ce_dyn_bcast_rate_en; + u8 ce_default_mcs_ofdm; + u8 ce_default_mcs_cck; + bool ce_prot_log_nav_en; + u8 ce_prot_mode; + u8 ce_prot_rate_format; + u8 ce_prot_rate_mcs; + u8 ce_prot_rate_pre_type; + u8 ce_bw_signaling_mode; + u8 ci_dyn_cts_sta_thr; + s8 ci_vns_pwr_limit; + u8 ci_vns_pwr_mode; + s8 ci_vns_rssi_auto_resp_thr; + s8 ci_vns_rssi_thr; + s8 ci_vns_rssi_hys; + u16 ci_vns_maintenance_time; + u16 ce_bcn_tx_path_min_time; + bool ci_backup_bcn_en; + bool ce_tx_txop_cut_en; + u8 ci_bcns_flushed_cnt_thr; + bool ci_phy_err_prevents_phy_dump; + u8 ci_tx_rx_delay; + u8 ci_fw_assert_time_diff_sec; + u8 ci_fw_assert_storm_detect_thd; + u32 ce_hw_assert_time_max; + u8 ce_bg_assert_print; + u8 ce_fw_watchdog_mode; + u8 ce_fw_watchdog_limit_count; + u32 ce_fw_watchdog_limit_time; + s8 ci_rx_remote_cpu_drv; + s8 ci_rx_remote_cpu_mac; + u16 ci_pending_queue_size; + u8 ce_tx_power_control; + bool ce_acs_coex_en; + u8 ci_dfs_initial_gain; + u8 ci_dfs_agc_cd_th; + u16 ci_dfs_long_pulse_min; + u16 ci_dfs_long_pulse_max; + s8 ce_dfs_tbl_overwrite[STR_LEN_64B]; + /* Power Per MCS values - 6g */ + s8 ce_ppmcs_offset_he_6g[WRS_MCS_MAX_HE]; + /* Power Per MCS values - 5g */ + s8 ce_ppmcs_offset_he_36_64[WRS_MCS_MAX_HE]; + s8 ce_ppmcs_offset_he_100_140[WRS_MCS_MAX_HE]; + s8 ce_ppmcs_offset_he_149_165[WRS_MCS_MAX_HE]; + s8 ce_ppmcs_offset_ht_vht_36_64[WRS_MCS_MAX_VHT]; + s8 ce_ppmcs_offset_ht_vht_100_140[WRS_MCS_MAX_VHT]; + s8 ce_ppmcs_offset_ht_vht_149_165[WRS_MCS_MAX_VHT]; + s8 ce_ppmcs_offset_ofdm_36_64[WRS_MCS_MAX_OFDM]; + s8 ce_ppmcs_offset_ofdm_100_140[WRS_MCS_MAX_OFDM]; + s8 ce_ppmcs_offset_ofdm_149_165[WRS_MCS_MAX_OFDM]; + /* Power Per MCS values - 24g */ + s8 ce_ppmcs_offset_he[WRS_MCS_MAX_HE]; + s8 ce_ppmcs_offset_ht[WRS_MCS_MAX_HT]; + s8 ce_ppmcs_offset_ofdm[WRS_MCS_MAX_OFDM]; + s8 ce_ppmcs_offset_cck[WRS_MCS_MAX_CCK]; + /* Power Per BW values - all bands */ + s8 ce_ppbw_offset[CHNL_BW_MAX]; + bool ce_power_offset_prod_en; + bool ci_bf_en; + u8 ci_bf_max_nss; + u16 ce_sounding_interval_coefs[SOUNDING_INTERVAL_COEF_MAX]; + u8 ci_rate_fallback[CL_RATE_FALLBACK_MAX]; + u16 ce_rx_pkts_budget; + u8 ci_band_num; + bool ci_mult_ampdu_in_txop_en; + u8 ce_wmm_aifsn[AC_MAX]; + u8 ce_wmm_cwmin[AC_MAX]; + u8 ce_wmm_cwmax[AC_MAX]; + u16 ce_wmm_txop[AC_MAX]; + u8 ci_su_force_min_spacing; + u8 ci_mu_force_min_spacing; + u8 ci_tf_mac_pad_dur; + u32 ci_cca_timeout; + u16 ce_tx_ba_session_timeout; + bool ci_motion_sense_en; + s8 ci_motion_sense_rssi_thr; + u8 ci_wrs_max_bw; + u8 ci_wrs_min_bw; + s8 ci_wrs_fixed_rate[WRS_FIXED_PARAM_MAX]; + u8 ce_he_mcs_nss_supp_tx[WRS_SS_MAX]; + u8 ce_he_mcs_nss_supp_rx[WRS_SS_MAX]; + u8 ce_vht_mcs_nss_supp_tx[WRS_SS_MAX]; + u8 ce_vht_mcs_nss_supp_rx[WRS_SS_MAX]; + u8 ci_pe_duration; + u8 ci_pe_duration_bcast; + u8 ci_gain_update_enable; + u8 ci_mcs_sig_b; + u8 ci_spp_ksr_value; + bool ci_rx_padding_en; + bool ci_stats_en; + bool ci_bar_disable; + bool ci_ofdm_only; + bool ci_hw_bsr; + bool ci_drop_to_lower_bw; + bool ci_force_icmp_single; + bool ce_wrs_rx_en; + u8 ci_hr_factor[CHNL_BW_MAX]; + bool ci_csd_en; + bool ci_signal_extension_en; + bool ci_vht_cap_24g; + u32 ci_tx_digital_gain; + u32 ci_tx_digital_gain_cck; + s8 ci_ofdm_cck_power_offset; + bool ci_mac_clk_gating_en; + bool ci_phy_clk_gating_en; + bool ci_imaging_blocker; + u8 ci_sensing_ndp_tx_chain_mask; + u8 ci_sensing_ndp_tx_bw; + u8 ci_sensing_ndp_tx_format; + u8 ci_sensing_ndp_tx_num_ltf; + u8 ci_calib_ant_tx[MAX_ANTENNAS]; + u8 ci_calib_ant_rx[MAX_ANTENNAS]; + s8 ci_cca_ed_rise_thr_dbm; + s8 ci_cca_ed_fall_thr_dbm; + u8 ci_cca_cs_en; + u8 ci_cca_modem_en; + u8 ci_cca_main_ant; + u8 ci_cca_second_ant; + u8 ci_cca_flag0_ctrl; + u8 ci_cca_flag1_ctrl; + u8 ci_cca_flag2_ctrl; + u8 ci_cca_flag3_ctrl; + s8 ci_cca_gi_rise_thr_dbm; + s8 ci_cca_gi_fall_thr_dbm; + s8 ci_cca_gi_pow_lim_dbm; + u16 ci_cca_ed_en; + u8 ci_cca_gi_en; + bool ci_rx_he_mu_ppdu; + bool ci_fast_rx_en; + u8 ci_distance_auto_resp_all; + u8 ci_distance_auto_resp_msta; + bool ci_fw_disable_recovery; + bool ce_listener_en; + bool ci_tx_delay_tstamp_en; + u8 ci_calib_tx_init_tx_gain[MAX_ANTENNAS]; + u8 ci_calib_tx_init_rx_gain[MAX_ANTENNAS]; + u8 ci_calib_rx_init_tx_gain[MAX_ANTENNAS]; + u8 ci_calib_rx_init_rx_gain[MAX_ANTENNAS]; + u8 ci_calib_conf_rx_gain_upper_limit; + u8 ci_calib_conf_rx_gain_lower_limit; + u8 ci_calib_conf_tone_vector_20bw[IQ_NUM_TONES_REQ]; + u8 ci_calib_conf_tone_vector_40bw[IQ_NUM_TONES_REQ]; + u8 ci_calib_conf_tone_vector_80bw[IQ_NUM_TONES_REQ]; + u8 ci_calib_conf_tone_vector_160bw[IQ_NUM_TONES_REQ]; + u32 ci_calib_conf_gp_rad_trshld; + u32 ci_calib_conf_ga_lin_upper_trshld; + u32 ci_calib_conf_ga_lin_lower_trshld; + u8 ci_calib_conf_singletons_num; + u16 ci_calib_conf_rampup_time; + u16 ci_calib_conf_lo_coarse_step; + u16 ci_calib_conf_lo_fine_step; +#ifdef CONFIG_CL8K_EEPROM_STM24256 + u16 ci_calib_eeprom_channels_20mhz[EEPROM_CALIB_DATA_ELEM_NUM_20MHZ_TCV0]; + u16 ci_calib_eeprom_channels_40mhz[EEPROM_CALIB_DATA_ELEM_NUM_40MHZ_TCV0]; + u16 ci_calib_eeprom_channels_80mhz[EEPROM_CALIB_DATA_ELEM_NUM_80MHZ_TCV0]; + u16 ci_calib_eeprom_channels_160mhz[EEPROM_CALIB_DATA_ELEM_NUM_160MHZ_TCV0]; +#endif + u16 ci_mesh_basic_rates[MESH_BASIC_RATE_MAX]; +}; + +int cl_tcv_config_read(struct cl_hw *cl_hw); +u8 cl_tcv_config_get_num_ap(struct cl_hw *cl_hw); +int cl_tcv_config_alloc(struct cl_hw *cl_hw); +void cl_tcv_config_free(struct cl_hw *cl_hw); +void cl_tcv_config_validate_calib_params(struct cl_hw *cl_hw); + +#endif /* CL_TCV_CONFIG_H */ From patchwork Tue May 24 11:34:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576840 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 D417FC433EF for ; Tue, 24 May 2022 11:40:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236086AbiEXLkn (ORCPT ); Tue, 24 May 2022 07:40:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236939AbiEXLkb (ORCPT ); Tue, 24 May 2022 07:40:31 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2071.outbound.protection.outlook.com [40.107.20.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC3D33C734 for ; Tue, 24 May 2022 04:39:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Utc5RqpMHigRTnRoi35rkH9tjIZfMvSK4LtM3ImrGpgG62YkbBftiJgFzyE0le/XzxWHwZQ2TPmFuvGsE7FZSdjttMoAJqe7s2tPtc/X8ajoqSQOVq+H8hbC5cHiiy10nGQ17UXCIXN54UE/hmDiozdLEyb6usIhTCe6OI9wvlb3ySnfxqNWWObPSskW+Ym5iVs0FGXnuiG9KTzCV8djurCfpTPDuku+IoLz6ByxDvhIGrgcbWkR6Z2toMfd6HfbyNt/AuJ5v/zKwhHzU7juobvvd1qovv1f3pC8I3VUCoTbWNDJry8XS46ndhQLw+ttqcJ7+DuA44EZP87jZoVTWA== 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=DgWPC1KCI3G9ezS9UigUn+P3W1nhuO+mGYJ8F5BubbA=; b=hoHisof7qu0X09fDELSGix804yMH98Op59CuLlnvCe1mq0EzlUETUaCJDJ+iWycW4NRL3/Nkc4H4uSjucNAqTxwlaSMjoRdUls33O63KtkVnyzFZvsjqCQeAW8OwlcJYWbHlLvYgp//jCrJXTO/z74l4/zAL0G63XVNzESYW809TqmuhAQe4EEHWVSZtRuSTOU0CnOQRNJOW+Y8odCsZ9gXdpr2AjAMdOm1swJiJp66xMyUnW6tTP46PW6edh8arqomhC17fpqdv3bAyU1Vx1q1RWmeqluPEFITLthFFXX6mHPqpp4TZfrmQoHU75JW2eFzW6SGbZuoFTmEhrc0JEw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DgWPC1KCI3G9ezS9UigUn+P3W1nhuO+mGYJ8F5BubbA=; b=Pq5gHyRWRs5nIk7traMkVmIoy4dN872hMQIc02EvSO7XRR86iBdWanqtyNp5WICLX32isYyAhYvG8u65qp73jgdB2V3ji22nj8P63jrbXhxNsDzVUCK2FnlUsjeGAk8umXdyqT4Ede+hO7EjYK8G1vJto79GpJdxfZ3uNIMtq24= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:29 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:29 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 80/96] cl8k: add temperature.c Date: Tue, 24 May 2022 14:34:46 +0300 Message-Id: <20220524113502.1094459-81-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ddd1f043-20df-48fa-b8ac-08da3d79fae0 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: pg5JyQgwArSC8+/Ts/C7eq9st4tao9+RHvyKgOh0/hxHNTfd+ajOLsPoNDKMp4ZrPDFZgJeaPEHNkRNFroe+MLVJ+zJAx/Q+UL8Ny9tdiw4IVD7B8ItiUJ8cy7qF9q77Le7TUT8zwho668avEy5nJRjR6uByJv/LPL4y7GGV2olh/dkdU/yNRYL8Iq77vyRLyOWPfzr06OvBi0P/mLRw/np9Mw7+kmsN/9pTdiYFn3xY4tKaISsz0qJHClEzT5rsiZl3l6T5mfDT3KbS06KDSApjcqntYb0g0mQZNn4Ta4mMmx0ng1opFOobu7JUsFhGKun/SoPyXfNo7lYUNr7l9j2Vko3OONepS4WuhRywx79p7ADuhnz3e8nwa8/J3zbWnFRQ6R43+uwi1U8u6714Q5DMtTllTL+AHKW7Yj1uNy0jh+k312TQkNujmx7o1NKrBDFIhQH4JECC6+g9dLuu6vF87/3RF+hHs2q3lVwYH+PjJOCGW/Eg7BW1GcBwHczxNA9pbHkWUa9v1yNYj4MwxwtXSPlR1KViw8wvtE5+ikZM7hoFoGOxCdJ3IEhes3gN37w9ndmGCQAXw57Sbq0h9h2V4C8yJXpJng5NHTOMjMaOP+XSEP2eLadKp43YYm4y3qp6HHC8OaoTa3ZOddgl7syH6BAvBT1v4Dg2ZBq304m1lu6VUmKO18jMY5ZJhzJ/d5DERZgQJf2UHlbciB1xqrtbqak74CyMka6ltc+mvDs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: iI0cfWGiL20NybzQii5AO8vPsjzVVz1AT0cAWxVDTdMWIIYk8R5eFIx9OH4F0teBFwV1mXUcWSIQ84cZNnMpgUNxIsbNoJjsJsXc9k6bQhjpoY2AnhI6k/FEHz0ioZF4nRIgXOo/o+MPhaCZtRar6L8H5TD6Ek33f5EBMjbCTzd/A2DeAZkw25ztSYUwt4E1+fXq74bbzovGOikKwmjn8yfTlKwh7uTthkemIDDn5TgNJNcARRLhzZg1WdBnagHsJBlA9MpdmoVHUeIzlCvdKXmPbeRxP4hGbvKWxsz95+EB5MKK6wW3hmVpwtXGPDJb/kCM91akSfvy31ObMSvcn5vbGTe5igzZFRFrUzfUQR0GxTCjzHxKT/taVp3NIQxpEleBHFFNFcVf6Dx8wix/oBcLxfp+NKViQNhx4htUm7KNbmY7cmuL05Q5fwaOiyGpc/2OsEiGj6IbtwSzWJDSKLOtp1uL/9kwWaUVN1Yja8ftwpjDnmTwZ795RG93e5griczUdc0U7xns9Zu3I7IQiAngPLXmS35YO7R6M0ft1N2DbHPlaK+r2qOg+P3IJR9z2aRjPm3DdSc/cY0QvVzsIxo9cU0RgyahI5r9kqq/HtWPOdqc/HBkUsOREr/JbkF+b2Sk2t47AIOTv065BFkk19f+idnc6GPjwJlvJ69EoXFZa+ixVjpO/fi3xEiYVANYtQZMKzwsrg4X2nwuOf4Ca4cKeuH4piROwSu/Dq94ug+zVK47P/Wysdd8qJsCXOy52O5sIFnpUjl7SRwVtYHnMVa+GfVZGW7/b8nsp4kCl0MOmKpN7YftIEjsYImxoxxjrc4Fea1BjzwK2FnijZiU06ZTi+w6U3S46Ig4qNhql2ajNTms75ilvXNV6OlrMfjAeCvo4ksibaC3RAby1ZI/sHgVMDXjXJ5gg93BVqRHDFsayqu1BJnNQ5EAHi7zCFyak7GNRLTBiegfSPYeP+gZRKEGA3klUALbn1Xa6Wxaulf97iyKqjFMpbAXaSWsiy/RtiX7ecGJGFl7+ZNXn0cbJoXvanJfvkerr/rUAHmNbTP0GXfP9IWAxJ8pK4joTyLydXa/qsZqS9Pn7j3Co0vMABgfyF6cvafTbLB/mCBow0ayMrrgFRGUOyDarCzCjVWiOlGPcPI9rW/j+1tvec8ZmvtGgsxbDilOBoU53WKiuGRHYz6gZ+BTuHUbPB95oKAe7Wh0oLTMoFVxP8hI8flKnD4vS07O4yYX00hUAt2oM/U+zNFF8rrcVhYj9NIS8uuumAvoVDvcMJHZ/lHE/UiBB/Y913iCONdqcSbQW2qDqChK64yPJGPr4PKKYc+vz4+5Ix8Y1rA6vOchgZQYC1zmAIwtksE0cywUX9RpYMD//YMBA3MyFMfgA67E0FRXTqnh83b6OjXsBY0Iin6SmGP54RmZUHWaqKNVtBNvy1TB2Uzmw3EnUzZE/M7VU4bkDZM1hFd4CL4N0EjlJ+WQSMNU8/jF9UTe0EHpHD3831NPbGdFwfJQcGL78cEvj1Hgphqu41FFYxS+y+rGLVv6BQ1T6WhHmD6ji1KtdkB99XfdGorH1GTDsQTbav8wqzNL1YPfd42iu/iDj1xyZTJr/4C1JTBGYOTLXoY2lfgkndUH8J3umRCOLI+1+yHWtQxoTY4KKsCnjaiHamqXKOT55t40+Fw+l1ENOGON5kfBYjKwQZ+ej7oK5NAVJssX/xIDuZCzfbB6Os5Pabkad9rnT2yy+4ad7lshb96ttHPGvm+2RzE= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ddd1f043-20df-48fa-b8ac-08da3d79fae0 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:53.7433 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9Ea5kyyFvIX2OOyRn7tsy0e2zGeFL47TG36cIR9pR6UonBjp7zpkXb0M4qTOvUtIpXh/z0dMR9V8mhvs6dVLmQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/temperature.c | 634 ++++++++++++++++++ 1 file changed, 634 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/temperature.c diff --git a/drivers/net/wireless/celeno/cl8k/temperature.c b/drivers/net/wireless/celeno/cl8k/temperature.c new file mode 100644 index 000000000000..f3c773d957f6 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/temperature.c @@ -0,0 +1,634 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "hw.h" +#include "e2p.h" +#include "channel.h" +#include "power.h" +#include "debug.h" +#include "utils.h" +#include "radio.h" +#include "temperature.h" + +#define TEMP_DIFF_INVALID 0x7F + +#define TEMPERATURE_MIN 0 +#define TEMPERATURE_MAX 127 + +#define DUTY_CYCLE_MAX 100 +#define DUTY_CYCLE_MIN 20 +#define DUTY_CYCLE_STEP 20 + +#define TEMP_MEASUREMENT_TIMEOUT msecs_to_jiffies(500) + +static int cl_temperature_read_fw(struct cl_hw *cl_hw, enum cl_temp_mode desired_temp_mode, + u16 *raw_bits) +{ + u8 retval = 0; + struct mm_anamon_read_cfm *cfm; + + if (cl_msg_tx_anamon_read(cl_hw, ANAMON_MODE_TEMPERATURE, desired_temp_mode, 0) != 0) { + cl_dbg_err(cl_hw, "cl_msg_tx_anamon_read failed\n"); + cl_msg_tx_free_cfm_params(cl_hw, MM_ANAMON_READ_CFM); + return -1; + } + + cfm = (struct mm_anamon_read_cfm *)(cl_hw->msg_cfm_params[MM_ANAMON_READ_CFM]); + if (!cfm) + return -ENOMSG; + + retval = cfm->retval; + *raw_bits = ((le16_to_cpu(cfm->raw_bits_data_0) + le16_to_cpu(cfm->raw_bits_data_1)) / 2); + cl_msg_tx_free_cfm_params(cl_hw, MM_ANAMON_READ_CFM); + + return retval ? 0 : -1; +} + +static s16 cl_raw_bits_to_temperature(u16 raw_bits, enum cl_temp_mode desired_temp_mode) +{ + s16 adcmv = cl_adc_to_mv(raw_bits); + + /* Calculation of external thermistor */ + if (desired_temp_mode == TEMP_MODE_EXTERNAL) { + /* + * External-temperature calculation: + * Ext_tmp = -196 * adcv ^ 3 + 403 * adcv ^ 2 - 356 * adcv + 146 + * + * Ext_tmp = -196 * (adcmv / 1000) ^ 3 + + * 403 * (adcmv / 1000) ^ 2 - + * 356 * (adcmv / 1000) + + * 146 + * + * Ext_tmp = (-196 * adcmv ^ 3 + + * 403000 * adcmv ^ 2 - + * 356000000 * adcmv + + * 146000000000) / 1000000000 + */ + return (s16)div_s64(-196ULL * adcmv * adcmv * adcmv + + 403000ULL * adcmv * adcmv - + 356000000ULL * adcmv + + 146000000000ULL, + 1000000000); + } + + /* Calculation of internal thermistor - ADCmv * slope - 163 (slope=0.290) */ + if (desired_temp_mode == TEMP_MODE_INTERNAL) + return ((adcmv * 29) / 100) - 163; + + return 0; +} + +static void cl_temperature_set_power_offset(struct cl_hw *cl_hw, s8 power_offset) +{ + s8 total_pwr_offset[MAX_ANTENNAS] = {0}; + u8 chan_idx = cl_channel_to_index(cl_hw, cl_hw->channel); + u8 i = 0; + + cl_hw->temp_comp_db.power_offset = power_offset; + + if (chan_idx == INVALID_CHAN_IDX) + goto out; + + for (i = 0; i < MAX_ANTENNAS; i++) { + total_pwr_offset[i] = + (cl_hw->tx_pow_info[chan_idx][i].offset + + POWER_OFFSET_RES * power_offset); + } + +out: + cl_msg_tx_set_ant_pwr_offset(cl_hw, total_pwr_offset); +} + +static void cl_temperature_comp_tcv(struct cl_chip *chip, struct cl_hw *cl_hw, s16 temp_internal) +{ + struct cl_temp_comp_db *temp_comp_db = &cl_hw->temp_comp_db; + s8 new_power_offset = 0; + + /* Accumulate temperature delta */ + temp_comp_db->acc_temp_delta += (temp_internal - temp_comp_db->calib_temperature); + + /* Check if it is time to make a new decision */ + if ((chip->temperature.comp_iterations % CL_TEMP_COMP_ITERATIONS) != 0) + return; + + /* Average the temperature delta over the last CL_TEMP_COMP_ITERATIONS samples */ + temp_comp_db->avg_temp_delta = DIV_ROUND_CLOSEST(temp_comp_db->acc_temp_delta, + CL_TEMP_COMP_ITERATIONS); + + /* Reset accumulated temp delta */ + temp_comp_db->acc_temp_delta = 0; + + new_power_offset = (s8)DIV_ROUND_CLOSEST(temp_comp_db->avg_temp_delta * + cl_hw->conf->ce_temp_comp_slope, 100); + + if (temp_comp_db->power_offset == new_power_offset) + return; + + cl_dbg_trace(cl_hw, "calib_temperature %d, avg_temp_delta %d, power_offset %d\n", + temp_comp_db->calib_temperature, + temp_comp_db->avg_temp_delta, + new_power_offset); + + cl_temperature_set_power_offset(cl_hw, new_power_offset); +} + +static void cl_temperature_comp(struct cl_chip *chip, struct cl_hw *cl_hw) +{ + struct cl_temperature *temperature = &chip->temperature; + s16 temp_internal = 0; + + if (!chip->conf->ce_temp_comp_en) + return; + + temp_internal = cl_temperature_read(cl_hw, TEMP_MODE_INTERNAL); + temperature->comp_iterations++; + + cl_dbg_chip_trace(chip, "comp_iterations = %u, temp_internal = %d\n", + (temperature->comp_iterations % CL_TEMP_COMP_ITERATIONS), temp_internal); + + if (cl_chip_is_tcv0_enabled(chip)) + cl_temperature_comp_tcv(chip, chip->cl_hw_tcv0, temp_internal); + + if (cl_chip_is_tcv1_enabled(chip)) + cl_temperature_comp_tcv(chip, chip->cl_hw_tcv1, temp_internal); +} + +static void cl_temperature_tx_duty_cycle(struct cl_chip *chip, u8 duty_cycle) +{ + u16 periodic_tx_time_on = chip->conf->ce_temp_protect_tx_period_ms * duty_cycle / 100; + u16 periodic_tx_time_off = chip->conf->ce_temp_protect_tx_period_ms - periodic_tx_time_on; + + if (cl_chip_is_tcv0_enabled(chip)) + cl_msg_tx_start_periodic_tx_time(chip->cl_hw_tcv0, + periodic_tx_time_off, periodic_tx_time_on); + + if (cl_chip_is_tcv1_enabled(chip)) + cl_msg_tx_start_periodic_tx_time(chip->cl_hw_tcv1, + periodic_tx_time_off, periodic_tx_time_on); +} + +static void cl_temperature_protect_radio_off(struct cl_chip *chip, s16 temp_avg) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + struct cl_chip_conf *conf = chip->conf; + + if (temp_protect_db->force_radio_off) + return; + + cl_radio_off_chip(chip); + temp_protect_db->force_radio_off = true; + cl_dbg_chip_verbose(chip, "temperature [%d] >= radio off threshold [%d] --> radio off!\n", + temp_avg, conf->ce_temp_protect_radio_off_th); +} + +static void cl_temperature_protect_radio_on(struct cl_chip *chip, s16 temp_avg) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + struct cl_chip_conf *conf = chip->conf; + s16 temp_thr = conf->ce_temp_protect_radio_off_th - CL_TEMP_PROTECT_RADIO_OFF_HYST; + + if (temp_avg >= temp_thr) + return; + + cl_radio_on_chip(chip); + temp_protect_db->force_radio_off = false; + cl_dbg_chip_verbose(chip, "temperature [%d] < radio off threshold - hysteresis [%d] " + "--> radio on!\n", + temp_avg, temp_thr); +} + +static void cl_temperature_protect_dec_duty_cycle(struct cl_chip *chip, s16 temp_avg) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + struct cl_chip_conf *conf = chip->conf; + + if (temp_protect_db->duty_cycle == DUTY_CYCLE_MIN) + return; + + temp_protect_db->duty_cycle -= DUTY_CYCLE_STEP; + cl_temperature_tx_duty_cycle(chip, temp_protect_db->duty_cycle); + cl_dbg_chip_warn(chip, + "temperature [%d] > protect_th_max [%d] --> decrease duty cycle [%u]!\n", + temp_avg, conf->ce_temp_protect_th_max, temp_protect_db->duty_cycle); +} + +static void cl_temperature_protect_inc_duty_cycle(struct cl_chip *chip, s16 temp_avg) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + struct cl_chip_conf *conf = chip->conf; + + if (temp_protect_db->duty_cycle == DUTY_CYCLE_MAX) + return; + + temp_protect_db->duty_cycle += DUTY_CYCLE_STEP; + cl_temperature_tx_duty_cycle(chip, temp_protect_db->duty_cycle); + cl_dbg_chip_warn(chip, + "temperature [%d] < protect_th_min [%d] --> increase duty cycle [%u]!\n", + temp_avg, conf->ce_temp_protect_th_min, temp_protect_db->duty_cycle); +} + +static void cl_temperature_protect_decision(struct cl_chip *chip, s16 temp_avg) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + struct cl_chip_conf *conf = chip->conf; + + /* Test mode - force test_mode_duty_cycle */ + if (unlikely(temp_protect_db->test_mode_duty_cycle != DUTY_CYCLE_MAX)) { + cl_temperature_tx_duty_cycle(chip, temp_protect_db->test_mode_duty_cycle); + return; + } + + /* Temperature protection logic: + * + * If the temperature is greater or equal to the radio off threshold + * then set the radio off. + * If the temperature is below the (radio off threshold - hysteresis [10]) + * then set the radio on again. + * + * Any time the temperature is greater than the max threshold then we + * decrease the duty cycle. + * Any time the temperature is below the min threshold then we increase + * the duty cycle. + */ + if (temp_avg >= conf->ce_temp_protect_radio_off_th) { + cl_temperature_protect_radio_off(chip, temp_avg); + return; + } + + if (temp_protect_db->force_radio_off) { + cl_temperature_protect_radio_on(chip, temp_avg); + return; + } + + if (temp_avg > conf->ce_temp_protect_th_max) { + cl_temperature_protect_dec_duty_cycle(chip, temp_avg); + return; + } + + if (temp_avg < chip->conf->ce_temp_protect_th_min) { + cl_temperature_protect_inc_duty_cycle(chip, temp_avg); + return; + } +} + +static s16 cl_temperature_avg_protect(struct cl_temp_protect_db *temp_protect_db) +{ + /* Calculate average of last_samples */ + u8 i; + s32 temp_avg = 0; + + for (i = 0; i < CL_TEMP_PROTECT_NUM_SAMPLES; i++) + temp_avg += temp_protect_db->last_samples[i]; + + return (s16)(temp_avg / CL_TEMP_PROTECT_NUM_SAMPLES); +} + +static void cl_temperature_protect_handle_read(struct cl_chip *chip, s16 temp) +{ + struct cl_temp_protect_db *temp_protect_db = &chip->temperature.protect_db; + unsigned long curr_time = jiffies_to_msecs(jiffies); + unsigned long delta_time = curr_time - temp_protect_db->last_timestamp; + + /* Add current read */ + temp_protect_db->last_samples[temp_protect_db->curr_idx] = temp; + temp_protect_db->curr_idx = (temp_protect_db->curr_idx + 1) % CL_TEMP_PROTECT_NUM_SAMPLES; + + if (delta_time >= CL_TEMP_PROTECT_INTERVAL_MS) { + s16 temp_avg = cl_temperature_avg_protect(temp_protect_db); + + cl_dbg_chip_trace(chip, "temp_avg = %d, delta_time = %lu\n", temp_avg, delta_time); + cl_temperature_protect_decision(chip, temp_avg); + temp_protect_db->last_timestamp = curr_time; + } +} + +static void cl_temperature_protect(struct cl_chip *chip, struct cl_hw *cl_hw) +{ + s16 protect_temp = 0; + struct cl_chip_conf *conf = chip->conf; + + switch (conf->ce_temp_protect_en) { + case TEMP_PROTECT_OFF: + return; + case TEMP_PROTECT_INTERNAL: + protect_temp = cl_temperature_read(cl_hw, TEMP_MODE_INTERNAL) + + conf->ce_temp_protect_delta; + break; + case TEMP_PROTECT_EXTERNAL: + protect_temp = cl_temperature_read(cl_hw, TEMP_MODE_EXTERNAL) + + conf->ce_temp_protect_delta; + break; + case TEMP_PROTECT_DIFF: + protect_temp = cl_temperature_read(cl_hw, TEMP_MODE_INTERNAL) - + chip->temperature.diff_internal_external + conf->ce_temp_protect_delta; + break; + } + + cl_temperature_protect_handle_read(chip, protect_temp); +} + +static int cl_e2p_read_temp_diff(struct cl_chip *chip, s8 *temp_diff) +{ + /* Read temp_diff from eeprom */ + return cl_e2p_read(chip, temp_diff, SIZE_GEN_TEMP_DIFF, ADDR_GEN_TEMP_DIFF); +} + +static int cl_e2p_write_temp_diff(struct cl_chip *chip, s8 temp_diff) +{ + /* Writing temp_diff to eeprom */ + return cl_e2p_write(chip, (u8 *)&temp_diff, SIZE_GEN_TEMP_DIFF, ADDR_GEN_TEMP_DIFF); +} + +static int cl_temperature_diff_update(struct cl_hw *cl_hw) +{ + s8 temp_diff = cl_temperature_read(cl_hw, TEMP_MODE_INTERNAL) - + cl_temperature_read(cl_hw, TEMP_MODE_EXTERNAL); + + if (cl_e2p_write_temp_diff(cl_hw->chip, temp_diff)) { + cl_dbg_err(cl_hw, "Error occurred while writing temperature diff to EEPROM.\n"); + return -1; + } + + cl_hw->chip->temperature.diff_internal_external = temp_diff; + return 0; +} + +static struct cl_hw *cl_init_measurement(struct cl_chip *chip) +{ + struct cl_hw *cl_hw = NULL; + + mutex_lock(&chip->temperature.hw_lock); + cl_hw = cl_chip_is_tcv0_enabled(chip) ? chip->cl_hw_tcv0 : chip->cl_hw_tcv1; + if (cl_hw && test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) && + !(cl_hw->conf && cl_hw->conf->ce_listener_en)) + set_bit(cl_hw->tcv_idx, &chip->temperature.used_hw_map); + else + cl_hw = NULL; + mutex_unlock(&chip->temperature.hw_lock); + + return cl_hw; +} + +static void cl_deinit_measurement(struct cl_hw *cl_hw) +{ + struct cl_temperature *temperature = &cl_hw->chip->temperature; + + clear_bit(cl_hw->tcv_idx, &temperature->used_hw_map); + wake_up(&temperature->measurement_done); +} + +void cl_temperature_wait_for_measurement(struct cl_chip *chip, u8 tcv_idx) +{ + struct cl_temperature *temperature = &chip->temperature; + int timeout = 0; + + mutex_lock(&temperature->hw_lock); + if (!test_bit(tcv_idx, &temperature->used_hw_map)) + goto exit; + + timeout = wait_event_timeout(temperature->measurement_done, + !test_bit(tcv_idx, &temperature->used_hw_map), + TEMP_MEASUREMENT_TIMEOUT); + WARN_ONCE(timeout != 0, "Measurment timeout reached!\n"); + +exit: + mutex_unlock(&temperature->hw_lock); +} + +static int cl_temperature_kthread(void *arg) +{ + struct cl_chip *chip = (struct cl_chip *)arg; + struct cl_hw *cl_hw = NULL; + unsigned long timeout = msecs_to_jiffies(CL_TEMPERATURE_TIMER_INTERVAL_MS); + + while (!kthread_should_stop()) { + cl_hw = cl_init_measurement(chip); + if (cl_hw) { + cl_temperature_comp(chip, cl_hw); + cl_temperature_protect(chip, cl_hw); + cl_deinit_measurement(cl_hw); + } + + if (wait_event_timeout(chip->temperature.wait_done, + kthread_should_stop(), timeout)) { + cl_dbg_chip_trace(chip, "exit temperature kthread\n"); + return 0; + } + } + + return 0; +} + +static void cl_temperature_recovery_protect(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + + if (chip->conf->ce_temp_protect_en != TEMP_PROTECT_OFF) { + u8 duty_cycle = chip->temperature.protect_db.duty_cycle; + + if (duty_cycle < DUTY_CYCLE_MAX) { + u16 periodic_tx_time_on = + chip->conf->ce_temp_protect_tx_period_ms * duty_cycle / 100; + u16 periodic_tx_time_off = + chip->conf->ce_temp_protect_tx_period_ms - periodic_tx_time_on; + + cl_msg_tx_start_periodic_tx_time(cl_hw, periodic_tx_time_off, + periodic_tx_time_on); + } + } +} + +static void cl_temperature_recovery_comp(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + s8 power_offset = cl_hw->temp_comp_db.power_offset; + + if (!chip->conf->ce_temp_comp_en) + return; + + if (power_offset) + cl_temperature_set_power_offset(cl_hw, power_offset); +} + +void cl_temperature_init(struct cl_chip *chip) +{ + struct cl_temperature *temperature = &chip->temperature; + struct cl_temp_protect_db *temp_protect_db = &temperature->protect_db; + unsigned long curr_time_ms = jiffies_to_msecs(jiffies); + + init_waitqueue_head(&temperature->wait_done); + init_waitqueue_head(&temperature->measurement_done); + + mutex_init(&temperature->mutex); + mutex_init(&temperature->hw_lock); + + temperature->internal_last = UNCALIBRATED_TEMPERATURE; + temperature->internal_read_timestamp = curr_time_ms; + temperature->external_last = UNCALIBRATED_TEMPERATURE; + temperature->external_read_timestamp = curr_time_ms; + + /* Temp_protect_db init */ + temp_protect_db->duty_cycle = DUTY_CYCLE_MAX; + temp_protect_db->test_mode_duty_cycle = DUTY_CYCLE_MAX; + temp_protect_db->last_timestamp = curr_time_ms; + + temperature->kthread = kthread_run(cl_temperature_kthread, + chip, + "cl_temperature_kthread_%u", + chip->idx); + if (IS_ERR(temperature->kthread)) { + cl_dbg_chip_err(chip, "Failed to create temperature kthread\n"); + temperature->kthread = NULL; + } +} + +void cl_temperature_close(struct cl_chip *chip) +{ + struct cl_temperature *temperature = &chip->temperature; + + if (temperature->kthread) { + cl_dbg_chip_trace(chip, "stopping temperature kthread\n"); + if (kthread_stop(temperature->kthread) != -EINTR) + wake_up(&temperature->wait_done); + + temperature->kthread = NULL; + } +} + +s8 cl_temperature_read(struct cl_hw *cl_hw, enum cl_temp_mode mode) +{ + u16 raw_bits = 0; + s16 temp_val = 0; + unsigned long curr_time = jiffies_to_msecs(jiffies); + unsigned long diff_time = 0; + struct cl_chip *chip = cl_hw->chip; + struct cl_temperature *temperature = &chip->temperature; + + if (!IS_REAL_PHY(chip)) + return UNCALIBRATED_TEMPERATURE; + + mutex_lock(&temperature->mutex); + + switch (mode) { + case TEMP_MODE_INTERNAL: + diff_time = curr_time - temperature->internal_read_timestamp; + if (diff_time <= CL_TEMPERATURE_UPDATE_INTERVAL_MS) { + temp_val = temperature->internal_last; + cl_dbg_chip_trace(chip, "Return last internal temperature %d\n", temp_val); + goto read_out; + } + break; + case TEMP_MODE_EXTERNAL: + diff_time = curr_time - temperature->external_read_timestamp; + if (diff_time <= CL_TEMPERATURE_UPDATE_INTERVAL_MS) { + temp_val = temperature->external_last; + cl_dbg_chip_trace(chip, "Return last external temperature %d\n", temp_val); + goto read_out; + } + break; + default: + cl_dbg_chip_err(chip, "Invalid temperature mode %d\n", mode); + goto read_err; + } + + if (cl_temperature_read_fw(cl_hw, mode, &raw_bits)) { + cl_dbg_chip_err(chip, "Temperature read failed\n"); + goto read_err; + } + + temp_val = cl_raw_bits_to_temperature(raw_bits, mode); + + if (temp_val > TEMPERATURE_MAX || temp_val < TEMPERATURE_MIN) { + cl_dbg_chip_err(chip, "Invalid temperature value %d\n", temp_val); + goto read_err; + } + + /* Update temperature read db */ + if (mode == TEMP_MODE_INTERNAL) { + temperature->internal_last = temp_val; + temperature->internal_read_timestamp = jiffies_to_msecs(jiffies); + cl_dbg_chip_trace(chip, "Read and save internal temperature %d\n", temp_val); + } else { + temperature->external_last = temp_val; + temperature->external_read_timestamp = jiffies_to_msecs(jiffies); + cl_dbg_chip_trace(chip, "Read and save external temperature %d\n", temp_val); + } + +read_out: + mutex_unlock(&temperature->mutex); + return temp_val; + +read_err: + /* If temperature read failed return the last valid value */ + mutex_unlock(&temperature->mutex); + + return (mode == TEMP_MODE_INTERNAL) ? + temperature->internal_last : temperature->external_last; +} + +void cl_temperature_recovery(struct cl_hw *cl_hw) +{ + cl_temperature_recovery_protect(cl_hw); + cl_temperature_recovery_comp(cl_hw); +} + +int cl_temperature_diff_e2p_read(struct cl_hw *cl_hw) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_temperature *temperature = &chip->temperature; + + if (cl_e2p_read_temp_diff(chip, &temperature->diff_internal_external) || + temperature->diff_internal_external == TEMP_DIFF_INVALID) { + if (cl_temperature_diff_update(cl_hw)) + return -1; + + cl_dbg_chip_verbose(chip, "Temperature difference: Internal - External = %d\n", + temperature->diff_internal_external); + } + + return 0; +} + +s16 cl_temperature_calib_calc(struct cl_hw *cl_hw, u16 raw_bits) +{ + struct cl_chip *chip = cl_hw->chip; + s16 temperature = cl_raw_bits_to_temperature(raw_bits, TEMP_MODE_INTERNAL) + + chip->conf->ce_temp_protect_delta; + + if (temperature >= TEMPERATURE_MIN && temperature <= TEMPERATURE_MAX) + return temperature; + + cl_dbg_chip_err(chip, "Invalid temperature = %d\n", temperature); + + return (chip->temperature.internal_last + chip->conf->ce_temp_protect_delta); +} + +void cl_temperature_comp_update_calib(struct cl_hw *cl_hw) +{ + u8 chan_idx = cl_channel_to_index(cl_hw, cl_hw->channel); + u8 ant, ant_cnt = 0; + s16 total_temp = 0; + struct cl_tx_power_info *info = NULL; + + if (unlikely(chan_idx == INVALID_CHAN_IDX)) { + cl_dbg_err(cl_hw, "Unsupported frequency %u\n", cl_hw->center_freq); + return; + } + + info = &cl_hw->tx_pow_info[chan_idx][0]; + + /* Sum up the temperature of all phys */ + for (ant = 0; ant < MAX_ANTENNAS && ant_cnt < cl_hw->num_antennas; ant++) { + if (!(cl_hw->mask_num_antennas & BIT(ant))) + continue; + + total_temp += info[ant].temperature; + ant_cnt++; + } + + /* Average the total temperature and update chan_params */ + cl_hw->temp_comp_db.calib_temperature = DIV_ROUND_CLOSEST(total_temp, cl_hw->num_antennas); +} + From patchwork Tue May 24 11:34:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576827 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 CAC58C433FE for ; Tue, 24 May 2022 11:42:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236981AbiEXLmT (ORCPT ); Tue, 24 May 2022 07:42:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237003AbiEXLmO (ORCPT ); Tue, 24 May 2022 07:42:14 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2050.outbound.protection.outlook.com [40.107.20.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A90450440 for ; Tue, 24 May 2022 04:41:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ObfeQgQL7H+WfFGYFUiSAB7vwG4nuWtpATMEJrCD4hMBkVkvwudSQ4KkYR16Gz+htjZL7tGrCNa4fnAawCp0m8DDUgecNSQKXmgJsSsFGHG4sajNpc0EfxD+wTg+5sJhY38I6TrOBDDC9xSDgFMnrdhBFSRXhTniqCtdKvFgC/Q1/6ZTzkRxkbLFg7gLB63Mj4zz3LYQqOvQ5f2I+hV/Akv+lCNkvY6zHYHjZK9GvMjXKOyBjTYRJAQNbB7QOPuwYF8/7oUy1GPYHKgHMLOxS3rgR0kf3Ugxfce5nQogl/6yUdAGlaD46N/q6DSQQ2RpLYpZ4TRVd8e3JeAMaB9TAg== 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=B1TUN//VIfhqSrNOT4S1q54sDdl75aZGWUQmjxQV1s8=; b=RdR05GU+Uwxb44WFB9csbCPSWIloSrWqRkZ5cWtocbwfhNEJI1bqbd4ClMYFbyFQUzS/AQynkl8DU/wzrWSlTw3oD/QJBUUEapvb+z+VE/Nr5vxUx7yhJ5BrXYi3+dX28Q+r6rtutCRDqlO3hNaPY/qLVOoohNKItjFlge2iD0ZMsnbEvti2K3yssZxCdaJz2RuFPbqD0Z8lAM5Hz91Y3f7QD1p8ZjI8goi4QhqWJfYwnngFqxOM9DT070CMimVzjk/h5eJJ8P12qaNntyjyUCkhRJ0jG9wYkxqtR7ilmBJ+VzeBPev0FqiTXel6Nn6gvqVHheFI7LA9yHVh8BAUww== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=B1TUN//VIfhqSrNOT4S1q54sDdl75aZGWUQmjxQV1s8=; b=Bm3NGLzXf71x1NTbbX+qSgFMQQS/H850RmtRafENnPWOA69Ob0VThbuUlPCwMOjdBMDCROrqQbs4nQYnsN3rWjMVHO12lt8vaIX4SWiQR6UqeDscr4qqVbj/AwHjkEHG4LbdlYJQxjblo+2vARpZdCzUHv/RDwPQGbfjIgPxk/I= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:30 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:30 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 81/96] cl8k: add temperature.h Date: Tue, 24 May 2022 14:34:47 +0300 Message-Id: <20220524113502.1094459-82-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 5d29ad78-2e3e-4ed8-8464-08da3d79fb5c X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 9PPeybzNuQGzncTIawzefL5Xp7ra3rgIp3Wb1wi8mTkteoTLuVi6NxlAwLZ+E4XbXoR6biS7fUWgqQyE+OlG72gv3DBaMtut0zkP02pqs7VG0pA5bo9HegLHRc6wM/UbVBd1H+bDoHqLxI1NKvnaGP0dWF4FzenjuwRclPXGoMTlhk48gibRSFFtTJ86uP3R+5Etvo25c8fTeaCLYLDlrgbzB5feutlsi3RYfKl93JhozoXypgNUmiVy+R5hZbggYgVBF1BFoXa3ngOTSLeG2mWo5H2WVib2zfhp9eqO/hMKXLw7CrmR3tz9GmIn+eRKuPUKPTb9QEMNTvgS9KfRxvdAnhlwFsMEZsHJVwf9yD7Imj1VTtgTcARSliH7wkFrkTNe4Yy+0lMRR8A1EKGzb4ZFRwCjZX3cwdrkFu0Ir3Cq1LqKlbox7W+8WdvMKTYQVzrO9ufUpgZuFfVNNTNTuApwWveFM3k2tKEuQrClpBcG41lTINZ5Q0pPpJP2vcwF82+h0jgy0zh2HESb7zsORcR4KxBgvA4St65iA/3Be4OOdfBBhKSdsN4TRTa8gOo1CX0STcvYHu1SKsrfMseOyCJMz4iB3Zsn4DkU7Xu1HKzRRgnc/NYDFGwH49R0anKhgk0p5oURCfkiJ7MEXznHyyjt8+NfFCxZA11DHWZxuH31bwO+DU3LmDcr9hbAxCMAsSZ3ThbUAL86PoGT+AiH5SskpWZSAdTRQ68X9/DBSfY= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Sl7jNflxk6UbE0unayZRRlneU9AoQ2uB5kJVmDVF/G+xiifbLoDW/g08yRSrPgaLo5sPowp1tk8V313VseAyrCP7UyYv3BxhR87dsdpKONZ5GRPLYThYJNKxLMGLNnxQNgbyKQ4e+EmxB4h8aSreGVaef9KiAH46JmFPsCQ4K5Vd/iN5XDtrg4vC0IgSACuGgEUQFIKJYNOZ6QEeQP0Uzx/T3eN7bFituhRhmj2FJfbdQFq2tdLMFlshFgdjx15oqisRreEI/9uM7wacNt+JoLqCgdk6nwfWoEF2VzM6b860OnTeOWAO2MKeGtA4Wbcj+nOWFbcXq7pDMxkPQB4mg4zPaaNbWya58uNVVBdapLqDg/iLXmyE7eAj1ojZ8l8cUSN+Bp+XfV7xu/NEFQ1C4dw5oNWuVcToqevTM4QHMZG6eHLzuTij6A8udIoHtgMDNsKLiOvXF9F7xkD1YvZ6nZdDMGbHgiPSx90ORtmq85tMPllnE2N7Qmx9Py9Mr0i64Hh90qpD7p/Wzz8IYtVJDTxNJebmsQYrh3/6ePoO8HF6BV00YpB1UUkwJOULM0PXep1Y4mHprWaRYk744HxVeEXQ4bcZ1Vqu+WSbM36wDRNRYPqlv9G524NfmexM8LndWp8kJH5R9felzFNjy8Ur8zpZl4M08VzmQ6WneGCUdBaxYSHleQ8C+hd8/dzhy7S2QnqZyHIdB398/NdCeVM1HTZLPq3TtR5rx0rJfl2DYbJy11fzDHBVQX6S3uSLasGA0XTzQyrRuRZW3QtoFJP0huPTkv7f8e0XsrVE0/gq/dwVl2/AqtP8wmwe4z5dmaf87ZAzROaUIzwKXn0SGXimd5xIuUii7XoDpecKbjWrWej/q+FoKu2IViQcbuqMVPcOFWMorB4dQLv4q/GXunmWpIBhi9t+DcWkQ4wndLD7wZnscXaekF7DhUnEzBOaxneO2IhpI64ppIVw3/wSSkc6Be0gi3A8Z+7pk+E0L5Q6H9XdWMvDH2hBgUkkusPNVLZIrob07uwaTVyJ1NBgV2x16eZuZxtNK7Maq1cvhRQwx7+9CRhJZeJNw+mFs2SGaNSA14rCBUywDJ9DE3wJIqlVq2h6cRl5KXwdgUHW7U3Wh/vUEf+6dCAupMAN5cjd190b1U9bfKdDrm/8cdHKn2gO1cTJCrsi0jmEEnVzFx/uc79bmppiil7eCmGRrXxomWts11hb93t97IsEzGOLgfDpp2xAkCdN1yuvHvtKzM5GKKBPnVC5QvsT+oV37HTkF1gsZ59X9UmP22kMm7k9UpPeVv1kdHiT0QIxiLNizFVBqzwHErrTe8JuFfCI46lsYNHULnetr/nucqHbosR27XALLIlgBD79PrOUA39TF8BDgCSX43M5xeWGTKoIgdqXIsAO8PZ9dB+AN5xZ4IuPuwGgS4P1C5mcNG8GlpRt20FIiGwSYKZ05x9zdui4oYGuIge8CFqmLLhhhc7JaTKaxLkGMwD1LYLi3wolY7TAj4JSVcnfR1vyemdH/d2XdQJ1HMTwECAMhtx+zkvfKucalk4pX1Qm+MbQCeOup32b5QKWBZeq4AxNmevgQ0/vSUSxDrMB8NYwIlCHC/FRYiSmwxFmM3+CeOylL8puilYU2J4eJ2pBtchprxmoV4NDoPtkg/38QptYoRrQ/+aZ2+r2crSAnOR5WOAhqt3S17F/4EUgSoiXaHXvI3ZO/5Df8Cj2rNHQpIHP0rfvk8Uof5Vk+3PCViv1o+gfr85k3myndnA6fxM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5d29ad78-2e3e-4ed8-8464-08da3d79fb5c X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:54.5077 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: h8Eeq9iIVbAHmTJp5WUbrZhWZW9emirZaaZzusJk+NKGJrvZvgPW1KDplp3Z9p3ZP9aDs+dvmoRzDAZZlD26Ww== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- .../net/wireless/celeno/cl8k/temperature.h | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/temperature.h diff --git a/drivers/net/wireless/celeno/cl8k/temperature.h b/drivers/net/wireless/celeno/cl8k/temperature.h new file mode 100644 index 000000000000..e5ab770199e8 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/temperature.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_TEMPERATURE_H +#define CL_TEMPERATURE_H + +#include + +#define CL_TEMP_PROTECT_INTERVAL_MS 40000 +#define CL_TEMP_PROTECT_NUM_SAMPLES 4 +#define CL_TEMP_PROTECT_RADIO_OFF_HYST 10 +#define CL_TEMP_COMP_ITERATIONS 4 +#define CL_TEMPERATURE_TIMER_INTERVAL_MS 4000 +#define CL_TEMPERATURE_UPDATE_INTERVAL_MS (CL_TEMPERATURE_TIMER_INTERVAL_MS - 100) + +enum cl_temp_state { + TEMP_PROTECT_OFF, + TEMP_PROTECT_INTERNAL, + TEMP_PROTECT_EXTERNAL, + TEMP_PROTECT_DIFF +}; + +enum cl_temp_mode { + TEMP_MODE_INTERNAL, + TEMP_MODE_EXTERNAL +}; + +struct cl_temp_comp_db { + s8 calib_temperature; + s8 power_offset; + s32 acc_temp_delta; + s32 avg_temp_delta; +}; + +struct cl_temp_protect_db { + bool force_radio_off; + u8 duty_cycle; + u8 test_mode_duty_cycle; + u8 curr_idx; + s16 last_samples[CL_TEMP_PROTECT_NUM_SAMPLES]; + unsigned long last_timestamp; +}; + +struct cl_temperature { + s8 diff_internal_external; + u8 comp_iterations; + struct cl_temp_protect_db protect_db; + struct task_struct *kthread; + wait_queue_head_t wait_done; + wait_queue_head_t measurement_done; + s16 internal_last; + s16 external_last; + unsigned long internal_read_timestamp; + unsigned long external_read_timestamp; + struct mutex mutex; + struct mutex hw_lock; + unsigned long used_hw_map; +}; + +struct cl_chip; + +void cl_temperature_init(struct cl_chip *chip); +void cl_temperature_close(struct cl_chip *chip); +s8 cl_temperature_read(struct cl_hw *cl_hw, enum cl_temp_mode mode); +void cl_temperature_recovery(struct cl_hw *cl_hw); +int cl_temperature_diff_e2p_read(struct cl_hw *cl_hw); +s16 cl_temperature_calib_calc(struct cl_hw *cl_hw, u16 raw_bits); +void cl_temperature_comp_update_calib(struct cl_hw *cl_hw); +void cl_temperature_wait_for_measurement(struct cl_chip *chip, u8 tcv_idx); + +#endif /* CL_TEMPERATURE_H */ From patchwork Tue May 24 11:34:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576839 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 974E2C4332F for ; Tue, 24 May 2022 11:40:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236901AbiEXLkr (ORCPT ); Tue, 24 May 2022 07:40:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43138 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236944AbiEXLkm (ORCPT ); Tue, 24 May 2022 07:40:42 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2050.outbound.protection.outlook.com [40.107.20.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A2008CB3D for ; Tue, 24 May 2022 04:40:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AKemsCIoxL8TQYhTXToEPxKIkm3j+Fa5XGWvq8opBKVL26ye1DBx7G6nNBW9A0y2wYZCp3HzX+zBWQa4q4if64BsrZ5YOxLgTf1FrBFUZDsiaI9DGa952vLPhZoMHqtJM7RgJmV6HsLYvLc2q1unS4pTnNpeSS625XbrIYg65uNPvajBCTr/irxMZMRLgwYaGaE5xJBdSbzxsttstorxX+UN2EBKJNy7H8Sddw5W71PRoFas7hTt1tWl6iexKOVzREB6L6K0Og69p23IAp+IcBBbVd8Pm7WCPzHNtlInk9x9rDf0ZscTWGNvlZlMZkouo1xATlY8326TwLiTTFDfNA== 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=D2U4qluKHCl0d8fU+sfaEKKogD0PPdx32kBb6Om9l5A=; b=KZ8FHL1zyv331G4ltV8bEn6oUrl3H28QQiCXjY6XFPPngKBPyQG3rnaSM9uu1r0bMFpzC0lyYyoZYzI31guOwT00D8qGCifG+NOi0If9TGmbP1aaDnBa0RkgeDT8cA9U7TXzpJeGAvdt/6jcm+I2lljqxNCSGar+qzgHclYCaxcyzpO3IfUcbz2zyZrLuKuLQxOvMgrhT7ipl/JbtGRin99JRtg3JHkgBkpDmKnzCROKuYvQugeBbS2emLbfHyswC5LQ5zx+0kvas7emuplaWUUEbZlvhRzcPXUfpN4QFU5onVvW+9SjddSIPm46vPNVwQASyF4vaaihNHWBf3el4Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=D2U4qluKHCl0d8fU+sfaEKKogD0PPdx32kBb6Om9l5A=; b=bbVH+UljaXPEkquV+uLkxGdTE071sDoDhC3w6q/+SIAMqBf8P+6g9ExVtd5ZFm7Bvcvcml7MMWqWwR/7eOQvzYqW2D1jbsACR/YlFttHUYaPdXE64TJkgGb2HHlhym30uPq4/SJNeyOvyDJmZmEbaBrUn6E20DcvWuQC3rFo1Zo= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:31 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:30 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 82/96] cl8k: add traffic.c Date: Tue, 24 May 2022 14:34:48 +0300 Message-Id: <20220524113502.1094459-83-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c50ac4d9-d24a-4aae-486a-08da3d79fbd6 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: AfxbRTIZdhrLb6oREwPeJBPcGhxDGN5xDf87JRqDa96ncgijlxcXMSM2eXUG5zaorwiX1/SvttJ+6hoSYLrIjppwwgiDWYNiMABVm2nyMuYPCJ4Ofn8Sc7XuCfYZCq230TYu1H5NGZ7lyi1xRxBOBIDgXnhrx3+4LPbKcQABiEjBlXA+QSOnmzEp4WhjAalwHY/WRWs7v/wJmUA4rrg8WhNp7KIQCQWkONpwFhyFuOanYTQ9umIdeAgBP9A9H1QGNbf6NyBiYrZHz2lLpDP8ZI/AIu5MGROz3Yyz8tI6pB45IVqmhMtgKShExRCmAw//3u6tI1FSUXJhxr3EETwulLH4dD+jd6IBTsNAYt5/pR9PUiXEMOtdOX6Zzc7uRrU62fkZLWtw2h49rWZa+0WaCMtk2KEICTSFR6X1lLY1Hnv93xBcjlNLTPFpDTqVtBivGYTd76jnfgiQOaEp6+ooHLDvQILKC2MVzJn3BXuhq0Dn232JoNZenMwTCbOLhNX/AiDLYMFXVOIU3wFL5NtRKsza6oFwgknrrGlWRGCtAIUBKygmwL496mcuNdtGRXuxhp3IEn5D0ubQcv88PbU5sfUG5HHFscHnyKK+eSwbxnmWA4n6BTp6IyDATY4AcKoHl0IpRCwAq3R7t6kJGudGtsCNK9wiS+gYjz/yh9ttzI6WSL1ee64AobFGb8C3ODONSdJTHbos5S1Bh9KQ10rzkV+EZLFrNKbJF7krBwAEAdU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: kY7ZonhisMMBdklCfVZOFaT2sLmPFvh9utUasL1zWTrT/DS3xPzMDYX3jEh6vfDMLItqKt9d4RzFrTR3kE0j5Z75HvUx7T3P+OdDzHIn1R/NHW/Vswso0MEMmhNcdBwWRPu30QS/jkTnxFcg8TH7E63skkzhfWypEyz2hEaaQZSCzkXg0gavPPfajMYAo/tE4n0mV2ypkDYvK8d3J63PIuhkg2z6M6UuOaUVtp+EtgZrg6Fy/NipzvDPBOPuILOO5TDZvLzsq+T2+kBKoKnqSuhehEa2g7vfkn0Wj8MtpiKaKpvYbWxmgwxxSlKoYyGk28VDahMEcCufNzohFKUy5ZZ9gNdJa1uGB7c6MA/2/G7a1l6i8uc9USvcOhWwluhylInLir9l6jQFL5XNvl+PMkC5jmnl7kunfQKNhqm0ZrjdgT7yvvjU+z0W4XlWYZMzFjz4I0vIyL6TYkWBdAH0wbGaG+Fwh494V1DygnLSUb6v8bSNW7cf8PRJvnI2uKFFX9E2Vpzk3Y8Yuj80X7ot4kAO+SHR9A4AjGgVl9KG+ycA20sdRIq5ueHnN9A7FS8FiNpZPKme1MOFTemzYAn6slBvixUvgyxKJBzLMkFQG3mOJmgwRurBjP+cfoM+I3ohGA3jce4puyZMQN93g9pJFTZxe0V58ecj87YULWcHs4p0GXnrOK03UShG8isRnhWfQs9maqsryFFgC4fCSUdmOs3dMldhsl6c9GrhxeIDMjcUaGFARYT7KA6vmrVSLWKiXpZ78b59cqi7CHf7Tpa44I8jVCQVC3BLI7vDyardonUTi8znsJ0RZDchoHkPtzYLaYpPdm+9qSzyVCzkLcZ0VDs3v9iirPqlxvH4GG2Fow0FctNk1xAimeNiu9YDUYy4yAj6vqgE5blscSD3CGofh/tS6QgedcIjZ4ImIUD5uNnMtNUwHq4rXW9+VT634VdWjMR/5lD9gdDDMi8c4Tb6tM6UxSFv558DFjVlCR8nWl3JisuNu895Q2mAgZ4vc9muT3EAlb2Vq+32GEDdXe2JUuUy1phyOdAsXO4+k//rOXWUKWZjnLegRVjdzEXOyKx03/zq9R3pOeIWHpoN/sgPKDG8QkjKazeperLrwCuBTuqWE7jKFbNwkeu922y9nriZwH6UWD3OxKclStzfoBIZ4u4kystd9SJj1Ub1bjBNh/V8Lxlxb+gVdWM4fn5+AFBR/x6Fdy78IGDPhgBcsiq8tJDmdS5H13x4ocE1DBpHrZWlaXl4oRDo6vp3zWNLnDpdvPrduOV+h3XReIe/iQuuVGcUvIs0XaA7pOWqn1pTIUZxcWs4DSN9daSFXash+gCwBIWlfzLi9a5KFX3HY2vceSDpIvZOOVZrPG0qEofwnLziJTTnWlz+atluuA7rObUyWfG6iHcsM7BmxSqwCsmNE2rQ8Kopjw1E1rLOxIIWP0mttYh5ZZffDVv0v591e+26C943oF2LFt03dV6TW84o0SBBxSPllnjaG8yiZwmkNxNDhX8JittHp9QcS6aPIO6DCH/QGz6WtWnCgHA3FLMxyoN3VGuPjbCs6XFKTCTgMM8yl206hPw370MRL/cfOIAf7y7hP0N/EZfNJyniVfu/o7l1b4kbDZ289iJ+mwpbKVQ2yTKXU1AMTltT/Pt0+2p4fYfnA372xl5EyENxklGz8V+jjZpZ47QhvzpH408KD30Jf50lsbuPSMNRdJ1qcuo2mKHHGs3IvekVBneaoGY8aFtAvSl6i68MDXvvKpgIkn4= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: c50ac4d9-d24a-4aae-486a-08da3d79fbd6 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:55.3682 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: g7OW3UiAtuFEQyPaulxUUicuEnTG0XVPkQ0vnMPWRxAcn6nYYqTUrJ4aATbihgnC/Jyd74juDWoXH3vvWa7cgg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/traffic.c | 254 +++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/traffic.c diff --git a/drivers/net/wireless/celeno/cl8k/traffic.c b/drivers/net/wireless/celeno/cl8k/traffic.c new file mode 100644 index 000000000000..788fd02e28a8 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/traffic.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include + +#include "bf.h" +#include "tx.h" +#include "radio.h" +#include "utils.h" +#include "debug.h" +#include "hw.h" +#include "traffic.h" + +#define TRAFFIC_CNTR_ACTIVE_THR 3 /* 3 * 100ms = 300ms */ +#define TRAFFIC_CNTR_IDLE_THR 20 /* 20 * 100ms = 2sec */ + +/* Threshold in bytes */ +#define TRAFFIC_ACTIVE_THR_DRV 1920 /* = 150Kbit/sec (150 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_BF 26214 /* = 2mbit/sec (2 * 1024 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_MU 131070 /* = 10mbit/sec (10 * 1024 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_EDCA_6G 2621440 /* = 200mbit/sec (200 * 1024 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_EDCA_5G 2621440 /* = 200mbit/sec (200 * 1024 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_EDCA_24G 655360 /* = 50mbit/sec (50 * 1024 * 1024 / 8 / 10) */ +#define TRAFFIC_ACTIVE_THR_DFS 13107 /* = 1mbit/sec (1 * 1024 * 1024 / 8 / 10) */ + +static void cl_traffic_mon_ipv4(struct sk_buff *skb, struct cl_sta *cl_sta, + enum cl_traffic_mon_direction direction) +{ + struct iphdr *iphdr = ip_hdr(skb); + + if (iphdr->protocol == IPPROTO_UDP) + cl_sta->traffic_mon[CL_TRFC_MON_PROT_UDP][direction].bytes += + ntohs(iphdr->tot_len) - IPV4_HDR_LEN(iphdr->ihl) - sizeof(struct udphdr); + else if (iphdr->protocol == IPPROTO_TCP) + cl_sta->traffic_mon[CL_TRFC_MON_PROT_TCP][direction].bytes += + ntohs(iphdr->tot_len) - IPV4_HDR_LEN(iphdr->ihl) - sizeof(struct tcphdr); +} + +static void cl_traffic_mon_ipv6(struct sk_buff *skb, struct cl_sta *cl_sta, + enum cl_traffic_mon_direction direction) +{ + struct ipv6hdr *ipv6hdr = ipv6_hdr(skb); + + if (ipv6hdr->nexthdr == IPPROTO_UDP) + cl_sta->traffic_mon[CL_TRFC_MON_PROT_UDP][direction].bytes += + ntohs(ipv6hdr->payload_len) - sizeof(struct udphdr); + else if (ipv6hdr->nexthdr == IPPROTO_TCP) + cl_sta->traffic_mon[CL_TRFC_MON_PROT_TCP][direction].bytes += + ntohs(ipv6hdr->payload_len) - sizeof(struct tcphdr); +} + +static void cl_traffic_mon_calc(struct sk_buff *skb, struct cl_sta *cl_sta, + enum cl_traffic_mon_direction direction) +{ + if (cl_set_network_header_if_proto(skb, ETH_P_IP)) + cl_traffic_mon_ipv4(skb, cl_sta, direction); + else if (cl_set_network_header_if_proto(skb, ETH_P_IPV6)) + cl_traffic_mon_ipv6(skb, cl_sta, direction); +} + +void cl_traffic_mon_tx(struct cl_sta *cl_sta, struct sk_buff *skb) +{ + struct cl_hw *cl_hw = cl_sta->cl_vif->cl_hw; + + if (cl_hw->conf->ci_traffic_mon_en) + cl_traffic_mon_calc(skb, cl_sta, CL_TRFC_MON_DIR_DL); +} + +void cl_traffic_mon_rx(struct cl_sta *cl_sta, struct sk_buff *skb) +{ + struct cl_hw *cl_hw = cl_sta->cl_vif->cl_hw; + + if (cl_hw->conf->ci_traffic_mon_en) + cl_traffic_mon_calc(skb, cl_sta, CL_TRFC_MON_DIR_UL); +} + +void cl_traffic_mon_sta_maintenance(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + u8 i, j; + + for (i = 0; i < CL_TRFC_MON_PROT_MAX; i++) + for (j = 0; j < CL_TRFC_MON_DIR_MAX; j++) { + cl_sta->traffic_mon[i][j].bytes_per_sec = cl_sta->traffic_mon[i][j].bytes; + cl_sta->traffic_mon[i][j].bytes = 0; + } +} + +static void cl_traffic_sta_start(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + enum cl_traffic_level level, enum cl_traffic_direction direction) +{ + cl_hw->traffic_db.num_active_sta_dir[direction][level]++; + + /* If other direction is not active increase num_active_sta */ + if (!cl_sta->traffic_db[1 - direction].activity_db[level].is_active) + cl_hw->traffic_db.num_active_sta[level]++; + + if (level == TRAFFIC_LEVEL_DRV) { + /* + * Dynamic CTS: + * If protection mode is disabled, environment is clean, + * and station threshold was reached switch to CTS. + */ + if (cl_hw->traffic_db.num_active_sta[TRAFFIC_LEVEL_DRV] == + cl_hw->conf->ci_dyn_cts_sta_thr) { + if (cl_prot_mode_get(cl_hw) == TXL_NO_PROT) { + cl_hw->traffic_db.dynamic_cts = true; + cl_prot_mode_set(cl_hw, TXL_PROT_CTS); + } + } + } else if (level == TRAFFIC_LEVEL_BF) { + if (direction == TRAFFIC_DIRECTION_TX) + cl_bf_sta_active(cl_hw, cl_sta, true); + } +} + +static void cl_traffic_sta_stop(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + enum cl_traffic_level level, enum cl_traffic_direction direction) +{ + cl_hw->traffic_db.num_active_sta_dir[direction][level]--; + + /* If other direction is not active decrease num_active_sta */ + if (!cl_sta->traffic_db[1 - direction].activity_db[level].is_active) + cl_hw->traffic_db.num_active_sta[level]--; + + if (level == TRAFFIC_LEVEL_DRV) { + /* Dynamic CTS: + * If it was turned on and active station count became lower than + * threshold --> return to no protection + */ + if (cl_hw->traffic_db.dynamic_cts) { + if (cl_hw->traffic_db.num_active_sta[TRAFFIC_LEVEL_DRV] == + (cl_hw->conf->ci_dyn_cts_sta_thr - 1)) { + cl_hw->traffic_db.dynamic_cts = false; + cl_prot_mode_set(cl_hw, TXL_NO_PROT); + } + } + } else if (level == TRAFFIC_LEVEL_BF) { + if (direction == TRAFFIC_DIRECTION_TX) + cl_bf_sta_active(cl_hw, cl_sta, false); + } +} + +static void cl_traffic_check_activity(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + enum cl_traffic_level level, + enum cl_traffic_direction direction) +{ + struct cl_traffic_activity *activity_db = + &cl_sta->traffic_db[direction].activity_db[level]; + u32 num_bytes = cl_sta->traffic_db[direction].num_bytes; + + if (num_bytes > cl_hw->traffic_db.active_bytes_thr[level]) { + activity_db->cntr_active++; + activity_db->cntr_idle = 0; + + /* If traffic is above threshold for X consective times change state to active */ + if (!activity_db->is_active && + activity_db->cntr_active >= TRAFFIC_CNTR_ACTIVE_THR) { + activity_db->is_active = true; + cl_traffic_sta_start(cl_hw, cl_sta, level, direction); + } + } else { + activity_db->cntr_active = 0; + activity_db->cntr_idle++; + + /* If traffic is below threshold for Y consective times change state to idle */ + if (activity_db->is_active && activity_db->cntr_idle >= TRAFFIC_CNTR_IDLE_THR) { + activity_db->is_active = false; + cl_traffic_sta_stop(cl_hw, cl_sta, level, direction); + } + } +} + +static void cl_traffic_monitor_sta_traffic(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + enum cl_traffic_level level = 0; + + /* Check Tx & Rx activity in all levels */ + for (level = 0; level < TRAFFIC_LEVEL_MAX; level++) { + cl_traffic_check_activity(cl_hw, cl_sta, level, TRAFFIC_DIRECTION_TX); + cl_traffic_check_activity(cl_hw, cl_sta, level, TRAFFIC_DIRECTION_RX); + } + + /* Save previous Tx num bytes */ + cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes_prev = + cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes; + + /* Reset num_bytes */ + cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes = 0; + cl_sta->traffic_db[TRAFFIC_DIRECTION_RX].num_bytes = 0; +} + +void cl_traffic_init(struct cl_hw *cl_hw) +{ + struct cl_traffic_main *traffic_db = &cl_hw->traffic_db; + + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_DRV] = TRAFFIC_ACTIVE_THR_DRV; + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_BF] = TRAFFIC_ACTIVE_THR_BF; + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_MU] = TRAFFIC_ACTIVE_THR_MU; + + if (cl_band_is_6g(cl_hw)) + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_EDCA] = TRAFFIC_ACTIVE_THR_EDCA_6G; + else if (cl_band_is_5g(cl_hw)) + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_EDCA] = TRAFFIC_ACTIVE_THR_EDCA_5G; + else + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_EDCA] = TRAFFIC_ACTIVE_THR_EDCA_24G; + + traffic_db->active_bytes_thr[TRAFFIC_LEVEL_DFS] = TRAFFIC_ACTIVE_THR_DFS; +} + +void cl_traffic_tx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u32 num_bytes) +{ + cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes += num_bytes; + cl_sta->tx_bytes += num_bytes; +} + +void cl_traffic_rx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u32 num_bytes) +{ + cl_sta->traffic_db[TRAFFIC_DIRECTION_RX].num_bytes += num_bytes; + cl_sta->rx_bytes += num_bytes; +} + +void cl_traffic_maintenance(struct cl_hw *cl_hw) +{ + cl_sta_loop(cl_hw, cl_traffic_monitor_sta_traffic); +} + +void cl_traffic_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + /* Check if station disconnected during traffic */ + enum cl_traffic_level level = 0; + enum cl_traffic_direction direction = 0; + + for (direction = 0; direction < TRAFFIC_DIRECTION_MAX; direction++) { + for (level = 0; level < TRAFFIC_LEVEL_MAX; level++) { + if (cl_sta->traffic_db[direction].activity_db[level].is_active) + cl_traffic_sta_stop(cl_hw, cl_sta, level, direction); + } + + memset(&cl_sta->traffic_db, 0, sizeof(cl_sta->traffic_db)); + } +} + +bool cl_traffic_is_sta_active(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + return (cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].activity_db[TRAFFIC_LEVEL_DRV].is_active || + cl_sta->traffic_db[TRAFFIC_DIRECTION_RX].activity_db[TRAFFIC_LEVEL_DRV].is_active); +} + +bool cl_traffic_is_sta_tx_exist(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + return ((cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes != 0) || + (cl_sta->traffic_db[TRAFFIC_DIRECTION_TX].num_bytes_prev != 0)); +} From patchwork Tue May 24 11:34:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576828 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 36F1EC433EF for ; Tue, 24 May 2022 11:42:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236980AbiEXLmG (ORCPT ); Tue, 24 May 2022 07:42:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236983AbiEXLk6 (ORCPT ); Tue, 24 May 2022 07:40:58 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2088.outbound.protection.outlook.com [40.107.20.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2006A9347F for ; Tue, 24 May 2022 04:40:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HHCYfWENgX9edqHq7ZAr6m/r6xddqjtCgv39Ma0w6qUC6jKGldp8jqjeymHYsJPxG1M5H0CXafvTYHOLOtkyOkp3Bu1Km8PInl/HtkzexvwRvKb+H9K9Si3TqfHoVc1sT7IqFUv83Nw6lTHcOazbBjRynvd4PbwXlUEWYC0804+owst91qa7XeEKU0FHaOI6mJEonntxu2Oq6SKgDmq8CLYtJvc69Ju/gNaMUcna5mnAFMwa+t5evRf0uxSSPzwTvcPJJogqvZnubTL2GaCkY5xA5koOT4hda7j4HSPpa1oIShY4+rzaRuznxRXzXyyYGX9jYMfH0lHGL8PW1Ab2pQ== 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=Lr4KfbZp0c5+FYZarLChMg4QXcVBZDHWfkW1aTrtzyM=; b=Qgslz37XtYga1DXRoICcGjWln4jf4BEKD/LUGjxleV1SZdfzUqg6NEuA5lcnhZeKcbhd71HIer2g+LF62qiV4YJ38cqbXyIiEV7UdZl66ABIETPwrU5V+5KRAkQpiiDl53uI0NXW8mii3ShjQkkdFn3TdXNfP8XHBxi9nFRFzDgDpfI3f4DcUT/DicI/JslszKWls6NZzwuFFiNtvuQWMLHfIP0zJKURWLyknBdJUmrbHf/SvN53aPKBvpxJpzeVRbBJMyr2xB73exirn1eVSVPv7CF2MR9N9ydmU7Ci3wTPO+pkxRZZzvJcvnaQ8R1yFck1scKEuxTLFc6HGZd7tA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Lr4KfbZp0c5+FYZarLChMg4QXcVBZDHWfkW1aTrtzyM=; b=FJYOiWdt35KO1v6fpGjRP1zlvNtRR+gy/HtuMtzPQ5sPbNmAHPbOI119Qm6NYqgPLHN3Xyge8kpi8uKUb42X/m5nC96JkAd46utnpxP1997JSRG8+RW0xSK0Av3tPKrfNXsgm07NI/yb+DQgm0TsMFiEFJPJ7J0auD0KL6cE9JI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:31 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:31 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 83/96] cl8k: add traffic.h Date: Tue, 24 May 2022 14:34:49 +0300 Message-Id: <20220524113502.1094459-84-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ae011785-a594-4742-15f7-08da3d79fc4b X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: r1QIp5Tjp+kOUcgj/B/0qnuQy9BRlH744f0WNPfIpvHvYTYcAZ2/gxOeJoyQPSkvqDs6qt7BypGdlNV2VGtlplW8U65flA9/C4nsFqooJsvaMb62hka8ISO5d331RKpqklutUV/P8ILgv1qSwVUW49sEjNd3PCg14pfIIOHG60mUj6XPDTgxUlXQamTgJztLRlUU4YsG52PzQ+9+nZ7R2gOswlkm4xW9z2rjAI5VsRrxUMj+1ZM6uecwnXmHlS76N9y0LPmfqYfhYLNB0lLdA2icMwmTptE7iq0AZOKCjVBsbHrxWZwosVw9hR4IlS6u7HRKTJ9R/YdVhkF8+VR43Jc9DU8X282qQzeNfzN3/RjK24PqTtPY4DgR/ZFkDg4j+Vr046PjGN5FT03FGObK0Zc9l3ufEHjNbClHHCzNwV8suBknPHUpl0JOIDeKHtFRq/6KVBmAeO7FOrBajxAjxOkp2SwxaN1F5GhrMK492vajQ+AMocmPAccBPDKnVb4R5RJmDLz8fhH6O30JwlcV4AMNhlgeYTJns16Yr4auu65vhPoDwzpKt6Fo2FmlJUsMeOm75T9UCTacTF6JzGbOhackiqxcBzY5s1wnfDO7r0/7rwXN2beqtPg6z1oaDzVujo4wYZL3SHwmJeIGA/zqOr2mvZfnoOuQEoXeusyeWSNaOIr/HDU63OJpq5igJuELW8/gvslxH1kzWKqlabid3h47Bta4aBg6DujzdhgSYYM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: b5OMfFk1W3wr8W7wO0RsMy1hVgBJEpjoK3gsNXB6SX2LeBdrND6X9lvEgacbtY1/c8CN9DkqOIEVjA7jfQBQyL+OPtHNdejawF1DEnO04P/0NYk7xz2oSoY814OocPGY2VZlZb6VET+GzZLf4GKbTAPOipba8LzSR4Bxkcx6xkSAwJ9z9z1DlSl5dvk04SOSRMhO7Bcf6xsG/ZABtVeZl9ia98rSvc+/yXjWc5jbfdwalerVAgzrnAgLLhHOFpCFTGb0tA3qom+HSgkv9sPZ6ylJ1bpYY9YK48SoiEO2+dwj2cua7x+jS/iYIRRv8iM6o7WWZAWQWQqPpLdiXRCZdhAicHvX3+LLX3ygAnrvtiYPtitI/vIILqDMJ+e4psaAATWH/gIZJz82jlZ/hVOuxUageHBK8Asa/ftjMVBrvDlOB6fYrRiVOItkAGOCGHGxJVU+tlyyym71iAK1NCDL/1znhP08ZRdqJXHNU9nABRtnGGkks13qD0qOOJDcbN1mQV9lNZ4zyF6HIh5gTwWCw0K2kFSOW/wfM+ClaNOAcgm0CdfZPpAlgI+/+2pKE3p4P5c5/XnZyswaaQUIYAelH0aORxozVA47OUyKlnehMo1glqi5A8tFpOBkyCV6Prle/UlGOCId8DNuKynOkWSJT+CB92odt1nN1P5+CvX5zjPu5t4gLPEdDCmAR2qykVYvaE7apGxQMn9ftLxxA4RIqF/QEQ9t7PV4IkjQKSoKOT9eYvqgzjfucXTfyXMGXGiwRzpyBsT3LERYFdlDWT1WreM/b2/GaKxZIBhmhwfa7vZeMjNHgQHGio68ydXCYr+gjGOjquBSjzKanVgDWO4yplvG0fK8JnDtOwAHUN1pD047kP7r8oaN+6hlAsPd6IEDer06hV47zmNn0DyphRR089i9ee5QvkyL8el0MmhrbaLadjPradu+RBCLnk0LdZ7G8Ik9SxhCilZsKksbt6++RI8uWA5Aboy8aSVnY+8S9HP2fnP28mKP43dh4HaRwDa2bJLl6YVGfX2bjXSDJMpR35qfX6q6ShMyZynEg/p9/UNJEpediyAsdxvNANhairAPJk1mjLoxJ45BZd+oD9xKUxozOr+mWsxpyttjfquVwTdll2AMRGDkURt0hi0hjDS6odno9JcFfadwG49qWKrhwX6ku+Y9NRoNwYQeMI2i+li2y/qzqi+S99Pl6GzKbukqAL7pwM750w9zXvjowieBO8j4Z50T15z4b7wDsPY1iWW+IAOSF9ifE5Lwh7BkYP8zORB5RFmig5c+YKIQ8gFIBEzRtbp6OD2y48YRWlUH+hPOsDpz9V3nUBDaa+mEZBtXG1Nqr3pJ9Rk5Egay7svNzkSrRjp57YGmfd777ZFAQWpLiEHKZnh0XHY65KP6dyo0gdQyO7CvWIeAg0jgVUTHRhjblVVJYNtfRuzcdPaAjPKQZbp01MJtUkj1fI3YEUpCB9h4K4cxMXFe1XJ1i00P+OAZacqoYZW0kMforyDkOF8xdSkKSppAFrcCYwWN3zafVL/aXeRPsTOrLJ1MrWkct8k6oDd841DTWQYF0SEdwMoiXdSuk++USDxFF7rak/4y4AGlAKOp5OtIdeK5GEvPpwk6mYpgE8uZmYB1nbkKqjKTiS2Cl3wP4UTbMvVHv7YQqFde0M5jYSez0GMBSJfrSREMo8Ntad9/WhybC1y7AXWBaBtVTAWasxvqMPVD8aITR7GY6tsui2KV95lxnWEIoqqWn9f5TGq8B1kI7/GNQOc= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ae011785-a594-4742-15f7-08da3d79fc4b X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:56.0868 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: nU+LL1GQBIqUodwG3nWJqiRbzRAZ/mHA6B5BO79NJ1o9PpbujtH5xasT3MbbrGyOPUau3bnedUCeVtjDN1XkZA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/traffic.h | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/traffic.h diff --git a/drivers/net/wireless/celeno/cl8k/traffic.h b/drivers/net/wireless/celeno/cl8k/traffic.h new file mode 100644 index 000000000000..1b820602c94a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/traffic.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_TRAFFIC_H +#define CL_TRAFFIC_H + +#include +#include + +enum cl_traffic_mon_protocol { + CL_TRFC_MON_PROT_TCP, + CL_TRFC_MON_PROT_UDP, + CL_TRFC_MON_PROT_MAX, +}; + +enum cl_traffic_mon_direction { + CL_TRFC_MON_DIR_DL, + CL_TRFC_MON_DIR_UL, + CL_TRFC_MON_DIR_MAX, +}; + +struct cl_traffic_mon { + u32 bytes_per_sec; + u32 bytes; +}; + +enum cl_traffic_direction { + TRAFFIC_DIRECTION_TX, + TRAFFIC_DIRECTION_RX, + + TRAFFIC_DIRECTION_MAX +}; + +enum cl_traffic_level { + TRAFFIC_LEVEL_DRV, + TRAFFIC_LEVEL_BF, + TRAFFIC_LEVEL_MU, + TRAFFIC_LEVEL_EDCA, + TRAFFIC_LEVEL_DFS, + + TRAFFIC_LEVEL_MAX +}; + +struct cl_traffic_activity { + u8 cntr_active; + u8 cntr_idle; + bool is_active; +}; + +struct cl_traffic_sta { + struct cl_traffic_activity activity_db[TRAFFIC_LEVEL_MAX]; + u32 num_bytes; + u32 num_bytes_prev; +}; + +struct cl_traffic_main { + u32 num_active_sta[TRAFFIC_LEVEL_MAX]; + u32 num_active_sta_dir[TRAFFIC_DIRECTION_MAX][TRAFFIC_LEVEL_MAX]; + u32 active_bytes_thr[TRAFFIC_LEVEL_MAX]; + bool dynamic_cts; +}; + +struct cl_sta; +struct cl_hw; + +void cl_traffic_mon_tx(struct cl_sta *cl_sta, struct sk_buff *skb); +void cl_traffic_mon_rx(struct cl_sta *cl_sta, struct sk_buff *skb); +void cl_traffic_mon_sta_maintenance(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_traffic_init(struct cl_hw *cl_hw); +void cl_traffic_tx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u32 num_bytes); +void cl_traffic_rx_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u32 num_bytes); +void cl_traffic_maintenance(struct cl_hw *cl_hw); +void cl_traffic_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +bool cl_traffic_is_sta_active(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +bool cl_traffic_is_sta_tx_exist(struct cl_hw *cl_hw, struct cl_sta *cl_sta); + +#endif /* CL_TRAFFIC_H */ From patchwork Tue May 24 11:34:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576831 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 794F2C433EF for ; Tue, 24 May 2022 11:41:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235369AbiEXLlr (ORCPT ); Tue, 24 May 2022 07:41:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237001AbiEXLlk (ORCPT ); Tue, 24 May 2022 07:41:40 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2071.outbound.protection.outlook.com [40.107.20.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1D56BFB for ; Tue, 24 May 2022 04:41:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KdGhyxI7oDxVtIRTddic9qgcFcmAcy3DuCsiLKBdw/X1mUe9Ruz1Z1JFnL1wrzwoQYwfsGtqFr98b5QQsTIXqX42QoxrxC1aCk7bzPmEMOjCYoxLQ2y/h4XUbrnYV2mwNBbdovjIuix72RLl/HNDFGtSnq9+ZsJ8TkX1v83BFAQEeh05BkXmOOVrZgf1K/9PUjSYBf9JmTDFMCSDFv3cpe6kMXidxg6lF2q5DBjRV+An6Z2d9n3/FJ6yCdjnRSXo3/QgbLytWPeKsRSqceyMpMtrwq4DonbCyvDCihUgK/V7q0iYOXba8LzoI8WX2nhVb4at636MOZLk42FqdNg/sQ== 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=VgD513CnW7Cnv2NkpNG6OpPUMuAKEBnc0sjA00HpdEw=; b=CdrUmUIpPr/Voo8yrhJ/LNEL0coPngxr1E24sRCa4DGkuKsMIL2w+YNcApatteJzqvL+8Y5RDZrJL99E+jQXK52ArfCe1raIToU/0XKwHaoueY9m2h+yy1F3PZGREzNh1jvjdUNWcELQ6ZLZmLSK8Eqp9cHy7g51dEh18Nyvglw3aup/cGleLr7UYjZ+gQnfnOefifiPAEhPkDhcQmcyxn1sJTFOlNyZj5NRCmWZTSkqW5qtEJ8tDIuJbs4N43JZyL3qPqz9Tf0Iw48ITahJ97oWhr4hnE1js6uaG0tjQrhjDi61RVOi3rvcrvkWPPSQzWD1VWoms0WT7xFqLfmTiw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VgD513CnW7Cnv2NkpNG6OpPUMuAKEBnc0sjA00HpdEw=; b=fy3bAzlYM6QAUq3dgkTcTD3nc7+rgoz2a3OTht3vqq0z7mhN5h24vtPizGnvwIUYoGeVsCWKPKxP1BuznlghGXWU8lv8SBzqcA074lKIl5jTpclzwTpVLtUvSrVOqpyIYJHrleZ6ldLjW9fWidLUc4SvJFsF9doWj0XKYJAdRV0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:31 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:31 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 84/96] cl8k: add tx.c Date: Tue, 24 May 2022 14:34:50 +0300 Message-Id: <20220524113502.1094459-85-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c2204166-cb8c-47a7-6c7a-08da3d79fcc9 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: KikxTzTUIEOlSG4+HUdeNzSdrO9PmHT/nh5cDkEDhPFdnCGqdl8s+o6ONvKkvTpayqN7A3+Qm9TlewPemsFUPzYyiuXqncFmp7uP8d2l0R1CmB5f51/YlJwW8wNqcNaEwgYfYIF2pg4DzXkGgliDOWsiUsUHeP4o5AQQ0W9tZOZ582qtdTj8C0eEqAtlI7bN7SUboj8t1YMLQYdNJmS7Z+pQPba3sIgOxFB4y4rXKLGBCfpdUnithNT/Ez9bYbiEZxMRkJQp/Z67f568Vev6qljbvPslA/Or3KKXqWcB+mV2I4m4q+v/sO+Fe63J/ZL8zYxO+EjjKi9YlshEpQKmh40wzynCVL3MKUCyeYJD+xa6ZTLE4WKvX/zgqEZpHfELEQJatJafxcxF8zBuF42cTmc5uXnjFbXD/GaUpPXYd8NUKFGWfJmiJQUdRswVOJCFeI4wXMwm+i/BXN8MwNh2/2p0SC2RBxC/1RdouFwUmBWRzULoMgZmN3fPKrpXgwoG7yvpQpViPc8pZHTr/fJcFw8HsBl+Cl/7VFXXHoxlhSx/fRCz71j5bLrX9XlslRb7aw/pJpWJs5DJb1MCi0wVMsWwM4zoo3r2UWFAhPEPVNUO9L0aJkNr/2XN+GJl0HZXmPcVHP8STdGgRcRR8iN10lhlZD2lu3EgYwDBL+yXUhS1nZu7kza+VtPdUdpbEhXjSJqAoeBAkp7MxsYgDA1wHwHVl8DQAgzC9UN+AJL5Po2BpoyxPawnLoKDrFIHQbT9 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001)(579004)(559001)(309714004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: YTsN+dIaVG+GQy+SwvtwT7U4cuhMMv8t+i11uY0tZl2eZMx/p3dvo07ZC2vOgnXR9ixf4uwT/pEJqmY7qKIyoXoG7G8L7gDdilhxniDhqTe7lv7uFQ0CapUa5a8k4hheQGLs/rtF2ulG6oSG6Z1B/4Ew3eOJb/vExZIxEFHhNOQ0eCEff6HW2GH3QI735UV8dpY1NRQgbm+RrPqCqvxRCjzQwR1WMSF758zGcolwY8xiHUhhn2u8dfus9Kgfi6XYWw5QlgcQaWXcZy4qpcfu30TK3jt0RrFGSYVe5RO4ndCCd6xPxU4uw/tct8WdmS3KaphGqzggAY7deZ1d3Z45fw5CVrHpJYbgDrv/aO/RgSUljmfbZfkoVTHvdFSXxXJMQG2qDW3HbpdmDFnsOMhsn1//bGTQ36KwnmMcPpfBO0TnoA/1IUweznzPgC6+uPslE109HKIouRyde5RToFFGJEfwph8rMrUvN+fRdIGZx+aAwwWOdf18W+bHvb/1LHWpD0ZyJvB48LaY14UPydYkYpaV63c0+OmQNl/ORAvcjsL7+8Mzo6rcrZlk5Tu3TQXXdzsmvuNABmtIvLz8ZEE0kOQnwJwp4XFGGyPHO66Lle0cIxI8mt8bZR9S+A4rSjWG87VAwsOEt8WdfVKtZdk35fl4qlJQj5Kw+5AWqpZgbJayPWbwgwEr6YwQdgMAqEmCYGVasB9pgG0SZZc3ErFn4+9r7s3WIs8ICiWVRsS+droopwihJkh+H4fhq+pTVOlSO93kk+rRbbBy+/YzlnnA5rBzuoWRQslVW4zC/17IR37xHmclqJQoLwZN8buLp5LjgrIsTlDUdNS7EnlAkB1CSMIcN1DXT0OsxWbyjHxTZzIFrhZR7wJMnh9tJrYGC9J7Ufhpm+Qs5q89Q9SWe4suPwOPtxLUMIXzpMJtBfeiJFWzpCGk/5y2oosM4oh21VI1SMDf4t9Cj+7MyEUSfhQ3lv05zrUP1d9PNjZQEmJgnA8Wy8g7Z0BgEmmqFKziLqfZOPZUZp2DquDQrU9nXZYND7c3hJsCv6YPcCK8ldCCw0QvzpmUAmporvBXwJg9ZNKHIdo7UXhw4KhOI+Sf9Qu0C8GLP6xcqudkbleL0dREzAtzZokQhvUDjBRrJjAG1Z88FzCWbFRF4rT781n0VHzLrBd9bjIEiHnsEMDna37ZRQBGSaMET5cN+JBuDHfgvbiVd+CWQNoVtGjwx8pF6oQ1xWw+67AX1LPZKhUE7ipVeeTBwwYO2oEysMucZj7EHBGaPsDKwuBDUPz/E7yKEkGkurIpMAZ5lQFKff9yFlIhuZAC2wAhOsWhsvm7444Xjv0esX7mTwt5aBmoTAOykM9C5uFzAfStVlXX4KeDr3Z321UKORDyrZwwaRExZJVAo/REiEFKTqXqQC1cK9+7OjnBwcghmLgyQuPHRr8wFCENxZCPfB8wRLQekEHglBJRsBYBrdkFg9I/NgIvoEl9vn1zSzprpUbzEpE/X+dWZi0xEz2z6aP/d6xB8rF3GkxgbpgzEorQ8hVUVSd1sp4ngeQqyVJHCzzzc22R9KgcchTyP6mAqyI0bxr0vV1a1U3rxPWgH8hl+KQdS0HUatzV1lwZRnt38uA36pKiFj/IolzOxIRZSg/SxX/lEEbpmyoZnCO+mNMR68J6n9OpJzZcx0s4FqAjmPSc+3nGcLlo2fNkK8ofZZL4q2yrjoR1HP41Ccja5xFE4itmlDCcLOSyJAngUCxKf68wBUxLZOcRAw1h9fE= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: c2204166-cb8c-47a7-6c7a-08da3d79fcc9 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:57.2911 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: a/hHB7pdupO8ZzwP0fICReXcWAzMBn0IislwnIOWXwsV66VF/X9+0V+IgyRe9eN0KmqnRXPwFxLpKR7T8ZYUrA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/tx.c | 3397 +++++++++++++++++++++++++ 1 file changed, 3397 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/tx.c diff --git a/drivers/net/wireless/celeno/cl8k/tx.c b/drivers/net/wireless/celeno/cl8k/tx.c new file mode 100644 index 000000000000..52a8d558f3f2 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/tx.c @@ -0,0 +1,3397 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "mac_addr.h" +#include "sta.h" +#include "hw.h" +#include "utils.h" +#include "fw.h" +#include "key.h" +#include "dfs.h" +#include "radio.h" +#include "enhanced_tim.h" +#include "rates.h" +#include "stats.h" +#include "debug.h" +#include "tx.h" + +/* Expected Acknowledgment */ +#define EXPECTED_NO_ACK 0 +#define EXPECTED_ACK 1 + +void cl_tx_update_hist_tstamp(struct cl_tx_queue *tx_queue, struct sk_buff *skb, + u32 tstamp_hist[], bool update_skb_ktime) +{ + s64 diff_ms; + ktime_t ktime = ktime_get(); + + diff_ms = ktime_ms_delta(ktime, skb->tstamp); + + if (diff_ms >= DELAY_HIST_SIZE) + diff_ms = DELAY_HIST_SIZE - 1; + + tstamp_hist[diff_ms]++; + + if (update_skb_ktime) + skb->tstamp = ktime; +} + +static void cl_tx_cpu_single(struct cl_hw *cl_hw) +{ + u32 processor_id = smp_processor_id(); + + if (processor_id < CPU_MAX_NUM) + cl_hw->cpu_cntr.tx_single[processor_id]++; +} + +static void cl_tx_cpu_agg(struct cl_hw *cl_hw) +{ + u32 processor_id = smp_processor_id(); + + if (processor_id < CPU_MAX_NUM) + cl_hw->cpu_cntr.tx_agg[processor_id]++; +} + +static char cl_tx_ctrl_single_frame_type(__le16 fc) +{ + if (ieee80211_is_data_qos(fc)) + return CL_TX_SINGLE_FRAME_TYPE_QOS_DATA; + else if (ieee80211_is_qos_nullfunc(fc)) + return CL_TX_SINGLE_FRAME_TYPE_QOS_NULL; + else if (ieee80211_is_mgmt(fc)) + return CL_TX_SINGLE_FRAME_TYPE_MANAGEMENT; + else + return CL_TX_SINGLE_FRAME_TYPE_OTHER; +} + +static void cl_tx_single_prep(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + u16 frame_len, u8 hdr_pads, bool is_vns) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + struct txdesc *txdesc = &sw_txhdr->txdesc; + struct tx_host_info *host_info = &txdesc->host_info; + struct cl_vif *cl_vif = NULL; + + /* Reset txdesc */ + memset(txdesc, 0, sizeof(struct txdesc)); + + /* Vif_index must be filled in even without header conversion */ + cl_vif = (struct cl_vif *)tx_info->control.vif->drv_priv; + host_info->vif_index = cl_vif->vif_index; + + if (hdr_pads) + host_info->host_padding |= BIT(0); + + host_info->is_bcn = sw_txhdr->is_bcn; + host_info->expected_ack = (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ? + EXPECTED_NO_ACK : EXPECTED_ACK; + + /* Beware when prot and sta is unknown */ + if (key_conf) { + frame_len += key_conf->icv_len; + host_info->is_protected = true; + host_info->hw_key_idx = key_conf->hw_key_idx; + } + + host_info->packet_cnt = 1; + + txdesc->umacdesc.packet_len[0] = cpu_to_le16(frame_len); + txdesc->e2w_txhdr_param.frame_ctrl = sw_txhdr->fc; + txdesc->e2w_result.bcmc = (sw_txhdr->sta_idx == STA_IDX_INVALID); + txdesc->e2w_result.tid = sw_txhdr->tid; + txdesc->e2w_result.is_vns = is_vns; + txdesc->e2w_result.is_txinject = false; + txdesc->e2w_result.single_type = cl_tx_ctrl_single_frame_type(sw_txhdr->fc); + txdesc->e2w_result.single_valid_sta__agg_e2w_tx_done = !!sw_txhdr->cl_sta; + txdesc->e2w_natt_param.sta_index = sw_txhdr->sta_idx; + + /* Set rate control */ + cl_rate_ctrl_update_desc_single(cl_hw, host_info, sw_txhdr); +} + +static void cl_tx_sub_frame_set(struct cl_sta *cl_sta, u8 tid) +{ + struct cl_tx_queue *tx_queue = cl_sta->agg_tx_queues[tid]; + + if (tx_queue) + tx_queue->total_packets++; +} + +static void cl_tx_send(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + struct cl_amsdu_ctrl *amsdu_anchor) +{ + struct cl_tx_queue *tx_queue = sw_txhdr->tx_queue; + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + + tx_queue->total_packets++; + + if (cl_txq_is_fw_full(tx_queue) || (cl_sta && cl_sta->pause_tx)) { + /* If firmware is full push the packet to the queue */ + cl_txq_push(cl_hw, sw_txhdr); + } else if (amsdu_anchor && amsdu_anchor->is_sw_amsdu) { + cl_txq_push(cl_hw, sw_txhdr); + tasklet_schedule(&cl_hw->tx_task); + } else if (!list_empty(&tx_queue->hdrs) || cl_hw->tx_db.force_amsdu) { + /* + * If queue in driver is not empty push the packet to the queue, + * and call cl_txq_sched() to transfer packets from the queue to firmware + */ + cl_txq_push(cl_hw, sw_txhdr); + cl_txq_sched(cl_hw, tx_queue); + } else { + /* Push the packet directly to firmware */ + cl_tx_push(cl_hw, sw_txhdr, tx_queue); + } +} + +void cl_tx_push(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, struct cl_tx_queue *tx_queue) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + struct ieee80211_key_conf *keyconf = tx_info->control.hw_key; + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + struct cl_vif *cl_vif = sw_txhdr->cl_vif; + u8 tid = sw_txhdr->tid; + struct txdesc *txdesc = &sw_txhdr->txdesc; + struct tx_host_info *host_info = &txdesc->host_info; + struct cl_e2w_txhdr_param *e2w_txhdr_param = &txdesc->e2w_txhdr_param; + struct ieee80211_hdr *hdr80211 = sw_txhdr->hdr80211; + u8 queue_type = tx_queue->type; + bool is_mgmt = ieee80211_is_mgmt(sw_txhdr->fc); + + if (cl_key_is_cipher_ccmp_gcmp(keyconf)) { + /* + * In case of CCMP or GCMP encryption we need to inc pn. + * In case of amsdu/header_conversion we need to pass it to firmware as well + */ + u64 pn = atomic64_inc_return(&keyconf->tx_pn); + + if (txdesc->e2w_natt_param.hdr_conv_enable) { + memcpy(&e2w_txhdr_param->encrypt_pn, &pn, CL_CCMP_GCMP_PN_SIZE); + } else { + u8 hdrlen = ieee80211_hdrlen(sw_txhdr->fc); + + cl_key_ccmp_gcmp_pn_to_hdr((u8 *)hdr80211 + hdrlen, pn, keyconf->keyidx); + } + } + + if (queue_type == QUEUE_TYPE_AGG) { + struct cl_baw *baw = &cl_sta->baws[tid]; + bool is_amsdu = cl_tx_ctrl_is_amsdu(tx_info); + + if (is_amsdu) { + struct cl_amsdu_ctrl *amsdu_anchor = &cl_sta->amsdu_anchor[tid]; + + if (sw_txhdr->is_sw_amsdu) { + u8 pkt_cnt = sw_txhdr->sw_amsdu_packet_cnt; + + if (pkt_cnt == 1) + cl_tx_amsdu_unset(sw_txhdr); /* Clear AMSDU bit. */ + + if (hdr80211) + hdr80211->seq_ctrl = cpu_to_le16(baw->tid_seq); + + tx_queue->stats_sw_amsdu_cnt[pkt_cnt - 1]++; + } else { + u8 pkt_cnt = host_info->packet_cnt; + + if (pkt_cnt == 1) + cl_tx_amsdu_unset(sw_txhdr); /* Clear AMSDU bit. */ + + tx_queue->stats_hw_amsdu_cnt[pkt_cnt - 1]++; + } + + /* Reset anchor if needed */ + if (amsdu_anchor->sw_txhdr == sw_txhdr) + cl_tx_amsdu_anchor_init(amsdu_anchor); + } + + if (hdr80211) + hdr80211->seq_ctrl = cpu_to_le16(baw->tid_seq); + + /* Update sequence number and increase it */ + e2w_txhdr_param->seq_ctrl = cpu_to_le16(baw->tid_seq); + baw->tid_seq = INC_SN(baw->tid_seq); + + } else { + /* + * Update sequence number and increase it + * Management sequence number is set by firmware. + */ + if (!is_mgmt) { + hdr80211->seq_ctrl |= cpu_to_le16(cl_vif->sequence_number); + cl_vif->sequence_number = INC_SN(cl_vif->sequence_number); + } else { + if (ieee80211_vif_is_mesh(cl_vif->vif)) { + struct ieee80211_mgmt *mgmt = (void *)sw_txhdr->skb->data; + u16 capab; + + if (mgmt->u.action.u.addba_req.action_code == + WLAN_ACTION_ADDBA_RESP) { + capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); + capab &= ~IEEE80211_ADDBA_PARAM_AMSDU_MASK; + mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); + } + } + } + } + + cl_drv_ops_pkt_fw_send(cl_hw, sw_txhdr, tx_queue); +} + +void cl_tx_single_free_skb(struct cl_hw *cl_hw, struct sk_buff *skb) +{ + if (IEEE80211_SKB_CB(skb)->ack_frame_id) + ieee80211_tx_status(cl_hw->hw, skb); + else + dev_kfree_skb_any(skb); +} + +void cl_tx_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool is_vns, bool lock) +{ + struct cl_tx_queue *tx_queue; + struct cl_sw_txhdr *sw_txhdr; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct cl_vif *cl_vif = TX_INFO_TO_CL_VIF(cl_hw, tx_info); + struct ieee80211_hdr *hdr80211 = (struct ieee80211_hdr *)skb->data; + u8 hdr_pads = CL_SKB_DATA_ALIGN_PADS(hdr80211); + __le16 fc = hdr80211->frame_control; + u16 frame_len = (u16)skb->len; + u8 tid = ieee80211_is_data_qos(fc) ? ieee80211_get_tid(hdr80211) : 0; + u8 ac = tid_to_ac[tid]; + bool is_beacon = ieee80211_is_beacon(fc); + + cl_tx_cpu_single(cl_hw); + + if (unlikely(!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags))) { + cl_tx_single_free_skb(cl_hw, skb); + cl_hw->tx_packet_cntr.drop.dev_flags++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + if (unlikely(!cl_vif->tx_en || cl_hw->tx_disable_flags)) { + cl_tx_single_free_skb(cl_hw, skb); + cl_hw->tx_packet_cntr.drop.tx_disable++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + /* Check if packet length exceeds max size */ + if (unlikely(frame_len > CL_TX_MAX_FRAME_LEN_SINGLE)) { + cl_tx_single_free_skb(cl_hw, skb); + cl_dbg_err(cl_hw, "frame_len (%u) exceeds max size\n", frame_len); + cl_hw->tx_packet_cntr.drop.length_limit++; + cl_vif->trfc_cntrs[ac].tx_errors++; + return; + } + + if (cl_sta && cl_sta->key_disable) { + cl_tx_single_free_skb(cl_hw, skb); + cl_hw->tx_packet_cntr.drop.key_disable++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + /* Allocate sw_txhdr */ + sw_txhdr = cl_sw_txhdr_alloc(cl_hw); + + if (unlikely(!sw_txhdr)) { + cl_tx_single_free_skb(cl_hw, skb); + cl_dbg_verbose(cl_hw, "sw_txhdr alloc failed\n"); + cl_hw->tx_packet_cntr.drop.txhdr_alloc_fail++; + cl_vif->trfc_cntrs[ac].tx_errors++; + return; + } + + /* Prepare sw_txhdr */ + sw_txhdr->hdr80211 = hdr80211; + sw_txhdr->hw_queue = tx_info->hw_queue; + sw_txhdr->is_bcn = is_beacon; + sw_txhdr->skb = skb; + sw_txhdr->map_len = frame_len + hdr_pads; + sw_txhdr->fc = fc; + sw_txhdr->cl_vif = cl_vif; + sw_txhdr->tid = tid; + sw_txhdr->ac = ac; + + if (cl_sta) { + sw_txhdr->cl_sta = cl_sta; + sw_txhdr->sta_idx = cl_sta->sta_idx; + } else { + sw_txhdr->cl_sta = NULL; + sw_txhdr->sta_idx = STA_IDX_INVALID; + } + + /* Prepare txdesc */ + cl_tx_single_prep(cl_hw, sw_txhdr, frame_len, hdr_pads, is_vns); + + /* + * Fetch the driver queue. + * IEEE80211_TX_CTL_AMPDU is not set in tx_info->flags, otherwise cl_tx_agg() + * would have been called and not cl_tx_single(). + * Therefore there is no need to check if tx_queue is NULL or if queue type + * is QUEUE_TYPE_AGG. + */ + tx_queue = cl_txq_get(cl_hw, sw_txhdr); + if (!tx_queue) { + cl_tx_single_free_skb(cl_hw, skb); + cl_dbg_verbose(cl_hw, "tx_queue is NULL\n"); + cl_vif->trfc_cntrs[ac].tx_errors++; + cl_sw_txhdr_free(cl_hw, sw_txhdr); + return; + } + + sw_txhdr->tx_queue = tx_queue; + + if (lock) { + if (tx_queue->type == QUEUE_TYPE_BCMC) { + /* + * All other broadcast/multicast packets are buffered in + * ieee80211_tx_h_multicast_ps_buf() and will follow the beacon. + */ + spin_lock_bh(&cl_hw->tx_lock_bcmc); + cl_tx_send(cl_hw, sw_txhdr, NULL); + spin_unlock_bh(&cl_hw->tx_lock_bcmc); + } else { + spin_lock_bh(&cl_hw->tx_lock_single); + cl_tx_send(cl_hw, sw_txhdr, NULL); + spin_unlock_bh(&cl_hw->tx_lock_single); + } + } else { + cl_tx_send(cl_hw, sw_txhdr, NULL); + } +} + +void cl_tx_fast_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool lock) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; + + /* hw_key must be set before calling cl_tx_8023_to_wlan() */ + tx_info->control.hw_key = cl_key_get(cl_sta); + + /* Convert 802.3 to 802.11 header */ + if (cl_tx_8023_to_wlan(cl_hw, skb, cl_sta, tid) == 0) { + bool is_vns = cl_vns_is_very_near(cl_hw, cl_sta, skb); + u8 ac = tid_to_ac[tid]; + + tx_info->hw_queue = ac; + tx_info->control.vif = cl_sta->cl_vif->vif; + + cl_hw->tx_packet_cntr.forward.drv_fast_single++; + + cl_tx_single(cl_hw, cl_sta, skb, is_vns, lock); + } +} + +void cl_tx_agg_prep(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + u16 frame_len, u8 hdr_pads, bool hdr_conv) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + struct txdesc *txdesc = &sw_txhdr->txdesc; + struct lmacapi *umacdesc = &txdesc->umacdesc; + struct tx_host_info *host_info = &txdesc->host_info; + u16 qos_ctrl = sw_txhdr->tid; + + /* Reset txdesc */ + memset(txdesc, 0, sizeof(struct txdesc)); + + txdesc->e2w_result.tid = sw_txhdr->tid; + txdesc->e2w_result.is_txinject = false; + txdesc->e2w_natt_param.sta_index = sw_txhdr->sta_idx; + txdesc->e2w_natt_param.ampdu = true; + txdesc->e2w_natt_param.hdr_conv_enable = hdr_conv; + + if (hdr_conv) { + if (cl_tx_ctrl_is_amsdu(tx_info)) + qos_ctrl |= IEEE80211_QOS_CTL_A_MSDU_PRESENT; + + txdesc->e2w_txhdr_param.frame_ctrl = sw_txhdr->fc; + txdesc->e2w_txhdr_param.qos_ctrl = cpu_to_le16(qos_ctrl); + } + + if (hdr_pads) + host_info->host_padding |= BIT(0); + + /* Vif_index must be filled in even without header conversion */ + host_info->vif_index = sw_txhdr->cl_sta->cl_vif->vif_index; + + /* Set the expected_ack flag */ + host_info->expected_ack = (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ? + EXPECTED_NO_ACK : EXPECTED_ACK; + + if (key_conf) { + host_info->is_protected = true; + host_info->hw_key_idx = key_conf->hw_key_idx; + + if (!hdr_conv) + frame_len += key_conf->icv_len; + } + + host_info->packet_cnt = 1; + umacdesc->packet_len[0] = cpu_to_le16(frame_len); + + /* Set rate control */ + cl_rate_ctrl_update_desc_agg(cl_hw, host_info); +} + +static __le16 cl_tx_agg_frame_control(struct cl_vif *cl_vif, + struct ieee80211_key_conf *key_conf, + u8 *hdrlen) +{ + struct ieee80211_vif *vif = cl_vif->vif; + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + enum nl80211_iftype type = vif->type; + __le16 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); + + if (type == NL80211_IFTYPE_AP) { + fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); + *hdrlen = 26; + } else if (type == NL80211_IFTYPE_STATION) { + fc |= cpu_to_le16(IEEE80211_FCTL_TODS); + + if (sdata->u.mgd.use_4addr) { + fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); + *hdrlen = 32; + } else { + *hdrlen = 26; + } + } + + if (key_conf) + fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); + + return fc; +} + +static void _cl_tx_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool hdr_conv) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct cl_tx_queue *tx_queue = NULL; + struct cl_vif *cl_vif = cl_sta->cl_vif; + u16 frame_len = (u16)skb->len; + u16 total_frame_len = 0; + u8 hdr_pads = CL_SKB_DATA_ALIGN_PADS(skb->data); + u8 is_amsdu = cl_tx_ctrl_is_amsdu(tx_info); + u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + u8 ac = tid_to_ac[tid]; + u8 hdrlen = 0; + + cl_tx_cpu_agg(cl_hw); + + if (unlikely(!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags))) { + kfree_skb(skb); + cl_hw->tx_packet_cntr.drop.dev_flags++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + if (unlikely(!cl_vif->tx_en || cl_hw->tx_disable_flags)) { + kfree_skb(skb); + cl_hw->tx_packet_cntr.drop.tx_disable++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + /* Check if packet length exceeds max size */ + if (unlikely(frame_len > CL_TX_MAX_FRAME_LEN_AGG)) { + kfree_skb(skb); + cl_dbg_err(cl_hw, "frame_len exceeds max size %d\n", frame_len); + cl_hw->tx_packet_cntr.drop.length_limit++; + cl_vif->trfc_cntrs[ac].tx_errors++; + return; + } + + if (cl_sta->key_disable) { + kfree_skb(skb); + cl_hw->tx_packet_cntr.drop.key_disable++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + /* Check if amsdu is enable for current skb */ + if (is_amsdu) { + enum cl_amsdu_result amsdu_res = cl_tx_amsdu_set(cl_hw, cl_sta, skb, tid); + + switch (amsdu_res) { + case CL_AMSDU_SKIP: + is_amsdu = false; + tx_info->control.flags &= ~IEEE80211_TX_CTRL_AMSDU; + case CL_AMSDU_ANCHOR_SET: + /* + * If new anchor was set, or AMSDU is + * skipped continue building sw_txhdr + */ + break; + case CL_AMSDU_SUB_FRAME_SET: + cl_tx_sub_frame_set(cl_sta, tid); + fallthrough; + case CL_AMSDU_FAILED: + default: + return; + } + } else { + /* + * If not amsdu & anchor exist. reset current anchor + * in order to avoid reordring packets. + */ + if (cl_sta->amsdu_anchor[tid].sw_txhdr) + cl_tx_amsdu_anchor_init(&cl_sta->amsdu_anchor[tid]); + } + + /* Allocate sw_txhdr */ + sw_txhdr = cl_sw_txhdr_alloc(cl_hw); + if (unlikely(!sw_txhdr)) { + kfree_skb(skb); + cl_dbg_err(cl_hw, "sw_txhdr alloc failed\n"); + cl_hw->tx_packet_cntr.drop.txhdr_alloc_fail++; + cl_vif->trfc_cntrs[ac].tx_errors++; + return; + } + + if (cl_vif->vif->type == NL80211_IFTYPE_MESH_POINT) + tx_info->hw_queue = ac; + + /* Fill sw_txhdr */ + sw_txhdr->tid = tid; + sw_txhdr->ac = ac; + sw_txhdr->hw_queue = tx_info->hw_queue; + sw_txhdr->cl_sta = cl_sta; + sw_txhdr->sta_idx = cl_sta->sta_idx; + sw_txhdr->is_bcn = 0; + sw_txhdr->skb = skb; + sw_txhdr->map_len = frame_len + hdr_pads; + sw_txhdr->cl_vif = cl_vif; + + if (cl_sta->amsdu_anchor[tid].is_sw_amsdu) { + sw_txhdr->is_sw_amsdu = true; + sw_txhdr->sw_amsdu_packet_cnt = 1; + } else { + sw_txhdr->is_sw_amsdu = false; + } + + if (hdr_conv) { + sw_txhdr->hdr80211 = NULL; + sw_txhdr->fc = cl_tx_agg_frame_control(cl_vif, key_conf, &hdrlen); + } else { + struct ieee80211_hdr *hdr80211 = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr80211->frame_control; + + sw_txhdr->hdr80211 = hdr80211; + sw_txhdr->fc = fc; + hdrlen = ieee80211_hdrlen(fc); + } + + /* Fetch the relevant agg queue */ + tx_queue = cl_sta->agg_tx_queues[tid]; + + if (unlikely(!tx_queue)) { + kfree_skb(skb); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + cl_dbg_err(cl_hw, "tx_queue is NULL [sta_idx = %u] [tid = %u]\n", + cl_sta->sta_idx, tid); + cl_hw->tx_packet_cntr.drop.queue_null++; + cl_vif->trfc_cntrs[ac].tx_dropped++; + return; + } + + sw_txhdr->tx_queue = tx_queue; + + total_frame_len = frame_len + hdrlen - sizeof(struct ethhdr); + + if (key_conf) + total_frame_len += key_conf->icv_len; + + /* Prepare txdesc */ + cl_tx_agg_prep(cl_hw, sw_txhdr, frame_len, hdr_pads, hdr_conv); + + /* + * AMSDU - first sub frame + * !!! Must be done after calling cl_tx_agg_prep() !!! + */ + if (is_amsdu) + cl_tx_amsdu_first_sub_frame(sw_txhdr, cl_sta, skb, tid); + + cl_tx_send(cl_hw, sw_txhdr, &cl_sta->amsdu_anchor[tid]); +} + +void cl_tx_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool hdr_conv, bool lock) +{ + if (lock) { + spin_lock_bh(&cl_hw->tx_lock_agg); + _cl_tx_agg(cl_hw, cl_sta, skb, hdr_conv); + spin_unlock_bh(&cl_hw->tx_lock_agg); + } else { + _cl_tx_agg(cl_hw, cl_sta, skb, hdr_conv); + } +} + +static void cl_tx_reset_session_timer(struct ieee80211_sta *sta, u8 tid) +{ + struct tid_ampdu_tx *tid_tx = NULL; + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(sta); + + tid_tx = rcu_dereference(stainfo->ampdu_mlme.tid_tx[tid]); + + if (tid_tx && tid_tx->timeout) + tid_tx->last_tx = jiffies; +} + +void cl_tx_fast_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool lock) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = cl_sta->cl_vif->vif; + u16 ac = skb_get_queue_mapping(skb); + u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + + tx_info->control.vif = vif; + tx_info->control.hw_key = cl_key_get(cl_sta); + tx_info->hw_queue = vif->hw_queue[ac]; + tx_info->flags |= IEEE80211_TX_CTL_AMPDU; + + if (cl_sta->baws[tid].amsdu && + (cl_wrs_api_get_tx_sta_data_rate(cl_sta) > cl_hw->conf->ci_tx_amsdu_min_data_rate)) + tx_info->control.flags |= IEEE80211_TX_CTRL_AMSDU; + + cl_tx_agg(cl_hw, cl_sta, skb, true, lock); + cl_tx_reset_session_timer(cl_sta->sta, tid); + cl_hw->tx_packet_cntr.forward.drv_fast_agg++; +} + +void cl_tx_wlan_to_8023(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ethhdr tmp_eth; + struct ethhdr *ehdr; + struct { + u8 hdr[ETH_ALEN]__aligned(2); + __be16 proto; + } payload; + u16 hdrlen = ieee80211_hdrlen(hdr->frame_control); + u8 enc_len = cl_key_get_cipher_len(skb); + + cl_mac_addr_copy(tmp_eth.h_dest, ieee80211_get_DA(hdr)); + cl_mac_addr_copy(tmp_eth.h_source, ieee80211_get_SA(hdr)); + skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); + tmp_eth.h_proto = payload.proto; + + if (enc_len) { + memcpy(skb->data + hdrlen, + skb->data + hdrlen + enc_len, + skb->len - hdrlen - enc_len); + skb_trim(skb, skb->len - enc_len); + } + + if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && + tmp_eth.h_proto != htons(ETH_P_AARP) && + tmp_eth.h_proto != htons(ETH_P_IPX)) || + ether_addr_equal(payload.hdr, bridge_tunnel_header))) + /* Remove RFC1042 or Bridge-Tunnel encapsulation and replace ether_type */ + hdrlen += ETH_ALEN + 2; + else + tmp_eth.h_proto = htons(skb->len - hdrlen); + + skb_pull(skb, hdrlen); + ehdr = skb_push(skb, sizeof(struct ethhdr)); + memcpy(ehdr, &tmp_eth, sizeof(tmp_eth)); +} + +u16 cl_tx_prepare_wlan_hdr(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, struct ieee80211_hdr *hdr) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + u16 hdrlen = 0; + __le16 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); + struct ieee80211_vif *vif = cl_sta->cl_vif->vif; + + if (tx_info->control.hw_key) + fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); + + switch (vif->type) { + case NL80211_IFTYPE_AP: + fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); + /* DA BSSID SA */ + memcpy(hdr->addr1, skb->data, ETH_ALEN); + memcpy(hdr->addr2, vif->addr, ETH_ALEN); + memcpy(hdr->addr3, skb->data + ETH_ALEN, ETH_ALEN); + hdrlen = 24; + break; + case NL80211_IFTYPE_STATION: + { + struct wireless_dev *wdev = skb->dev->ieee80211_ptr; + + if (wdev && wdev->use_4addr) { + fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS); + /* RA TA DA SA */ + memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN); + memcpy(hdr->addr2, vif->addr, ETH_ALEN); + memcpy(hdr->addr3, skb->data, ETH_ALEN); + memcpy(hdr->addr4, skb->data + ETH_ALEN, ETH_ALEN); + hdrlen = 30; + } else { + fc |= cpu_to_le16(IEEE80211_FCTL_TODS); + /* BSSID SA DA */ + memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN); + memcpy(hdr->addr2, skb->data + ETH_ALEN, ETH_ALEN); + memcpy(hdr->addr3, skb->data, ETH_ALEN); + hdrlen = 24; + } + } + break; + case NL80211_IFTYPE_MESH_POINT: + cl_dbg_trace(cl_hw, "vif type mesh_point, invalid tx path\n"); + return 0; + default: + cl_dbg_err(cl_hw, "Unknown vif type %d !!!\n", vif->type); + return 0; + } + + if (cl_sta->sta->wme) { + fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + hdrlen += 2; + } + + hdr->frame_control = fc; + hdr->duration_id = 0; + hdr->seq_ctrl = 0; + + return hdrlen; +} + +int cl_tx_8023_to_wlan(struct cl_hw *cl_hw, struct sk_buff *skb, struct cl_sta *cl_sta, u8 tid) +{ + struct ieee80211_hdr hdr; + int head_need, ret = 0; + u16 ethertype, hdrlen; + const u8 *encaps_data = NULL; + int encaps_len = 0, skip_header_bytes = ETH_HLEN; + u8 enc_len = cl_key_get_cipher_len(skb); + + /* Convert Ethernet header to proper 802.11 header */ + ethertype = (skb->data[12] << 8) | skb->data[13]; + + hdrlen = cl_tx_prepare_wlan_hdr(cl_hw, cl_sta, skb, &hdr); + if (!hdrlen) { + ret = -EINVAL; + goto free; + } + + if (ethertype >= ETH_P_802_3_MIN) { + encaps_data = rfc1042_header; + encaps_len = sizeof(rfc1042_header); + skip_header_bytes -= 2; + } + + skb_pull(skb, skip_header_bytes); + head_need = hdrlen + enc_len + encaps_len - skb_headroom(skb); + + if (head_need > 0) { + head_need = ((head_need + 3) & ~3); + if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { + ret = -ENOMEM; + goto free; + } + } + + if (encaps_data) + memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len); + + skb_push(skb, hdrlen + enc_len); + + if (cl_sta->sta->wme) { + u16 qos_ctrl = tid; + + memcpy(skb->data, &hdr, hdrlen - 2); + memcpy(skb->data + hdrlen - 2, &qos_ctrl, 2); + } else { + memcpy(skb->data, &hdr, hdrlen); + } + + skb_reset_mac_header(skb); + + return ret; +free: + cl_hw->tx_packet_cntr.drop.build_hdr_fail++; + cl_sta->cl_vif->trfc_cntrs[tid_to_ac[tid]].tx_errors++; + kfree_skb(skb); + skb = NULL; + + return ret; +} + +void cl_tx_check_start_ba_session(struct cl_hw *cl_hw, + struct ieee80211_sta *sta, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct sta_info *stainfo = IEEE80211_STA_TO_STAINFO(sta); + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + u8 tid; + + /* TODO: What about HE? */ + if (!sta->ht_cap.ht_supported && + !sta->vht_cap.vht_supported && + !cl_band_is_6g(cl_hw)) + return; + + if (test_sta_flag(stainfo, WLAN_STA_PS_STA)) + return; + + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + !(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) + return; + + if (cl_tx_ctrl_is_eapol(tx_info)) + return; + + if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) + return; + + if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) + return; + + tid = ieee80211_get_tid(hdr); + + if (likely(stainfo->ampdu_mlme.tid_tx[tid])) + return; + + ieee80211_start_tx_ba_session(sta, tid, cl_hw->conf->ce_tx_ba_session_timeout); +} + +static void cl_tx_handle_beacon_tim(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct cl_hw *cl_hw = (struct cl_hw *)hw->priv; + struct cl_sta *cl_sta = NULL; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, mgmt->u.beacon.variable, skb->len); + struct ieee80211_tim_ie *tim = NULL; + + /* Offset of the element */ + tim = (void *)(tim_ie + BCN_IE_TIM_BIT_OFFSET); + + cl_sta_lock(cl_hw); + + /* Loop through all STA's */ + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) { + if (cl_traffic_is_sta_tx_exist(cl_hw, cl_sta)) { + u8 sta_aid = cl_sta->sta->aid; + u8 map_index = sta_aid / BITS_PER_BYTE; + + /* Update STA's AID in TIM bit */ + tim->virtual_map[map_index] |= BIT(sta_aid % BITS_PER_BYTE); + } + } + + cl_sta_unlock(cl_hw); +} + +static struct sk_buff *cl_tx_beacon_get(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct sk_buff *skb = NULL; + + skb = ieee80211_beacon_get(hw, vif); + + /* Handle beacon TIM bitmap */ + if (skb) + cl_tx_handle_beacon_tim(hw, skb); + + return skb; +} + +static void cl_tx_mc(struct cl_vif *cl_vif, int *mc_fw_free) +{ + struct cl_hw *cl_hw = cl_vif->cl_hw; + struct ieee80211_vif *vif = cl_vif->vif; + struct sk_buff *skb = NULL; + struct ieee80211_tx_info *tx_info; + + if (unlikely(!vif)) + return; + + while (((*mc_fw_free) > 0) && + (skb = ieee80211_get_buffered_bc(cl_hw->hw, vif))) { + /* Route this MCBC frame to the BCN ipc queue */ + tx_info = IEEE80211_SKB_CB(skb); + tx_info->hw_queue = CL_HWQ_BCN; + + (*mc_fw_free)--; + + /* Clear more data bit if this is the last frame in this SP */ + if (*mc_fw_free == 0) { + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *)skb->data; + hdr->frame_control &= + cpu_to_le16(~IEEE80211_FCTL_MOREDATA); + } + + cl_tx_single(cl_hw, NULL, skb, false, true); + } +} + +void cl_tx_bcn_mesh_task(unsigned long data) +{ + struct cl_vif *cl_vif = NULL; + struct cl_hw *cl_hw = NULL; + struct ieee80211_tx_info *tx_info; + struct sk_buff *skb; + int mc_fw_free; + + cl_vif = (struct cl_vif *)data; + if (!cl_vif) + return; + + cl_hw = cl_vif->cl_hw; + + if (!cl_hw || !cl_vif->vif || cl_vif->vif->type != NL80211_IFTYPE_MESH_POINT || + cl_radio_is_off(cl_hw) || + cl_recovery_in_progress(cl_hw) || + !test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags) || + cl_hw->tx_disable_flags) + return; + + skb = cl_tx_beacon_get(cl_hw->hw, cl_vif->vif); + if (!skb) + return; + + /* Route this BCN to the BCN ipc queue */ + tx_info = IEEE80211_SKB_CB(skb); + tx_info->hw_queue = CL_HWQ_BCN; + + cl_tx_single(cl_hw, NULL, skb, false, true); + + mc_fw_free = cl_hw->tx_queues->bcmc.fw_free_space; + cl_tx_mc(cl_vif, &mc_fw_free); +} + +static void cl_tx_bcn(struct cl_vif *cl_vif) +{ + struct cl_hw *cl_hw = cl_vif->cl_hw; + struct ieee80211_vif *vif = cl_vif->vif; + struct ieee80211_tx_info *tx_info; + struct sk_buff *skb; + + if (!vif || vif->type != NL80211_IFTYPE_AP) + return; + + /* + * If we are in the middle of the CAC, we allow regular channel switch + * and retrigger the CAC (If needed). + * Or - if radar is detected, we wait for all CSAs to be transmitted, + * before allowing channel switch + */ + if (cl_dfs_is_in_cac(cl_hw) && vif->csa_active) { + ieee80211_csa_finish(vif); + return; + } + + skb = cl_tx_beacon_get(cl_hw->hw, vif); + if (!skb) + return; + + /* Route this BCN to the BCN ipc queue */ + tx_info = IEEE80211_SKB_CB(skb); + tx_info->hw_queue = CL_HWQ_BCN; + + cl_tx_single(cl_hw, NULL, skb, false, true); +} + +bool cl_is_tx_allowed(struct cl_hw *cl_hw) +{ + return !(cl_radio_is_off(cl_hw) || + cl_hw->vif_db.num_iface_bcn == 0 || + cl_recovery_in_progress(cl_hw) || + cl_hw->tx_db.block_bcn || + cl_hw->tx_disable_flags || + !test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)); +} + +/* cl_tx_bcns_tasklet - generate BCNs and TX buffered MC frames each BCN DTIM interval + * + * Beacons are sent first followed by cyclic MC for fairness between VIF's + * the FW buffer is restricted to "IPC_TXDESC_CNT_BCMC" buffer size. + */ +void cl_tx_bcns_tasklet(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + struct cl_vif *cl_vif = NULL; + int mc_fw_free = 0; + + read_lock(&cl_hw->vif_db.lock); + + if (!cl_is_tx_allowed(cl_hw)) + goto out; + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + cl_tx_bcn(cl_vif); + + cl_vif = cl_hw->mc_vif; + mc_fw_free = cl_hw->tx_queues->bcmc.fw_free_space; + + do { + cl_tx_mc(cl_vif, &mc_fw_free); + /* Cl_vif_get_next() is cyclic */ + cl_vif = cl_vif_get_next(cl_hw, cl_vif); + } while ((cl_vif != cl_hw->mc_vif) && mc_fw_free); + + cl_hw->mc_vif = cl_vif_get_next(cl_hw, cl_hw->mc_vif); + +out: + read_unlock(&cl_hw->vif_db.lock); +} + +void cl_tx_en(struct cl_hw *cl_hw, u8 reason, bool enable) +{ + unsigned long tx_disable_flags_prev = cl_hw->tx_disable_flags; + + if (enable) { + clear_bit(reason, &cl_hw->tx_disable_flags); + + if (tx_disable_flags_prev != 0 && cl_hw->tx_disable_flags == 0) + if (cl_hw->conf->ci_backup_bcn_en) + cl_msg_tx_backup_bcn_en(cl_hw, true); + } else { + set_bit(reason, &cl_hw->tx_disable_flags); + + if (tx_disable_flags_prev == 0) + if (cl_hw->conf->ci_backup_bcn_en) + cl_msg_tx_backup_bcn_en(cl_hw, false); + } +} + +static void cl_tx_flush(struct cl_hw *cl_hw) +{ + /* Flush bcmc */ + spin_lock_bh(&cl_hw->tx_lock_bcmc); + cl_bcmc_cfm_flush_queue(cl_hw, NULL); + spin_unlock_bh(&cl_hw->tx_lock_bcmc); + + /* Flush single */ + spin_lock_bh(&cl_hw->tx_lock_single); + cl_txq_flush_all_single(cl_hw); + cl_single_cfm_flush_all(cl_hw); + spin_unlock_bh(&cl_hw->tx_lock_single); + + /* Flush agg */ + spin_lock_bh(&cl_hw->tx_lock_agg); + cl_txq_flush_all_agg(cl_hw); + cl_agg_cfm_flush_all(cl_hw); + spin_unlock_bh(&cl_hw->tx_lock_agg); +} + +void cl_tx_off(struct cl_hw *cl_hw) +{ + cl_txq_stop(cl_hw); + cl_tx_flush(cl_hw); +} + +void cl_tx_drop_skb(struct sk_buff *skb) +{ + skb->dev->stats.rx_dropped++; + kfree_skb(skb); +} + +#define AGG_POLL_TIMEOUT 50 + +/* + * cl_hw->agg_cfm_queues: + * These queues are used to keep pointers to skb's sent + * as aggregation and waiting for confirmation. + */ + +void cl_agg_cfm_init(struct cl_hw *cl_hw) +{ + int i = 0; + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + INIT_LIST_HEAD(&cl_hw->agg_cfm_queues[i].head); +} + +void cl_agg_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, u8 agg_idx) +{ + spin_lock(&cl_hw->tx_lock_cfm_agg); + list_add_tail(&sw_txhdr->cfm_list, &cl_hw->agg_cfm_queues[agg_idx].head); + spin_unlock(&cl_hw->tx_lock_cfm_agg); +} + +static void cl_agg_cfm_amsdu_free(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + struct cl_amsdu_txhdr *amsdu_txhdr = NULL; + struct cl_amsdu_txhdr *tmp = NULL; + struct sk_buff *sub_skb = NULL; + struct ieee80211_tx_info *tx_info_sub_skb = NULL; + + list_for_each_entry_safe(amsdu_txhdr, tmp, &sw_txhdr->amsdu_txhdr.list, list) { + sub_skb = amsdu_txhdr->skb; + tx_info_sub_skb = IEEE80211_SKB_CB(sub_skb); + + list_del(&amsdu_txhdr->list); + dma_unmap_single(cl_hw->chip->dev, amsdu_txhdr->dma_addr, + (size_t)sub_skb->len, DMA_TO_DEVICE); + kfree_skb(sub_skb); + cl_tx_amsdu_txhdr_free(cl_hw, amsdu_txhdr); + } +} + +void cl_agg_cfm_free_head_skb(struct cl_hw *cl_hw, + struct cl_agg_cfm_queue *cfm_queue, + u8 ba_queue_idx) +{ + struct cl_sw_txhdr *sw_txhdr = list_first_entry(&cfm_queue->head, + struct cl_sw_txhdr, + cfm_list); + struct sk_buff *skb = sw_txhdr->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + dma_addr_t dma_addr = le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]); + + if (cl_hw->conf->ci_tx_delay_tstamp_en) + cl_tx_update_hist_tstamp(cfm_queue->tx_queue, skb, + cfm_queue->tx_queue->hist_push_to_cfm, false); + + dma_unmap_single(cl_hw->chip->dev, dma_addr, sw_txhdr->map_len, DMA_TO_DEVICE); + + /* If amsdu list not empty free sub MSDU frames first, including amsdu_txhdr */ + if (cl_tx_ctrl_is_amsdu(tx_info)) + if (!list_empty(&sw_txhdr->amsdu_txhdr.list)) + cl_agg_cfm_amsdu_free(cl_hw, sw_txhdr); + + consume_skb(skb); + list_del(&sw_txhdr->cfm_list); + cl_sw_txhdr_free(cl_hw, sw_txhdr); +} + +static void cl_agg_cfm_flush_queue(struct cl_hw *cl_hw, u8 agg_idx) +{ + struct cl_agg_cfm_queue *cfm_queue = &cl_hw->agg_cfm_queues[agg_idx]; + struct cl_tx_queue *tx_queue = cfm_queue->tx_queue; + struct sk_buff *skb = NULL; + struct cl_sw_txhdr *sw_txhdr = NULL; + dma_addr_t dma_addr = 0; + struct ieee80211_tx_info *tx_info; + + if (!tx_queue) + return; + + if (list_empty(&cfm_queue->head)) + return; + + do { + sw_txhdr = list_first_entry(&cfm_queue->head, struct cl_sw_txhdr, cfm_list); + skb = sw_txhdr->skb; + + dma_addr = le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]); + dma_unmap_single(cl_hw->chip->dev, dma_addr, sw_txhdr->map_len, DMA_TO_DEVICE); + + tx_info = IEEE80211_SKB_CB(skb); + + /* If amsdu list not empty free sub MSDU frames first, including amsdu_txhdr */ + if (cl_tx_ctrl_is_amsdu(tx_info)) + if (!list_empty(&sw_txhdr->amsdu_txhdr.list)) + cl_agg_cfm_amsdu_free(cl_hw, sw_txhdr); + + tx_queue->total_fw_cfm++; + + kfree_skb(skb); + list_del(&sw_txhdr->cfm_list); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + } while (!list_empty(&cfm_queue->head)); + + /* + * Set fw_free_space back to maximum after flushing the queue + * and clear the enhanced TIM. + */ + tx_queue->fw_free_space = tx_queue->fw_max_size; + cl_enhanced_tim_clear_tx_agg(cl_hw, agg_idx, tx_queue->hw_index, + tx_queue->cl_sta, tx_queue->tid); + + cfm_queue->tx_queue = NULL; +} + +void cl_agg_cfm_flush_all(struct cl_hw *cl_hw) +{ + int i = 0; + + /* Don't use BH lock, because cl_agg_cfm_flush_all() is called with BH disabled */ + spin_lock(&cl_hw->tx_lock_cfm_agg); + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + cl_agg_cfm_flush_queue(cl_hw, i); + + spin_unlock(&cl_hw->tx_lock_cfm_agg); +} + +static void cl_agg_cfm_poll_timeout(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, + u8 agg_idx, bool flush) +{ + /* + * When polling failed clear the enhanced TIM so that firmware will + * not try to transmit these packets. + * If flush is set cl_enhanced_tim_clear_tx_agg() is called inside + * cl_agg_cfm_flush_queue(). + */ + cl_dbg_err(cl_hw, "Polling timeout (queue_idx = %u)\n", agg_idx); + + spin_lock_bh(&cl_hw->tx_lock_cfm_agg); + + if (flush) + cl_agg_cfm_flush_queue(cl_hw, agg_idx); + else + cl_enhanced_tim_clear_tx_agg(cl_hw, agg_idx, tx_queue->hw_index, + tx_queue->cl_sta, tx_queue->tid); + + spin_unlock_bh(&cl_hw->tx_lock_cfm_agg); +} + +void cl_agg_cfm_poll_empty(struct cl_hw *cl_hw, u8 agg_idx, bool flush) +{ + struct cl_agg_cfm_queue *cfm_queue = &cl_hw->agg_cfm_queues[agg_idx]; + bool empty = false; + int i = 0; + + if (test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)) + return; + + while (true) { + spin_lock_bh(&cl_hw->tx_lock_cfm_agg); + empty = list_empty(&cfm_queue->head); + spin_unlock_bh(&cl_hw->tx_lock_cfm_agg); + + if (empty) + return; + + if (++i == AGG_POLL_TIMEOUT) { + cl_agg_cfm_poll_timeout(cl_hw, cfm_queue->tx_queue, agg_idx, flush); + return; + } + + msleep(20); + } +} + +void cl_agg_cfm_poll_empty_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + int i = 0; + struct cl_tx_queue *tx_queue = NULL; + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + tx_queue = cl_sta->agg_tx_queues[i]; + + if (tx_queue) + cl_agg_cfm_poll_empty(cl_hw, tx_queue->index, false); + } +} + +void cl_agg_cfm_clear_tim_bit_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + int i = 0; + struct cl_tx_queue *tx_queue = NULL; + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + tx_queue = cl_sta->agg_tx_queues[i]; + + if (tx_queue) { + spin_lock_bh(&cl_hw->tx_lock_agg); + cl_enhanced_tim_clear_tx_agg(cl_hw, tx_queue->index, tx_queue->hw_index, + tx_queue->cl_sta, tx_queue->tid); + spin_unlock_bh(&cl_hw->tx_lock_agg); + } + } +} + +void cl_agg_cfm_set_ssn(struct cl_hw *cl_hw, u16 ssn, u8 idx) +{ + spin_lock_bh(&cl_hw->tx_lock_cfm_agg); + cl_hw->agg_cfm_queues[idx].ssn = ssn; + spin_unlock_bh(&cl_hw->tx_lock_cfm_agg); +} + +void cl_agg_cfm_set_tx_queue(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, u8 idx) +{ + spin_lock_bh(&cl_hw->tx_lock_cfm_agg); + cl_hw->agg_cfm_queues[idx].tx_queue = tx_queue; + spin_unlock_bh(&cl_hw->tx_lock_cfm_agg); +} + +static bool cl_is_same_rate(struct cl_agg_tx_report *agg_report, + struct cl_wrs_rate_params *rate_params) +{ + union cl_rate_ctrl_info rate_ctrl_info = { + .word = le32_to_cpu(agg_report->rate_cntrl_info)}; + u8 mcs = U8_MAX, nss = U8_MAX; + + if (agg_report->bw_requested != rate_params->bw) + return false; + + cl_rate_ctrl_parse(&rate_ctrl_info, &nss, &mcs); + + return ((mcs == rate_params->mcs) && (nss == rate_params->nss)); +} + +static void cl_sync_tx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report, + struct cl_wrs_info *wrs_info, struct cl_wrs_params *wrs_params) +{ + if (!agg_report->is_fallback && cl_is_same_rate(agg_report, &wrs_params->rate_params)) { + cl_wrs_api_rate_sync(cl_hw, cl_sta, wrs_params); + + wrs_info->synced = true; + wrs_info->quick_rate_check = true; + wrs_info->quick_rate_agg_cntr = 0; + wrs_info->quick_rate_pkt_cntr = 0; + } else { + wrs_info->sync_attempts++; + } +} + +static void cl_ba_not_received_handler(struct cl_hw *cl_hw, struct cl_wrs_info *wrs_info, + struct cl_agg_tx_report *agg_report) +{ + /* Ignore 'BA not received' if station is in power-save or if RTS limit was reached */ + if (agg_report->is_sta_ps || agg_report->is_rts_retry_limit_reached) + return; + + /* Count number of consecutive 'BA not received' */ + wrs_info->ba_not_rcv_consecutive++; + + /* Save longest sequence of consecutive 'BA not received' */ + if (wrs_info->ba_not_rcv_consecutive > wrs_info->ba_not_rcv_consecutive_max) + wrs_info->ba_not_rcv_consecutive_max = wrs_info->ba_not_rcv_consecutive; + + if (cl_hw->wrs_db.ba_not_rcv_collision_filter) { + /* + * First 'BA not received' - might just be a collision. + * Don't add fail to ba_not_rcv but keep aside. + * Second consecutive 'BA not received' - not likely to be a collisions. + * Add fail to ba_not_rcv including previous fail that was kept aside. + * More than two consecutive 'BA not received' - very unlikely to be a collisions. + * Add fail to ba_not_rcv. + */ + if (wrs_info->ba_not_rcv_consecutive == 1) + wrs_info->fail_prev = agg_report->fail; + else if (wrs_info->ba_not_rcv_consecutive == 2) + wrs_info->ba_not_rcv += (agg_report->fail + wrs_info->fail_prev); + else + wrs_info->ba_not_rcv += agg_report->fail; + } else { + wrs_info->ba_not_rcv += agg_report->fail; + } +} + +void cl_agg_tx_report_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report) +{ + struct cl_wrs_info *wrs_info = NULL; + struct cl_wrs_params *wrs_params = NULL; + u8 group_id; + bool skip_epr_update = false; + union cl_rate_ctrl_info rate_ctrl_info = { + .word = le32_to_cpu(agg_report->rate_cntrl_info)}; + + wrs_params = &cl_sta->wrs_sta.tx_su_params; + wrs_info = &cl_sta->wrs_info_tx_su; + group_id = 0; + + /* Retry_count for cl_wlan */ + cl_sta->retry_count += agg_report->success_after_retry; + + /* + * In case of big packets (4300 in VHT and 5400 in HE) and low + * rate (BW 20, NSS 1, MCS 0), firmware will increase rate to MCS 1, + * and give an indication to driver (set rate_fix_mcs1 in cl_agg_tx_report). + * WRS should also move to MCS 1, and give the maximum time + * penalty time from MCS 0 toMCS 1. + */ + if (agg_report->rate_fix_mcs1 && + !agg_report->is_fallback && + cl_wrs_api_up_mcs1(cl_hw, cl_sta, wrs_params)) + return; + + /* WRS sync mechanism */ + if (!wrs_info->synced) + cl_sync_tx_rate(cl_hw, cl_sta, agg_report, wrs_info, wrs_params); + + if (agg_report->bf && cl_sta->bf_db.is_on && !cl_sta->bf_db.synced) { + cl_sta->bf_db.synced = true; + /* Resetting the WRS UP weights */ + cl_wrs_api_beamforming_sync(cl_hw, cl_sta); + } + + if (agg_report->ba_not_received) { + cl_ba_not_received_handler(cl_hw, wrs_info, agg_report); + } else { + if (!skip_epr_update) + wrs_info->fail += agg_report->fail; + + wrs_info->ba_not_rcv_consecutive = 0; + } + + if (!skip_epr_update) { + u8 mcs = 0, nss = 0, bw = 0; + u16 data_rate = 0; + + switch (agg_report->bw_requested) { + case CHNL_BW_160: + bw = (cl_hw->wrs_db.adjacent_interference20 || + cl_hw->wrs_db.adjacent_interference40 || + cl_hw->wrs_db.adjacent_interference80) ? + rate_ctrl_info.field.bw : agg_report->bw_requested; + break; + case CHNL_BW_80: + bw = (cl_hw->wrs_db.adjacent_interference20 || + cl_hw->wrs_db.adjacent_interference40) ? + rate_ctrl_info.field.bw : agg_report->bw_requested; + break; + case CHNL_BW_40: + bw = cl_hw->wrs_db.adjacent_interference20 ? + rate_ctrl_info.field.bw : agg_report->bw_requested; + break; + case CHNL_BW_20: + bw = agg_report->bw_requested; + break; + } + + cl_rate_ctrl_parse(&rate_ctrl_info, &nss, &mcs); + + data_rate = cl_data_rates_get_x10(rate_ctrl_info.field.format_mod, + bw, + nss, + mcs, + rate_ctrl_info.field.gi); + + wrs_info->epr_acc += ((u64)agg_report->success * data_rate); + wrs_info->success += agg_report->success; + } + + if (cl_hw->wrs_db.quick_down_en && + wrs_info->quick_rate_check && + cl_is_same_rate(agg_report, &wrs_params->rate_params)) { + wrs_info->quick_rate_agg_cntr++; + wrs_info->quick_rate_pkt_cntr += (agg_report->success + agg_report->fail); + + if (wrs_info->quick_rate_agg_cntr >= cl_hw->wrs_db.quick_down_agg_thr && + wrs_info->quick_rate_pkt_cntr > cl_hw->wrs_db.quick_down_pkt_thr) { + wrs_info->quick_rate_check = false; + cl_wrs_api_quick_down_check(cl_hw, cl_sta, wrs_params); + } + } +} + +void cl_agg_tx_report_simulate_for_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_hw_tx_status *status) +{ + /* Assign statistics struct */ + struct cl_agg_tx_report agg_report; + union cl_rate_ctrl_info rate_ctrl_info; + + memset(&agg_report, 0, sizeof(struct cl_agg_tx_report)); + + agg_report.bf = status->bf; + agg_report.success = status->frm_successful; + agg_report.fail = status->num_mpdu_retries + (status->frm_successful ? 0 : 1); + agg_report.success_after_retry = + (status->frm_successful && status->num_mpdu_retries); + agg_report.retry_limit_reached = !status->frm_successful; + agg_report.success_more_one_retry = + (status->frm_successful && (status->num_mpdu_retries > 1)); + agg_report.sta_idx = cl_sta->sta_idx; + agg_report.bw_requested = status->bw_requested; + + rate_ctrl_info.field.bw = status->bw_transmitted; + rate_ctrl_info.field.gi = status->gi; + rate_ctrl_info.field.format_mod = status->format_mod; + rate_ctrl_info.field.mcs_index = status->mcs_index; + + cl_rate_ctrl_convert(&rate_ctrl_info); + + agg_report.rate_cntrl_info = cpu_to_le32(rate_ctrl_info.word); + cl_agg_tx_report_handler(cl_hw, cl_sta, &agg_report); + cl_stats_update_tx_single(cl_hw, cl_sta, &agg_report); +} + +void cl_baw_init(struct cl_sta *cl_sta) +{ + u8 tid; + + for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) + __skb_queue_head_init(&cl_sta->baws[tid].pending); +} + +void cl_baw_start(struct cl_baw *baw, u16 ssn) +{ + baw->ssn = ssn; + baw->action_start = true; +} + +void cl_baw_operational(struct cl_hw *cl_hw, struct cl_baw *baw, + u8 fw_agg_idx, bool amsdu_supported) +{ + baw->fw_agg_idx = fw_agg_idx; + baw->tid_seq = IEEE80211_SN_TO_SEQ(baw->ssn); + baw->action_start = false; + baw->amsdu = (cl_hw->txamsdu_en && amsdu_supported); +} + +void cl_baw_stop(struct cl_baw *baw) +{ + baw->action_start = false; +} + +void cl_baw_pending_to_agg(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u8 tid) +{ + struct cl_baw *baw = &cl_sta->baws[tid]; + struct sk_buff *skb; + + while (!skb_queue_empty(&baw->pending)) { + skb = __skb_dequeue(&baw->pending); + cl_tx_fast_agg(cl_hw, cl_sta, skb, false); + } +} + +void cl_baw_pending_to_single(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + struct cl_baw *baw) +{ + struct sk_buff *skb; + + while (!skb_queue_empty(&baw->pending)) { + skb = __skb_dequeue(&baw->pending); + cl_tx_fast_single(cl_hw, cl_sta, skb, false); + } +} + +void cl_baw_pending_purge(struct cl_baw *baw) +{ + if (!skb_queue_empty(&baw->pending)) + __skb_queue_purge(&baw->pending); +} + +/* + * cl_hw->bcmc_cfm_queue: + * This queue is used to keep pointers to already sent + * beacon skb's that are waiting for confirmation. + */ + +static void cl_bcmc_free_sw_txhdr(struct cl_hw *cl_hw, + struct cl_sw_txhdr *sw_txhdr) +{ + dma_addr_t dma_addr; + struct sk_buff *skb = NULL; + + dma_addr = le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]); + skb = sw_txhdr->skb; + + dma_unmap_single(cl_hw->chip->dev, dma_addr, sw_txhdr->map_len, DMA_TO_DEVICE); + dev_kfree_skb_irq(skb); + list_del(&sw_txhdr->cfm_list); + cl_sw_txhdr_free(cl_hw, sw_txhdr); +} + +static bool cl_bcmc_is_list_empty_per_vif(struct cl_hw *cl_hw, + struct cl_vif *cl_vif) +{ + struct cl_single_cfm_queue *cfm_queue = &cl_hw->bcmc_cfm_queue; + struct cl_sw_txhdr *sw_txhdr = NULL; + + list_for_each_entry(sw_txhdr, &cfm_queue->head, cfm_list) + if (sw_txhdr->cl_vif == cl_vif) + return false; + + return true; +} + +void cl_bcmc_cfm_init(struct cl_hw *cl_hw) +{ + INIT_LIST_HEAD(&cl_hw->bcmc_cfm_queue.head); +} + +void cl_bcmc_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + list_add_tail(&sw_txhdr->cfm_list, &cl_hw->bcmc_cfm_queue.head); +} + +struct cl_sw_txhdr *cl_bcmc_cfm_find(struct cl_hw *cl_hw, dma_addr_t dma_addr, bool keep_in_list) +{ + struct cl_single_cfm_queue *cfm_queue = &cl_hw->bcmc_cfm_queue; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct cl_sw_txhdr *tmp = NULL; + + list_for_each_entry_safe(sw_txhdr, tmp, &cfm_queue->head, cfm_list) { + if (le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]) == dma_addr) { + if (!keep_in_list) + list_del(&sw_txhdr->cfm_list); + + return sw_txhdr; + } + } + + return NULL; +} + +void cl_bcmc_cfm_flush_queue(struct cl_hw *cl_hw, + struct cl_vif *cl_vif) +{ + struct cl_single_cfm_queue *cfm_queue = &cl_hw->bcmc_cfm_queue; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct cl_sw_txhdr *tmp = NULL; + + /* Only flush the specific cl_vif related confirmations */ + if (cl_vif) { + list_for_each_entry_safe(sw_txhdr, tmp, &cfm_queue->head, cfm_list) { + if (sw_txhdr->cl_vif == cl_vif) { + cl_bcmc_free_sw_txhdr(cl_hw, sw_txhdr); + cl_hw->tx_queues->bcmc.fw_free_space++; + } + } + + return; + } + + while (!list_empty(&cfm_queue->head)) { + sw_txhdr = list_first_entry(&cfm_queue->head, struct cl_sw_txhdr, cfm_list); + cl_bcmc_free_sw_txhdr(cl_hw, sw_txhdr); + } + + /* Set fw_free_space back to maximum after flushing the queue */ + cl_hw->tx_queues->bcmc.fw_free_space = cl_hw->tx_queues->bcmc.fw_max_size; +} + +void cl_bcmc_cfm_poll_empty_per_vif(struct cl_hw *cl_hw, + struct cl_vif *cl_vif) +{ + bool empty = false; + int i = 0; + + if (test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)) + return; + + while (i++ < BCMC_POLL_TIMEOUT) { + spin_lock_bh(&cl_hw->tx_lock_bcmc); + empty = cl_bcmc_is_list_empty_per_vif(cl_hw, cl_vif); + spin_unlock_bh(&cl_hw->tx_lock_bcmc); + + if (empty) + return; + + msleep(20); + } + + cl_dbg_err(cl_hw, "Polling timeout vif_index %d\n", cl_vif->vif_index); + + spin_lock_bh(&cl_hw->tx_lock_bcmc); + cl_bcmc_cfm_flush_queue(cl_hw, cl_vif); + spin_unlock_bh(&cl_hw->tx_lock_bcmc); +} + +/* + * cl_hw->single_cfm_queues: + * These queues are used to keep pointers to skb's sent + * as singles and waiting for confirmation. + */ + +#define SINGLE_POLL_TIMEOUT 50 + +void cl_single_cfm_init(struct cl_hw *cl_hw) +{ + int i = 0; + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + INIT_LIST_HEAD(&cl_hw->single_cfm_queues[i].head); +} + +void cl_single_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, u32 queue_idx) +{ + list_add_tail(&sw_txhdr->cfm_list, &cl_hw->single_cfm_queues[queue_idx].head); +} + +struct cl_sw_txhdr *cl_single_cfm_find(struct cl_hw *cl_hw, u32 queue_idx, + dma_addr_t dma_addr) +{ + struct cl_single_cfm_queue *cfm_queue = NULL; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct cl_sw_txhdr *tmp = NULL; + + if (queue_idx >= MAX_SINGLE_QUEUES) + return NULL; + + cfm_queue = &cl_hw->single_cfm_queues[queue_idx]; + + list_for_each_entry_safe(sw_txhdr, tmp, &cfm_queue->head, cfm_list) + if (le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]) == dma_addr) { + list_del(&sw_txhdr->cfm_list); + + return sw_txhdr; + } + + return NULL; +} + +static void cl_single_cfm_flush_queue(struct cl_hw *cl_hw, u32 queue_idx) +{ + struct cl_single_cfm_queue *cfm_queue = &cl_hw->single_cfm_queues[queue_idx]; + struct cl_tx_queue *tx_queue = NULL; + struct cl_sw_txhdr *sw_txhdr = NULL; + struct sk_buff *skb = NULL; + struct ieee80211_tx_info *tx_info = NULL; + dma_addr_t dma_addr; + + if (list_empty(&cfm_queue->head)) + return; + + do { + sw_txhdr = list_first_entry(&cfm_queue->head, struct cl_sw_txhdr, cfm_list); + dma_addr = le32_to_cpu(sw_txhdr->txdesc.umacdesc.packet_addr[0]); + skb = sw_txhdr->skb; + tx_info = IEEE80211_SKB_CB(skb); + + dma_unmap_single(cl_hw->chip->dev, dma_addr, sw_txhdr->map_len, DMA_TO_DEVICE); + + cl_tx_single_free_skb(cl_hw, skb); + list_del(&sw_txhdr->cfm_list); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + } while (!list_empty(&cfm_queue->head)); + + /* + * Set fw_free_space back to maximum after flushing the queue + * and clear the enhanced TIM. + */ + tx_queue = &cl_hw->tx_queues->single[queue_idx]; + tx_queue->fw_free_space = tx_queue->fw_max_size; + cl_enhanced_tim_clear_tx_single(cl_hw, queue_idx, tx_queue->hw_index, + false, tx_queue->cl_sta, tx_queue->tid); +} + +void cl_single_cfm_flush_all(struct cl_hw *cl_hw) +{ + u32 i = 0; + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + cl_single_cfm_flush_queue(cl_hw, i); +} + +void cl_single_cfm_flush_sta(struct cl_hw *cl_hw, u8 sta_idx) +{ + /* Flush all single confirmation queues of this sta, and reset write index */ + u8 ac; + u16 queue_idx; + + spin_lock_bh(&cl_hw->tx_lock_single); + + for (ac = 0; ac < AC_MAX; ac++) { + queue_idx = QUEUE_IDX(sta_idx, ac); + cl_single_cfm_flush_queue(cl_hw, queue_idx); + + cl_hw->ipc_env->ring_indices_elem->indices->txdesc_write_idx.single[queue_idx] = 0; + } + + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +static void cl_single_cfm_poll_timeout(struct cl_hw *cl_hw, u32 queue_idx) +{ + /* + * When polling failed clear the enhanced TIM so that firmware will + * not try to transmit these packets. + */ + struct cl_tx_queue *tx_queue = &cl_hw->tx_queues->single[queue_idx]; + + cl_dbg_err(cl_hw, "Polling timeout (queue_idx = %u)\n", queue_idx); + + spin_lock_bh(&cl_hw->tx_lock_single); + cl_enhanced_tim_clear_tx_single(cl_hw, queue_idx, tx_queue->hw_index, + false, tx_queue->cl_sta, tx_queue->tid); + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +void cl_single_cfm_poll_empty(struct cl_hw *cl_hw, u32 queue_idx) +{ + struct cl_single_cfm_queue *cfm_queue = &cl_hw->single_cfm_queues[queue_idx]; + bool empty = false; + int i = 0; + + if (test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)) + return; + + while (true) { + spin_lock_bh(&cl_hw->tx_lock_single); + empty = list_empty(&cfm_queue->head); + spin_unlock_bh(&cl_hw->tx_lock_single); + + if (empty) + return; + + if (++i == SINGLE_POLL_TIMEOUT) { + cl_single_cfm_poll_timeout(cl_hw, queue_idx); + return; + } + + msleep(20); + } +} + +static bool cl_list_hp_empty_sta(struct cl_hw *cl_hw, u8 sta_idx) +{ + struct cl_single_cfm_queue *hp_cfm_queue = &cl_hw->single_cfm_queues[HIGH_PRIORITY_QUEUE]; + struct cl_sw_txhdr *sw_txhdr = NULL; + + list_for_each_entry(sw_txhdr, &hp_cfm_queue->head, cfm_list) + if (sw_txhdr->sta_idx == sta_idx) + return false; + + return true; +} + +static void cl_single_cfm_poll_empty_hp(struct cl_hw *cl_hw, u8 sta_idx) +{ + bool empty = false; + int i = 0; + + if (test_bit(CL_DEV_FW_ERROR, &cl_hw->drv_flags)) + return; + + while (true) { + spin_lock_bh(&cl_hw->tx_lock_single); + empty = cl_list_hp_empty_sta(cl_hw, sta_idx); + spin_unlock_bh(&cl_hw->tx_lock_single); + + if (empty) + return; + + if (++i == SINGLE_POLL_TIMEOUT) { + cl_single_cfm_poll_timeout(cl_hw, HIGH_PRIORITY_QUEUE); + return; + } + + msleep(20); + } +} + +void cl_single_cfm_poll_empty_sta(struct cl_hw *cl_hw, u8 sta_idx) +{ + /* + * Poll all single queues belonging to this station, and poll all + * packets belonging to this station in the high priority queue. + */ + u8 ac; + u16 queue_idx; + + for (ac = 0; ac < AC_MAX; ac++) { + queue_idx = QUEUE_IDX(sta_idx, ac); + cl_single_cfm_poll_empty(cl_hw, queue_idx); + } + + cl_single_cfm_poll_empty_hp(cl_hw, sta_idx); +} + +void cl_single_cfm_clear_tim_bit_sta(struct cl_hw *cl_hw, u8 sta_idx) +{ + u8 ac; + u16 queue_idx; + struct cl_tx_queue *tx_queue = NULL; + + for (ac = 0; ac < AC_MAX; ac++) { + queue_idx = QUEUE_IDX(sta_idx, ac); + tx_queue = &cl_hw->tx_queues->single[queue_idx]; + + spin_lock_bh(&cl_hw->tx_lock_single); + cl_enhanced_tim_clear_tx_single(cl_hw, queue_idx, tx_queue->hw_index, + false, tx_queue->cl_sta, tx_queue->tid); + spin_unlock_bh(&cl_hw->tx_lock_single); + } + + tx_queue = &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE]; + + spin_lock_bh(&cl_hw->tx_lock_single); + cl_enhanced_tim_clear_tx_single(cl_hw, HIGH_PRIORITY_QUEUE, tx_queue->hw_index, + false, tx_queue->cl_sta, tx_queue->tid); + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +static int cl_sw_txhdr_init_pool(struct cl_hw *cl_hw, u16 sw_txhdr_pool) +{ + u16 i = 0; + u32 sw_txhdr_pool_size = sw_txhdr_pool * sizeof(struct cl_sw_txhdr); + struct cl_sw_txhdr *sw_txhdr; + + INIT_LIST_HEAD(&cl_hw->head_sw_txhdr_pool); + spin_lock_init(&cl_hw->lock_sw_txhdr_pool); + + for (i = 0; i < sw_txhdr_pool; i++) { + sw_txhdr = kzalloc(sizeof(*sw_txhdr), GFP_ATOMIC); + + if (unlikely(!sw_txhdr)) { + cl_dbg_verbose(cl_hw, "sw_txhdr NULL\n"); + return -1; + } + + list_add(&sw_txhdr->list_pool, &cl_hw->head_sw_txhdr_pool); + } + + cl_dbg_verbose(cl_hw, " - pool %u, size %u\n", sw_txhdr_pool, sw_txhdr_pool_size); + + return 0; +} + +static int cl_sw_txhdr_init_cache(struct cl_hw *cl_hw) +{ + char sw_txhdr_cache_name[MODULE_NAME_LEN + 32] = {0}; + + snprintf(sw_txhdr_cache_name, sizeof(sw_txhdr_cache_name), + "%s_sw_txhdr_cache", THIS_MODULE->name); + + cl_hw->sw_txhdr_cache = kmem_cache_create(sw_txhdr_cache_name, + sizeof(struct cl_sw_txhdr), + 0, + (SLAB_HWCACHE_ALIGN | SLAB_PANIC), + NULL); + + if (!cl_hw->sw_txhdr_cache) { + cl_dbg_verbose(cl_hw, "sw_txhdr_cache NULL\n"); + return -1; + } + + return 0; +} + +int cl_sw_txhdr_init(struct cl_hw *cl_hw) +{ + u16 sw_txhdr_pool = cl_hw->conf->ci_sw_txhdr_pool; + + if (sw_txhdr_pool) + return cl_sw_txhdr_init_pool(cl_hw, sw_txhdr_pool); + else + return cl_sw_txhdr_init_cache(cl_hw); +} + +static void cl_sw_txhdr_deinit_pool(struct cl_hw *cl_hw) +{ + struct cl_sw_txhdr *sw_txhdr, *tmp; + + list_for_each_entry_safe(sw_txhdr, tmp, &cl_hw->head_sw_txhdr_pool, list_pool) { + list_del(&sw_txhdr->list_pool); + kfree(sw_txhdr); + } +} + +static void cl_sw_txhdr_deinit_cache(struct cl_hw *cl_hw) +{ + kmem_cache_destroy(cl_hw->sw_txhdr_cache); +} + +void cl_sw_txhdr_deinit(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_sw_txhdr_pool) + cl_sw_txhdr_deinit_pool(cl_hw); + else + cl_sw_txhdr_deinit_cache(cl_hw); +} + +static inline struct cl_sw_txhdr *cl_sw_txhdr_alloc_pool(struct cl_hw *cl_hw) +{ + struct cl_sw_txhdr *sw_txhdr = NULL; + + spin_lock_bh(&cl_hw->lock_sw_txhdr_pool); + sw_txhdr = list_first_entry_or_null(&cl_hw->head_sw_txhdr_pool, + struct cl_sw_txhdr, list_pool); + + if (sw_txhdr) { + list_del(&sw_txhdr->list_pool); + spin_unlock_bh(&cl_hw->lock_sw_txhdr_pool); + return sw_txhdr; + } + + spin_unlock_bh(&cl_hw->lock_sw_txhdr_pool); + return NULL; +} + +static inline struct cl_sw_txhdr *cl_sw_txhdr_alloc_cache(struct cl_hw *cl_hw) +{ + return kmem_cache_alloc(cl_hw->sw_txhdr_cache, GFP_ATOMIC); +} + +struct cl_sw_txhdr *cl_sw_txhdr_alloc(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_sw_txhdr_pool) + return cl_sw_txhdr_alloc_pool(cl_hw); + else + return cl_sw_txhdr_alloc_cache(cl_hw); +} + +static inline void cl_sw_txhdr_free_pool(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + spin_lock_bh(&cl_hw->lock_sw_txhdr_pool); + list_add_tail(&sw_txhdr->list_pool, &cl_hw->head_sw_txhdr_pool); + spin_unlock_bh(&cl_hw->lock_sw_txhdr_pool); +} + +static inline void cl_sw_txhdr_free_cache(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + kmem_cache_free(cl_hw->sw_txhdr_cache, sw_txhdr); +} + +void cl_sw_txhdr_free(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + if (cl_hw->conf->ci_sw_txhdr_pool) + cl_sw_txhdr_free_pool(cl_hw, sw_txhdr); + else + cl_sw_txhdr_free_cache(cl_hw, sw_txhdr); +} + +#define CL_AMSDU_HDR_LEN 14 + +static bool cl_tx_amsdu_is_sw(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, u16 pkt_len) +{ + bool syn_rst_push = false; + bool tcp_ack = false; + + if (cl_hw->conf->ci_tx_sw_amsdu_max_packets <= 1) + return false; + + tcp_ack = cl_is_tcp_ack(skb, &syn_rst_push); + + if (!tcp_ack || syn_rst_push) + return false; + + if ((cl_wrs_api_get_tx_sta_data_rate(cl_sta) * cl_sta->ampdu_min_spacing) <= + (pkt_len << 3)) + return false; + + return true; +} + +static int cl_tx_amsdu_anchor_set(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, u8 tid) +{ + /* + * Packet length calculation in HW - + * Add 802.11 header (maximum possible size) instead if 802.3 + * Add AMSDU header + * Add RFC1042 header (according to ether-type) + * Add IV and ICV (if there is encryption) + */ + struct cl_amsdu_ctrl *amsdu_anchor = &cl_sta->amsdu_anchor[tid]; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + u16 ethertype = (skb->data[12] << 8) | skb->data[13]; + u16 pkt_len = skb->len + CL_WLAN_HEADER_MAX_SIZE; + + if (key_conf) + pkt_len += (key_conf->iv_len + key_conf->icv_len); + + if (ethertype >= ETH_P_802_3_MIN) + pkt_len += sizeof(rfc1042_header); + + amsdu_anchor->rem_len = amsdu_anchor->max_len - pkt_len; + amsdu_anchor->packet_cnt = 1; + amsdu_anchor->is_sw_amsdu = cl_tx_amsdu_is_sw(cl_hw, cl_sta, skb, pkt_len); + + return CL_AMSDU_ANCHOR_SET; +} + +static void cl_tx_amsdu_anchor_umacdesc_update(struct txdesc *txdesc, u8 idx, + u16 len, dma_addr_t dma_addr, + bool is_padding) +{ + struct lmacapi *umacdesc = &txdesc->umacdesc; + + umacdesc->packet_len[idx] = cpu_to_le16(len); + umacdesc->packet_addr[idx] = cpu_to_le32(dma_addr); + txdesc->host_info.packet_cnt++; + + /* Update padding bit of current msdu sub-frame */ + if (is_padding) + txdesc->host_info.host_padding |= BIT(idx); +} + +static struct cl_amsdu_txhdr *cl_tx_amsdu_txhdr_alloc(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_amsdu_txhdr_pool) { + struct cl_amsdu_txhdr *amsdu_txhdr = + list_first_entry_or_null(&cl_hw->head_amsdu_txhdr_pool, + struct cl_amsdu_txhdr, + list_pool); + + if (amsdu_txhdr) { + list_del(&amsdu_txhdr->list_pool); + return amsdu_txhdr; + } + + return NULL; + } else { + return kmem_cache_alloc(cl_hw->amsdu_txhdr_cache, GFP_ATOMIC); + } +} + +static void _cl_tx_amsdu_transfer_single(struct cl_hw *cl_hw, + struct sk_buff *skb, + struct cl_sta *cl_sta, + u8 tid) +{ + struct ieee80211_tx_info *tx_info; + + tx_info = IEEE80211_SKB_CB(skb); + tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; + tx_info->control.flags &= ~IEEE80211_TX_CTRL_AMSDU; + + if (cl_tx_8023_to_wlan(cl_hw, skb, cl_sta, tid) == 0) { + cl_hw->tx_packet_cntr.transfer.agg_to_single++; + cl_tx_single(cl_hw, cl_sta, skb, false, false); + } +} + +static void cl_tx_amsdu_set_sw_sub_amsdu_hdr(struct sk_buff *skb) +{ + u16 ethertype = (skb->data[12] << 8) | skb->data[13]; + int rfc1042_len = 0; + void *data; + struct ethhdr *amsdu_hdr; + + if (ethertype >= ETH_P_802_3_MIN) + rfc1042_len = sizeof(rfc1042_header); + + data = skb_push(skb, rfc1042_len + 2); + memmove(data, data + rfc1042_len + 2, 2 * ETH_ALEN); + + amsdu_hdr = (struct ethhdr *)data; + amsdu_hdr->h_proto = cpu_to_be16(skb->len - ETH_HLEN); + + memcpy(data + ETH_HLEN, rfc1042_header, rfc1042_len); +} + +static int cl_tx_amsdu_add_sw_amsdu_hdr(struct cl_hw *cl_hw, + struct cl_amsdu_ctrl *amsdu_anchor) +{ + struct cl_sw_txhdr *anchor_sw_txhdr = amsdu_anchor->sw_txhdr; + struct sk_buff *skb = anchor_sw_txhdr->skb; + struct cl_sta *cl_sta = anchor_sw_txhdr->cl_sta; + struct ieee80211_hdr hdr; + u16 ethertype = (skb->data[12] << 8) | skb->data[13]; + u16 hdrlen = cl_tx_prepare_wlan_hdr(cl_hw, cl_sta, skb, &hdr); + int rfc1042_len = 0; + int head_need = 0; + u8 enc_len = cl_key_get_cipher_len(skb); + u16 qos_ctrl = anchor_sw_txhdr->tid | IEEE80211_QOS_CTL_A_MSDU_PRESENT; + + if (!hdrlen) + return -EINVAL; + + if (ethertype >= ETH_P_802_3_MIN) + rfc1042_len = sizeof(rfc1042_header); + + amsdu_anchor->hdrlen = hdrlen; + head_need = hdrlen + enc_len + rfc1042_len - skb_headroom(skb); + if (head_need > 0) { + head_need = ((head_need + 3) & ~3); + if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) + return -ENOMEM; + } + + cl_tx_amsdu_set_sw_sub_amsdu_hdr(skb); + + skb_push(skb, hdrlen + enc_len); + memcpy(skb->data, &hdr, hdrlen - 2); + memcpy(skb->data + hdrlen - 2, &qos_ctrl, 2); + skb_reset_mac_header(skb); + anchor_sw_txhdr->txdesc.e2w_natt_param.hdr_conv_enable = false; + anchor_sw_txhdr->hdr80211 = (struct ieee80211_hdr *)skb->data; + + return 0; +} + +static int cl_tx_amsdu_sw_aggregate(struct cl_hw *cl_hw, + struct cl_amsdu_ctrl *amsdu_anchor, + struct sk_buff *skb) +{ + struct cl_sw_txhdr *anchor_sw_txhdr = amsdu_anchor->sw_txhdr; + struct sk_buff *anchor_skb = anchor_sw_txhdr->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(anchor_skb); + struct ieee80211_key_conf *key_conf = tx_info->control.hw_key; + u16 total_frame_len = 0; + struct cl_tx_queue *tx_queue = anchor_sw_txhdr->tx_queue; + int head_pad = 0; + int sub_pad = 0; + bool syn_rst_push = false; + bool tcp_ack = cl_is_tcp_ack(skb, &syn_rst_push); + + /* Worst case: rfc1042(6) + ET(2) + pad(2) = 10 */ + if (!tcp_ack || + (skb_tailroom(anchor_skb) < (skb->len + 10))) { + if (tx_queue->num_packets == 1) + cl_txq_sched(cl_hw, tx_queue); + cl_tx_amsdu_anchor_init(amsdu_anchor); + return cl_tx_amsdu_anchor_set(cl_hw, anchor_sw_txhdr->cl_sta, + skb, anchor_sw_txhdr->tid); + } + + if (amsdu_anchor->packet_cnt == 1 && + cl_tx_amsdu_add_sw_amsdu_hdr(cl_hw, amsdu_anchor)) + return CL_AMSDU_FAILED; + + cl_tx_amsdu_set_sw_sub_amsdu_hdr(skb); + sub_pad = CL_SKB_DATA_ALIGN_PADS(anchor_skb->len - + amsdu_anchor->hdrlen); + memset(skb_push(skb, sub_pad), 0, sub_pad); + memcpy(skb_put(anchor_skb, skb->len), skb->data, skb->len); + + kfree_skb(skb); + amsdu_anchor->packet_cnt++; + anchor_sw_txhdr->sw_amsdu_packet_cnt++; + head_pad = CL_SKB_DATA_ALIGN_PADS(anchor_skb->data); + + if (head_pad) { + anchor_sw_txhdr->map_len = anchor_skb->len + head_pad; + anchor_sw_txhdr->txdesc.host_info.host_padding |= BIT(0); + } else { + anchor_sw_txhdr->map_len = anchor_skb->len; + anchor_sw_txhdr->txdesc.host_info.host_padding = 0; + } + + total_frame_len = anchor_skb->len; + if (key_conf) + total_frame_len += key_conf->icv_len; + + anchor_sw_txhdr->txdesc.umacdesc.packet_len[0] = cpu_to_le16(total_frame_len); + + if (amsdu_anchor->packet_cnt == cl_hw->conf->ci_tx_sw_amsdu_max_packets || + syn_rst_push) { + if (tx_queue->num_packets == 1) + cl_txq_sched(cl_hw, tx_queue); + cl_tx_amsdu_anchor_init(amsdu_anchor); + } + + return CL_AMSDU_SUB_FRAME_SET; +} + +void cl_tx_amsdu_anchor_init(struct cl_amsdu_ctrl *amsdu_anchor) +{ + amsdu_anchor->rem_len = amsdu_anchor->max_len; + amsdu_anchor->sw_txhdr = NULL; + amsdu_anchor->packet_cnt = 0; + amsdu_anchor->is_sw_amsdu = false; +} + +void cl_tx_amsdu_anchor_reset(struct cl_amsdu_ctrl *amsdu_anchor) +{ + amsdu_anchor->sw_txhdr = NULL; + amsdu_anchor->rem_len = 0; + amsdu_anchor->max_len = 0; + amsdu_anchor->packet_cnt = 0; + amsdu_anchor->is_sw_amsdu = false; +} + +void cl_tx_amsdu_set_max_len(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 tid) +{ + struct ieee80211_sta_vht_cap *vht_cap = &cl_sta->sta->vht_cap; + struct cl_amsdu_ctrl *amsdu_anchor = &cl_sta->amsdu_anchor[tid]; + u32 length = U32_MAX; + + amsdu_anchor->max_len = 3839; + + if (cl_band_is_6g(cl_hw)) { + u16 capa = le16_to_cpu(cl_sta->sta->he_6ghz_capa.capa); + + length = (capa & IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN) >> + HE_6GHZ_CAP_MAX_MPDU_LEN_OFFSET; + } else if (vht_cap->vht_supported) { + length = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK; + } + + switch (length) { + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895: + amsdu_anchor->max_len = 3895; + break; + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: + amsdu_anchor->max_len = 7991; + break; + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: + amsdu_anchor->max_len = 11454; + break; + default: + break; + } + + amsdu_anchor->rem_len = amsdu_anchor->max_len; + + cl_dbg_trace(cl_hw, "AMSDU supported - sta_idx=%u, max_len=%d\n", + cl_sta->sta_idx, amsdu_anchor->max_len); +} + +void cl_tx_amsdu_first_sub_frame(struct cl_sw_txhdr *sw_txhdr, struct cl_sta *cl_sta, + struct sk_buff *skb, u8 tid) +{ + /* Set the anchor sw_txhdr */ + cl_sta->amsdu_anchor[tid].sw_txhdr = sw_txhdr; + + INIT_LIST_HEAD(&sw_txhdr->amsdu_txhdr.list); + sw_txhdr->amsdu_txhdr.skb = skb; +} + +void cl_tx_amsdu_flush_sub_frames(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + struct cl_amsdu_txhdr *amsdu_txhdr = NULL, *tmp = NULL; + struct sk_buff *sub_skb = NULL; + + /* Free mid & last AMSDU sub frames */ + list_for_each_entry_safe(amsdu_txhdr, tmp, &sw_txhdr->amsdu_txhdr.list, list) { + sub_skb = amsdu_txhdr->skb; + list_del(&amsdu_txhdr->list); + + dma_unmap_single(cl_hw->chip->dev, amsdu_txhdr->dma_addr, + (size_t)sub_skb->len, DMA_TO_DEVICE); + kfree_skb(sub_skb); + cl_tx_amsdu_txhdr_free(cl_hw, amsdu_txhdr); + cl_hw->tx_packet_cntr.drop.queue_flush++; + sw_txhdr->cl_vif->trfc_cntrs[sw_txhdr->ac].tx_dropped++; + } + + /* Free first AMSDU sub frame */ + kfree_skb(sw_txhdr->skb); + cl_sw_txhdr_free(cl_hw, sw_txhdr); +} + +void cl_tx_amsdu_transfer_single(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + /* + * Transfer all skbs in sw_txhdr to a temporary list, free sw_txhdr, + * and then push the temporary list to the single path. + */ + struct cl_amsdu_txhdr *amsdu_txhdr, *tmp; + struct sk_buff *skb; + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + u8 tid = sw_txhdr->tid; + + /* Transfer first AMSDU sub frame */ + _cl_tx_amsdu_transfer_single(cl_hw, sw_txhdr->skb, cl_sta, tid); + + /* Transfer mid & last AMSDU sub frames */ + list_for_each_entry_safe(amsdu_txhdr, tmp, &sw_txhdr->amsdu_txhdr.list, list) { + skb = amsdu_txhdr->skb; + + list_del(&amsdu_txhdr->list); + dma_unmap_single(cl_hw->chip->dev, amsdu_txhdr->dma_addr, + (size_t)skb->len, DMA_TO_DEVICE); + cl_tx_amsdu_txhdr_free(cl_hw, amsdu_txhdr); + + _cl_tx_amsdu_transfer_single(cl_hw, skb, cl_sta, tid); + } +} + +int cl_tx_amsdu_set(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb, u8 tid) +{ + struct cl_amsdu_ctrl *amsdu_anchor = &cl_sta->amsdu_anchor[tid]; + struct cl_sw_txhdr *anchor_sw_txhdr = amsdu_anchor->sw_txhdr; + u16 packet_len = skb->len; + u8 packet_cnt; + bool is_mesh = ieee80211_vif_is_mesh(cl_sta->cl_vif->vif); + u8 packet_cnt_max = cl_hw->txamsdu_en; + + /* Check if anchor exist */ + if (!anchor_sw_txhdr) { + /* Sanity check - skb len < amsdu_max_len */ + if (unlikely(packet_len > amsdu_anchor->max_len) || is_mesh) + return CL_AMSDU_SKIP; + else + return cl_tx_amsdu_anchor_set(cl_hw, cl_sta, skb, tid); + } + + if (amsdu_anchor->is_sw_amsdu) + return cl_tx_amsdu_sw_aggregate(cl_hw, amsdu_anchor, skb); + + /* + * 1. Check if there is enough space in AMSDU + * 2. Check if A-MSDU packet count is less than maximum. + */ + packet_cnt = amsdu_anchor->packet_cnt; + + if (amsdu_anchor->rem_len > packet_len && + packet_cnt < packet_cnt_max && + !is_mesh) { + struct cl_amsdu_txhdr *amsdu_txhdr = NULL; + u8 hdr_pads = CL_SKB_DATA_ALIGN_PADS(skb->data); + u16 ethertype = (skb->data[12] << 8) | skb->data[13]; + u16 total_packet_len = packet_len + hdr_pads; + u16 curr_amsdu_len = amsdu_anchor->max_len - amsdu_anchor->rem_len; + dma_addr_t dma_addr; + + if (ethertype >= ETH_P_802_3_MIN) + total_packet_len += sizeof(rfc1042_header); + + /* + * High number of MSDUs in AMSDU can cause underrun in the + * E2W module. + * Therefore, host is required to set Num MSDU in AMSDU using + * the following rules + * + * AMSDU Length AMSDU agg size + * len < 4*256 3 or less + * len >= 4*256 4 or less + * len >= 5*256 5 or less + * len >= 6*256 6 or less + * len >= 7*256 7 or less + * len >= 8*256 8 or less + */ + if (packet_cnt >= CL_AMSDU_MIN_AGG_SIZE) { + u16 new_amsdu_len = curr_amsdu_len + packet_len; + + if (new_amsdu_len < ((packet_cnt + 1) * CL_AMSDU_CONST_LEN)) + return cl_tx_amsdu_anchor_set(cl_hw, cl_sta, skb, tid); + } + + amsdu_txhdr = cl_tx_amsdu_txhdr_alloc(cl_hw); + if (unlikely(!amsdu_txhdr)) { + kfree_skb(skb); + cl_dbg_err(cl_hw, "AMSDU FAILED to alloc amsdu txhdr\n"); + cl_hw->tx_packet_cntr.drop.amsdu_alloc_fail++; + cl_sta->cl_vif->trfc_cntrs[anchor_sw_txhdr->ac].tx_errors++; + return CL_AMSDU_FAILED; + } + + amsdu_txhdr->skb = skb; + list_add_tail(&amsdu_txhdr->list, &anchor_sw_txhdr->amsdu_txhdr.list); + + /* Update anchor fields */ + amsdu_anchor->rem_len -= total_packet_len; + amsdu_anchor->packet_cnt++; + + /* Get DMA address for skb */ + dma_addr = dma_map_single(cl_hw->chip->dev, (u8 *)skb->data - hdr_pads, + packet_len + hdr_pads, DMA_TO_DEVICE); + if (WARN_ON(dma_mapping_error(cl_hw->chip->dev, dma_addr))) { + kfree_skb(skb); + cl_tx_amsdu_txhdr_free(cl_hw, amsdu_txhdr); + cl_dbg_err(cl_hw, "dma_mapping_error\n"); + cl_hw->tx_packet_cntr.drop.amsdu_dma_map_err++; + cl_sta->cl_vif->trfc_cntrs[anchor_sw_txhdr->ac].tx_errors++; + return CL_AMSDU_FAILED; + } + + /* Add AMSDU HDR len of the first packet */ + if (amsdu_anchor->packet_cnt == 2) + total_packet_len += CL_AMSDU_HDR_LEN; + + amsdu_txhdr->dma_addr = dma_addr; + + /* Update sw_txhdr packet_len, packet_addr, packet_cnt fields */ + cl_tx_amsdu_anchor_umacdesc_update(&anchor_sw_txhdr->txdesc, packet_cnt, + packet_len, dma_addr, hdr_pads); + + /* If we reached max AMSDU payload count, mark anchor as NULL */ + if (amsdu_anchor->packet_cnt >= packet_cnt_max) + cl_tx_amsdu_anchor_init(amsdu_anchor); + + return CL_AMSDU_SUB_FRAME_SET; + } + /* Not enough space remain, set new anchor length is ok */ + if (unlikely(packet_len > amsdu_anchor->max_len) || is_mesh) { + cl_tx_amsdu_anchor_init(amsdu_anchor); + return CL_AMSDU_SKIP; + } else { + return cl_tx_amsdu_anchor_set(cl_hw, cl_sta, skb, tid); + } +} + +void cl_tx_amsdu_unset(struct cl_sw_txhdr *sw_txhdr) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + + tx_info->control.flags &= ~IEEE80211_TX_CTRL_AMSDU; + + sw_txhdr->txdesc.e2w_txhdr_param.qos_ctrl &= + ~cpu_to_le16(IEEE80211_QOS_CTL_A_MSDU_PRESENT); +} + +/* + * Two options for allocating cl_amsdu_txhdr: + * 1) pool + * 2) cache + */ + +static int cl_tx_amsdu_txhdr_init_pool(struct cl_hw *cl_hw) +{ + u16 amsdu_txhdr_pool = cl_hw->conf->ci_amsdu_txhdr_pool; + u32 i = 0; + u32 amsdu_txhdr_pool_size = amsdu_txhdr_pool * sizeof(struct cl_amsdu_txhdr); + struct cl_amsdu_txhdr *amsdu_txhdr; + + INIT_LIST_HEAD(&cl_hw->head_amsdu_txhdr_pool); + + for (i = 0; i < amsdu_txhdr_pool; i++) { + amsdu_txhdr = kzalloc(sizeof(*amsdu_txhdr), GFP_ATOMIC); + + if (unlikely(!amsdu_txhdr)) { + cl_dbg_err(cl_hw, "amsdu_txhdr NULL\n"); + return -1; + } + + list_add(&amsdu_txhdr->list_pool, &cl_hw->head_amsdu_txhdr_pool); + } + + cl_dbg_verbose(cl_hw, " - pool %u, size %u\n", + amsdu_txhdr_pool, amsdu_txhdr_pool_size); + + return 0; +} + +static int cl_tx_amsdu_txhdr_init_cache(struct cl_hw *cl_hw) +{ + char amsdu_txhdr_cache_name[MODULE_NAME_LEN + 32] = {0}; + + snprintf(amsdu_txhdr_cache_name, sizeof(amsdu_txhdr_cache_name), + "%s_amsdu_txhdr_cache", THIS_MODULE->name); + + cl_hw->amsdu_txhdr_cache = kmem_cache_create(amsdu_txhdr_cache_name, + sizeof(struct cl_amsdu_txhdr), + 0, + (SLAB_HWCACHE_ALIGN | SLAB_PANIC), + NULL); + + if (!cl_hw->amsdu_txhdr_cache) { + cl_dbg_err(cl_hw, "amsdu_txhdr_cache NULL\n"); + return -1; + } + + return 0; +} + +int cl_tx_amsdu_txhdr_init(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_amsdu_txhdr_pool) + return cl_tx_amsdu_txhdr_init_pool(cl_hw); + else + return cl_tx_amsdu_txhdr_init_cache(cl_hw); +} + +static void cl_tx_amsdu_txhdr_deinit_pool(struct cl_hw *cl_hw) +{ + struct cl_amsdu_txhdr *amsdu_txhdr, *tmp; + + list_for_each_entry_safe(amsdu_txhdr, tmp, &cl_hw->head_amsdu_txhdr_pool, list_pool) { + list_del(&amsdu_txhdr->list_pool); + kfree(amsdu_txhdr); + } +} + +static void cl_tx_amsdu_txhdr_deinit_cache(struct cl_hw *cl_hw) +{ + kmem_cache_destroy(cl_hw->amsdu_txhdr_cache); +} + +void cl_tx_amsdu_txhdr_deinit(struct cl_hw *cl_hw) +{ + if (cl_hw->conf->ci_amsdu_txhdr_pool) + cl_tx_amsdu_txhdr_deinit_pool(cl_hw); + else + cl_tx_amsdu_txhdr_deinit_cache(cl_hw); +} + +void cl_tx_amsdu_txhdr_free(struct cl_hw *cl_hw, struct cl_amsdu_txhdr *amsdu_txhdr) +{ + if (cl_hw->conf->ci_amsdu_txhdr_pool) + list_add_tail(&amsdu_txhdr->list_pool, &cl_hw->head_amsdu_txhdr_pool); + else + kmem_cache_free(cl_hw->amsdu_txhdr_cache, amsdu_txhdr); +} + +static const u8 cl_tid2hwq[IEEE80211_NUM_TIDS] = { + CL_HWQ_BE, + CL_HWQ_BK, + CL_HWQ_BK, + CL_HWQ_BE, + CL_HWQ_VI, + CL_HWQ_VI, + CL_HWQ_VO, + CL_HWQ_VO, + /* At the moment, all others TID are mapped to BE */ + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, + CL_HWQ_BE, +}; + +static void cl_txq_sched_list_add(struct cl_tx_queue *tx_queue, struct cl_hw *cl_hw) +{ + /* Add to schedule queue */ + if (tx_queue->sched) + return; + + tx_queue->sched = true; + if (tx_queue->type == QUEUE_TYPE_AGG) + list_add_tail(&tx_queue->sched_list, &cl_hw->list_sched_q_agg); + else + list_add_tail(&tx_queue->sched_list, &cl_hw->list_sched_q_single); +} + +static void cl_txq_sched_list_remove(struct cl_tx_queue *tx_queue) +{ + /* Remove from schedule queue */ + if (tx_queue->sched) { + tx_queue->sched = false; + list_del(&tx_queue->sched_list); + } +} + +static void cl_txq_sched_list_remove_if_empty(struct cl_tx_queue *tx_queue) +{ + /* If queue is empty remove it from schedule list */ + if (list_empty(&tx_queue->hdrs)) + cl_txq_sched_list_remove(tx_queue); +} + +static void cl_txq_transfer_single_to_agg(struct cl_hw *cl_hw, + struct cl_tx_queue *single_queue, + struct cl_tx_queue *agg_queue, u8 tid) +{ + struct cl_sw_txhdr *sw_txhdr, *sw_txhdr_tmp; + struct ieee80211_tx_info *tx_info; + struct sk_buff *skb; + u8 hdr_pads; + + spin_lock_bh(&cl_hw->tx_lock_single); + + if (single_queue->num_packets == 0) + goto out; + + list_for_each_entry_safe(sw_txhdr, sw_txhdr_tmp, &single_queue->hdrs, tx_queue_list) { + if (sw_txhdr->tid != tid) + continue; + + if (!ieee80211_is_data_qos(sw_txhdr->fc)) + continue; + + cl_hw->tx_packet_cntr.transfer.single_to_agg++; + + /* Remove from single queue */ + list_del(&sw_txhdr->tx_queue_list); + + /* Update single queue counters */ + single_queue->num_packets--; + single_queue->total_packets--; + + /* Turn on AMPDU flag */ + skb = sw_txhdr->skb; + tx_info = IEEE80211_SKB_CB(skb); + tx_info->flags |= IEEE80211_TX_CTL_AMPDU; + + /* Convert header back and Push skb to agg queue */ + cl_tx_wlan_to_8023(skb); + hdr_pads = CL_SKB_DATA_ALIGN_PADS(skb->data); + cl_tx_agg_prep(cl_hw, sw_txhdr, skb->len, hdr_pads, true); + agg_queue->total_packets++; + sw_txhdr->hdr80211 = NULL; + sw_txhdr->tx_queue = agg_queue; + cl_txq_push(cl_hw, sw_txhdr); + + /* Schedule tasklet to try and empty the queue */ + tasklet_schedule(&cl_hw->tx_task); + } + + /* If single queue is empty remove it from schedule list */ + cl_txq_sched_list_remove_if_empty(single_queue); + +out: + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +static void cl_txq_delete_packets(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, u8 sta_idx) +{ + struct cl_sw_txhdr *sw_txhdr, *sw_txhdr_tmp; + + list_for_each_entry_safe(sw_txhdr, sw_txhdr_tmp, &tx_queue->hdrs, tx_queue_list) { + /* + * Brodcast frames do not have cl_sta and should not be + * deleted at station remove sequence. + */ + if (!sw_txhdr->cl_sta) + continue; + + if (sw_txhdr->sta_idx != sta_idx) + continue; + + list_del(&sw_txhdr->tx_queue_list); + tx_queue->num_packets--; + + cl_tx_single_free_skb(cl_hw, sw_txhdr->skb); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + } + + /* If queue is empty remove it from schedule list */ + cl_txq_sched_list_remove_if_empty(tx_queue); +} + +static void cl_txq_reset_counters(struct cl_tx_queue *tx_queue) +{ + tx_queue->total_fw_push_desc = 0; + tx_queue->total_fw_push_skb = 0; + tx_queue->total_fw_cfm = 0; + tx_queue->total_packets = 0; + tx_queue->dump_queue_full = 0; + tx_queue->dump_dma_map_fail = 0; + + memset(tx_queue->stats_hw_amsdu_cnt, 0, + sizeof(tx_queue->stats_hw_amsdu_cnt)); + + memset(tx_queue->stats_sw_amsdu_cnt, 0, + sizeof(tx_queue->stats_sw_amsdu_cnt)); +} + +static void cl_txq_flush(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue) +{ + struct cl_sw_txhdr *sw_txhdr, *sw_txhdr_tmp; + struct ieee80211_tx_info *tx_info; + + if (tx_queue->num_packets == 0) + return; + + list_for_each_entry_safe(sw_txhdr, sw_txhdr_tmp, &tx_queue->hdrs, tx_queue_list) { + list_del(&sw_txhdr->tx_queue_list); + tx_queue->num_packets--; + + /* Can not send AMSDU frames as singles */ + tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + + /* Free mid & last AMSDU sub frames */ + if (cl_tx_ctrl_is_amsdu(tx_info)) { + cl_tx_amsdu_flush_sub_frames(cl_hw, sw_txhdr); + } else { + if (tx_queue->type == QUEUE_TYPE_SINGLE) + cl_tx_single_free_skb(cl_hw, sw_txhdr->skb); + else + kfree_skb(sw_txhdr->skb); + + cl_hw->tx_packet_cntr.drop.queue_flush++; + sw_txhdr->cl_vif->trfc_cntrs[sw_txhdr->ac].tx_dropped++; + cl_sw_txhdr_free(cl_hw, sw_txhdr); + } + } + + /* Remove from schedule queue */ + cl_txq_sched_list_remove(tx_queue); + + /* Sanity check that queue is empty */ + WARN_ON(tx_queue->num_packets > 0); +} + +static void cl_txq_agg_size_set(struct cl_hw *cl_hw) +{ + struct cl_tx_queue *tx_queue = NULL; + u16 new_size = 0; + u16 drv_max_size = 0; + int i = 0; + int j = 0; + + if (!cl_hw->used_agg_queues || !cl_hw->conf->ci_tx_packet_limit) + return; + + new_size = cl_hw->conf->ci_tx_packet_limit / cl_hw->used_agg_queues; + drv_max_size = max(new_size, cl_hw->conf->ci_tx_queue_size_agg); + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) { + tx_queue = &cl_hw->tx_queues->agg[i]; + + if (!tx_queue->cl_sta) + continue; + + tx_queue->max_packets = drv_max_size; + + j++; + if (j == cl_hw->used_agg_queues) + break; + } + + cl_dbg_trace(cl_hw, "drv_max_size = %u\n", drv_max_size); +} + +static int cl_txq_request_find(struct cl_hw *cl_hw, u8 sta_idx, u8 tid) +{ + int i = 0; + struct cl_req_agg_db *req_agg_db = NULL; + u8 req_agg_queues = 0; + + for (i = 0; (i < IPC_MAX_BA_SESSIONS) && (req_agg_queues < cl_hw->req_agg_queues); i++) { + req_agg_db = &cl_hw->req_agg_db[i]; + + if (!req_agg_db->is_used) + continue; + + req_agg_queues++; + + if (sta_idx == req_agg_db->sta_idx && tid == req_agg_db->tid) + return i; + } + + return -1; +} + +static void cl_txq_push_cntrs_update(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, + u32 orig_drv_cnt, u32 orig_fw_cnt) +{ + u32 total_pushed; + u32 idx; + + if (!cl_hw->conf->ci_tx_push_cntrs_stat_en) + return; + + total_pushed = orig_drv_cnt - tx_queue->num_packets; + idx = tx_queue->push_cntrs_db.tx_push_logger_idx % TX_PUSH_LOGGER_SIZE; + tx_queue->push_cntrs_db.tx_push_cntr_hist[total_pushed]++; + tx_queue->push_cntrs_db.tx_push_logger[idx][TX_PUSH_LOGGER_DRV_CNT] = orig_drv_cnt; + tx_queue->push_cntrs_db.tx_push_logger[idx][TX_PUSH_LOGGER_FW_CNT] = orig_fw_cnt; + tx_queue->push_cntrs_db.tx_push_logger[idx][TX_PUSH_LOGGER_PKT_PUSHED] = total_pushed; + ++tx_queue->push_cntrs_db.tx_push_logger_idx; +} + +static void cl_txq_task_single(struct cl_hw *cl_hw) +{ + /* Schedule single queues */ + struct cl_tx_queue *tx_queue, *tx_queue_tmp; + + spin_lock(&cl_hw->tx_lock_single); + + list_for_each_entry_safe(tx_queue, tx_queue_tmp, &cl_hw->list_sched_q_single, sched_list) + cl_txq_sched(cl_hw, tx_queue); + + /* Rotate the queue so next schedule will start with a different queue */ + list_rotate_left(&cl_hw->list_sched_q_single); + + spin_unlock(&cl_hw->tx_lock_single); +} + +static void cl_txq_task_agg(struct cl_hw *cl_hw) +{ + /* Schedule agg queueus */ + struct cl_tx_queue *tx_queue, *tx_queue_tmp; + + spin_lock(&cl_hw->tx_lock_agg); + + list_for_each_entry_safe(tx_queue, tx_queue_tmp, &cl_hw->list_sched_q_agg, sched_list) + cl_txq_sched(cl_hw, tx_queue); + + /* Rotate the queue so next schedule will start with a different queue */ + list_rotate_left(&cl_hw->list_sched_q_agg); + + spin_unlock(&cl_hw->tx_lock_agg); +} + +static void cl_txq_task(unsigned long data) +{ + struct cl_hw *cl_hw = (struct cl_hw *)data; + + cl_txq_task_single(cl_hw); + cl_txq_task_agg(cl_hw); +} + +static void cl_txq_agg_inc_usage_cntr(struct cl_hw *cl_hw) +{ + /* Should be called in cl_hw->tx_lock_agg context */ + cl_hw->used_agg_queues++; + cl_txq_agg_size_set(cl_hw); +} + +static void cl_txq_agg_dec_usage_cntr(struct cl_hw *cl_hw) +{ + /* Should be called in cl_hw->tx_lock_agg context */ + WARN_ON_ONCE(cl_hw->used_agg_queues == 0); + + cl_hw->used_agg_queues--; + cl_txq_agg_size_set(cl_hw); +} + +static void cl_txq_init_single(struct cl_hw *cl_hw) +{ + struct cl_tx_queue *tx_queue; + u32 i; + + spin_lock_bh(&cl_hw->tx_lock_single); + + INIT_LIST_HEAD(&cl_hw->list_sched_q_single); + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) { + tx_queue = &cl_hw->tx_queues->single[i]; + memset(tx_queue, 0, sizeof(struct cl_tx_queue)); + INIT_LIST_HEAD(&tx_queue->hdrs); + tx_queue->hw_index = i / FW_MAX_NUM_STA; + tx_queue->fw_max_size = IPC_TXDESC_CNT_SINGLE; + tx_queue->fw_free_space = IPC_TXDESC_CNT_SINGLE; + tx_queue->index = i; + tx_queue->max_packets = cl_hw->conf->ci_tx_queue_size_single; + tx_queue->type = QUEUE_TYPE_SINGLE; + } + + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +static void cl_txq_init_bcmc(struct cl_hw *cl_hw) +{ + struct cl_tx_queue *tx_queue; + + spin_lock_bh(&cl_hw->tx_lock_bcmc); + + tx_queue = &cl_hw->tx_queues->bcmc; + memset(tx_queue, 0, sizeof(struct cl_tx_queue)); + INIT_LIST_HEAD(&tx_queue->hdrs); + tx_queue->hw_index = CL_HWQ_BCN; + tx_queue->fw_max_size = IPC_TXDESC_CNT_BCMC; + tx_queue->fw_free_space = IPC_TXDESC_CNT_BCMC; + tx_queue->index = 0; + tx_queue->max_packets = 0; + tx_queue->type = QUEUE_TYPE_BCMC; + + spin_unlock_bh(&cl_hw->tx_lock_bcmc); +} + +static void cl_txq_init_agg(struct cl_hw *cl_hw) +{ + spin_lock_bh(&cl_hw->tx_lock_agg); + INIT_LIST_HEAD(&cl_hw->list_sched_q_agg); + spin_unlock_bh(&cl_hw->tx_lock_agg); +} + +static void cl_txq_agg_request_reset(struct cl_hw *cl_hw) +{ + cl_hw->req_agg_queues = 0; + memset(cl_hw->req_agg_db, 0, sizeof(cl_hw->req_agg_db)); +} + +void cl_txq_init(struct cl_hw *cl_hw) +{ + tasklet_init(&cl_hw->tx_task, cl_txq_task, (unsigned long)cl_hw); + + cl_txq_agg_request_reset(cl_hw); + cl_txq_init_single(cl_hw); + cl_txq_init_bcmc(cl_hw); + cl_txq_init_agg(cl_hw); +} + +void cl_txq_stop(struct cl_hw *cl_hw) +{ + tasklet_kill(&cl_hw->tx_task); +} + +struct cl_tx_queue *cl_txq_get(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(sw_txhdr->skb); + u8 hw_queue = sw_txhdr->hw_queue; + + if (!cl_sta && + hw_queue == CL_HWQ_VO && + is_multicast_ether_addr(sw_txhdr->hdr80211->addr1)) { + /* + * If HW queue is VO and packet is multicast, it was not buffered + * by mac80211, and it should be pushed to the high-priority queue + * and not to the bcmc queue. + */ + return &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE]; + } else if (!cl_sta && + (hw_queue != CL_HWQ_BCN) && + !(tx_info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) { + /* + * If station is NULL, but HW queue is not BCN, + * it most go to the high-priority queue. + */ + tx_info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; + sw_txhdr->hw_queue = CL_HWQ_VO; + return &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE]; + } else if (cl_sta && (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { + /* Agg packet */ + return cl_sta->agg_tx_queues[sw_txhdr->tid]; + } else if (hw_queue == CL_HWQ_BCN) { + return &cl_hw->tx_queues->bcmc; + } else if (tx_info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) { + /* + * Only frames that are power save response or non-bufferable MMPDU + * will have this flag set our driver will push those frame to the + * highiest priority queue. + */ + return &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE]; + } + + return &cl_hw->tx_queues->single[QUEUE_IDX(sw_txhdr->sta_idx, hw_queue)]; +} + +void cl_txq_push(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr) +{ + struct cl_tx_queue *tx_queue = sw_txhdr->tx_queue; + + if (tx_queue->num_packets < tx_queue->max_packets) { + tx_queue->num_packets++; + + /* + * This prioritization of action frames helps Samsung Galaxy Note 8 to + * open BA session more easily, when phy dev is PHY_DEV_OLYMPUS + * and helps open BA on all system emulators + */ + if (ieee80211_is_action(sw_txhdr->fc) && !IS_REAL_PHY(cl_hw->chip)) + list_add(&sw_txhdr->tx_queue_list, &tx_queue->hdrs); + else + list_add_tail(&sw_txhdr->tx_queue_list, &tx_queue->hdrs); + + /* If it is the first packet in the queue, add the queue to the sched list */ + cl_txq_sched_list_add(tx_queue, cl_hw); + } else { + struct cl_sta *cl_sta = sw_txhdr->cl_sta; + u8 tid = sw_txhdr->tid; + + /* If the SW queue full, release the packet */ + tx_queue->dump_queue_full++; + + if (cl_sta && cl_sta->amsdu_anchor[tid].sw_txhdr) { + if (cl_sta->amsdu_anchor[tid].sw_txhdr == sw_txhdr) { + cl_sta->amsdu_anchor[tid].sw_txhdr = NULL; + cl_sta->amsdu_anchor[tid].packet_cnt = 0; + } + } + + dev_kfree_skb_any(sw_txhdr->skb); + cl_sw_txhdr_free(cl_hw, sw_txhdr); + + /* Schedule tasklet to try and empty the queue */ + tasklet_schedule(&cl_hw->tx_task); + } +} + +void cl_txq_sched(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue) +{ + struct cl_sw_txhdr *sw_txhdr, *sw_txhdr_tmp; + u32 orig_drv_cnt = tx_queue->num_packets; + u32 orig_fw_cnt = cl_txq_desc_in_fw(tx_queue); + struct cl_sta *cl_sta = tx_queue->cl_sta; + + if (!test_bit(CL_DEV_STARTED, &cl_hw->drv_flags) || + cl_hw->tx_disable_flags || + cl_txq_is_fw_full(tx_queue) || + (cl_sta && cl_sta->pause_tx)) + return; + + /* Go over all descriptors in queue */ + list_for_each_entry_safe(sw_txhdr, sw_txhdr_tmp, &tx_queue->hdrs, tx_queue_list) { + list_del(&sw_txhdr->tx_queue_list); + tx_queue->num_packets--; + + if (cl_hw->tx_db.force_amsdu && + sw_txhdr->txdesc.host_info.packet_cnt < cl_hw->txamsdu_en) + break; + + cl_tx_push(cl_hw, sw_txhdr, tx_queue); + + if (cl_txq_is_fw_full(tx_queue)) + break; + } + + cl_txq_push_cntrs_update(cl_hw, tx_queue, orig_drv_cnt, orig_fw_cnt); + + /* If queue is empty remove it from schedule list */ + cl_txq_sched_list_remove_if_empty(tx_queue); +} + +void cl_txq_agg_alloc(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct mm_ba_add_cfm *ba_add_cfm, u16 buf_size) +{ + u8 tid = ba_add_cfm->tid; + u8 fw_agg_idx = ba_add_cfm->agg_idx; + u8 sta_idx = cl_sta->sta_idx; + u8 ac = cl_tid2hwq[tid]; + u16 single_queue_idx = QUEUE_IDX(sta_idx, ac); + struct cl_tx_queue *tx_queue = &cl_hw->tx_queues->agg[fw_agg_idx]; + + spin_lock_bh(&cl_hw->tx_lock_agg); + + /* Init aggregated queue struct */ + memset(tx_queue, 0, sizeof(struct cl_tx_queue)); + INIT_LIST_HEAD(&tx_queue->hdrs); + + /* + * Firmware agg queues size is static and set to 512, so that for the worst + * case of HE stations,that support AMPDU of 256, it has room for two full + * aggregation. + * To keep this logic, of room for two aggregations, for non-HE stations, or + * for HE stations that do not support AMPDU of 256, we initialize fw_max_size + to twice the buffer size supported by the station. + */ + tx_queue->fw_max_size = min_t(u16, TXDESC_AGG_Q_SIZE_MAX, buf_size * 2); + tx_queue->fw_free_space = tx_queue->fw_max_size; + + tx_queue->max_packets = cl_hw->conf->ci_tx_queue_size_agg; + tx_queue->hw_index = ac; + tx_queue->cl_sta = cl_sta; + tx_queue->type = QUEUE_TYPE_AGG; + tx_queue->tid = tid; + tx_queue->index = fw_agg_idx; + + /* Reset the synchronization counters between the fw and the IPC layer */ + cl_hw->ipc_env->ring_indices_elem->indices->txdesc_write_idx.agg[fw_agg_idx] = 0; + + /* Attach the cl_hw chosen queue to the station and agg queues DB */ + cl_sta->agg_tx_queues[tid] = tx_queue; + cl_agg_cfm_set_tx_queue(cl_hw, tx_queue, fw_agg_idx); + + /* Notify upper mac80211 layer of queues resources status */ + cl_txq_agg_inc_usage_cntr(cl_hw); + cl_txq_agg_request_del(cl_hw, sta_idx, tid); + + /* + * Move the qos descriptors to the new allocated aggregated queues, + * otherwise we might reorder packets) + */ + cl_txq_transfer_single_to_agg(cl_hw, &cl_hw->tx_queues->single[single_queue_idx], + tx_queue, tid); + /* Move the BA window pending packets to agg path */ + cl_baw_pending_to_agg(cl_hw, cl_sta, tid); + + spin_unlock_bh(&cl_hw->tx_lock_agg); + + cl_dbg_trace(cl_hw, "Allocate queue [%u] to station [%u] tid [%u]\n", + fw_agg_idx, sta_idx, tid); +} + +void cl_txq_agg_free(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, + struct cl_sta *cl_sta, u8 tid) +{ + spin_lock_bh(&cl_hw->tx_lock_agg); + + cl_dbg_trace(cl_hw, "Free queue [%u] of station [%u] tid [%u]\n", + tx_queue->index, cl_sta->sta_idx, tid); + + memset(tx_queue, 0, sizeof(struct cl_tx_queue)); + + cl_txq_agg_dec_usage_cntr(cl_hw); + + spin_unlock_bh(&cl_hw->tx_lock_agg); +} + +void cl_txq_agg_stop(struct cl_sta *cl_sta, u8 tid) +{ + cl_sta->agg_tx_queues[tid] = NULL; +} + +void cl_txq_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + /* Set cl_sta field for all single queues of this station */ + u8 ac; + u16 queue_idx; + + for (ac = 0; ac < AC_MAX; ac++) { + queue_idx = QUEUE_IDX(cl_sta->sta_idx, ac); + cl_hw->tx_queues->single[queue_idx].cl_sta = cl_sta; + } + + /* Reset pointers to TX agg queues */ + memset(cl_sta->agg_tx_queues, 0, sizeof(cl_sta->agg_tx_queues)); +} + +void cl_txq_sta_remove(struct cl_hw *cl_hw, u8 sta_idx) +{ + /* Clear cl_sta field for all single queues of this station */ + u8 ac; + u16 queue_idx; + + for (ac = 0; ac < AC_MAX; ac++) { + queue_idx = QUEUE_IDX(sta_idx, ac); + cl_hw->tx_queues->single[queue_idx].cl_sta = NULL; + } +} + +void cl_txq_transfer_agg_to_single(struct cl_hw *cl_hw, struct cl_tx_queue *agg_queue) +{ + /* + * 1) Remove from aggregation queue + * 2) Free sw_txhdr + * 3) Push to single queue + */ + struct cl_sw_txhdr *sw_txhdr, *sw_txhdr_tmp; + struct sk_buff *skb; + struct ieee80211_tx_info *tx_info; + struct cl_tx_queue *single_queue; + struct cl_sta *cl_sta = agg_queue->cl_sta; + u16 single_queue_idx = 0; + + if (agg_queue->num_packets == 0) + return; + + single_queue_idx = QUEUE_IDX(cl_sta->sta_idx, agg_queue->hw_index); + single_queue = &cl_hw->tx_queues->single[single_queue_idx]; + + list_for_each_entry_safe(sw_txhdr, sw_txhdr_tmp, &agg_queue->hdrs, tx_queue_list) { + list_del(&sw_txhdr->tx_queue_list); + agg_queue->num_packets--; + + skb = sw_txhdr->skb; + tx_info = IEEE80211_SKB_CB(skb); + + if (cl_tx_ctrl_is_amsdu(tx_info)) { + cl_tx_amsdu_transfer_single(cl_hw, sw_txhdr); + } else { + tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; + + if (cl_tx_8023_to_wlan(cl_hw, skb, cl_sta, sw_txhdr->tid) == 0) { + cl_hw->tx_packet_cntr.transfer.agg_to_single++; + cl_tx_single(cl_hw, cl_sta, skb, false, false); + } + } + + cl_sw_txhdr_free(cl_hw, sw_txhdr); + } + + /* If queue is empty remove it from schedule list */ + cl_txq_sched_list_remove_if_empty(agg_queue); +} + +void cl_txq_flush_agg(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, bool lock) +{ + if (lock) { + spin_lock_bh(&cl_hw->tx_lock_agg); + cl_txq_flush(cl_hw, tx_queue); + spin_unlock_bh(&cl_hw->tx_lock_agg); + } else { + cl_txq_flush(cl_hw, tx_queue); + } +} + +void cl_txq_flush_all_agg(struct cl_hw *cl_hw) +{ + int i = 0; + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + cl_txq_flush(cl_hw, &cl_hw->tx_queues->agg[i]); +} + +void cl_txq_flush_all_single(struct cl_hw *cl_hw) +{ + int i = 0; + + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + cl_txq_flush(cl_hw, &cl_hw->tx_queues->single[i]); +} + +void cl_txq_flush_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + int i = 0; + u8 sta_idx = cl_sta->sta_idx; + u32 queue_idx = 0; + struct cl_tx_queue *tx_queue = NULL; + + spin_lock_bh(&cl_hw->tx_lock_agg); + + /* Flush all aggregation queues for this station */ + for (i = 0; i < IEEE80211_NUM_TIDS; i++) + if (cl_sta->agg_tx_queues[i]) + cl_txq_flush(cl_hw, cl_sta->agg_tx_queues[i]); + + spin_unlock_bh(&cl_hw->tx_lock_agg); + + spin_lock_bh(&cl_hw->tx_lock_single); + + /* Flush all single queues for this station */ + for (i = 0; i < AC_MAX; i++) { + queue_idx = QUEUE_IDX(sta_idx, i); + tx_queue = &cl_hw->tx_queues->single[queue_idx]; + cl_txq_flush(cl_hw, tx_queue); + cl_txq_reset_counters(tx_queue); + } + + /* Go over high prioirty queue and delete packets belonging to this station */ + cl_txq_delete_packets(cl_hw, &cl_hw->tx_queues->single[HIGH_PRIORITY_QUEUE], sta_idx); + + spin_unlock_bh(&cl_hw->tx_lock_single); +} + +void cl_txq_agg_request_add(struct cl_hw *cl_hw, u8 sta_idx, u8 tid) +{ + int i = cl_txq_request_find(cl_hw, sta_idx, tid); + struct cl_req_agg_db *req_agg_db = NULL; + + if (i != -1) { + cl_dbg_trace(cl_hw, "ALREADY_ADDED - entry = %d, sta_idx = %u, tid = %u\n", + i, sta_idx, tid); + return; + } + + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) { + req_agg_db = &cl_hw->req_agg_db[i]; + + if (!req_agg_db->is_used) { + cl_dbg_trace(cl_hw, "ADD - entry = %d, sta_idx = %u, tid = %u\n", + i, sta_idx, tid); + req_agg_db->is_used = true; + req_agg_db->sta_idx = sta_idx; + req_agg_db->tid = tid; + cl_hw->req_agg_queues++; + return; + } + } +} + +void cl_txq_agg_request_del(struct cl_hw *cl_hw, u8 sta_idx, u8 tid) +{ + int i = cl_txq_request_find(cl_hw, sta_idx, tid); + + if (i != -1) { + cl_dbg_trace(cl_hw, "DEL - entry = %d, sta_idx = %u, tid = %u\n", + i, sta_idx, tid); + cl_hw->req_agg_db[i].is_used = false; + cl_hw->req_agg_queues--; + } +} + +bool cl_txq_is_agg_available(struct cl_hw *cl_hw) +{ + u8 total_agg_queues = cl_hw->used_agg_queues + cl_hw->req_agg_queues; + + return (total_agg_queues < IPC_MAX_BA_SESSIONS); +} + +bool cl_txq_is_fw_empty(struct cl_tx_queue *tx_queue) +{ + return (tx_queue->fw_free_space == tx_queue->fw_max_size); +} + +bool cl_txq_is_fw_full(struct cl_tx_queue *tx_queue) +{ + return (tx_queue->fw_free_space == 0); +} + +u16 cl_txq_desc_in_fw(struct cl_tx_queue *tx_queue) +{ + return (tx_queue->fw_max_size - tx_queue->fw_free_space); +} + +bool cl_txq_frames_pending(struct cl_hw *cl_hw) +{ + int i = 0; + + /* Check if we have multicast/bradcast frame in FW queues */ + if (!cl_txq_is_fw_empty(&cl_hw->tx_queues->bcmc)) + return true; + + /* Check if we have singles frame in FW queues */ + for (i = 0; i < MAX_SINGLE_QUEUES; i++) + if (!cl_txq_is_fw_empty(&cl_hw->tx_queues->single[i])) + return true; + + /* Check if we have aggregation frame in FW queues */ + for (i = 0; i < IPC_MAX_BA_SESSIONS; i++) + if (!cl_txq_is_fw_empty(&cl_hw->tx_queues->agg[i])) + return true; + + return false; +} + From patchwork Tue May 24 11:34:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575954 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 7C7A3C433EF for ; Tue, 24 May 2022 11:41:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237012AbiEXLl0 (ORCPT ); Tue, 24 May 2022 07:41:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237017AbiEXLlH (ORCPT ); Tue, 24 May 2022 07:41:07 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2071.outbound.protection.outlook.com [40.107.20.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10383939BE for ; Tue, 24 May 2022 04:40:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AeChDJQW2HtgD9WHtLgW+fgvSN7tG9L5+LCkHGO1nQSU1sWv1wo8o49UmpK0Pwd9t4c5nZ3CBfLo4UhFmVMdaHbGIr2lpm3lrNKsVc8VuxQ0a7Q3daiRPQ58eNR8n2MX3ksoF/EODNKmzlXrLH8m8Qcw0ogNPOnrM1EI8sih/vEkRlWNDt0CXm4BrKTGg0ezFwkMBL2fGg3L7h6zGlcHhKEjSqeSyqNVvC86PKWHUtJdptRofy7rgxTlrZJmjYocyP6X2oGvN3QYNTNLMSisRUV0d8UwVjlNc3+JA7F0+pSBEl7FDqf1kJSOc7/8PewcZdYLljtIBNFgfN/8vtbyTg== 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=16SuCED5knND0f2MxrWSMbU0eRI0jQmTNqWcGCg9jaQ=; b=B/J2YQ+PqeGL7DG635pJ+A0oLRzdJ6YUdoYTbxc5ag3qv20+SDpBjeD5ywzIjXsaJaBok7biL2JtoVKPx+jyb3sgGA4hCx9w6f97L12+UfECyYC6x9ZH8lqP1CirX2aHOOsJmSZfUgxVBVP6L7R9NfJsAeowjX3Lc7PleSNp4NUm8vaIt6zVdkAOnYe7+waRPnN0ckgJBVcbqtCoValv+Z+YNAdau6TBcm8CRADH9mwNSjSWG2YWON92BIbFCfc4qH3WgTpBfd8KYWuk98HUXwE5kGry1Rrd1YcLyjhEypmGxbYO1yCs3jlxZfp6eSv7zc7I0EfZajXnnh6FSD9u9A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=16SuCED5knND0f2MxrWSMbU0eRI0jQmTNqWcGCg9jaQ=; b=D2afiEZJTtOsg82SM909VxQXOl0fmtRatxo3UuB7i2Rep1nYJWCoVWDepDg5et/uurR09nZMN/pRgXB2HizgTMkh3jMKeXsqcMM1Bf2DSnokDNGvOfEjaNwDzfp0ZSJLqepcsVouicGVSfGBns7Nd2aNK5TQ92Fnuxg31OHRg7k= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:32 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:32 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 85/96] cl8k: add tx.h Date: Tue, 24 May 2022 14:34:51 +0300 Message-Id: <20220524113502.1094459-86-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7232e032-a562-418e-7c56-08da3d79fd70 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rBcp4u79+VEfkQf7xONjlUrmB6VtqJGNDWhXkacULVMzVCrPBwZb01aFXXUX02oAwHwcY47O3LhDNQYNDrBw89s+63XbTPAic9xMGW1u7fUjwCEejyCrxxK/ny6yBYUwuNAeuGee7PwR+XTHi/dNHZ93oU6KinJT8avoctWrBD6GxtWHDNr/L9RjKtHXT5IaIScumdyM4NvTrCofeqfPLL0YOegYF9Pq1NuhOHaO4uF/j/MnHVbbjjpKoundqzJNbeUwlfzD+ElW6jDgjVWhzU0NKKrWyJLBBJtNECmvBerII6b6RNyBFKlCNLg0oP+KhXbw7pMEG7jtkG8uyQFkZuKQ9m1rZornTxYsKhEGQOD29pY2gW7ulHVJLP3BmKO5lgjHPbmULJ5rGFxgP0Xe+nt3jCVb56059ShSveuw7s8xjj92qYLsq3eEt8Mbsa4/N7Vte6FAEVwV8dQbXJhjZf+4F2J8yP+ZrH3r+vnKEurBNTXrHxUfd86Wsf/EQkysW/+ginLZZ/Og4qltrYlwL0Kynqy/GL/PEXhVBVDopojrjgHQaxUr/YeEpmJGK74bKFW9SICF8YbT8h8tPtEswfDBW18Us5AoXumWbKAdpG+ky9G0TbBVxIL2Smq6/6g8ON/ulXZB5vaUNO9PeJKXNvdkmXqIrLOUluIq0h7iGyRT+eQjob8H2OBdlT+U6BL6MhvOrLoWZPmqwOYPQd2OqW0GLGI/8+krst3G6xie+ZQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: wyL/M6hquR8nUeP0JdpImrpJ6Ao8lZ7+qBUwzqqe59pyMSXU88v5H8vcYhwXVFuKGBfFZ8u0xq6M5nlcFCfMNudccDOMcKwav287wPKPkO9biU0KkixM7TUcQKnVMfxS0pLLptny3Za3tOG/P0AImtm/0AI26ptTY9LLdAiTo+jUsnna5maXW427/SbBFBmdl+4vYXHcUCR711FO4+RPqKxROrat1bWUv4yzJO7Q/tgotfznF4bpSDyvJE7NWv7srUim30MsBTVOtbqZBcRqflePmWF+1aZe5Qq4qkCrwdmWGo396GANXUqVOSprF4xZNlClzr/lADnYId+dFPg/YDmwpOiZnU4CZNvCM1wDzukITkN2FhCF7KHxXfMqKrnWLHusPlF4O4tUJXMi/g+kFFIsLdjvLHauOYJIArfznmZSKKDt6+TN4lG1UVFDlEMLVxibcoejr4TJVQT9r57Met8syWAsjxuAi7KGIsP1Cc/+XuK3yUYP9Ux+J17ZLqMFEZOb5JSHOIPx7xi+TbazWP4j9HGrc7M3Ob/2EkqgtCltt8nU/hWe0bfTSFlhk1F1sobq1mb7yqY/uqnBeBODarfgmIpZV0h3RnKw6hAYnebkVjWFHUOSbb2M9FkK7ahHsOMxaYV3q/L5Mp8sfpCv/fWZTGOPxkImgZNV9noa+YulAkylWdw2vlGEb50gtxI8PD72O+GJQFAhZ6zzPlrwUAOPuPwFFEbqPp/8lDAHXnMQ/4m9tC0iGWwdCB/AAgz50EGt4iNO45ubpKO3htRIHD6SjyMJ4hX1a84H5SFFvbZuz2r4d2S8uJplRbNwBla73Rpzw8V0FRkackW5YDoW7+dCEM7i1RYkeetGndFurxl7tb/Evm3hg/5UBqYn9CND6keb0SshfC5g2Bt9md4CgNTEB/0udZm4UnS12CVDX4jZ+tw9eu7TupXQcLQB1KyuawlXO0RP8LTBgqtn/bONue4PPRs1varkKW005R9Z5B4NprW7XnqXMaaulDRwYZqXcBcz1+pSp+ONEIIgrVNbZDoEGU93VMCr5QuHFhUKZcqz0axvmE2y5So1RsLYLzPzCsT12yGlH0jKEx8L3sdGLT9HuN8g6+x5viUfFfSu41zAdnu5TXACw1PgWuZ/etix305deWInEba7C2KsbC3Ba/U7dH5gT/Q4kZ6unUsgdAuzu4F4226ou/5ciFtX9oJFxPP1HrwF9P/+CbSPoqPsOUB8FOyPnROUhaVjL9aTd8TX/ngyAerO/36V5aBdbzXVUvvxRFmUcErF/eWWwPGhc25/Js1bfmsgXILD9MKe8Qv7ztxNGJP3iDbdVRUyx2Pf086wz2+AVTUY994obW0GIUsArPOn2k373M+74uUHRwahQ4rx43VQ2mmoQhF/uQA/sxthtuy53EcbAsk2lUdPK6zFoMDhZ528LRMHgcONsRFuYrcXTCv+sDeYgBRNfWv5W1UbqJRcO5+uWLhmMpuGbwVxk+U9mkGkuCtahp3Sw3dI8nvmFE0mOFwPWIVkDdotUxMNPUwsguiBEfjCr3bPUW4tEsI02WxlpLhVSu8MN5Ok8aRluPOPCqHtlfvSnr0SjxLdiVMedi3jt54DYo9FqBQ2fqIfkKvQFzFCo0AISNefImjOdiIjm0fAk24RuChwZQqAweJ2zUY4t6i92xfQfx1FBEWvYm21V9LnSPSa2TqI51KcJNHiHW8q7ILQP4G1RNYgIT4iBvZeKlXhxgKZ5vEboQGMaBXiLsQQUMZgoZU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7232e032-a562-418e-7c56-08da3d79fd70 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:58.0097 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: x2de/OPgdmeBmiKg+PcNeC1HwFL4ilVXeMUlGbGxPpApIG3NeEpFYs6E44skFBK27QSvbgXfyYiDKE/QNH4+Zg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/tx.h | 467 ++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/tx.h diff --git a/drivers/net/wireless/celeno/cl8k/tx.h b/drivers/net/wireless/celeno/cl8k/tx.h new file mode 100644 index 000000000000..d36a7d703df6 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/tx.h @@ -0,0 +1,467 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_TX_H +#define CL_TX_H + +#include + +#include "sta_info.h" +#include "vif.h" +#include "ipc_shared.h" +#include "fw.h" +#include "wrs.h" + +enum cl_queue_type { + QUEUE_TYPE_SINGLE, + QUEUE_TYPE_AGG, + QUEUE_TYPE_BCMC, + + QUEUE_TYPE_MAX +}; + +#define QUEUE_IDX(sta, ac) ((sta) + (ac) * FW_MAX_NUM_STA) + +#define TX_PUSH_LOGGER_SIZE 256 + +#define BCMC_POLL_TIMEOUT 50 + +enum cl_tx_push_logger_param { + TX_PUSH_LOGGER_DRV_CNT, + TX_PUSH_LOGGER_FW_CNT, + TX_PUSH_LOGGER_PKT_PUSHED, + TX_PUSH_LOGGER_MAX, +}; + +struct cl_tx_push_cntrs { + u32 tx_push_cntr_hist[TXDESC_AGG_Q_SIZE_MAX + 1]; + u32 tx_push_logger[TX_PUSH_LOGGER_SIZE][TX_PUSH_LOGGER_MAX]; + u32 tx_push_logger_idx; +}; + +struct cl_tx_queue { + struct list_head sched_list; + struct list_head hdrs; + struct cl_sta *cl_sta; + bool sched; + u16 fw_free_space; + u16 fw_max_size; + u8 type; + u8 tid; + u8 hw_index; + u16 index; + u16 max_packets; + u16 num_packets; + u32 total_packets; + u32 total_fw_push_desc; + u32 total_fw_push_skb; + u32 total_fw_cfm; + u32 dump_queue_full; + u32 dump_dma_map_fail; + u32 stats_hw_amsdu_cnt[CL_AMSDU_TX_PAYLOAD_MAX]; + u32 stats_sw_amsdu_cnt[MAX_TX_SW_AMSDU_PACKET]; + u32 hist_xmit_to_push[DELAY_HIST_SIZE]; + u32 hist_push_to_cfm[DELAY_HIST_SIZE]; + struct cl_tx_push_cntrs push_cntrs_db; +}; + +/* + * struct cl_tx_queues: + * This structure holds all driver TX queues, + * The queues buffer frames pushed by upper layer and push them to lower IPC layer. + */ +struct cl_tx_queues { + struct cl_tx_queue agg[IPC_MAX_BA_SESSIONS]; + struct cl_tx_queue single[MAX_SINGLE_QUEUES]; + struct cl_tx_queue bcmc; +}; + +struct cl_req_agg_db { + bool is_used; + u8 sta_idx; + u8 tid; +}; + +#define INC_SN(sn) (((sn) + 0x10) & IEEE80211_SCTL_SEQ) +#define DEC_SN(sn) (((sn) - 0x10) & IEEE80211_SCTL_SEQ) + +#define CL_TX_LIFETIME_MS 4000 + +#define CL_SKB_DATA_ALIGN_SZ 4 +#define CL_SKB_DATA_ALIGN_MSK (CL_SKB_DATA_ALIGN_SZ - 1) +#define CL_SKB_DATA_ALIGN_PADS(x) \ + ((CL_SKB_DATA_ALIGN_SZ - ((ptrdiff_t)(x) & CL_SKB_DATA_ALIGN_MSK)) & CL_SKB_DATA_ALIGN_MSK) + +#define CL_TX_MAX_FRAME_LEN_SINGLE 4096 +#define CL_TX_MAX_FRAME_LEN_AGG 2000 + +struct cl_hw_tx_status { + u32 mcs_index : 7; /* [6:0] */ + u32 is_bcmc : 1; /* [7] */ + u32 num_mpdu_retries : 4; /* [11:8] */ + u32 rsv : 4; /* [15:12] */ + u32 format_mod : 4; /* [19:16] */ + u32 bw_requested : 2; /* [21:20] */ + u32 bf : 1; /* [22] */ + u32 frm_successful : 1; /* [23] */ + u32 bw_transmitted : 2; /* [25:24] */ + u32 freespace_inc_skip : 1; /* [26] */ + u32 keep_skb : 1; /* [27] */ + u32 gi : 2; /* [29:28] */ + u32 descriptor_done_sw : 1; /* [30] */ + u32 descriptor_done_hw : 1; /* [31] */ +}; + +enum cl_tx_flags { + CL_TX_EN_DFS, + CL_TX_EN_SCAN +}; + +enum cl_tx_single_frame_type { + CL_TX_SINGLE_FRAME_TYPE_QOS_DATA, + CL_TX_SINGLE_FRAME_TYPE_QOS_NULL, + CL_TX_SINGLE_FRAME_TYPE_MANAGEMENT, + CL_TX_SINGLE_FRAME_TYPE_OTHER +}; + +struct cl_tx_db { + bool force_amsdu; + bool block_bcn; + bool block_prob_resp; +}; + +struct cl_tx_drop_cntr { + u32 radio_off; + u32 in_recovery; + u32 short_length; + u32 pending_full; + u32 packet_limit; + u32 dev_flags; + u32 tx_disable; + u32 length_limit; + u32 txhdr_alloc_fail; + u32 queue_null; + u32 amsdu_alloc_fail; + u32 amsdu_dma_map_err; + u32 build_hdr_fail; + u32 key_disable; + u32 queue_flush; + u32 probe_response; + u32 sta_null_in_agg; + u32 sta_stop_tx; +}; + +struct cl_tx_forward_cntr { + u32 tx_start; + u32 drv_fast_agg; + u32 drv_fast_single; + u32 to_mac; + u32 from_mac_single; + u32 from_mac_agg; +}; + +struct cl_tx_transfer_cntr { + u32 single_to_agg; + u32 agg_to_single; +}; + +struct cl_tx_packet_cntr { + struct cl_tx_forward_cntr forward; + struct cl_tx_drop_cntr drop; + struct cl_tx_transfer_cntr transfer; +}; + +struct cl_cpu_cntr { + u32 tx_agg[CPU_MAX_NUM]; + u32 tx_single[CPU_MAX_NUM]; +}; + +static inline bool cl_tx_ctrl_is_amsdu(struct ieee80211_tx_info *tx_info) +{ + return !!(tx_info->control.flags & IEEE80211_TX_CTRL_AMSDU); +} + +static inline bool cl_tx_ctrl_is_eapol(struct ieee80211_tx_info *tx_info) +{ + return !!(tx_info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO); +} + +struct cl_agg_cfm_queue { + struct list_head head; + struct cl_tx_queue *tx_queue; + u16 ssn; +}; + +/* Structure containing the parameters of the MM_AGG_TX_REPORT_IND message. */ +struct cl_agg_tx_report { + __le32 rate_cntrl_info; + __le32 rate_cntrl_info_he; + +#if defined(__LITTLE_ENDIAN_BITFIELD) + u32 sta_idx : 8, + is_sta_ps : 1, + bw_requested : 2, + is_agg : 1, + ba_not_received : 1, + ba_received_empty : 1, + bf : 1, + is_fallback : 1, + mu_su_gid : 6, + mu_mimo_valid : 1, + mu_ofdma_valid : 1, + rate_fix_mcs1 : 1, + rsv0 : 7; + + u32 success : 9, + fail : 9, + below_baw_cnt : 9, + num_prot_retries : 5; + + u32 success_after_retry : 9, + success_more_one_retry : 9, + retry_limit_reached : 9, + is_retry : 1, + is_rts_retry_limit_reached : 1, + prot_type : 3; + + u32 rssi1 : 8, + rssi2 : 8, + rssi3 : 8, + rssi4 : 8; + + u32 rssi5 : 8, + rssi6 : 8, + rsv1 : 16; +#else + u32 rsv0 : 7, + rate_fix_mcs1 : 1, + mu_ofdma_valid : 1, + mu_mimo_valid : 1, + mu_su_gid : 6, + is_fallback : 1, + bf : 1, + ba_received_empty : 1, + ba_not_received : 1, + is_agg : 1, + bw_requested : 2, + is_sta_ps : 1, + sta_idx : 8; + + u32 num_prot_retries : 5, + below_baw_cnt : 9, + fail : 9, + success : 9; + + u32 prot_type : 3, + is_rts_retry_limit_reached : 1, + is_retry : 1, + retry_limit_reached : 9, + success_more_one_retry : 9, + success_after_retry : 9; + + u32 rssi4 : 8, + rssi3 : 8, + rssi2 : 8, + rssi1 : 8; + + u32 rsv1 : 16, + rssi6 : 8, + rssi5 : 8; +#endif + u16 new_ssn; + u8 tx_queue_idx; + +}; + +void cl_agg_tx_report_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_agg_tx_report *agg_report); +void cl_agg_tx_report_simulate_for_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_hw_tx_status *status); + +/* Per RA/TID Data for AMPDU TX */ +struct cl_baw { + u8 fw_agg_idx; + bool amsdu; + bool action_start; + u16 ssn; + u16 tid_seq; + struct sk_buff_head pending; +}; + +enum cl_amsdu_result { + CL_AMSDU_ANCHOR_SET, + CL_AMSDU_SUB_FRAME_SET, + CL_AMSDU_SKIP, + CL_AMSDU_FAILED +}; + +/* Max size of 802.11 WLAN header */ +#define CL_WLAN_HEADER_MAX_SIZE 36 + +#define CL_AMSDU_MIN_AGG_SIZE 3 +#define CL_AMSDU_CONST_LEN 256 + +struct cl_amsdu_txhdr { + struct list_head list; + struct list_head list_pool; + struct sk_buff *skb; + dma_addr_t dma_addr; +}; + +struct cl_amsdu_ctrl { + struct cl_sw_txhdr *sw_txhdr; + u16 rem_len; + u16 max_len; + u16 hdrlen; + u8 packet_cnt; + bool is_sw_amsdu; +}; + +struct cl_sw_txhdr { + struct list_head list_pool; + struct list_head tx_queue_list; + struct list_head cfm_list; + struct ieee80211_hdr *hdr80211; + struct cl_tx_queue *tx_queue; + struct cl_sta *cl_sta; + struct cl_vif *cl_vif; + struct cl_amsdu_txhdr amsdu_txhdr; + u8 hw_queue : 3, + is_bcn : 1, + tid : 4; + u8 ac : 2, + is_sw_amsdu : 1, + sw_amsdu_packet_cnt : 4, + rsv : 1; + /* + * singles queue index used to push the txdesc to the ipc layer + * this issue solve race condition in which we + * CFM of packet that associated with disconnected STA and has invalid + * cl_sta pointerinside this struct + */ + u8 sta_idx; + __le16 fc; + struct sk_buff *skb; + struct txdesc txdesc; + size_t map_len; + u16 total_pkt_len; +}; + +void cl_tx_init(struct cl_hw *cl_hw); +void cl_tx_check_start_ba_session(struct cl_hw *cl_hw, + struct ieee80211_sta *sta, + struct sk_buff *skb); +void cl_tx_bcns_tasklet(unsigned long data); +void cl_tx_single_free_skb(struct cl_hw *cl_hw, struct sk_buff *skb); +void cl_tx_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool is_vns, bool lock); +void cl_tx_fast_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool lock); +void cl_tx_agg_prep(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, + u16 frame_len, u8 hdr_pads, bool hdr_conv); +void cl_tx_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool hdr_conv, bool lock); +void cl_tx_fast_agg(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, bool lock); +u16 cl_tx_prepare_wlan_hdr(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct sk_buff *skb, struct ieee80211_hdr *hdr); +void cl_tx_wlan_to_8023(struct sk_buff *skb); +int cl_tx_8023_to_wlan(struct cl_hw *cl_hw, struct sk_buff *skb, struct cl_sta *cl_sta, u8 tid); +void cl_tx_push(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, struct cl_tx_queue *tx_queue); +void cl_tx_bcn_mesh_task(unsigned long data); +void cl_tx_en(struct cl_hw *cl_hw, u8 reason, bool enable); +void cl_tx_off(struct cl_hw *cl_hw); +void cl_tx_drop_skb(struct sk_buff *skb); +void cl_tx_update_hist_tstamp(struct cl_tx_queue *tx_queue, struct sk_buff *skb, + u32 tstamp_hist[DELAY_HIST_SIZE], bool update_skb_ktime); +bool cl_is_tx_allowed(struct cl_hw *cl_hw); +void cl_agg_cfm_init(struct cl_hw *cl_hw); +void cl_agg_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, u8 agg_idx); +void cl_agg_cfm_free_head_skb(struct cl_hw *cl_hw, + struct cl_agg_cfm_queue *cfm_queue, + u8 ba_queue_idx); +void cl_agg_cfm_flush_all(struct cl_hw *cl_hw); +void cl_agg_cfm_poll_empty(struct cl_hw *cl_hw, u8 agg_idx, bool flush); +void cl_agg_cfm_poll_empty_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_agg_cfm_clear_tim_bit_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_agg_cfm_set_ssn(struct cl_hw *cl_hw, u16 ssn, u8 idx); +void cl_agg_cfm_set_tx_queue(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, u8 idx); +void cl_baw_init(struct cl_sta *cl_sta); +void cl_baw_start(struct cl_baw *baw, u16 ssn); +void cl_baw_operational(struct cl_hw *cl_hw, struct cl_baw *baw, + u8 fw_agg_idx, bool amsdu_supported); +void cl_baw_stop(struct cl_baw *baw); +void cl_baw_pending_to_agg(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + u8 tid); +void cl_baw_pending_to_single(struct cl_hw *cl_hw, + struct cl_sta *cl_sta, + struct cl_baw *baw); +void cl_baw_pending_purge(struct cl_baw *baw); + +void cl_bcmc_cfm_init(struct cl_hw *cl_hw); +void cl_bcmc_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +struct cl_sw_txhdr *cl_bcmc_cfm_find(struct cl_hw *cl_hw, dma_addr_t dma_addr, + bool keep_in_list); +void cl_bcmc_cfm_flush_queue(struct cl_hw *cl_hw, struct cl_vif *cl_vif); +void cl_bcmc_cfm_poll_empty_per_vif(struct cl_hw *cl_hw, + struct cl_vif *cl_vif); + +struct cl_single_cfm_queue { + struct list_head head; +}; + +void cl_single_cfm_init(struct cl_hw *cl_hw); +void cl_single_cfm_add(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr, u32 queue_idx); +struct cl_sw_txhdr *cl_single_cfm_find(struct cl_hw *cl_hw, u32 queue_idx, + dma_addr_t dma_addr); +void cl_single_cfm_flush_all(struct cl_hw *cl_hw); +void cl_single_cfm_flush_sta(struct cl_hw *cl_hw, u8 sta_idx); +void cl_single_cfm_poll_empty(struct cl_hw *cl_hw, u32 queue_idx); +void cl_single_cfm_poll_empty_sta(struct cl_hw *cl_hw, u8 sta_idx); +void cl_single_cfm_clear_tim_bit_sta(struct cl_hw *cl_hw, u8 sta_idx); + +int cl_sw_txhdr_init(struct cl_hw *cl_hw); +void cl_sw_txhdr_deinit(struct cl_hw *cl_hw); +struct cl_sw_txhdr *cl_sw_txhdr_alloc(struct cl_hw *cl_hw); +void cl_sw_txhdr_free(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +void cl_tx_amsdu_anchor_init(struct cl_amsdu_ctrl *amsdu_anchor); +void cl_tx_amsdu_anchor_reset(struct cl_amsdu_ctrl *amsdu_anchor); +void cl_tx_amsdu_set_max_len(struct cl_hw *cl_hw, struct cl_sta *cl_sta, u8 tid); +void cl_tx_amsdu_first_sub_frame(struct cl_sw_txhdr *sw_txhdr, struct cl_sta *cl_sta, + struct sk_buff *skb, u8 tid); +void cl_tx_amsdu_flush_sub_frames(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +void cl_tx_amsdu_transfer_single(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +int cl_tx_amsdu_set(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb, u8 tid); +void cl_tx_amsdu_unset(struct cl_sw_txhdr *sw_txhdr); + +int cl_tx_amsdu_txhdr_init(struct cl_hw *cl_hw); +void cl_tx_amsdu_txhdr_deinit(struct cl_hw *cl_hw); +void cl_tx_amsdu_txhdr_free(struct cl_hw *cl_hw, struct cl_amsdu_txhdr *amsdu_txhdr); + +void cl_txq_init(struct cl_hw *cl_hw); +void cl_txq_stop(struct cl_hw *cl_hw); +struct cl_tx_queue *cl_txq_get(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +void cl_txq_push(struct cl_hw *cl_hw, struct cl_sw_txhdr *sw_txhdr); +void cl_txq_sched(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue); +void cl_txq_agg_alloc(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct mm_ba_add_cfm *ba_add_cfm, u16 buf_size); +void cl_txq_agg_free(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, + struct cl_sta *cl_sta, u8 tid); +void cl_txq_agg_stop(struct cl_sta *cl_sta, u8 tid); +void cl_txq_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_txq_sta_remove(struct cl_hw *cl_hw, u8 sta_idx); +void cl_txq_transfer_agg_to_single(struct cl_hw *cl_hw, struct cl_tx_queue *agg_queue); +void cl_txq_flush_agg(struct cl_hw *cl_hw, struct cl_tx_queue *tx_queue, bool lock); +void cl_txq_flush_all_agg(struct cl_hw *cl_hw); +void cl_txq_flush_all_single(struct cl_hw *cl_hw); +void cl_txq_flush_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_txq_agg_request_add(struct cl_hw *cl_hw, u8 sta_idx, u8 tid); +void cl_txq_agg_request_del(struct cl_hw *cl_hw, u8 sta_idx, u8 tid); +bool cl_txq_is_agg_available(struct cl_hw *cl_hw); +bool cl_txq_is_fw_empty(struct cl_tx_queue *tx_queue); +bool cl_txq_is_fw_full(struct cl_tx_queue *tx_queue); +u16 cl_txq_desc_in_fw(struct cl_tx_queue *tx_queue); +bool cl_txq_frames_pending(struct cl_hw *cl_hw); + +#endif /* CL_TX_H */ From patchwork Tue May 24 11:34:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575953 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 2BCB7C433FE for ; Tue, 24 May 2022 11:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236939AbiEXLl1 (ORCPT ); Tue, 24 May 2022 07:41:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237045AbiEXLlK (ORCPT ); Tue, 24 May 2022 07:41:10 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2050.outbound.protection.outlook.com [40.107.20.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2EB5094181 for ; Tue, 24 May 2022 04:40:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YvYHWzJS7WogT6dRVwS8X7XQT38oXay9UytdXdrlwouH2MIkEqaX3yHEAj378XJHiBleNl26sEGEpyE38w3GGhsY6l5Tu7K0txYWmsdjHJvz4KGTXp6mU9v26C2A3l4QUXIHywcGY26oa+MwoPbdEO043Qi/SPxo55TB/2dfQ0O6Yn7RDbYyeRiDeZNH69a0czVNKo6Yf5/ec9aqI6sVgUK1xuKpTQ9e6E4KveYZWtwN0oZnVDvn+2GV69E7QtORr34ccFm55P+vjRg8AlmJWhgBH5+jRyXi9AcPnM0OhrkrvE7px2Z2Z0dwh6oURKa+9h0pITQrsbqXBVxhjNIacg== 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=jQ5oewS1o33UM4gcl+FntTjVuVyd+jWmG0sYFqV785I=; b=aNPUPrWSmKyEMscJjZWcoDwpjvrkYr3h3ZlkL/i07L5baeoMclqyno3M4BHGTIlAApwyt44/GUigSD5bISnwQJw+80iDkbXOMksqbPqdqhJRuuDL/BDYZVPxK0uJDe9NlGyOexA9mzmPD6c74GiE9iMGvRsbe3HMS7G7MNlGaWTkBWxOfwUM9bYPb2IVZjtctapr5AVcJBhxHHQq5O3hWWsFk0ktqCgvXXWwnTGa3sLYZtAdO2/Pjh1dV73LsaaPKg4s0f/1FbRHeYq1CmZQ6Ogwf9t67y0M+Z/GHJdvvb8tYw1hIQ5u7mezhQdqSvZZoANNGDNQ7aK8yN0+/uEIrA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jQ5oewS1o33UM4gcl+FntTjVuVyd+jWmG0sYFqV785I=; b=OGQ9g3wp7V4SanFmUwd0fdOzUu7L1Fq4y7njaon8hsLxoIEaiY8usI2HnY2s5SLdTIp30ItpruKHhbbASpvKhW0FCZPmwYC8QDIKOWWpjRnqhfE8rKVB6w/77BA9QJ3hptqYDi1Z7Exr5Y+h0D0Bsl5jx2+IVt5KVGGaTq5T6NQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:33 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:33 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 86/96] cl8k: add utils.c Date: Tue, 24 May 2022 14:34:52 +0300 Message-Id: <20220524113502.1094459-87-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0e8b9b24-e92f-4ec0-e7cd-08da3d79fde2 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fQ48fZtIwOEuCJJGaGhL4hm7lV4UrDjEZJlYLvmcKuV8QfmjbJ1Ov0ttfYwLrL4RGJwiwXeNAkdi+uacc/mKERwnnpdBNGo3XHZ5flH0zCQqXnNEIb5LphyRAL++Ofj+Xr6WyEQPtsRNpeqWz/1vuW7++qqKuQZNehad1d/neYUTzbblH0yMq7lxJa9bTSu8ebfp043wcLtPzo881nGrmV7vDLx9kVMy8ZByrbuiHp8gfr3QdcEZpqh+yi20WcwD7yzQeQwh3Xp594CBExQGZ07o9bJ4PQvSjzXktYPKJHA7R9D5Zu5KfqyMCwe3FRYI8dL8GoCqWv1WmXpA4e1pury9ZxZKDYJZT6ruwT6e0LQubp+P8B9H1gM7gAcP6qvQ7kUI3IgJQwYq2Rp+ev3rbaRKCpVue8JBQTVFxVVmz0FsvVa2S3KYkKsmREWbXu0/BEwXibTlGCcQTob7fLXMifFOVjCF4JJM+xhqXlQzkce+A96Bl464Vcq1aLIFEAeP5mAtnEwrfleF5ctjA62rzxznzf+N7h3BgrEQWONhFZEf/n5L4PTj3tspfBGk17jOvIj4DeTBGQewUUU0HbZhDl+yr7VLxSYkY0WnnNQRtEoOmKMvx86sta/Qzk235sDUWQzsm8Sw9grLTxd2NbK/jlZeyJNVL3eu2y9RT1wAwKKPUx67BmtR4ojxAS5pRJ4JsMtAVX40pN+AJQn6b42hAhWGP1YS2YGg6VxlZ3h10eQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(30864003)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: il3780JClZic2+wL8K3eixoxL9c9jIqsRKb4dtor4LScFF4uYKsCJzYcpvWFydTIhqiWg0TZkItWrHKYxgLpOkHF+SgqpCWUIxoZ8ieS/rL7SnW+waNMkoxzGprUqz6DhBiza/dbcTMf7FshC0pgnhg8jOuwHj2KAEtXoUBQheP4G8W3gyP3UCCse+Q7UGQ+HASIfJrTJGG3MRu/LYSJ1NT7D5SGsZ8kKitK7eOUMQqobRI720mJl0cCb7N6iWnZlDIV9cWAu+43mGEcOsTnrO+efNnLOPQY9PkxzJF+fZ2liTC/vmi+ZDpNYHcR2otci7ByqcPfW7/uBVCIdYHmfJdeQx+gPyxro2jy/RWpgusNU6nKxWsONlH4Uqtm76PM1+AaupEVKo8pU3TgfnLhSKzCH+3paoWS6u7C0j9aPvNe7K8fOygiysiSYxoLylle3BlbX5RgrnDarQvv69TfZDppm4EhDOngYTZeDO8C2TFbQd9GtbfpnJFXrpCq/lTH9JBughU3OzVcUiPSrwPZ1uCt/ypjLMzgqawFBoksXm0oWWy6fxZU8q1mqhQXNGXgqHewZ5mt8zW1pO4V1v8NUPtBxRlCQ+7SKYb/HEIsuujKuLduyUByOYMd3KSNLZYzgBDuC+weEEqfDA6WVlLBQ5zy08pSVcVJETd2uIK4B/tQI4/I2pnLjxp0LsTwwPdb7qz/iug3iHzC9XP5RXnagFAQ9dp43oTgWTnsD5YLOqnwwclUD9t/MgWBntBCCdskxjv12UuMb5pSgSAo6YGpR7i3nmrKeZPsCCJIQlmbzShsmKk7Li+mj++JPDjKAocLmrLFI06zxtJW+hDs4vVqHoeE+RD2D8bozEGLxcHCvMa50Ma3NcPxDMdVsGR1/fk7s/gZ2/sGtZsnYAwdlprAU7BvUGhE3UhoTjmtSv4MIw8mkOrlHN273TUsSmHPh17zDlP76ut04Z3rjS4VloYgwQCO2mS6SycTz7BYtEP/7BqTdB2DZG4y8WfG0H57466UZG81wDRZUil796XMsK4VcD/wFTGxLG0jV9Y5dhq6OlpN2VGHYg+hA03HDBkJ+xMHJjRMInchDksr1kDDAAI4CMCaS0c8ln/7t4G4DtuMwY2Q02+2AUViJHKMRDT2ek/WK7Crbk+oxDLNjuDoY5OEGzW2E8rRWxtr18ozeWi7EwHBK3PdUSB/poyqc8y4JJzt3BQXv6uVrPbOCCut0IncQ76iv3prJFu7mIqWWn0rL0LufWCTXgI5K7hNnKqWN/5a77zHLba82ENrfs6r19S8HqMD7dttQnRO7ZyS65qR53hY68Fg+f9NBCy/zpeyTpn+pL5CVjAJ+hlDceWqjt8Kj6xh0SlTVpR3B5OWoP1hkCJDUyb2vvVXGIMTNP08sK4/BKdNcPDbyGrj9ttJC0d4VhfxihJV5hR20UOwg/B2ebzfS5zmjCahsaaBKhQtdLFRXCISpRMz7QaQkMJdMzvMVer4nLV4rkR1FH3of1btK0S/FjKDVMentY93Y2O5f1vEFy2l/MTyQG7weANyIAeCo3hna3LnGlGij2W+h6MxEMv0yS8pG/hP0yGqWC73IcSO5R/2rQ/bDUeAHhwkdp9ipPD9KOUeYL/SIW6musVKdTgyuUyZGHK3ItpqvjByDjiOQTlvwHO2hQj5CQn8mnW1xeA7ON61OutO+x/zB7JXNC3XVvuCP9+dkw/VHt1C78VApuGxac20KdMWlQdoa79bfOWcu0/EpnW0Ywm6wKMhJzM= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0e8b9b24-e92f-4ec0-e7cd-08da3d79fde2 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:58.7908 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: qISVjIc1bqTM6+bnzCV/HVh/4MREDHTKds7iwQGI+kpW30k2rM/LuqrAaqPW7+YsRIgeMWjMb5t0Rzj8sdam7w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/utils.c | 642 +++++++++++++++++++++++ 1 file changed, 642 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/utils.c diff --git a/drivers/net/wireless/celeno/cl8k/utils.c b/drivers/net/wireless/celeno/cl8k/utils.c new file mode 100644 index 000000000000..fadc586e9579 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/utils.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hw.h" +#include "ipc_shared.h" +#include "radio.h" +#include "traffic.h" +#include "reg/reg_defs.h" +#include "utils.h" + +#define GI_08 0 +#define GI_16 1 +#define GI_32 2 +#define GI_04 3 + +#define GI_MAX_FW 4 +#define GI_MAX_HE 3 +#define GI_MAX_HT_VHT 2 + +static u8 conv_wrs_gi_ht_vht[GI_MAX_HT_VHT] = { + [WRS_GI_LONG] = GI_08, + [WRS_GI_SHORT] = GI_04 +}; + +static u8 conv_wrs_gi_he[GI_MAX_HE] = { + [WRS_GI_LONG] = GI_32, + [WRS_GI_SHORT] = GI_16, + [WRS_GI_VSHORT] = GI_08 +}; + +static u8 conv_fw_gi_ht_vht[GI_MAX_FW] = { + [GI_08] = WRS_GI_LONG, + [GI_16] = 0, + [GI_32] = 0, + [GI_04] = WRS_GI_SHORT, +}; + +static u8 conv_fw_gi_he[GI_MAX_FW] = { + [GI_08] = WRS_GI_VSHORT, + [GI_16] = WRS_GI_SHORT, + [GI_32] = WRS_GI_LONG, + [GI_04] = 0, +}; + +static const u8 cl_mu_ofdma_ru_type_to_bw_conversion[CL_MU_OFDMA_RU_TYPE_MAX] = { + CHNL_BW_2_5, + CHNL_BW_2_5, + CHNL_BW_5, + CHNL_BW_10, + CHNL_BW_20, + CHNL_BW_40, + CHNL_BW_80, + CHNL_BW_160 +}; + +void cl_hex_dump(char *caption, u8 *buffer, u32 length, u32 offset, bool is_byte) +{ + u8 *pt = buffer; + u32 i; + bool end_nl = false; + char buf[STR_LEN_256B] = {0}; + int len = 0; + + if (caption) + pr_debug("%s: %p, len = %u\n", caption, buffer, length); + + if (is_byte) { + for (i = 0; i < length; i++) { + if (i % 16 == 0) + len += snprintf(buf + len, sizeof(buf) - len, + "0x%04x : ", i + offset); + len += snprintf(buf + len, sizeof(buf) - len, + "%02x ", ((u8)pt[i])); + end_nl = true; + if (i % 16 == 15) { + pr_debug("%s", buf); + len = 0; + end_nl = false; + } + } + } else { + for (i = 0; i < (length / sizeof(u32)); i++) { + if (i % 4 == 0) + len += snprintf(buf + len, sizeof(buf) - len, + "0x%04x : ", + (u32)(i * sizeof(u32) + offset)); + len += snprintf(buf + len, sizeof(buf) - len, + "%08x ", *((u32 *)(pt + i * sizeof(u32)))); + end_nl = true; + if (i % 4 == 3) { + pr_debug("%s", buf); + len = 0; + end_nl = false; + } + } + } + + if (end_nl) + pr_debug("%s", buf); +} + +u8 cl_convert_gi_format_wrs_to_fw(u8 wrs_mode, u8 gi) +{ + if (wrs_mode == WRS_MODE_HE && gi < GI_MAX_HE) + return conv_wrs_gi_he[gi]; + else if (wrs_mode > WRS_MODE_OFDM && gi < GI_MAX_HT_VHT) + return conv_wrs_gi_ht_vht[gi]; + else + return 0; +} + +u8 cl_convert_gi_format_fw_to_wrs(u8 format_mode, u8 gi) +{ + if (gi < GI_MAX_FW) { + if (format_mode >= FORMATMOD_HE_SU) + return conv_fw_gi_he[gi]; + else if (format_mode >= FORMATMOD_HT_MF) + return conv_fw_gi_ht_vht[gi]; + } + + return 0; +} + +static u8 map_gi_to_ltf[WRS_GI_MAX] = { + [WRS_GI_LONG] = LTF_X4, + [WRS_GI_SHORT] = LTF_X2, + [WRS_GI_VSHORT] = LTF_X2, +}; + +u8 cl_map_gi_to_ltf(u8 mode, u8 gi) +{ + if (mode == WRS_MODE_HE && gi < WRS_GI_MAX) + return map_gi_to_ltf[gi]; + + return 0; +} + +/* This table holds 10^(-110 -> 0) Q39 values for rx RSSI and noise floor calculations */ +#define CL_EXP_TBL_SIZE 111 /* 10^x table size (-110 -> 0dBm) */ + +static u64 CL_EXP_10[CL_EXP_TBL_SIZE] = { + 0x7FFFFFFFFFULL, 0x65AC8C2F36ULL, 0x50C335D3DBULL, 0x4026E73CCDULL, 0x32F52CFEEAULL, + 0x287A26C490ULL, 0x2026F30FBBULL, 0x198A13577CULL, 0x144960C577ULL, 0x101D3F2D96ULL, + 0x0CCCCCCCCDULL, 0x0A2ADAD185ULL, 0x08138561FCULL, 0x066A4A52E1ULL, 0x0518847FE4ULL, + 0x040C3713A8ULL, 0x0337184E5FULL, 0x028DCEBBF3ULL, 0x0207567A25ULL, 0x019C86515CULL, + 0x0147AE147BULL, 0x01044914F4ULL, 0x00CEC089CCULL, 0x00A43AA1E3ULL, 0x008273A664ULL, + 0x00679F1B91ULL, 0x00524F3B0AULL, 0x0041617932ULL, 0x0033EF0C37ULL, 0x002940A1BCULL, + 0x0020C49BA6ULL, 0x001A074EE5ULL, 0x0014ACDA94ULL, 0x00106C4364ULL, 0x000D0B90A4ULL, + 0x000A5CB5F5ULL, 0x00083B1F81ULL, 0x000689BF52ULL, 0x0005318139ULL, 0x000420102CULL, + 0x000346DC5DULL, 0x00029A54B1ULL, 0x000211490FULL, 0x0001A46D24ULL, 0x00014DF4DDULL, + 0x0001094565ULL, 0x0000D2B65AULL, 0x0000A75FEFULL, 0x000084F352ULL, 0x0000699B38ULL, + 0x000053E2D6ULL, 0x000042A212ULL, 0x000034EDB5ULL, 0x00002A0AEAULL, 0x0000216549ULL, + 0x00001A86F1ULL, 0x000015123CULL, 0x000010BCCBULL, 0x00000D4B88ULL, 0x00000A8F86ULL, + 0x000008637CULL, 0x000006A9CFULL, 0x0000054AF8ULL, 0x000004344BULL, 0x00000356EEULL, + 0x000002A718ULL, 0x0000021B6CULL, 0x000001AC7BULL, 0x000001545AULL, 0x0000010E5AULL, + 0x000000D6C0ULL, 0x000000AA95ULL, 0x000000877FULL, 0x0000006BA1ULL, 0x000000557EULL, + 0x00000043E9ULL, 0x00000035F1ULL, 0x0000002AD9ULL, 0x0000002209ULL, 0x0000001B09ULL, + 0x000000157AULL, 0x000000110FULL, 0x0000000D8DULL, 0x0000000AC3ULL, 0x000000088DULL, + 0x00000006CAULL, 0x0000000565ULL, 0x0000000449ULL, 0x0000000367ULL, 0x00000002B4ULL, + 0x0000000226ULL, 0x00000001B5ULL, 0x000000015BULL, 0x0000000114ULL, 0x00000000DBULL, + 0x00000000AEULL, 0x000000008AULL, 0x000000006EULL, 0x0000000057ULL, 0x0000000045ULL, + 0x0000000037ULL, 0x000000002CULL, 0x0000000023ULL, 0x000000001CULL, 0x0000000016ULL, + 0x0000000011ULL, 0x000000000EULL, 0x000000000BULL, 0x0000000009ULL, 0x0000000007ULL, + 0x0000000005ULL +}; + +static s8 cl_eng_to_noise_floor(u64 eng) +{ + s8 i = 0; + s8 noise = 0; + s64 min_delta = S64_MAX; + + for (i = CL_EXP_TBL_SIZE - 1; i >= 0; i--) { + if (abs((s64)(((s64)eng) - ((s64)CL_EXP_10[i]))) < min_delta) { + min_delta = abs((s64)(((s64)eng) - ((s64)CL_EXP_10[i]))); + noise = i; + } + } + + return (-noise); +} + +static void cl_read_reg_noise(struct cl_hw *cl_hw, s8 res[4]) +{ + u32 reg_val = riu_agcinbdpow_20_pnoisestat_get(cl_hw); + u8 i = 0; + + for (i = 0; i < 4; i++) { + u8 curr_val = (reg_val >> (i * 8)) & 0xFF; + /* Convert reg value to real value */ + res[i] = curr_val - 0xFF; + } +} + +s8 cl_calc_noise_floor(struct cl_hw *cl_hw, const s8 *reg_noise_floor) +{ + s8 noise_floor[4] = {0}; + u64 noise_floor_eng = 0; + + if (reg_noise_floor) + memcpy(noise_floor, reg_noise_floor, sizeof(noise_floor)); + else + cl_read_reg_noise(cl_hw, noise_floor); + + noise_floor[0] = abs(noise_floor[0]); + noise_floor[1] = abs(noise_floor[1]); + noise_floor[2] = abs(noise_floor[2]); + noise_floor[3] = abs(noise_floor[3]); + + BUILD_BUG_ON(CL_EXP_TBL_SIZE > S8_MAX); + noise_floor_eng = (CL_EXP_10[min_t(s8, noise_floor[0], CL_EXP_TBL_SIZE - 1)] + + CL_EXP_10[min_t(s8, noise_floor[1], CL_EXP_TBL_SIZE - 1)] + + CL_EXP_10[min_t(s8, noise_floor[2], CL_EXP_TBL_SIZE - 1)] + + CL_EXP_10[min_t(s8, noise_floor[3], CL_EXP_TBL_SIZE - 1)]); + + noise_floor_eng = div64_u64(noise_floor_eng, 4); + + return cl_eng_to_noise_floor(noise_floor_eng); +} + +u8 cl_convert_signed_to_reg_value(s8 val) +{ + bool sign = val < 0; + u8 res = abs(val); + + if (sign) + res |= (1 << 7); + + return res; +} + +static const int nl_width_to_phy_bw[] = { + [NL80211_CHAN_WIDTH_20_NOHT] = CHNL_BW_20, + [NL80211_CHAN_WIDTH_20] = CHNL_BW_20, + [NL80211_CHAN_WIDTH_40] = CHNL_BW_40, + [NL80211_CHAN_WIDTH_80] = CHNL_BW_80, + [NL80211_CHAN_WIDTH_80P80] = CHNL_BW_20, + [NL80211_CHAN_WIDTH_160] = CHNL_BW_160, + [NL80211_CHAN_WIDTH_5] = CHNL_BW_20, + [NL80211_CHAN_WIDTH_10] = CHNL_BW_20, +}; + +u8 cl_width_to_bw(enum nl80211_chan_width width) +{ + if (width <= NL80211_CHAN_WIDTH_10) + return nl_width_to_phy_bw[width]; + + return CHNL_BW_20; +} + +u8 cl_center_freq_offset(u8 bw) +{ + if (bw == CHNL_BW_160) + return 70; + + if (bw == CHNL_BW_80) + return 30; + + if (bw == CHNL_BW_40) + return 10; + + return 0; +} + +u8 cl_max_bw_idx(u8 wrs_mode, bool is_24g) +{ + if (wrs_mode < WRS_MODE_HT) + return CHNL_BW_20 + 1; + + if (wrs_mode == WRS_MODE_HT || is_24g) + return CHNL_BW_40 + 1; + + return CHNL_BW_MAX; +} + +bool cl_hw_mode_is_b_or_bg(struct cl_hw *cl_hw) +{ + return (cl_hw->hw_mode == HW_MODE_B || + cl_hw->hw_mode == HW_MODE_BG); +} + +#define LENGTH_LLC 3 +#define LENGTH_SSNAP 5 + +bool cl_is_eapol(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + unsigned int hdrlen = 0; + unsigned short ethertype = 0; + u8 *temp = NULL; + + /* Find the wireless header size */ + hdrlen = ieee80211_has_a4(fc) ? 30 : 24; + + if (ieee80211_is_data_qos(fc)) { + hdrlen += IEEE80211_QOS_CTL_LEN; + + if (ieee80211_has_order(fc)) + hdrlen += IEEE80211_HT_CTL_LEN; + } + + /* Skip wireless header */ + temp = (u8 *)(skb->data + hdrlen); + + /* Skip LLC and SNAP header */ + if (PKT_HAS_LLC_HDR(temp)) + ethertype = cl_get_ether_type(LENGTH_LLC + LENGTH_SSNAP - 2, temp); + + return ethertype == ETH_P_PAE; +} + +u8 cl_ru_alloc_to_ru_type(u8 ru_alloc) +{ + if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_1) + return CL_MU_OFDMA_RU_TYPE_26; + else if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_2) + return CL_MU_OFDMA_RU_TYPE_52; + else if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_3) + return CL_MU_OFDMA_RU_TYPE_106; + else if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_4) + return CL_MU_OFDMA_RU_TYPE_242; + else if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_5) + return CL_MU_OFDMA_RU_TYPE_484; + else if (ru_alloc <= CL_TF_RU_ALLOC_MAX_TYPE_6) + return CL_MU_OFDMA_RU_TYPE_996; + else + return CL_MU_OFDMA_RU_TYPE_2x996; +} + +bool cl_is_valid_g_rates(const u8 *rate_ie) +{ + int i, rate; + + for (i = 0; i < rate_ie[1]; i++) { + rate = rate_ie[2 + i] & CL_SUPP_RATE_MASK; + switch (rate) { + case CL_80211G_RATE_6MB: + case CL_80211G_RATE_9MB: + case CL_80211G_RATE_12MB: + case CL_80211G_RATE_18MB: + case CL_80211G_RATE_24MB: + case CL_80211G_RATE_36MB: + case CL_80211G_RATE_48MB: + case CL_80211G_RATE_54MB: + return true; + } + } + return false; +} + +enum cl_wireless_mode cl_recalc_wireless_mode(struct cl_hw *cl_hw, + bool ieee80211n, + bool ieee80211ac, + bool ieee80211ax) +{ + enum cl_wireless_mode wireless_mode = cl_hw->wireless_mode; + + if (!ieee80211n && !ieee80211ac && !ieee80211ax) + wireless_mode = WIRELESS_MODE_LEGACY; + else if (ieee80211n && (cl_band_is_24g(cl_hw) || ieee80211ac) && ieee80211ax) + wireless_mode = WIRELESS_MODE_HT_VHT_HE; + else if (ieee80211n && ieee80211ac) + wireless_mode = WIRELESS_MODE_HT_VHT; + else if (ieee80211n) + wireless_mode = WIRELESS_MODE_HT; + else if (ieee80211ax) + wireless_mode = WIRELESS_MODE_HE; + + return wireless_mode; +} + +enum nl80211_he_ru_alloc cl_ru_type_to_nl80211_he_ru_alloc(enum cl_mu_ofdma_ru_type ru_type) +{ + switch (ru_type) { + case CL_MU_OFDMA_RU_TYPE_26: + return NL80211_RATE_INFO_HE_RU_ALLOC_26; + case CL_MU_OFDMA_RU_TYPE_52: + return NL80211_RATE_INFO_HE_RU_ALLOC_52; + case CL_MU_OFDMA_RU_TYPE_106: + return NL80211_RATE_INFO_HE_RU_ALLOC_106; + case CL_MU_OFDMA_RU_TYPE_242: + return NL80211_RATE_INFO_HE_RU_ALLOC_242; + case CL_MU_OFDMA_RU_TYPE_484: + return NL80211_RATE_INFO_HE_RU_ALLOC_484; + case CL_MU_OFDMA_RU_TYPE_996: + return NL80211_RATE_INFO_HE_RU_ALLOC_996; + case CL_MU_OFDMA_RU_TYPE_2x996: + return NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + default: + return 0; + } +} + +u8 cl_mu_ofdma_grp_convert_ru_type_to_bw(struct cl_hw *cl_hw, u8 ru_type) +{ + if (ru_type >= CL_MU_OFDMA_RU_TYPE_MAX) { + pr_err("Invalid RU type %u\n", ru_type); + return 0; + } + + return cl_mu_ofdma_ru_type_to_bw_conversion[ru_type]; +} + +void cl_ieee802_11_parse_elems(const u8 *ies, size_t ies_len, struct ieee802_11_elems *elems) +{ + u8 *ie = NULL; + + memset(elems, 0, sizeof(*elems)); + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len); + if (ie) { + elems->ssid = (const u8 *)&ie[2]; + elems->ssid_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len); + if (ie) { + elems->supp_rates = (const u8 *)&ie[2]; + elems->supp_rates_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len); + if (ie) + elems->ht_cap_elem = (struct ieee80211_ht_cap *)&ie[2]; + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_OPERATION, ies, ies_len); + if (ie) + elems->ht_operation = (struct ieee80211_ht_operation *)&ie[2]; + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len); + if (ie) + elems->vht_cap_elem = (struct ieee80211_vht_cap *)&ie[2]; + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_VHT_OPERATION, ies, ies_len); + if (ie) + elems->vht_operation = (struct ieee80211_vht_operation *)&ie[2]; + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); + if (ie) { + elems->tim = (struct ieee80211_tim_ie *)&ie[2]; + elems->tim_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ie(WLAN_EID_RSN, ies, ies_len); + if (ie) { + elems->rsn = (const u8 *)&ie[2]; + elems->rsn_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ext_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len); + if (ie) { + elems->ext_supp_rates = (const u8 *)&ie[2]; + elems->ext_supp_rates_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len); + if (ie) { + elems->he_cap = (const u8 *)&ie[2]; + elems->he_cap_len = ie[1]; + } + + ie = (u8 *)cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, ies, ies_len); + if (ie) + elems->he_operation = (struct ieee80211_he_operation *)&ie[2]; +} + +size_t cl_file_open_and_read(struct cl_chip *chip, const char *filename, + char **buf) +{ + const struct firmware *fw; + size_t size = 0; + int ret = 0; + char path_name[CL_PATH_MAX] = {0}; + + snprintf(path_name, sizeof(path_name), "cl8k/%s", filename); + ret = request_firmware_direct(&fw, path_name, chip->dev); + + if (ret) { + cl_dbg_chip_err(chip, "request_firmware_direct %s failed\n", + path_name); + return 0; + } + + if (!fw || !fw->data) { + cl_dbg_chip_err(chip, "Invalid firmware %s\n", path_name); + goto out; + } + + size = fw->size; + + /* + * Add one byte with a '\0' so that string manipulation functions + * used for parsing these files can find the string '\0' terminator. + * Make sure size is aligned to 4. + */ + *buf = kzalloc(ALIGN(size + 1, 4), GFP_KERNEL); + if (!(*buf)) { + size = 0; + goto out; + } + + memcpy(*buf, fw->data, size); + +out: + release_firmware(fw); + + return size; +} + +static __be16 cl_get_eth_proto(struct sk_buff *skb) +{ + if (!skb->mac_header) + skb_reset_mac_header(skb); + + if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)) + return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + return eth_hdr(skb)->h_proto; +} + +bool cl_set_network_header_if_proto(struct sk_buff *skb, u16 protocol) +{ + if (cl_get_eth_proto(skb) == htons(protocol)) { + const bool has_vlan_header = eth_hdr(skb)->h_proto == htons(ETH_P_8021Q); + const size_t h_offset = + (eth_hdr(skb) == (struct ethhdr *)(skb->data)) ? ETH_HLEN : 0; + + skb_set_network_header(skb, h_offset + ((has_vlan_header) ? VLAN_HLEN : 0)); + + return true; + } + + return false; +} + +bool cl_is_ipv4_packet(struct sk_buff *skb) +{ + return cl_set_network_header_if_proto(skb, ETH_P_IP) && + (ip_hdr(skb)->ihl >= 5) && + (ip_hdr(skb)->version == IPVERSION); +} + +bool cl_is_ipv6_packet(struct sk_buff *skb) +{ + return cl_set_network_header_if_proto(skb, ETH_P_IPV6) && + (ipv6_hdr(skb)->version == 6); +} + +#define TCP_ACK_MAX_LEN 100 + +bool cl_is_tcp_ack(struct sk_buff *skb, bool *syn_rst_push) +{ + if (skb->len > TCP_ACK_MAX_LEN) + goto out; + + if (cl_is_ipv4_packet(skb)) { + struct iphdr *iphdr = ip_hdr(skb); + + if (iphdr->protocol == IPPROTO_TCP) { + struct tcphdr *tcp_hdr = (struct tcphdr *) + ((char *)iphdr + + IPV4_HDR_LEN(iphdr->ihl)); + u16 data_size = ntohs(iphdr->tot_len) - + IPV4_HDR_LEN(iphdr->ihl) - + (tcp_hdr->doff * 4); + + *syn_rst_push = tcp_hdr->syn || tcp_hdr->rst || tcp_hdr->psh; + + return (data_size == 0); + } + } else if (cl_is_ipv6_packet(skb)) { + struct ipv6hdr *ipv6hdr = ipv6_hdr(skb); + + if (ipv6hdr->nexthdr == IPPROTO_TCP) { + struct tcphdr *tcp_hdr = (struct tcphdr *) + ((char *)ipv6hdr + + sizeof(struct ipv6hdr)); + u16 data_size = ntohs(ipv6hdr->payload_len) - + (tcp_hdr->doff * 4); + + *syn_rst_push = tcp_hdr->syn || tcp_hdr->rst || tcp_hdr->psh; + + return (data_size == 0); + } + } + +out: + *syn_rst_push = false; + return false; +} + +bool cl_band_is_6g(struct cl_hw *cl_hw) +{ + return (cl_hw->conf->ci_band_num == 6); +} + +bool cl_band_is_5g(struct cl_hw *cl_hw) +{ + return (cl_hw->conf->ci_band_num == 5); +} + +bool cl_band_is_24g(struct cl_hw *cl_hw) +{ + return (cl_hw->conf->ci_band_num == 24); +} + +u8 cl_band_to_fw_idx(struct cl_hw *cl_hw) +{ + if (cl_hw->nl_band == NL80211_BAND_6GHZ) + return FW_BAND_6GHZ; + + if (cl_hw->nl_band == NL80211_BAND_5GHZ) + return FW_BAND_5GHZ; + + return FW_BAND_2GHZ; +} + +static u8 fw_to_nl_band[FW_BAND_MAX] = { + [FW_BAND_6GHZ] = NL80211_BAND_6GHZ, + [FW_BAND_5GHZ] = NL80211_BAND_5GHZ, + [FW_BAND_2GHZ] = NL80211_BAND_2GHZ, +}; + +u8 cl_band_from_fw_idx(u32 phy_band) +{ + if (phy_band < FW_BAND_MAX) + return fw_to_nl_band[phy_band]; + + return FW_BAND_MAX; +} From patchwork Tue May 24 11:34:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576833 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 DD07DC433FE for ; Tue, 24 May 2022 11:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234493AbiEXLlj (ORCPT ); Tue, 24 May 2022 07:41:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235724AbiEXLlf (ORCPT ); Tue, 24 May 2022 07:41:35 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2088.outbound.protection.outlook.com [40.107.20.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71B9D41316 for ; Tue, 24 May 2022 04:40:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AmA2g69I2MKneHs6rxRuya8wRBG3TMyh/5F4jpJstQgbnQ4/OK6CGD0xwHCcI8r6vhogDD0z9/rpY5QZF3t3/4YSPYrc+3oqhlC1U0jkX59amJ4pyACz341G7bOnDOXkfJgj4OJRXm7RM7XS7c6j5rycqf0acNFMPqQDmJW65mXG0A/7dhCIs5tPvOdhwF33Ga1N15psTQjFpQR5F+0kxvHbRDGjys7skSaDidMO3BlVjZSt/HWlzhUhKmppkBaNsq5B1kCAU0dWX6VkDOASAENO8WDz6IyaI0Vl6+GVPo4jOO+0E+5lSLmNg52qoMkTruPYf6dkFK8a3pfc6pItsw== 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=Vv3Azjr+w6grboMjCEQiIIVS7F/Ov3OpdstixAN8Moc=; b=Nr4xkNzlbCGv/4FEEC2nikUk1dh1MXqgze2mka+jB4yiRD2oB1lEfg/PxBvxdt1LxsLB6oWOImhPCAKQrnZEjm1pP21aAXX6q7G84So+3n7owoaFkj7tVtlokflB43d2jQ1E4m+uhbRyE+5opOG6dDmEtKKleOxhDZU4yBkXw11Md+4AKZ14wuWi1El+rwWdE5ujYn6GCIKzoRdg3KaQaWwGlrf0tf4gx5JyA5gJlW5l5/Qyf3r/fOFIZ7lrNvWkjRvFeOJmT1xfQJtdBBRH+dStaVVoZxbIC0hgNvlj+WJpoX368eoCo+aD1J39E55GqhQurme5N5tlaC39bbE6bg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Vv3Azjr+w6grboMjCEQiIIVS7F/Ov3OpdstixAN8Moc=; b=y09XWT+3Cz7YIS+XH6RMrLJlhrKtroZ6Ju0JvZaQ157ujnW1kKxJ/32g3/pV0KLmYOl3RnbFWObVNgUOBD74xVV/MyDv8FpNQcl21kwi9C/znAqNwWlORvIlOjtfcNyEhz/TPqRRauiJTK/hO9zFjgPYI/1t3wvRwHsc4Uz77WE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:33 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:33 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 87/96] cl8k: add utils.h Date: Tue, 24 May 2022 14:34:53 +0300 Message-Id: <20220524113502.1094459-88-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8b7de008-f36f-47b1-20da-08da3d79fe5a X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Bc0CB20GHBakoVz6zAmDpfKwDMevHSN8D2o9iFHoIMo07AjJ+b5nlMu/IcLELrKvgdsmc6PJpqfOH4ilVs5ju3/5POETsI9EHbOLRH6blulsqRnkRVqWO9/8Kls9M5i3KT1S1ZwMFuCMjlUXxxFkoM3YmRdcGgncfEu1lqON0ec2AGbwdsApDChkAmXuQjSyUkE9hlVZtC8JQ137KggRgxzShlB+kOZo2udWGItiNfrKAR1CWIr9uXyv7SdV27LARgnMs0soPTjSWGpwOTXMG9DzrPDd2BVyowJaBSPY9ARyluFdDlsn17z1B+GQ6mWAZcegPU3CA1omZ92Z0YmHfQPVYDWy+9ViCTp1DE93sOu3+AJ+zHnb5pWwFPQqZeipLH/acluZwgRBPRkm74uH4PgDOXdIWc77CUJ5RlfqeuG6F/3h6jqL/jKjKNotWfZb/G4YR2GlC3zSAktWewicAc972wQJFYpowXa/Oa15bbHEPHYeI2pW6ltLX6pezR0iXeAklbgZO5WK6wUthLoJp08dFstWFdmGvNGhUHxC/cdDWQbXA8Ck+dAOL/N7vrQFstfrQexTj9LReDWDEc9YMLOb+OTMlODkbdczQLfrA7+SJ0yDaOJSLPyf56OnbELm12ZgRq2MZ3fskRhm+nq3p1Fh0Wo0b80D1WNpCPWJ9ZDKI1ORb/h/pqz5Jh+LGrhvPE5UrAMwtJ4Dw5yaoIZYPYD0oEaKhdV0V3AURfAMOuY= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: RbHyk4SePv3cQPm6qp3JZ4NM76fodeCW6Xcrc2wFc/YdOFhk7nEt24b5SvbHEOjQuKLq7FcU+UXhudYgheYNqetF5fs6xza/dtTTaZ6ZDuGnxkMZV5h4mtQitnuGt01HtQ3GCPNS0Cfg4ZKKmO+tyx70VWdYNvePCn+0et0V6xnNIFmiMxWDKp2s0anjPqblww5r1+OvTBakCrou2KyTrmV9IMhfOhjhK4jWtfGRHYsrPyz8f+Py9bi/0ki+oyftyj8OoNuNL0L9jNWr0LXFo5v/tgKICgmiosY42JhEP7NXq1xjTAeDXqgfX52ih6oj+oHBulcvr4cMziuZSfSJ87qFzkVhEoUNkZAwcf5iDPDDd6xfmzcVhT2OI1yY5kkNPYIVrDHbNCdTbUAARFXieCvVPvpk/1f77R/td/WPoG6++h6nXsDyD9Y8YmKc/mSEkLAg/bAxtFrCy9RFChRUc0eycZ4ohT+/lB2H4DGPlGzAxBQ0HbdprrYOBIw2dXOnaXFTkEYj8EYWmq8xDO8M22uZY9/jAB6g+0MWuf/swyx6Fw4//kD0cqFO3bviXWkonK6h/gCfIchBrky6fXyngcTBDtF4kUFUbslY7X2+U/R+ajSEpdn77MiKfrb0w7vEmt4KFSCL/Oc8WYFv5r3ccZmf7tFzYugMNqce2yjTs5rGoF+n+gBPe9oI2UdgdNtdxjv1LLvLxFeqhfKFmtUtXmvuOx4AEADLYNVoyPyX7Lky6vZ288VD9h6tU3nihzc3n1KHoi+iqFFgWzbLnMhhaPJGTxpRRdwt6n52hKCh1ynx9xoLrKSAUuZZCgBesjo0ekpnPQeceHh3TkQoMRdTmLgue+XvQrYbx4aEolgJ3MkQvAErV7y+YtmKZGrNsUjwSeI5efBd3Zdvs/gOQpgV+I40j77K9pY3/OC3sJ5EKZWgY24UI86iSJg/0E/uwDUsTbjdFxOYm2TY3DNY+Xcs/dD16ut6mZv8pVd9cpwRNGczfPQrwWmIT/iQG7pFNqF1/C8uQVGbP17f82qp4Gx+TFlx1oObGY6x92LcNR/ZWCEmlHssEW4mBKwgO5E3P6yAM/M1DpxKbzYHH6p6PVLZAIXHNXqNC86sndL4ryChvftgUHYzj1ruinnpIhINtDZ3wS8r+NGCR7tykgGbYQYsk+NEBPlD1OFpsOKilTza8L0Ei+XturFCsCp6W/1r50VgdzVfiUnQZbIhLdvmWMfOS4Kp+Vo1x/vMvW+L0BMeDXJzY6+oR50vc3XqeAQsuViyCQ97MlzveFXmS9hm/gTzH2aZVkiVjdQl2Kq07WiD0cHVcUp4xzwFZOkhvdCZCMcHFwLc8GtG7gCRrPwxrHJ+1XfE9vuFJJp3eVbDInjSrmbI6N+7GKgfbijBCg6nkH44W2zvXbGwM4AkmfmghlgzN8/++HiqCtaFfXlGNwb2MGdShERNO53Nyk1UbipagPecaywwM9978Nw4elfILdgEjHuG3fsd06PNkmEiiBNU9ptICXzLjqE266xANLiv5kb7qPsHrbc40L4s3Qo9ejNMZkBVv91RmNzBrafsruv+Omt4hQeeVEgWp70esvgOyTi9NU2jhMH/kVp1HKH5WpvM5rzHj/US5/UfP7nsBICTYCboHpDBeyrFbGkBd6u+zN0AFysJVtzFQ8FEU8GQEUkx7TOb31MmcF5r/zOnMdTcFrwxhDpTY5OQQmRCgGZAdi8fRSegCEa2TvgM6/cZaASgwEtbIzxrZcK7Nyb7cSuKoMk= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8b7de008-f36f-47b1-20da-08da3d79fe5a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:38:59.5565 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0Q2+0BkXMa225GkI9yyzvGokMAnWz0nZgIsdoyFIR40ThakhSIUSbAeDK9Eq/286GcODtwYN4Wrui1MKD9prdQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/utils.h | 185 +++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/utils.h diff --git a/drivers/net/wireless/celeno/cl8k/utils.h b/drivers/net/wireless/celeno/cl8k/utils.h new file mode 100644 index 000000000000..052687183dd3 --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/utils.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_UTILS_H +#define CL_UTILS_H + +#include "def.h" +#include "ieee80211_i.h" +#include "chip.h" + +/* + * GI_LTF field for common info + * 0 - 1x HE-LTF + 1.6 us GI + * 1 - 2x HE-LTF + 1.6 us GI + * 2 - 4x HE-LTF + 3.2 us GI + */ +enum cl_he_ltf_gi { + HE_LTF_X1_GI_16, /* Not supported */ + HE_LTF_X2_GI_16, + HE_LTF_X4_GI_32, + + HE_LTF_MAX +}; + +#define CL_TF_GI_LTF_TO_GI(gi_ltf) \ + ((gi_ltf) == HE_LTF_X4_GI_32 ? WRS_GI_LONG : \ + ((gi_ltf) == HE_LTF_X2_GI_16 ? WRS_GI_SHORT : \ + ((gi_ltf) == HE_LTF_X1_GI_16 ? WRS_GI_SHORT : WRS_GI_LONG))) + +#define CL_TF_GI_TO_GI_LTF(gi) \ + ((gi) == WRS_GI_LONG ? HE_LTF_X4_GI_32 : \ + ((gi) == WRS_GI_SHORT ? HE_LTF_X2_GI_16 : \ + ((gi) == WRS_GI_VSHORT ? HE_LTF_X2_GI_16 : HE_LTF_X4_GI_32))) + +#define CL_TF_RU_ALLOC_MAX_TYPE_1 36 +#define CL_TF_RU_ALLOC_MAX_TYPE_2 52 +#define CL_TF_RU_ALLOC_MAX_TYPE_3 60 +#define CL_TF_RU_ALLOC_MAX_TYPE_4 64 +#define CL_TF_RU_ALLOC_MAX_TYPE_5 66 +#define CL_TF_RU_ALLOC_MAX_TYPE_6 67 +#define CL_TF_RU_ALLOC_MAX_TYPE_7 68 + +/* + *IEEE80211 G Rate provided by Hostapd in WLAN_EID_SUPP_RATES EID + *EID Rate = ieee802Rate/5 + */ +#define CL_80211G_RATE_6MB 12 +#define CL_80211G_RATE_9MB 18 +#define CL_80211G_RATE_12MB 24 +#define CL_80211G_RATE_18MB 36 +#define CL_80211G_RATE_24MB 48 +#define CL_80211G_RATE_36MB 72 +#define CL_80211G_RATE_48MB 96 +#define CL_80211G_RATE_54MB 108 + +#define CL_SUPP_RATE_MASK 0x7F + +#define BAND_IS_5G_6G(cl_hw) \ + (cl_band_is_5g(cl_hw) || cl_band_is_6g(cl_hw)) + +static const u8 tid_to_ac[] = { + AC_BE, AC_BK, AC_BK, AC_BE, AC_VI, AC_VI, AC_VO, AC_VO +}; + +static inline u16 cl_adc_to_mv(u16 adc) +{ + return (adc * 1800) >> 12; +} + +static inline struct ieee80211_vif *NETDEV_TO_VIF(struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (!wdev) + return NULL; + + return wdev_to_ieee80211_vif(wdev); +} + +static inline struct cl_hw *NETDEV_TO_CL_HW(struct net_device *dev) +{ + struct ieee80211_hw *hw = wdev_priv(dev->ieee80211_ptr); + + return hw->priv; +} + +static inline struct cl_vif *NETDEV_TO_CL_VIF(struct net_device *dev) +{ + struct ieee80211_vif *vif = NETDEV_TO_VIF(dev); + + WARN_ON(!vif); + + if (unlikely(vif->type == NL80211_IFTYPE_AP_VLAN)) { + struct cl_hw *cl_hw = NETDEV_TO_CL_HW(dev); + + return cl_vif_get_by_dev(cl_hw, dev); + } + + return (struct cl_vif *)vif->drv_priv; +} + +static inline struct cl_vif *TX_INFO_TO_CL_VIF(struct cl_hw *cl_hw, + struct ieee80211_tx_info *tx_info) +{ + struct ieee80211_vif *vif = tx_info->control.vif; + + WARN_ON(!vif); + + if (unlikely(vif->type == NL80211_IFTYPE_AP_VLAN)) + return cl_vif_get_by_mac(cl_hw, vif->addr); + + return (struct cl_vif *)(vif->drv_priv); +} + +void cl_hex_dump(char *caption, u8 *buffer, u32 length, u32 offset, bool is_byte); +u8 cl_convert_gi_format_wrs_to_fw(u8 wrs_mode, u8 gi); +u8 cl_convert_gi_format_fw_to_wrs(u8 format_mode, u8 gi); +u8 cl_map_gi_to_ltf(u8 mode, u8 gi); +s8 cl_calc_noise_floor(struct cl_hw *cl_hw, const s8 *reg_noise_floor); +u8 cl_convert_signed_to_reg_value(s8 val); +u8 cl_width_to_bw(enum nl80211_chan_width width); +u8 cl_center_freq_offset(u8 bw); +u8 cl_max_bw_idx(u8 wrs_mode, bool is_24g); +bool cl_hw_mode_is_b_or_bg(struct cl_hw *cl_hw); +bool cl_is_eapol(struct sk_buff *skb); +u8 cl_ru_alloc_to_ru_type(u8 ru_alloc); +bool cl_is_valid_g_rates(const u8 *rate_ie); +enum cl_wireless_mode cl_recalc_wireless_mode(struct cl_hw *cl_hw, + bool ieee80211n, + bool ieee80211ac, + bool ieee80211ax); + +enum cl_mu_ofdma_ru_type { + CL_MU_OFDMA_RU_TYPE_NONE = 0, + CL_MU_OFDMA_RU_TYPE_26, /* 2.5MHz */ + CL_MU_OFDMA_RU_TYPE_52, /* 5MHz */ + CL_MU_OFDMA_RU_TYPE_106, /* 10MHz */ + CL_MU_OFDMA_RU_TYPE_242, /* 20MHz */ + CL_MU_OFDMA_RU_TYPE_484, /* 40MHz */ + CL_MU_OFDMA_RU_TYPE_996, /* 80MHz */ + CL_MU_OFDMA_RU_TYPE_2x996, /* 160MHz */ + CL_MU_OFDMA_RU_TYPE_MAX +}; + +enum nl80211_he_ru_alloc cl_ru_type_to_nl80211_he_ru_alloc(enum cl_mu_ofdma_ru_type ru_type); +u8 cl_mu_ofdma_grp_convert_ru_type_to_bw(struct cl_hw *cl_hw, u8 ru_type); +void cl_ieee802_11_parse_elems(const u8 *ies, size_t ies_len, struct ieee802_11_elems *elems); + +/* + * cl_file_open_and_read - Read the whole file into an allocated buffer. + * + * Allocates a buffer large enough to hold the contents of file at @filename and reads the + * contents of that file into that buffer. Upon success, the address of the allocated buffer + * is returned (which needs to be free later). Upon failure, returns NULL. + */ +size_t cl_file_open_and_read(struct cl_chip *chip, const char *filename, + char **buf); + +/* Traffic analysis */ +/* Check if a packet has specific LLC fields e.g. DSAP, SSAP and Control */ +#define PKT_HAS_LLC_HDR(a) ((a[0] == 0xAA) && (a[1] == 0xAA) && (a[2] == 0x03)) + +/* Multiply by 4 because IHL is number of 32-bit words */ +#define IPV4_HDR_LEN(ihl) ((ihl) << 2) + +bool cl_set_network_header_if_proto(struct sk_buff *skb, u16 protocol); +bool cl_is_ipv4_packet(struct sk_buff *skb); +bool cl_is_ipv6_packet(struct sk_buff *skb); +bool cl_is_tcp_ack(struct sk_buff *skb, bool *syn_rst_push); + +/* Band helpers */ +bool cl_band_is_6g(struct cl_hw *cl_hw); +bool cl_band_is_5g(struct cl_hw *cl_hw); +bool cl_band_is_24g(struct cl_hw *cl_hw); +u8 cl_band_to_fw_idx(struct cl_hw *cl_hw); +u8 cl_band_from_fw_idx(u32 phy_band); + +static inline unsigned short cl_get_ether_type(int offset, unsigned char *src_buf) +{ + unsigned short type_len = *(unsigned short *)(src_buf + offset); + + return (unsigned short)be16_to_cpu(htons(type_len)); +} + +#endif /* CL_UTILS_H */ From patchwork Tue May 24 11:34:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575950 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 C1625C433F5 for ; Tue, 24 May 2022 11:41:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234655AbiEXLlt (ORCPT ); Tue, 24 May 2022 07:41:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236816AbiEXLln (ORCPT ); Tue, 24 May 2022 07:41:43 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2050.outbound.protection.outlook.com [40.107.20.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B5D2925EA for ; Tue, 24 May 2022 04:41:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AdgeZQYqTlJyU9XAa7lqEIxlGnpMGkfK42yvmrhpnMKgDnhCT3zuDIiMyOaPxhzYW3SinFo6f5tLw2cnyOVsdrqG6h7ERKlKYXyzntBeOvT/EsGj23bwmMo1UTF0oYxQy6awnc4qholMcBPi82mi3yzfz6wYF+srZ/BQ8Kr9QD0sB0LHv2R0oDPviK9z9agSEczzh9bgU2ZR69hAruBQwyXnb2vmcaRNNdMccNmrRH+mmQYdJGKUirbnXHNV9PTHyIMFl3o/WjaNNhXRUSoGjeEW9pMUpy6OpeQFUmTe54NXroYMcTnQly0NLCAmRIyUZSw/87tEX36b2y9KbOZJcg== 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=o2EsdmC0BYJQttpVsZdcSg4Qt8pRmjoMXU92ba804Ns=; b=i+7rADt+SZ1uCmOJmg/zWs0OZJvuuh2ZobHgxRJG46yJJP+UaqJPTRb33zdrPhrMUE5B9VfELwds+3JOsh/qu27E1S/67uKOZLTz6CIUj3RBnvRcxKhDuM423rzOoQHDTFqKh5uIGhvKsnOMimKY/ykwG12rKSjIUt6GXHeaTPplgHT7rMLIKLJT6R2D61jJ3GU+o9TCKVlJ+J90whlFmslvZxZOGNnr3xdIqGeTZVbTzeY4VDhfM4s7PShnlyWXHMDXcybL+QqYhxHU0aKlei8O7XUrSzQC7EKfdbt8UHp/v+eVBct7/RE1zJXoCbqL0i1tN8IJomKEHAiBSomRVQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=o2EsdmC0BYJQttpVsZdcSg4Qt8pRmjoMXU92ba804Ns=; b=Y76M+mke+tA/x61erOz9hWT74l+yQO+b2xx4Vviyf7jK/S0YfRXaE+S+x+Gd2zMiN84Md2bRDoP2z6JuU/3+rxrpluI0kIqdV2NIpxG3EzbkZjTkhLGkcATOUQPBh+y9fbi7M2l5Eeqla7S4VbuXWoqhdMcEvJzT11q/CEERHAs= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:34 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:34 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 88/96] cl8k: add version.c Date: Tue, 24 May 2022 14:34:54 +0300 Message-Id: <20220524113502.1094459-89-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d89b5423-586a-44bc-c7c8-08da3d79fec7 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LWBaPyg9MAq1lNALY+mNhe529b6ymlGhkw6dY9nXHQW2GqkMcbLg5FGqmo87ytlhKYjsb0lvAP5M+qEPTj/PcuHKaTloKrxM+BpPpq41sm3c8HHYhQ8m72KcQvJ31dhCGEhYfC2JHQzfrZcvufWwEWSGUdN/CcrnvpovnE+h/R8Swbh6Xj0BkoaW5oxIMBlBRpVjkIaFqY8BJxi4oU18Eyta9tSCVZPC9D0S7f4YX6DQueEn8+YkEKRe8quOeh0uvtRmdV4MJL0DmM6kQKC2M0qw6wY/OGSN94zPR90XbAJay4g6RJf0Hbg2lGXlGCsXWwXDaMbYN/WDjxWcyYMTsKmsMAsRKeiTu4BwdA7gog/Z8ic2xV/7jHUmMy4LOQOC37dK2sb0mmy3ix12eKGSgk5aptW2OB5Mx6WneVR+DXjeL8PQFzybqz/CTeVdYxFTAndbJhuucP7nW4q0fd4Jl4cTjg12BpJyg+DlE/GMoMIdvb2Q9qGkOlZLCWhreF/Kwj1cGJrBcQM3M1ySwtheEUEt76PQd68I5gzyQj1eunE8fqPygK+2O5kwjFQOJIIimmV1mxOsmX3IeUoKzrt9Ed+oE2lIy8R+f+NeRyW7Llc5yGY2fBjudSYwqdU3z2I+Q+5E0YDSdjky7ONdaBZteSm35dEM2AuUXqpCfrogNdoRvHoKG3SEDMlYvVetGjTCQTTkNJXfsBOZSbj1hF/aGN9dvKQJ5b5JYjmbzFusESo= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: LDgmkkAfqQHklnF0uiHQm8MBPVhMYH7NmZd+CuGe/0womPIdRidNgb76JPR3gh7ieMnTo/XefafnKGzhOJAWjOWsUGTA5xDh9+ba2puKDPKgpA0OqkZJ+YpYc7djCBmtnM7jQtQf601PsNPSKG2CXTUHRXh5X0qSTewOtLKtqndyxn9dkGKkA/xkAclisuRUfaVddhnrFu7q4lhJ1qTY1jaBc/Ke8xn+LjI77pHSw/8h3No5Fusvq68ljLhkk0lqhUh5Ipf8o2693Mp0lj4lwmzq4/zC+qb2/vuu+oi4hEustrdUYozdVrnMMGQJNOBqM0uBP39JmTQ600N1OZ25Hpvg9I6CM88qG3GedJ+WREdKdImd+eyoPMJORK3rpZw4lUMZYl0xf2uASn7rIYEfeldh1e7Gahbb9/+H94JH2VaaRy5P8xGY/RYP5MAEQz8vhV10/UAP68tIL3ATBSh9WZybUJ55HVekkTgHGqIKm1LKUtvkjZDBptdupMSRNliAeaGFRldVrAJmZjrJHvsAfuQ8yt++UzFToeOFZY13MCjcVS1foGg2KQSI/hhz5pIfJa6wHYBan6Tl7ogVyOO2W4VHUipFW90Ic9KOafq13c6RJR4sQR6usdwH/VZTZk5V+bLX6a1b+3jl/Lx7yTqOQPyhIG19cUKvZrN0fBWFTbwLwoxYfKFDnBNBvzNS3lFNTnWpKjlNk4CLOOGjrruGASvlBDugZHFgSweGL1npnGCbfMT9rTOJITOGn/MvrUEX7rpiq3mmww1ZVUhBGyzRDvmRNjTwcg9t9oYwcLR2IhLu5JbHt0C8rUZyLby9VeGIE2HTRev1YlBmQsqE7oOxrOlRXPn7nDHM+8hL829A9zHKFkRN0sgsdg5gHVl3qYC5qrsblN6qt5rVsX9N7rrVamJm5awlLL7OYDsLCJDh/0YLXdj2uZYVLGUHG+WKJPbLPLma6wPn5vNzAV0BRh28MRWctJTEUmpZ+bFf8DswwjogdM1I52YJHPu2TLu54el8X0jqy2zpLgywgqiAAmte7lfOKuuXsfFLMl95pCcPR8k4/+4PtL+fG9b8YArr8zjgVPpx9B7G0FKJugeBA6JfFWfUIqcJsmMMlBORIRg/tXX66rzeC6o+IvN6WJ3cuqO9OCWmYckuJmT6QbQx2n9z68zRRbJWtgsBQ5iiNe08261dLpIy67A807JSRIxaZfBfNFp2GTQbRCnBXCXNbPa6AT3GI04cMwjE35KfPT16Ffb0srAIivtBJ2V/divITsDUtMm2NvzIerf4kLYNXLxpAMZUwKETDpconESlwW8bYe4WTIyDvZft47eSt8rlTM1tgfUZibbpv0cYeRVC56iL58q7W6jioso205OwYkPPhPItq+/MnA/qnGPJvIotG8zZHK24cn3OLxx1y3vI1kZRUTtlJHuBXuoyivVET5ZzuEwOOfG6nu/Yfof7H4CZJ6ztox+aLVKuaZPMMI32jAWemlwddXbyGM8tde8topGyftAgG6DenvxxSCW7TLtZ7U/+Txrc0Ghh3OPsfmVlUUo6hqlrYE1AWJt3j+AM7aG7hntdJ2ps3A0j1apGilvkUvquoKKrLgRh71wHZohaHSYr2fqTbMSMba3ZmjQCSHDcY2qPui8rNOrOv7aANDM3+Fnf7V9DEQb+rkm3S5Jwi8d6qgKTEhwb1dAlw7ZVHzxsDjcG2gCrr0FwB24jvXn0CbzGR2a0klmJvaSyEdN1CFp8mJHH75q6658xVdHYbnGPfvU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: d89b5423-586a-44bc-c7c8-08da3d79fec7 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:00.2751 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: EzlG7DlNJ/rKeXMJnvASf3t2fekJIBTOtMWPR238rV2SmEXwINX/32SX/WC+gQjEX7CHcE7X2hIKXkNRW9uuew== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/version.c | 147 +++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/version.c diff --git a/drivers/net/wireless/celeno/cl8k/version.c b/drivers/net/wireless/celeno/cl8k/version.c new file mode 100644 index 000000000000..1965190a833a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/version.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "debug.h" +#include "chip.h" +#include "rfic.h" +#include "debug.h" +#include "version.h" + +static int cl_version_request(struct cl_hw *cl_hw) +{ + struct mm_version_cfm *cfm = NULL; + struct cl_version_db *vd = &cl_hw->version_db; + int ret = 0; + + ret = cl_msg_tx_version(cl_hw); + if (ret) + return ret; + + cfm = (struct mm_version_cfm *)cl_hw->msg_cfm_params[MM_VERSION_CFM]; + if (!cfm) + return -ENOMSG; + + vd->last_update = jiffies; + vd->dsp = le32_to_cpu(cfm->versions.dsp); + vd->rfic_sw = le32_to_cpu(cfm->versions.rfic_sw); + vd->rfic_hw = le32_to_cpu(cfm->versions.rfic_hw); + vd->agcram = le32_to_cpu(cfm->versions.agcram); + + cl_hw->rf_crystal_mhz = cfm->rf_crystal_mhz; + + strncpy(vd->fw, cfm->versions.fw, sizeof(vd->fw)); + vd->fw[sizeof(vd->fw) - 1] = '\0'; + + strncpy(vd->drv, CONFIG_CL8K_VERSION, sizeof(vd->drv)); + vd->drv[sizeof(vd->drv) - 1] = '\0'; + + cl_msg_tx_free_cfm_params(cl_hw, MM_VERSION_CFM); + + return ret; +} + +int cl_version_read(struct cl_hw *cl_hw, char *buf, ssize_t buf_size, ssize_t *total_len) +{ + struct cl_chip *chip = cl_hw->chip; + struct cl_version_db *vd = &cl_hw->version_db; + struct cl_agc_profile *agc_profile1 = &cl_hw->phy_data_info.data->agc_params.profile1; + struct cl_agc_profile *agc_profile2 = &cl_hw->phy_data_info.data->agc_params.profile2; + ssize_t len = 0; + int ret = 0; + u32 version_agcram = 0; + u32 major = 0; + u32 minor = 0; + u32 internal = 0; + + /* Request data if existing is not actual */ + if (!vd->last_update) { + ret = cl_version_request(cl_hw); + if (ret) + return ret; + } + + /* PHY components specifics */ + len += scnprintf(buf + len, buf_size - len, "DRV VERSION: %s\n", vd->drv); + len += scnprintf(buf + len, buf_size - len, "FW VERSION: %s\n", vd->fw); + len += scnprintf(buf + len, buf_size - len, "DSP VERSION: 0x%-.8X\n", vd->dsp); + len += scnprintf(buf + len, buf_size - len, "RFIC SW VERSION: %u\n", vd->rfic_sw); + len += scnprintf(buf + len, buf_size - len, "RFIC HW VERSION: 0x%X\n", vd->rfic_hw); + + version_agcram = vd->agcram; + major = (version_agcram >> 16) & 0xffff; + minor = (version_agcram >> 8) & 0xff; + internal = version_agcram & 0xff; + + len += scnprintf(buf + len, buf_size - len, + "AGC RAM VERSION: B.%x.%x.%x\n", major, minor, internal); + + if (agc_profile1) + cl_agc_params_dump_profile_id(buf, buf_size, &len, agc_profile1->id, + "AGC PARAMS PROFILE:"); + if (agc_profile2) + cl_agc_params_dump_profile_id(buf, buf_size, &len, agc_profile2->id, + "AGC PARAMS PROFILE (Elastic):"); + + len += scnprintf(buf + len, buf_size - len, + "TX POWER VERSION: %u\n", cl_hw->tx_power_version); + + switch (chip->conf->ci_phy_dev) { + case PHY_DEV_OLYMPUS: + len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: OLYMPUS\n"); + break; + case PHY_DEV_ATHOS: + len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: %s\n", + (cl_hw->chip->rfic_version == ATHOS_A_VER) ? "ATHOS" : "ATHOS B"); + break; + case PHY_DEV_DUMMY: + len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: DUMMY\n"); + break; + case PHY_DEV_FRU: + len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: FRU\n"); + break; + case PHY_DEV_LOOPBACK: + len += scnprintf(buf + len, buf_size - len, "RFIC TYPE: LOOPBACK\n"); + break; + } + + len += scnprintf(buf + len, buf_size - len, + "RF CRYSTAL: %uMHz\n", cl_hw->rf_crystal_mhz); + len += scnprintf(buf + len, buf_size - len, + "CHIP ID: 0X%x\n", cl_chip_get_device_id(cl_hw->chip)); + *total_len = len; + + return 0; +} + +int cl_version_update(struct cl_hw *cl_hw) +{ + char *buf = NULL; + ssize_t buf_size = PAGE_SIZE; + ssize_t len = 0; + int ret = 0; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + /* Force logic to update versions */ + cl_hw->version_db.last_update = 0; + + ret = cl_version_read(cl_hw, buf, buf_size, &len); + + if (ret == 0) { + pr_debug("%s\n", buf); + /* Share version info */ + cl_version_sync_wiphy(cl_hw, cl_hw->hw->wiphy); + } + + kfree(buf); + + return ret; +} + +void cl_version_sync_wiphy(struct cl_hw *cl_hw, struct wiphy *wiphy) +{ + strncpy(wiphy->fw_version, cl_hw->version_db.fw, sizeof(wiphy->fw_version)); +} + From patchwork Tue May 24 11:34:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575946 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 10898C433FE for ; Tue, 24 May 2022 11:42:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234302AbiEXLmQ (ORCPT ); Tue, 24 May 2022 07:42:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236962AbiEXLmC (ORCPT ); Tue, 24 May 2022 07:42:02 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2088.outbound.protection.outlook.com [40.107.20.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3945B13F34 for ; Tue, 24 May 2022 04:41:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lmunYP1Wh3HtGXm5LzIezqVvM2AiFMQRNC5gv0fw8sIFBO26Cx5He5Yuab5L3CRNzQ7v4P8Um18nKW00ZuLlYllt81t+P0RzrWHoyhDOCNNyEgrpMY696BFZp6YlAqxH/wQaFlvSyBp5t7Q9S4ou4Wirg3I6udFRCZFabuw7Aq/KFSyUHPmGu2m2R8rie8QcLE+Jsb6WloUeq/aMRSrTmNLxvYuY+Bzs3eKq7EB/Ap2tSOztr8q/AKQXbXDWHX/PfWEm87/H+pDEurQYA1o8geV62Cf75vVac1mWu8dD1ApW+X1BqY3qtYhGXMWEoJ2jyN1/lfyjXAw4D7dpzbP+4A== 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=ViCuvpRF0dGU5KmID2qInaDNXTIDrCXPKu2DOhlZuAs=; b=DEVhgcHfa23ir7GNLO2xPqAgyz5qg12cCIEsoVmNita/2kSW93v4Di2mjaZyL9oY3k0o/puesEP7x7IGE6CuE6ND8xuxiXMUlVb6JOIKJQckG+1Sr2MROpbj6/abU4CtAR6ti4is/eqE/IeknixLVxys/i60Wq2+HJZnt1AjeedtSF12sNyPpHyxRwX4Lqf2rDAXSDA8sfayYmVJahry884bvfPGwL+m9Bnk1Cp7jwMdYuFrffKSl3Hi9XYt5W9/PmCXKHRU1C0CEaKacBl0Hj0DPUX7zrsz6CbpwypdKtqYB2/D0Yr0bfsw58AY/EJRo9WjQVrKxx7aODfPgeiIUQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ViCuvpRF0dGU5KmID2qInaDNXTIDrCXPKu2DOhlZuAs=; b=c1ghw7RPwt03t/i4dH0jnPD7kmW3L5xrHaOk/PinGg0bY8NC6thiqfhAb4Sm/CK5qmCPnsbuoYxVmNXY5ZFH/Pl17bJmYOntYKMcSmAyjh3V9enRN8OHrtGwjWe7+8Q9oMlVY80dkKBpCNFJJO/UckkGl9WNxk5E+jxTJzEmcAA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:34 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:34 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 89/96] cl8k: add version.h Date: Tue, 24 May 2022 14:34:55 +0300 Message-Id: <20220524113502.1094459-90-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 302714aa-2c4a-4498-4d40-08da3d79ff33 X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: GVLUS1YqGWj/4pbkpiOutGGjw+wMQltFrfX/7zA0fz6thEA6z7F34FjKv/kKsh90bGhPEI9SksBRi4rRrLFuUFi85SKS6+jnteQ8UJWC9ryZ5YqPc8anOgmzLYd+FcQibPRfHYFshaC+LxKc5PDjtEQaKuCgiYBOmDtHqEzZQ5uTLA1B4vo/Lk0yqmvDBYdA452X0XOsq8h2cvmzFAkPPkgpLpb/F0hBEB8EbauJHlNSq8daEagxUWfZ0E7+LVETfNooGSSE2IWuQobyKoCWt914GPBXEsT8/fcLqu8nCruVVl6glWARMW/jjIa1BjwH1Waq4yvxyu1ZgvD+npiN1E/EtX/gKeZDF8IjHOwrnxcvyHSUkUuzisxqsXAZWdpG1PVuyFr6cQwkC1s3SlyaQBBmQodGQ6WpezWn+MWWWEN0rYHszyidUarzQjFUHJ/pBEupgTfZ8jSw/DZ9imcgmZ+43tjC7Z23bEW0Lps55FgsHVs9atpr+abgLN/njvYLHk7/qlNyvALyWjWmu1j0cX3nihyncMpq0q4b+c9NBlZF5eb2LmOtWKkKMBnhLQnGne7gGlNlGrA/zQq68bqwDUBSj9zXrv8lc8hGo1tkDwIiuZPh2AzNPM4tmWrJHQRKDY0hX7cfcWV944ue6C73jjcww9KNVonFD0qBwOO0Wdu8fc2z/Xa8oa1qO9GZXBAOT4MucIxw/mCUtW5yBMMoFe+agc5RRcTCfBh68Taa2cU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Or2xIbSkkR38cwqqloDV282RErKA2s1Ha/u0Z0WtnnAWSvyPPdYNibLUN/HBhiG/CPPBCpX4GzbfwdMQu1Z+ghVjFQtrRPt6dSrVPA1FTdUICWPpn2FEgGDBGZmz/JRXt9Bqhag91zF2bGooW4f4DI6htqadSRYwBy38+krU02XatypiS1tKNKDckUcx8KBl0+G/H9lREgIRKBqLJWD18iM23iIU79b2nlmN+BJEqmxdhDX1Odz7HZv5cp0NXvfqI777AIxikNDVvFfyK3GIwZ5cL2yHqw6x/dgwqyYbj1d7qti2zAk/cgIrnVeQbRr5C9zJNbksbudRK5YyQlLvmv82ChaTSp1xszkveuAJP8d1JA70pNEDPwXnVQuPVPPQiWvxFH2Nb4vaNgcSRk7XaVJNAUuXFFv1ojvTMj5Jer/XdapBgOWyKxt44STGC1RqIRajKgcxTszYB7mfgSE2ggXxHEMa2ZzDTxkfxCfyqTawbFKxeIU0HAwx5W2HK1GYA72Hi5GcZi9Pn1bFSLUAzAE0EsLACIF0fTZgZmPMS/TIvRSflYYx/fwRxrjIYR8sBreSRnq1c81HM8ZGWylJAL2vb3xcWDKxwZqZyg4100wtiEiCGnUzjXguQHe2VU+lSHk0pPrxx7ZBMmK5pbrimWZnJab4qZlViTze6IhNDYAZYBjt5a5l7N4Ncbh0L4rfpWZ7xW5kGPtnkZfQMOPN25hVhiORduDddU2eptrFVypxiv3LbPmzETjfrDKH7gyO04XUPTv2IKb535TvXW+bffHkDQGOta+5tHOeUJMZO26shlRa6KdN6B7BgcGJkmTPfIdaKWSQPiAm6EN5OikyKEZ8qN+oFY1balaEX781DyHy+4RRtBfOVmIZcDfEAcboqydwxKvwMwYoRDdXsY4kltwgjej/iwGYidrjr5db6Q0HgwNR69ZLexdjj+KBmk1EuBprKcZrjVUbxCMYz66DMQ0Wg54lnGFRiR+oWypBXDXIoMHNHHCr97crkqFkgpbVcfJWJTa3voyOYrPyV2e1UJkCvbgWEbKHKGiadXPyyUS91mnFfOOksgQcSPWRDwTFV3xldk3bEIHOFBCW/EvhqEVkWtCLT22ULZidtvB3PlqDPOI65qPE7/yc7sX3Qk46HoEFWz38qdEw08pgYfYMTycAPud1j9QFO3ymaA2hXwAGsIx7JutGac0wWAaWhZ1+F7teohBKNvdOS1iPzKUcgDeU+2Fj3VyiYAPsAmCHefHBDHKR7fC4c8SfLg4u87/quCggP+9TXVrT372/yN2X7tSxiVivOXYFqAbxlR6jwdMaba3oyFwpLqtO8KaeBAmqxeo/Bp7tFPlEcp1Y3so971OdKznQsObiNbI6KTQAqjHMP7+TD2IqmQopxfFu3n0lWJexMMA5wXL/bzw9sIcUk81Rgv7W/ye78I1mbJ4C1ZyFp5aq9CeaW/mp9m/J5xa27vM7kt4Z+Xn+2KqEe0XPPMfTOe+HOVX2e/cRHWbyigheGRw/hiVCwRGRJfC/nhvfiqjgH7aPHyqr8VFa9aqtSOjlrd06C/2rLqLj3JnJjz51mAEcnlet9tJmrtprSYKEUMX/ARTR4Hq8oQUG6LbxRnOr43ZK4BBb2hDO5jJw94BJrBUWLQdVzzFRHjWDg3dwnM2NLjSvU8I1invbr6/OOy4YIR31/EPARyx6d4pLi5ksdbceIGydpBP/gUaM6Ji85K1+PtkJKU3PzUxxCkc+W5/Dro+uD3aFgPXB9T+0l6s= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 302714aa-2c4a-4498-4d40-08da3d79ff33 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:00.9798 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2gGMdqXg9O7Dnah/CDZjEvTx5l+8TgqpDup1xN6Z+BtXFQARLHguqLBlX2H5Ub54Fbp6F09HjfhwxzXbmzZTdw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/version.h | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/version.h diff --git a/drivers/net/wireless/celeno/cl8k/version.h b/drivers/net/wireless/celeno/cl8k/version.h new file mode 100644 index 000000000000..bc6d2ad4153a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/version.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_VERSION_H +#define CL_VERSION_H + +#include "ipc_shared.h" + +struct cl_version_db { + u32 dsp; + u32 rfic_sw; + u32 rfic_hw; + u32 agcram; + char fw[CL_VERSION_STR_SIZE]; + char drv[CL_VERSION_STR_SIZE]; + unsigned long last_update; +}; + +int cl_version_read(struct cl_hw *cl_hw, char *buf, ssize_t buf_size, ssize_t *total_len); +int cl_version_update(struct cl_hw *cl_hw); +void cl_version_sync_wiphy(struct cl_hw *cl_hw, struct wiphy *wiphy); + +#endif /* CL_VERSION_H */ From patchwork Tue May 24 11:34:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576826 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 EF275C4332F for ; Tue, 24 May 2022 11:42:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236973AbiEXLmV (ORCPT ); Tue, 24 May 2022 07:42:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236996AbiEXLmM (ORCPT ); Tue, 24 May 2022 07:42:12 -0400 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2071.outbound.protection.outlook.com [40.107.20.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A58E8E40 for ; Tue, 24 May 2022 04:41:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YuU9eh70OS9giLWD1xDKUUxgJCTWU/i4aYo+xrLCB9E7bjeOGbmeyILOU8CeZTALacVwBBEldjFJw+Q5j2E1E1zwabpR4So4hJk0vEQyde5mYDUiuDLoAjJ+cJqFPrhVSJ56SHfqgk2uVoLcp4gCMqX3w1jI0Y8tfuEFzlnP1EZQqLgExmTV8rowxOeEVXqYRZGtwloWzpuGaqc64/4zmw92Aclxd0Q4gRcPKXeDHdaaKXt48f6yXT5mF5FvQr0Qmon92gP8oZmHykDTn1gM0riOkHZSbwuPM3fgr+BkbsMyqNIm7gVM5hSg3yvb89TQRvwF5pLK7Dg/+CtoPOQeRg== 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=7PXTbmhWxQv7mjh8kuNWJrgJdYxIJx6HW77pXz6jwYU=; b=RPgybN+Z9hNvmMmT7yVM1NNjGSWxHEpu5Xn3e8V2bffVQ+95dJ+7OTnkoLyIgWfaCGFMd5eejesPN7jgouS3OBZ2LpmbN4CFJGTiXUR+UDjPr6oA/X3UA0zymb2lXozIovkst30mH8I1eOgcVuXGUUrG9bkaxrjVCG8tvXn02wspO0DF8DtSZn8Yy3kqQngxit4trqy0PJCFNIkBcY7SFjlbqm2Q8Ysq40sAYB2YXRJ/zTvDKZkJcZAugHn+tFkmc0d9T2JY7n5BLQsTv6XB0Y4vsYoWqQHoMRdeuDZDF9u0RAr4P2g4ErmOmfNvDxWuNOMacXwGUxoYkuFLzwQZyQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7PXTbmhWxQv7mjh8kuNWJrgJdYxIJx6HW77pXz6jwYU=; b=FZzwXyVfOz/XNBRV9cF9LGqNczIH5Ul9ebs5ilMwNpJOPOruQ5ARWojeV7r7D8s27Ka03gedmB4dt7DxCHQMtNQL7Tnaygi17HPseb/kUZx4+fhlEYU8av9nhrWR58mh/uk31PCF6ULsxz9wb0nJnZfkTxl0ymx+IyOoCFloXzc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by VE1P192MB0669.EURP192.PROD.OUTLOOK.COM (2603:10a6:800:16f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Tue, 24 May 2022 11:39:35 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:39:35 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 90/96] cl8k: add vif.c Date: Tue, 24 May 2022 14:34:56 +0300 Message-Id: <20220524113502.1094459-91-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 23069032-f7a0-4314-1747-08da3d79ffad X-MS-TrafficTypeDiagnostic: VE1P192MB0669:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CJtWpU47e4sQSHRgZ6UzQ+tGeFtQORFHHDS973227Tc2/NSOkxGw/waF9CSt170ELIPsQ9IIa7s6AqwN8pEPMld7rtO00fZUiMXMLSjDPItl432kGLxEEnTJo3FJql9APebzcz1Up7TuWVEzJ5SD0RjLPKfWn27NFcpfh2vZHV9Wf3MoJc+ZivXrt632Nl4uOOGGjmp5QkvCOznDYNCmRCWOEQd011YEyV1R6qZ6bRgfGj036ETkMvB7lojewtiEDjjeusTjFcXR+wSS8uEmKKcbCsIS+2I65s+mRLcEALHhSVazvZukKhJgeUakVI/x1JnWt6KeryXT9CvprnfZTgW/0F3XMtwy03T3Yv1KMOkbZPeZun8Eq+9W9opHB7qqMMtn7ktLKDvEWgXMq7NQEOzRn4eFl7Z3+jBN0gMJ5fclmo2o1haRfBIgeB+vnsfndtXPi/Ag7Cw9nSi6AAWSdRZkBtPODTBbl1r73vRqh0Zxpz7IJjQfAH9VIKO89RZwh6imdqtyN6UWcv/UQWkMzbLrnZlxT64TjrEVUCYt6CtTtfc4tLGcouqLUCNzGcKkm/OmO1srtAlthhldgYYZKmHX7fJ4KSQEbedWf7g0rrAsVsbbYi0bTGMTwUXtLAapNlY4r8xsixHm461NMdbp2FYB7t+c4jyEB2seEjtVpsI/OaC9jM/FSdQYfe11Wfml+NDLBhpPTs2o+MZjdwjaOGNViMInP7u8PhFGnoywxv8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(366004)(346002)(39850400004)(8676002)(9686003)(26005)(36756003)(66946007)(66556008)(66476007)(4326008)(107886003)(83380400001)(6512007)(5660300002)(38350700002)(38100700002)(1076003)(2616005)(316002)(6916009)(6506007)(6486002)(54906003)(86362001)(8936002)(508600001)(41300700001)(6666004)(2906002)(186003)(52116002)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VUFoLcq97JpYjjkYKYMmYBYmXt8gUiFTAeTP2wTpXeKKQu4fdgrpdQ1qww0FMdwJnXIQ+8Fn+RbRK7mSkMdR+UztRELCufi8Udki1TGxyYYASZw8P3T2Yd5xpxkTw3FE3K9bIespb4czCMfQfvVKhXUKPF5KsMt9p/roDJcWsxWEZzaQsAQ2RXhTbSIYa9RDQG7I28/LSnXwmuIrVxvJPDt2A5XHWWAr7PjNJ69i5Zr5m53wNlMHIeXFLOpMArK9GoNuA4GasuWfndGcZDM3dfzYq1brQ/mJNYxLiOELfO3w9PcYSztJBAgNvR/escH49za5womAIExDHdvhgbIy5RA79enEjSLilD4bEk9xEH8V0RpffgPjeUzzPhwy5R8KLjIpZNJgXvULctSCfINh27Ct0/TSJghxA3ueETGC6ps3LNjvZUNmOxFRm6rfs/bqFF5DO1VrjgE9oYLan1oWbNnkfCI7/9fbuphYx6+fr5G7Xc87Xcg/ulEqHLe9lIY3y7rr+qo0fOIiWFBOMZy1L48bRFdb/4VThOOYylZjzPnQTLaIhfYFnSf76DoZFkjRPD4HHRTABaNgEAmmNylQtH10K7eqX1rW7Fu8NWjIUyQ8gS/RTnUeId/kwyNEkJwfuOAk4M1mPvwiV75Rb75L34lQHU0koXQiAgNOJpjK9TZvqFxkEmAMGG2DX5NPOOWFXpkF4lxgMgAkwvdYNN7J0e1Hb5tHqtrsPV2bcS0SkYuFsvBV+++zu8YD390OuCwIQu3MjQmbEIL6l4/k7t89rwrpvp/R/Zc0M6yL+Ozhu9/y3gtb17Cy3KBlyvU0t7MvTZwP3LvRUQHWVtuTIblpDrH754JFbWLh8LhND+/5Zps2BFKm9zm4ZtTunOTIghRdK1vlGJLYEMD1801kc+iZes5J/BvM6YVAEhc9Z3TJamnkK33LfCwyrPT8vTVfm2LSaeZHvseBhVbaRYHdW994WRZd4SRHmUmG7CN/8ZMf/sNWTm5qpYhSJt+PeA6iqQPWk13PIhmwXTiTlXKBQoWqWiwJKQIffynHzPdN4fOqGBKacozK6U5glzM4oatQJ/Fq99Qfchc34EHW94+Fg2cBLMUJKUqn2k/DrRpTa9rBqQQT2tWkwPhyx3P0jCFL9WFDaAsdq7QiKbYNxauZy097I+7XaGsJdXzk5freqQGl1W1lLhvQVve+s+s/zImpzjvuMR3HPWtdAZWMJ1F6JQjrA5nrAohN90C1K5absqPOTPaSOmw8PX5oGSAFfH3fl9VckhK1NnsrAHHjj/+wyuVt3v1IiHoNEvPIL8pxwhqP7oqrym6gHjuKk4QKs1qhvehVjAVg9HaLYpYysKrY4EdPJgMeQ1/V1GCNPPfQd5HOZFgg6Ieyod1QR9ferp/zF+nEKSZVLTpuKuKtaNScqhXYwUGQl+fORQg+/gPL3z+ouEecU94ooGNXU1d63DBUza+RJGFxSXs1l1NwFEdjlUshBDUHg1Nwt0ZVjTInxX7c642M3hCMjDHVsdjjAcDivuwVaORbO3JxNuPt7krFZ9/naTQE/Zm44431jjYEkDyIvFoP/Nr6xZM/9ptzRyFnditN7E9472z6oNyhg+Ze90PyvppXuoGXh16+irEjqWZdMm8KZMrqw4fxf0WC74hfCl1L6ZD9u6J4GT2ZOfBL3Lrq1jUuRGm9Gv/wcABGoPOGoy8ix2B09cj0JVOeeCelOEsusm0RbOx2obtBUyfTD+NFlwbQHinSD8V6V0ontdluL8Q= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 23069032-f7a0-4314-1747-08da3d79ffad X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:01.7623 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Nx4vHKcaHMToXQa6jBmBvK4zTJd3h/b8gBVkkw1uuXtZuQFvBYuzAdSLWfkgZnFBeAxfI9Wh7OZgr0QojoWD0w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1P192MB0669 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/vif.c | 162 +++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/vif.c diff --git a/drivers/net/wireless/celeno/cl8k/vif.c b/drivers/net/wireless/celeno/cl8k/vif.c new file mode 100644 index 000000000000..7592f0d32e7a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/vif.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "hw.h" +#include "mac_addr.h" +#include "vif.h" + +void cl_vif_init(struct cl_hw *cl_hw) +{ + rwlock_init(&cl_hw->vif_db.lock); + INIT_LIST_HEAD(&cl_hw->vif_db.head); +} + +void cl_vif_add(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + struct cl_vif_db *vif_db = &cl_hw->vif_db; + + write_lock_bh(&vif_db->lock); + list_add_tail(&cl_vif->list, &vif_db->head); + + if (cl_vif->vif->type != NL80211_IFTYPE_STATION) + vif_db->num_iface_bcn++; + + /* Multicast vif set */ + cl_hw->mc_vif = cl_vif; + + write_unlock_bh(&vif_db->lock); +} + +void cl_vif_remove(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + struct cl_vif_db *vif_db = &cl_hw->vif_db; + + write_lock_bh(&vif_db->lock); + /* Multicast vif unset */ + if (cl_hw->mc_vif == cl_vif) + cl_hw->mc_vif = cl_vif_get_next(cl_hw, cl_hw->mc_vif); + + list_del(&cl_vif->list); + + if (cl_vif->vif->type != NL80211_IFTYPE_STATION) + vif_db->num_iface_bcn--; + write_unlock_bh(&vif_db->lock); + + cl_bcmc_cfm_poll_empty_per_vif(cl_hw, cl_vif); +} + +struct cl_vif *cl_vif_get_next(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + if (list_is_last(&cl_vif->list, &cl_hw->vif_db.head)) + return list_first_entry_or_null(&cl_hw->vif_db.head, + struct cl_vif, list); + else + return list_next_entry(cl_vif, list); +} + +struct cl_vif *cl_vif_get_by_dev(struct cl_hw *cl_hw, struct net_device *dev) +{ + struct cl_vif *cl_vif = NULL, *cl_vif_ret = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->dev == dev) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct cl_vif *cl_vif_get_by_mac(struct cl_hw *cl_hw, u8 *mac_addr) +{ + struct cl_vif *cl_vif, *cl_vif_ret = NULL; + + read_lock(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_mac_addr_compare(cl_vif->vif->addr, mac_addr)) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct cl_vif *cl_vif_get_first(struct cl_hw *cl_hw) +{ + return list_first_entry_or_null(&cl_hw->vif_db.head, struct cl_vif, list); +} + +struct cl_vif *cl_vif_get_first_ap(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif, *cl_vif_ret = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->vif->type == NL80211_IFTYPE_AP || + cl_vif->vif->type == NL80211_IFTYPE_MESH_POINT || + cl_hw->conf->ce_listener_en) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct net_device *cl_vif_get_first_net_device(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif = NULL; + struct net_device *dev = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + cl_vif = list_first_entry_or_null(&cl_hw->vif_db.head, struct cl_vif, list); + if (cl_vif) + dev = cl_vif->dev; + read_unlock_bh(&cl_hw->vif_db.lock); + + return dev; +} + +struct net_device *cl_vif_get_dev_by_index(struct cl_hw *cl_hw, u8 index) +{ + struct cl_vif *cl_vif = NULL; + struct net_device *dev = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->vif_index == index) { + dev = cl_vif->dev; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return dev; +} + +void cl_vif_ap_tx_enable(struct cl_hw *cl_hw, bool enable) +{ + struct cl_vif *cl_vif; + struct ieee80211_vif *vif; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + vif = cl_vif->vif; + + if (vif->type != NL80211_IFTYPE_AP) + continue; + + cl_vif->tx_en = enable; + cl_dbg_verbose(cl_hw, "Set tx_en=%u for vif_index=%u\n", + enable, cl_vif->vif_index); + } + read_unlock_bh(&cl_hw->vif_db.lock); +} From patchwork Tue May 24 11:34:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575957 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 22F38C433FE for ; Tue, 24 May 2022 11:40:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236934AbiEXLks (ORCPT ); Tue, 24 May 2022 07:40:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236947AbiEXLkm (ORCPT ); Tue, 24 May 2022 07:40:42 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00041.outbound.protection.outlook.com [40.107.0.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 489AF8CCF2 for ; Tue, 24 May 2022 04:40:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Y10+JGXUeOkSl02b/vo7aelSFUkr4A50JcWoSDczOlXzF/e8TJEZvciCS6vFdb8ubb6ZCWzWZSeargbISPnwg25BgC7at6o0y5s+mLkVfAPLHaAOMiI1XZ19kBC0FJQZk9P9/THNoBUd2ceFo/4wDtANMfSRZz7KbZRTEJyFANdlQ+BiEsRsyFrUzZEDonlCuSN+dZU70VblGIrhqtz18oan6Pwp2iWa3sBghE5oczBvqf39aeiCmC4c2MAXDqFfaORJIpTKwbyjsryuNE7gkG3b/77ylIJsr3E6X1spc6GKlWltxumJKXd0YuWR3v0luMsQc3WIcjL+826+oWGRvA== 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=jq9xtePaeQ03sbSbP+zGe1BtdAMepLr/4o+DOmD1hJk=; b=XK5U8HomLkiN16k2u0LjPXnH6i0E9o/m/g+WEeX/nU5P092Y6zfiJ25PGLciJP0qoOzeu6afzwkGOGDXlyTBZkvUYLqE9NvbCxIPkRq8fPlR7wTVoXK/qNZ5y8nipdDfjjQWZ/ZSkWudhahtGX9eTrjpZU8tPABH20IfwXSFRUio73N9oC0/jRmwuKwwBvK7otRd50C5zqqPG4uUPVOe+G858VFT/NHD2qxIYZ1hWr7MXPXBAC5KyDgFA8cQEZFoucBKAp3X9BX3zv7OrHeTNH8LK+NntVoThG0cUdKogQIGVtpApmGTKG7nptT6Qk9yYAQ8jrduecL2dmXC0P7kXg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jq9xtePaeQ03sbSbP+zGe1BtdAMepLr/4o+DOmD1hJk=; b=SHd73JnIbP8qX2MU5TApWBIK5P2QPhXuD1UUdC2i96OC+2YUmhno/wlvCNRiWSpvuh4CH2XkKWY/LW6r3IdJJVzFgnh5WrXt1A2p9CTtYcqNUvfFlt7mW3VzTpOhzsKpxBhGO2Bp7yyQY+rKPs2iAlLV4LQmtSwlXLi+twrbk/0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:05 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:05 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 91/96] cl8k: add vif.h Date: Tue, 24 May 2022 14:34:57 +0300 Message-Id: <20220524113502.1094459-92-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7b63ce08-379f-46e5-6dae-08da3d7a002b X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yW4GqbLTfM+5OsnXMhGys4yrKW0XKuzSmI44q2zbc+RBpESpcnDElV/ulmZULNwZ8pMgEBjBClCxw72SFk8nJsLWGdKhF9AEDUYe4OvrHofU/L1+Jk7m4YDRVr3mYF21sNt9bGrkF3TpBR+s4bmihZs1MmjR7v2Uw+LResV+e7UbBiFPdAr4kq2BdkCEDFQzBgLkB6niQDyvDqhJgXyHrD/BGaOY5O8M+JmpVoNaVp/s4u2OR8HWbAwAv1agETQpXwqn9yCHETx6FdP+a2ZcoBfTGvLeaMDHT0KLHuUJhxyGLTyJyDNSzSi9wzNGNojfTuqTaSwNgmyULKIdxI3rD7KEdrlul6Q54Muxk5n3e6IV0ye2Bq0IUA+y9ll+cVZmLQY7gsCOp4WQhDypBC9cIdF/aXg2XU/IWFTTK3KuGqfiSZ9Nm0uwOJ6BdazryLlknfY6fziFn0zTG4SLzsmUWpIZ7bLa42Hd4at92Wo9H9kZ23xH1femYqGsbtvxFzJ0dPKsb9nEbFmKwksKhqvBa2xTkxdnbO4AKMFW56BtzIihY2tlpDvyLzO3c3j0T4NHOD4uh4t35b2Rf5SaS6shcKswiLBuNMGf+mjwu36pjwEG/eAvyPJww0516BbhuiHrcMvEbh6jWxgukiA4Z3E4F7Mr2JKBCGEVuqv2ucOIE0AfowdKvGSVzdjSLJkydvrRoVP17oxZ1aP1oIiBrLQFC3iBfoYVZ+LAlvMyj0RXEcA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(107886003)(5660300002)(508600001)(83380400001)(8936002)(186003)(1076003)(41300700001)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: FvFVUSydHtTTI0rVSsuwT53zFHX+fahEr2hVD7uMyPBuIlwnRoChzAn+FIJOXnkU1gE0MnZ/otQ4pXOVfgJaoNJbRDoosQy2GrCjqHTejBMCHJH8u3ULXN3uWwtDNwPb2CjPyQ6o5qChGL2JuiBlrvMQGhtUj0KnK/lz3/N/cy8vFupGXUN4h+pvp//XBEr/tqnpcAhwMROn4gPuVPRGoHdI3HJcUFpT0pqDP61C2OHJuC83xFT4C4zLiJFeEiKSvu3OdG2wpZooLT7/S0KTq+z/BBoXteW3jjxteXnbQCcX8E+faz/y6EXLvB6P1FHNWNGqHVs3/P6wEbO/UZs7SAEcuPqilRUGzxPo7nnKzmVB8Bx3kX4iLdrOMbYHPXrX05Gm9cyEaGkKiXNw/pJfGNcanKATL2bouSIDl4x41+XIljHPHfg1dOIgjl9pajUgIc+8mlneKEZmYx7DG171r3hQeTcSzH5pWl+E+QmPfOPEOH7ouu1SckNS3UU/oL16ACP7V+uoASiSNRV0ZrDDIwq5vZrVPfFSFAkIO7Tf4ITL9gXnCoRtw0L0bwU6sHUdEpyL7o8hc/xv4WegyAJlNLmFu5N+9f9Vz1OpnNKy2LsE8/mcMOkNYhslPfKa+DbhtKQHlEpwPJq9gg2UyGlgs6YZjmCH/rdYKqWnwpdFnanJCBSNMFW1H7T8fck4kgivs0NWBDOuLxFnhyFdNgsn8Md+05NSO5MicEzXprMOJXktgedy8PfFxU4uxUE+hg6WHyGsf4DKT+2QYtZHSCzGxqJNZKFfviUS4T3+uzRPoM1oOMjdDvxdJuk9ZMHYfmkw3e+8FcqGl/TlufU+YM6adnSyboC2WXf9P77iK/itSg8wNDZRlr4bSH0JQrrTuKVtyjnb6lYTpmjws9S35DUuHud+NIDikUjpONK8k2AT8FcoDvMDm2UCKPqSIPgODOSndwhGfK4cnjOqhQ3EQjqOrs4pHSa7e+Il6AZJVe0zUvQEgOKI692MSI1zqHhQ/WNkUTs3VN7NbUxLFvbxyUEmlZXV0qk8f+rPW0Q0E5LdM6LACTyJJMMbMMuc/uFUOu9GYpT7hIqaflIpSAQ0aCWXDKlf0Q1a5Ftir7acyxlB/7fl/qjbrYKiM5lXxHAnpdm60DtGELeFCyK0BDEzSCWGpuDCQ/zAp5NVce/jS0O+mklBfXg8+SsHo38KC0FuGQIWY12n8HcgwmpOSIqRo8kP1VXPlT4yEKwmI8IQOd/7C5PQwlVWGL9rp3xHWKh5Rldwc6J/0CO5FLakVhRwOftHkl9NpMybtRsW0cUIsQS3c6XLhI242X8bC8l84oACLBHhX5nTDMLsKr21x3tZJbvt21kaY55WZvd39lrXtQHuM2Li1t1QOxeRJpyiVEaYwaoHSB+Gd5lpIGMmtU1VlH8GiLrs04QXwaFhkJUi/lieeGgiLSO/wr+OsFudfCZ7h19B54VCRcNIQN3IvLVHLPWnJOQOXbBgmVzdrP8DVxAue9YYMeuyXk1g/XeJFaKd0rMkJyaiqFAerVX9PflECotGHMmAtPMHKD+1mOqVGadreqvi9RCPtzm8YxOsS1IXcVkQkNGDWmICrkm7kW6A0RSocKh+r3uel6B1EBLcsAo7ISgdYbB8aS43cICOI6iLD7gIl6SuapVNmw01mjxoJWWGWIj+OyzObL9bD+EMLPGE7A7pU6uaUPInDkN99Rr4iPr0Mkh6J6fEd2i2jMK3jYOugDgz4CTTc4718SVNsXzSwcY= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7b63ce08-379f-46e5-6dae-08da3d7a002b X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:02.6215 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: VDw6Em73yh4hCsrWSVWE043IJn/ll0Vx5z3XbqCEojFYK/MtpSaIsiRAZe0GcVDN12mzgTQV+tBqf5GqFX3a9Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/vif.h | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/vif.h diff --git a/drivers/net/wireless/celeno/cl8k/vif.h b/drivers/net/wireless/celeno/cl8k/vif.h new file mode 100644 index 000000000000..2563c6c3222d --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/vif.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_VIF_H +#define CL_VIF_H + +#include + +#include "wrs.h" + +struct cl_connection_data { + u32 max_client; /* MAX Clients of the SSID */ + u32 max_client_timestamp; /* MAX Clients Timestamp of the SSID */ + u32 watermark_threshold; /* Number of clients threshold for watermark */ + u32 watermark_reached_cnt; /* Number of times the watermark threshold was reached */ +}; + +struct cl_traffic_counters { + u64 tx_packets; + u64 tx_bytes; + u64 rx_packets; + u64 rx_bytes; + u32 tx_errors; + u32 rx_errors; + u32 tx_dropped; + u32 rx_dropped; +}; + +/* + * Structure used to save information relative to the managed interfaces. + * Will be used as the 'drv_priv' field of the "struct ieee80211_vif" structure. + * This is also linked within the cl_hw vifs list. + */ +struct cl_vif { + struct list_head list; + struct cl_hw *cl_hw; + struct ieee80211_vif *vif; + struct net_device *dev; + struct list_head key_list_head; + struct cl_key_conf *key; + int key_idx_default; + u32 unicast_tx; + u32 unicast_rx; + u32 multicast_tx; + u32 multicast_rx; + u32 broadcast_tx; + u32 broadcast_rx; + u16 sequence_number; + u8 num_sta; /* Number of station connected per SSID */ + struct cl_connection_data *conn_data; + u8 vif_index; + bool tx_en; + /* Holds info for channel utilization stats */ + u32 chan_util_last_tx_bytes; + u32 chan_util; + struct mcast_table *mcast_table; + struct cl_wrs_rate_params fixed_params; + struct cl_traffic_counters trfc_cntrs[AC_MAX]; + bool wmm_enabled; + u16 mesh_basic_rates; +}; + +struct cl_vif_db { + struct list_head head; + rwlock_t lock; + u8 num_iface_bcn; +}; + +void cl_vif_init(struct cl_hw *cl_hw); +void cl_vif_add(struct cl_hw *cl_hw, struct cl_vif *cl_vif); +void cl_vif_remove(struct cl_hw *cl_hw, struct cl_vif *cl_vif); +struct cl_vif *cl_vif_get_next(struct cl_hw *cl_hw, struct cl_vif *cl_vif); +struct cl_vif *cl_vif_get_by_dev(struct cl_hw *cl_hw, struct net_device *dev); +struct cl_vif *cl_vif_get_by_mac(struct cl_hw *cl_hw, u8 *mac_addr); +struct cl_vif *cl_vif_get_first(struct cl_hw *cl_hw); +struct cl_vif *cl_vif_get_first_ap(struct cl_hw *cl_hw); +struct net_device *cl_vif_get_first_net_device(struct cl_hw *cl_hw); +struct net_device *cl_vif_get_dev_by_index(struct cl_hw *cl_hw, u8 index); +void cl_vif_ap_tx_enable(struct cl_hw *cl_hw, bool enable); + +#endif /* CL_VIF_H */ From patchwork Tue May 24 11:34:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576834 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 8019FC433EF for ; Tue, 24 May 2022 11:41:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236975AbiEXLl2 (ORCPT ); Tue, 24 May 2022 07:41:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237053AbiEXLlL (ORCPT ); Tue, 24 May 2022 07:41:11 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00041.outbound.protection.outlook.com [40.107.0.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C62A1941BA for ; Tue, 24 May 2022 04:40:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n/wlAiSGQhkb2tRJ9DeuA7LOKHL0fy9qHf1I81O9hUBCsr20oCF0FURgz68Y+M12BPf/5MYmab9rnmBfxnNXTUfJaE6ngunbnSxytPwhm5j7uvOKfz+sGm+hNBPbgPWqFwockNDHB2O9tCZRtl9cI7S1/PpIE/k1asH+Jb3OzJMFBiU4V3bkcfYxuBOS1vjK0ZHnYwbdTqs0t2yTpNLrMTcr+rd8WNZp0JRPdTzoBJFoTXM0TZThxXGOQHV24uQwY7drUEcsDyfCYm8fEJ04vT5nTne1qF8RGV0pslgFUHIGLxRUfTSgHy+a7avLVp8vF3cdQZVEV3WT/0JRGH2bRQ== 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=hLsiStGhBV+fyJYbOK9tcR6/jxKYf7YVRl0ZH+zdLek=; b=E4KjV/119CwdlJ98xMLitilgy4wLxuRi8G1tMGIbg25xvmOCQdc5sujW/Jl1m9HIt5CBROVJbhlDTH+EV4RhSGX3Bb86lMurJSU+wc0lRmVS1PVww9VLakq5YgTDYsucNmal61ATdQnsKtdY3iCFNV9cMpy9HCPSlZVJ//E2DDJvGpyC5mMU1BusEUoZo9aserTUtVT0aRD6e22bzD69SOVeKs0Bd/3PXnWaeC8FvxXfElVvZSyKa6u783UVt59dwRmfL2bzXT8Gcx8UGuM37vRBcnbltfzm/wkGOiwtsiNTnm+K+LoPWSPVfEPzSAlkTkwZlZ89OWUDE4LSekVo6A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hLsiStGhBV+fyJYbOK9tcR6/jxKYf7YVRl0ZH+zdLek=; b=iyc68KrUggfVpTxPkfDJWer/IbGm/w5m+cmYB6l1InglPqZIuWorLr7bAaGtkw2q2klfdMWI51sK8XsHaB+1tmUwWYt1wYZhyI5KYsQkuOGbHPIKylolTapYKCUN/OQ9B9V33RA1xr7KcXHjCO0Lh3zyWa8MJVGzP5vh7cRJsvM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:05 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:05 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 92/96] cl8k: add vns.c Date: Tue, 24 May 2022 14:34:58 +0300 Message-Id: <20220524113502.1094459-93-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 478eed20-10ef-470e-57c8-08da3d7a00ac X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wLYHMZsga955sZsw7/yp97VmYJTCtbdDMxMBCDpwXKHI/D3lLqoNlJKWWuhFaK92aAUITv/FjAl+s3fObcB+e3KSvTPlKFB8g+2YRlggDXQ13xPc7LHnuGZHJqWZJS6A2Dx30YihjJpZQg6lbX9RCvIh6umgxJo0wxAUh87BdOmTNOJFCc7srDNb3CNzIdB0YCe8eULa7mu+i6zqFREBXkgpq8e4z3BBwdwZKpK9mpZONXu6pIVVgeP80yQ+MxVblcz5PWkhQXDsWRDcSD6yJVjkw4b1+hau5/a+cvpgJegkYCS0OHW8fdDcCAKTkp/lfOfHFGaHdFnx9/ZItJD5kOktTQdf9tNPEDYtWyYSnsCSZDqbUf2D4oeyrKHkTmWHvG3MK+Pz3QFMg5VXRlnPzgZ9nTmQv7GJYf/peHqxnkVoD+Pt28OcWx+6scTUyZ0VOjgiHrezVuMxhOVX3s9fZ/HunsabVJ4BXkoAaCxqvjehwIGTYKns5fYgbyrH43kDpvgODs9zojQsnKe5Cz9xoi8G4KzGPglvpfniuD2LJslxxnTGISzeELwrd18AnBy3EwZIuwuYBeW4JT21XTQE2r6QzK/WfCoXrAZBPTKImz+bCEq2SaJcmTx37dIXUQ/J4YjGrFej973M6tm/oX/hTqpEPngsAdhy4u2DF2Nmt975IitmynxGWqI4+WYhMxPcQR53w4DXM9KJMmU6QxRHhtvpeOro3fQ03cqG2iR75+o= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(107886003)(5660300002)(508600001)(83380400001)(8936002)(186003)(1076003)(41300700001)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: W6z7eB4gybonHrkr3TonQ1IhtIyioMJK60D2XzcHNrUvWWc6J1fIWmoj2vdJ+gZwnr0bq3uHkllSgN++tSYIhFUj2k+u3XFcdMcODygOVdBCe+qTAAICPQZ/QDocJKdOYJuvb98jazdk/a+v+woQ/IAARvHMGMjvq2nesGmFB63k5MiYcHPPCqLgeXEXRK2oS3KKUcG53oRTunsZdN+INVEGiR3CjXzJNVbq3fWt9InPnySofDeeBJBWjG8897EThoXKQlpnoXgKpGi0oOsjGQBef5wFzama45DjAc/FhIUFEDsmdoQKK8ujWawUa1Aee4EfXSUgzPSDmEHpUJ08pGJaTJzhsZBTjAU6GX+/XNvNYw8klKVOSS1k3w+mRHAAkqivpv+N395/n4fBz+wfiMEVBQ8l6OPkgNHhj/6zTy5Wqbf6/bb9de8zhinkSeoAFTcVGVmsvFXh9TQQjWJCJKtAzbZetpxeEAQVI25xnGm3V5/XEVupzv6mSTrd0CXy45uMvbaT1kRZsn97uOLA4VdBuBT0obzA23Gp/nWiTQQAjWKC/FI/p1UDvv7fo4RBsm5FDkISEsti+2ySnmvh5I+5r17Jge4gM2thnNVXDTSDsouHE4bWncS7lUiSj5EcMQVadD5tmF5g4vj0ctBzqRv9z6CVXylr517Qtljtx1m58pLL2RF4aU7zj+wX3rCmj89lm+e+UFoW/Z/HHHxxcv/hQrohFcaN6hLcCOoy5rslN47c+nkh9pzPrVXnGRIdSKc8TSsyTIUmINNbLzn4Wty5nBCy4ri/KvFymWKyUM62WDbcHNAMmBrZjyYk0eN1aia+fqMdQV7HwBunWI5ItYvigVse49oZW70BJEe4/qoPNvZ1lKP0aMdWeCVDSAofSoSzTSzozxiWDqyObQj22/Wf4AxFl2yBco1kec0psBww5kecDtHlKYRFZyqs9LH2pmW/aHkPWws1Auoxqp1qKU7i1KRyd2XTTT5+ySfzdvFDpcnWRBxfkDipTC3c9wDCRR0+B/ByvfIz9fWLbzOH7d8PXGtQliD3CAkt2fw0BnGlvtoFIOStua3hh+D+4IJ9OqmzVrb/fxQPC68eWuyiYtCihWEJ8kaz6DKpWgAvUJfMCd5+B0ymSodwvVHu4exgzJC6xjLoPwBEbx5Fj1VhbVSEkNJqaEv8ctrdYwBYXQNNfTHMaCAZ1GdaBbrX0ndVUTnYTwX76dKvyRjgcXUGUH4AQxxcLnmPvSGrPtQ8Z62GiUCq+zFmccIfpo7UQVobvng+M3YaBSMOSD7Ae1TpEfNtkqr81HoyJgdCqwabgu6uK+LjLKaHZ9IQOlVj5bgJCSxULeBfqpaRwHH/9Rl8rLqX8pXfNcp1fP3mKfVX3gZnnaw/QcYUyLY42/e7qdbpjYORZDDA0IeQizOgNs2d51QXrkLPnzpBnvicdqv1Jnbh+sdiERYXy+pIoDZP4HLkeDXpBhWqCnXHPLbf+0hyHI32E4t00rdDHoz8d4XeQuKEEfvEl9Tbz+d+SObL3/UJ8rSKsPw3pJ6ovm76TIMAkadmHv31kcBIHyaxiBpwKwy3/uXFNLyRzsMhbROA8kuJ8/GG57YEfjiUkSkKgD42IiMzlVt3hwDHkLwxkj4jCn5gGpMeDAtVUfWWJ1gnrKathsNubdnb1SzmC5Q2KSSntvXxZcVxLVgPhJzxIDrQtR4DYTUIT2leXQL28Ih0ALU1t/imZ06yWX88Rg0eukjgFJX0sgUMlvbXr7ctAypl7A8= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 478eed20-10ef-470e-57c8-08da3d7a00ac X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:03.4351 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 23m9EuLLu1BqmWZYG1Pg+6fM046CGpKcv84utPXiEFxScX0a4t0sndL6NfIP7VQ1cYYxmdGdxceVRPvnsv+axg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/vns.c | 354 +++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/vns.c diff --git a/drivers/net/wireless/celeno/cl8k/vns.c b/drivers/net/wireless/celeno/cl8k/vns.c new file mode 100644 index 000000000000..6f79b36d0a5c --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/vns.c @@ -0,0 +1,354 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include "maintenance.h" +#include "mac_addr.h" +#include "debug.h" +#include "vns.h" + +#define CL_VNS_HASH_IDX (ETH_ALEN - 2) +#define CL_VNS_MGMT_AGEOUT 200 + +#define vns_pr(...) \ + do { \ + if (unlikely(cl_hw->vns_db->dbg)) \ + pr_debug("[VNS]" __VA_ARGS__); \ + } while (0) + +#define vns_pr_pkt(...) \ + do { \ + if (unlikely(cl_hw->vns_db->dbg_per_packet)) \ + pr_debug("[VNS-pkt]" __VA_ARGS__); \ + } while (0) + +static void cl_vns_mgmt_list_add(struct cl_hw *cl_hw, u8 *addr, s8 strongset_rssi) +{ + /* Add entry to mgmt list */ + struct cl_vns_rssi_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + + if (!entry) + return; + + /* Fill entry parameters */ + INIT_LIST_HEAD(&entry->list_all); + INIT_LIST_HEAD(&entry->list_addr); + cl_mac_addr_copy(entry->addr, addr); + entry->strongset_rssi = strongset_rssi; + entry->timestamp = jiffies; + + /* Add to list */ + cl_hw->vns_db->mgmt_db.num_entries++; + list_add(&entry->list_all, &cl_hw->vns_db->mgmt_db.list_all); + list_add(&entry->list_addr, &cl_hw->vns_db->mgmt_db.list_addr[addr[CL_VNS_HASH_IDX]]); +} + +static void cl_vns_mgmt_list_remove(struct cl_hw *cl_hw, struct cl_vns_rssi_entry *entry) +{ + /* Remove entry from mgmt list */ + cl_hw->vns_db->mgmt_db.num_entries--; + list_del(&entry->list_all); + list_del(&entry->list_addr); + kfree(entry); +} + +static void cl_vns_mgmt_list_flush(struct cl_hw *cl_hw) +{ + /* Flush all mgmt list */ + if (cl_hw->vns_db->mgmt_db.num_entries > 0) { + struct cl_vns_rssi_entry *entry = NULL, *tmp = NULL; + + list_for_each_entry_safe(entry, tmp, &cl_hw->vns_db->mgmt_db.list_all, list_all) + cl_vns_mgmt_list_remove(cl_hw, entry); + } +} + +static struct cl_vns_rssi_entry *cl_vns_mgmt_list_find(struct cl_hw *cl_hw, u8 *addr) +{ + /* Search for entry in mgmt list */ + struct cl_vns_mgmt_db *mgmt_db = &cl_hw->vns_db->mgmt_db; + + if (mgmt_db->num_entries > 0) { + struct cl_vns_rssi_entry *entry = NULL; + + list_for_each_entry(entry, &mgmt_db->list_addr[addr[CL_VNS_HASH_IDX]], list_addr) + if (ether_addr_equal(entry->addr, addr)) + return entry; + } + + return NULL; +} + +static bool cl_vns_mgmt_list_find_and_remove(struct cl_hw *cl_hw, u8 *addr) +{ + /* + * Search for entry in mgmt list + * If entry found remove it and return true + */ + struct cl_vns_rssi_entry *entry = cl_vns_mgmt_list_find(cl_hw, addr); + + if (entry) { + cl_vns_mgmt_list_remove(cl_hw, entry); + return true; + } + + return false; +} + +static void cl_vns_mgmt_list_ageout(struct cl_hw *cl_hw) +{ + /* Remove old entries from mgmt list */ + struct cl_vns_mgmt_db *mgmt_db = &cl_hw->vns_db->mgmt_db; + + if (mgmt_db->num_entries > 0) { + struct cl_vns_rssi_entry *entry = NULL, *tmp = NULL; + unsigned long delta_time; + + list_for_each_entry_safe(entry, tmp, &mgmt_db->list_all, list_all) { + delta_time = jiffies_to_msecs(jiffies - entry->timestamp); + + if (delta_time > CL_VNS_MGMT_AGEOUT) { + vns_pr("sta %pM removed from list because of ageout\n", + entry->addr); + cl_vns_mgmt_list_remove(cl_hw, entry); + } + } + } +} + +static s8 cl_vns_get_strongest_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_vns_sta_db *vns_db = &cl_sta->vns_db; + s32 rssi_samples = vns_db->rssi_samples; + + if (rssi_samples > 0) { + u8 i; + s32 strongest_rssi = S32_MIN; + + for (i = 0; i < cl_hw->num_antennas; i++) + if (vns_db->rssi_sum[i] > strongest_rssi) + strongest_rssi = vns_db->rssi_sum[i]; + + /* Reset rssi for next time that cl_vns_get_strongest_rssi() will be called */ + memset(vns_db->rssi_sum, 0, sizeof(vns_db->rssi_sum)); + vns_db->rssi_samples = 0; + + return (s8)(strongest_rssi / rssi_samples); + } + + return 0; +} + +static void cl_vns_monitor_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + /* Monitor RSSI of associated stations and update state if necessary */ + struct cl_vns_sta_db *vns_db = &cl_sta->vns_db; + s8 strongset_rssi = cl_vns_get_strongest_rssi(cl_hw, cl_sta); + s8 rssi_thr = 0; + bool is_vns = false; + + if (strongset_rssi == 0) + return; + + /* + * Calculate RSSI threshold (take hystersis into + * consideration according to current state) + */ + if (vns_db->is_very_near) + rssi_thr = cl_hw->conf->ci_vns_rssi_thr - cl_hw->conf->ci_vns_rssi_hys; + else + rssi_thr = cl_hw->conf->ci_vns_rssi_thr + cl_hw->conf->ci_vns_rssi_hys; + + is_vns = strongset_rssi > rssi_thr; + /* Avoid toggling of VNS state - require two consecutive same decisions */ + if (is_vns != vns_db->prev_decision) { + vns_db->prev_decision = is_vns; + return; + } + + if (is_vns != vns_db->is_very_near) { + vns_pr("sta %pM changed state, strongset_rssi = %d, is_vns = %s\n", + cl_sta->addr, strongset_rssi, is_vns ? "TRUE" : "FALSE"); + vns_db->is_very_near = is_vns; + cl_msg_tx_set_vns(cl_hw, cl_sta->sta_idx, is_vns); + } +} + +static void cl_vns_recovery_sta(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + if (cl_sta->vns_db.is_very_near) + cl_msg_tx_set_vns(cl_hw, cl_sta->sta_idx, true); +} + +int cl_vns_init(struct cl_hw *cl_hw) +{ + int i = 0; + u8 vns_pwr_mode = cl_hw->conf->ci_vns_pwr_mode; + + cl_hw->vns_db = vzalloc(sizeof(*cl_hw->vns_db)); + if (!cl_hw->vns_db) + return -ENOMEM; + + if (vns_pwr_mode == VNS_MODE_DATA || vns_pwr_mode == VNS_MODE_ALL) + cl_hw->vns_db->enable = true; + + spin_lock_init(&cl_hw->vns_db->lock); + + INIT_LIST_HEAD(&cl_hw->vns_db->mgmt_db.list_all); + + for (i = 0; i < STA_HASH_SIZE; i++) + INIT_LIST_HEAD(&cl_hw->vns_db->mgmt_db.list_addr[i]); + + return 0; +} + +void cl_vns_close(struct cl_hw *cl_hw) +{ + if (cl_hw->vns_db->enable) { + spin_lock_bh(&cl_hw->vns_db->lock); + cl_vns_mgmt_list_flush(cl_hw); + spin_unlock_bh(&cl_hw->vns_db->lock); + + cl_hw->vns_db->enable = false; + } + + vfree(cl_hw->vns_db); + cl_hw->vns_db = NULL; +} + +void cl_vns_maintenance(struct cl_hw *cl_hw) +{ + /* + * Maintenance: + * 1) Remove old entries from mgmt list + * 2) Update state for associated clients + */ + if (!cl_hw->vns_db || !cl_hw->vns_db->enable) + return; + + cl_hw->vns_db->interval_period += CL_MAINTENANCE_PERIOD_SLOW_MS; + + if (cl_hw->vns_db->interval_period < cl_hw->conf->ci_vns_maintenance_time) + return; + + cl_hw->vns_db->interval_period = 0; + + spin_lock_bh(&cl_hw->vns_db->lock); + cl_vns_mgmt_list_ageout(cl_hw); + spin_unlock_bh(&cl_hw->vns_db->lock); + + /* Check RSSI of associated stations */ + cl_sta_loop(cl_hw, cl_vns_monitor_rssi); +} + +void cl_vns_mgmt_handler(struct cl_hw *cl_hw, u8 *addr, s8 rssi[MAX_ANTENNAS]) +{ + /* + * Handle management frames of non-associated stations, + * and save the very-near ones in the mgmt list + */ + s8 strongset_rssi = 0; + struct cl_vns_rssi_entry *entry = NULL; + + if (!cl_hw->vns_db->enable) + return; + + strongset_rssi = cl_rssi_get_strongest(cl_hw, rssi); + + spin_lock_bh(&cl_hw->vns_db->lock); + + entry = cl_vns_mgmt_list_find(cl_hw, addr); + + if (entry) { + if (strongset_rssi > cl_hw->conf->ci_vns_rssi_thr) { + /* Update exisiting entry */ + entry->strongset_rssi = strongset_rssi; + entry->timestamp = jiffies; + vns_pr("sta %pM updated in list (rssi=%d)\n", + addr, strongset_rssi); + } else { + /* Remove exisiting entry */ + cl_vns_mgmt_list_remove(cl_hw, entry); + vns_pr("sta %pM removed from list (rssi=%d)\n", + addr, strongset_rssi); + } + } else { + if (strongset_rssi > cl_hw->conf->ci_vns_rssi_thr) { + /* Add new entry */ + cl_vns_mgmt_list_add(cl_hw, addr, strongset_rssi); + vns_pr("sta %pM added to list (rssi=%d)\n", + addr, strongset_rssi); + } + } + + spin_unlock_bh(&cl_hw->vns_db->lock); +} + +bool cl_vns_is_very_near(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb) +{ + bool is_vns = false; + /* This function checks for every TX packet whether it's VNS or not */ + if (!cl_hw->vns_db->enable) + return false; + + if (unlikely(!cl_sta)) { + struct ieee80211_hdr *mac_hdr = (struct ieee80211_hdr *)skb->data; + + spin_lock_bh(&cl_hw->vns_db->lock); + is_vns = cl_vns_mgmt_list_find(cl_hw, mac_hdr->addr1); + spin_unlock_bh(&cl_hw->vns_db->lock); + + vns_pr_pkt("mgmt-sta %pM, is_vns = %s\n", + mac_hdr->addr1, is_vns ? "TRUE" : "FALSE"); + + return is_vns; + } + is_vns = cl_sta->vns_db.is_very_near; + + vns_pr_pkt("assoc-sta %pM, is_vns = %s\n", + cl_sta->addr, is_vns ? "TRUE" : "FALSE"); + + return is_vns; +} + +void cl_vns_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + /* Update is_very_near according to mgmt list */ + bool is_vns = false; + + if (!cl_hw->vns_db->enable) + return; + + spin_lock_bh(&cl_hw->vns_db->lock); + is_vns = cl_vns_mgmt_list_find_and_remove(cl_hw, cl_sta->addr); + spin_unlock_bh(&cl_hw->vns_db->lock); + + if (is_vns) { + vns_pr("sta %pM connected - is_vns = TRUE\n", cl_sta->addr); + cl_sta->vns_db.is_very_near = true; + cl_sta->vns_db.prev_decision = true; + cl_msg_tx_set_vns(cl_hw, cl_sta->sta_idx, true); + } else { + vns_pr("sta %pM connected - is_vns = FALSE\n", cl_sta->addr); + } +} + +void cl_vns_handle_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]) +{ + /* Collect rssi samples */ + int i; + + if (!cl_hw->vns_db->enable) + return; + + for (i = 0; i < cl_hw->num_antennas; i++) + cl_sta->vns_db.rssi_sum[i] += rssi[i]; + + cl_sta->vns_db.rssi_samples++; +} + +void cl_vns_recovery(struct cl_hw *cl_hw) +{ + vns_pr("Recovery\n"); + cl_sta_loop_bh(cl_hw, cl_vns_recovery_sta); +} + From patchwork Tue May 24 11:34:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575956 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 98AD8C433EF for ; Tue, 24 May 2022 11:40:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236947AbiEXLku (ORCPT ); Tue, 24 May 2022 07:40:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236951AbiEXLkm (ORCPT ); Tue, 24 May 2022 07:40:42 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00080.outbound.protection.outlook.com [40.107.0.80]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2DEC18CCDC for ; Tue, 24 May 2022 04:40:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hZIqz/okfmNOVeNEQV+EXKc/RXuURVqD8SGh7fujNGZbqHQ/T1Qelu5TSyxDgg1rxwKy07CBPGEZwMWKrFPpV/qHKHXUoIiZjHDfK1DuykidFt6S7AOQG5I6mbOXQA5+9u/FAorg6hSPB2grKtOdgua4I/SDjBgnm3c3OUCqrOyN459R6+55ul5Op9K0mhpwxG55Gkmz7U0V56LlIJy258kBpluuUSjFbe6bG/Idf5R1KYZLPoozK4lp1HR5ehNyisDNBNxvSDPVM45bA15A86p/dasELsHET/bGwblOAJ7BNLS62LrJuio9CqwDGxOFF035gIm6hf/+j1FvMaGgFw== 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=qYIF415s1BDyPgeTVJSYpCTcvR9hXJafxy8QLPL4wjs=; b=EVxFJsX4jy4QEmGLnKDLC9bNPpp1Rpzc3xRdUAH0UikHFSXur+TBMX5lubkuD5nopLl+Grz0//KVLM/D9elLiNI5aSvbt5yKyA7Th1AkmiPJIP5GQ8U7WA94ptijRW+EdZbNa8wHhHHk+Pg1JDsi2mxqWqLv79j0Y0IHjJFRpiv5Cui0d3QQNodWZyGAzwDdgTLP7Qjwa4ljXLS/yrWtoCqGaZkhNdPJek/bgNn3sjoz3CMtp3Um20TyISnaz7A4pIzXIBCPpt8jzhwEftfCwVsL9o8VRZqlEXgAejqhTrkCOERDX7bn2gUSq6NPdWrTStjJSJTe7T9GXX5COjfK8w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qYIF415s1BDyPgeTVJSYpCTcvR9hXJafxy8QLPL4wjs=; b=SzWcryY0GSMMeY3GHRq00dCgHtITtCLSWo2sfugz7vBDwN44XKM9ojLXTuhi1nt8J8yqNzWEo5XhHtSoheryACzoAqIHvltCMe/+nRB0hUKU2N4H0q3LDUfFhpLd1KXIDvOPaTmjEVBiK5w01370KDMGCiOM5+3NNuMqEq2UiGc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:06 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:06 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 93/96] cl8k: add vns.h Date: Tue, 24 May 2022 14:34:59 +0300 Message-Id: <20220524113502.1094459-94-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e05b8fe5-4f6c-4399-0bfc-08da3d7a0115 X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TIWoPwEYL1e5Sw4B75bsp5wPMkh5ZcwinXX04cpn3rxl9ZoKUN9Diqno5sKk3civAEXh3O7XZZ+7k31j1BGRwYnrWHEI1JF3SEqlqHtuyzFkfsus2CZtdIDpXJJXA6kPz3t7UUWVr6jNtfttcpUZBu5/ZMvYS6PrUnD3ZH/iw5X70ABp9ZLSjjtXpbDE6IqbysEGUARVUBbRppj0M4gGdOE0dCDoM9jXVYGBRN81DEKH76yHPWG7koJELnBAVGJZvqVy82M09AZ9RRhohxpZDR3hTWZF3wO0wA5YBlIXQHjAvzJwJspuhpPohoaHz45+Zc7wzTaz1qhuSrOJxc0m6o27YPB7SlXs/b/zI6plQVFlQV6XCMjLPB2YFfAb/wJ004VnsTD3RM6xg+6GBrxap0oOlcGz/7HTIo+fJ24FN8o5/dOKipNuLQ3o1O3FaQgBbz2ehOe9ilDM+n63mXuMhtf4NfQv2RL0rsyJAwjpYi53Hxh/zwVNBrHlbvjBg2a+03OJUBDeMvi8BCONBsiyzF/9rDo2CG+kpLhQjMNQULif1KTcI3nM7u/CRBRxboqbenp6NouVOmhKk0fncEoEH7lSakLUFcstfhF9jeGw+8ucSEfb1vUTPOIri0EHOs4fSTm61Jm1Ea20IQMhuU6rKrCGIEZAjhExLgnBgx1WunwaBPf9jomhoOjmpfyFgCCAW7LAyBJsweE3ciFfpvRgf2WLzTcQ3rIv3wSmfIonKQE= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(107886003)(5660300002)(508600001)(83380400001)(8936002)(186003)(1076003)(41300700001)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: K5qlSosVpEkTkxBOQSpdASPQdyquZj7nfv5n+t9JmnPpyQpMIWsfxhu+6uJt6GiJf6+zQBgIexm9oJsVmlI1UAk18zdaaN/DOUJmDJqD3nRNCdUa/HQxqbThqNhwFX7tG5L54Bs+6B/2UkZKxuOhdM2EIHw4063H1On5YqCe2H9vCB0RbFe9femWWUvDegepEVOiTcfFrx5I7eckF5Ab0OfnqhvhRerpZsnw1gV945lPCWdDKm5M/B1DHH8X2h9d9BEkjenUgJPEQMMWYUZdNLNExoF1vb0W7FCKELjV22h+qSmd7lvcGWQ0g+3+Hf6sv5S3Rd6ZC9mWFCqXmDQOGKnXDZxTWfyWBLTNEvK9zCAWBy1qUWSAjrsg9E7nhI42SQzHe23qc3IFUwOs8frjW67Hr6hzXZTy0ZQreVvh+yPTLD0vuBKbJoiiMxp/VnEiLmssyaungvx1jvZWjwjy2UEvfgvJphDi26Q9tg57sqlaUer+yq0U/hFWz7JxDvtuhFdXkKEIUmHXGAj+fT+NE4qvzo2k+Gyh+uSh7pBUTbyFpLd9RSdKKpCvXp+qnzhFL2RunSS0pOlxWq7qyTbQha6/DuTofQ7QFvT5RzY/XReIsJqII6BziFulZacNk5QK+CVKIpe9PS9v0gNabn86j98bVjRVHJKD9SVbl8oSZk4YmGSn5Hjvt4/xkyvDImY8lAhWHEmb/lSZgPKvYeQBnzECOxN1KRsYS8dBoZSyZ3fWcsTne6zPedA8A5MaF+GXpCD8ciYyinEhJG2W5MDOyYmhdOTZ7XfFXDQhFQCzeLiab+F3Wof67iPS+E/r/Z92Tw7rFwC3OBWBaUi1QB2izzWl/ZTkcwH5J4KYZQRTCUFd2457U6EmDYgmtDXos/vqyLKS4GnObLUvhUUoJ+Nc0wFVwkVnrgHxkAnIn9CBvZ+kIUQGb751mFd95mOFh26TNAav++WwleIuKgloEqSNPFcAU/y2roe5qRU25EyN9iSM1OjGCjcwgZWvmB/UoW7nJj4FQVrvnMnNEdlR2fTbDkbpwL2MyNMWLFyPC2UddXYKs5vCtEFVIjK+xqXFNgOkzXZI2zWMSwsxbv5oYLDRiunxWGwDPzUAKi+8JYiTVOU8ciKjw361NrMHa/d8O7Q8Iex1ngaFB2L+qZQkBhoA74Abh91uqwqRt3UlDCQSKsTf2VXBkF7DaSa9H8r7n3ercExCf0SdMuTYaMgvPVMDCCXYWTDd00UlCcqELi9Q6yxzFhQE8H9h9B2mMAhaDOqo/E5wPSlmjPgYVWbk0qzb2JNVUrNU3dBXuA/JWVIkdFPYv00EmQi9Kb0Yak91zn55ZZDwDra0UA7GziQAQSNNgpev0ZOPL77SI0ZNYGeIc4msbz/6pAMxz/aK2zfEcNcgUv+ruXBLcAn20Uj2xBJWbkB2/OThY/1SuFD9aQ/XTu7t/iyXtNrT6Zy9OahtBSMd4QLlvLzpqwkugSs9IU23iAFjHXd+Y33N6ngidEB179bYr97dcRVO/sdb782tS8qfqTNpmzziChqQcikk1l0xslPfQGYjZpJl7X04mxSk7fSC2mBMUoW78pPeXZmMyv8ypdRErFZ8vS2Bkm7rNLCyxI5LuvU19gbnx9ahRV4IyBxwu6Z54VJwQZb1DBUjbgjocpuPZqbauoJ9RCBDHZyokwWnCB16zE3x+OshHSxHET6PTXZORw0d8iZVw0MCe8SmiBb3s1NCljv2PqwkNgDb/4uGlORBXB9gpHMUi8InHuU= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: e05b8fe5-4f6c-4399-0bfc-08da3d7a0115 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:04.1369 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ZEAm07pCeKRUy+a6EXqGPrIn356JK/kJ7QfzFWfP5OpEMyQRMU/nCrEXYUsmwiJIFVI+hNo8W9klPUYuiXeScw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/vns.h | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/vns.h diff --git a/drivers/net/wireless/celeno/cl8k/vns.h b/drivers/net/wireless/celeno/cl8k/vns.h new file mode 100644 index 000000000000..904fa7a7fe1b --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/vns.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_VNS_H +#define CL_VNS_H + +#include "def.h" + +/** + * DOC: VNS (=Very Near STA) + * + * Feature is responsible for TX power adjustment regarding to the STA + * location. Near stations should get signal with lower power to avoid + * saturation. Power is contolled for both transmitted data (%VNS_MODE_DATA) + * and autoresponse frames (%VNS_AUTO_REPLY), including both cases for + * connected and not connected stations. + * + * In order to determine, whether a station is in VNS range, we rely on the + * RSSI values, received from the firmware for every RX frame. + */ + +#define VNS_MODE_DATA 0x1 +#define VNS_MODE_AUTO_REPLY 0x2 +#define VNS_MODE_ALL (VNS_MODE_DATA | VNS_MODE_AUTO_REPLY) + +struct cl_vns_rssi_entry { + struct list_head list_all; + struct list_head list_addr; + unsigned long timestamp; + s8 strongset_rssi; + u8 addr[ETH_ALEN]; +}; + +struct cl_vns_mgmt_db { + u32 num_entries; + struct list_head list_all; + struct list_head list_addr[STA_HASH_SIZE]; +}; + +struct cl_vns_db { + bool enable; + bool dbg; + bool dbg_per_packet; + u16 interval_period; + spinlock_t lock; + struct cl_vns_mgmt_db mgmt_db; +}; + +struct cl_vns_sta_db { + bool is_very_near; + bool prev_decision; + s32 rssi_sum[MAX_ANTENNAS]; + s32 rssi_samples; +}; + +int cl_vns_init(struct cl_hw *cl_hw); +void cl_vns_close(struct cl_hw *cl_hw); +void cl_vns_maintenance(struct cl_hw *cl_hw); +void cl_vns_mgmt_handler(struct cl_hw *cl_hw, u8 *addr, s8 rssi[MAX_ANTENNAS]); +bool cl_vns_is_very_near(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct sk_buff *skb); +void cl_vns_sta_add(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_vns_handle_rssi(struct cl_hw *cl_hw, struct cl_sta *cl_sta, s8 rssi[MAX_ANTENNAS]); +void cl_vns_recovery(struct cl_hw *cl_hw); + +#endif /* CL_VNS_H */ From patchwork Tue May 24 11:35:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 575949 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 B1444C4332F for ; Tue, 24 May 2022 11:41:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236969AbiEXLlu (ORCPT ); Tue, 24 May 2022 07:41:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236955AbiEXLls (ORCPT ); Tue, 24 May 2022 07:41:48 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00041.outbound.protection.outlook.com [40.107.0.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C038B219E for ; Tue, 24 May 2022 04:41:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NZvnQY60o5dNTN3BZSHnwjwsHKaM/51dekGohu1WrKdr7y9zSlXrpyhPFGENkZBV9JiSkbQfi3RMNzXbVhw/VJT/8z69f5CSLDyLnOdyoZLW/S/md8EIXtqawtQjqWTuHCRdIBM8kVBtx0Bp8NYDK5IAPAKuyPDGexlVnaN9dE/AmKvi7UCVZu9dpxcPWWSoAyV0HRx66l6YZiCMkia2+QnCOa7/Xtc//85aKB7NDc9+ivXaLcK7UQHYLZZkCWG8V8Hz4pdJnqjYHNBBbzA+LZs8lcaCKcMKqNP9IAFGF/AWdtN1wI9X2Fqm9eDBbC4ltAFNCM1F9WrVfJ0dJTQ8DQ== 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=p29A1K8b151fDW3Y4UfHqvIbDkZNU1nwQmdlhtvtRPk=; b=EMx4MYLS5v32fbsMcYFCYFHWEoZK48wyFy8NmmfDT4kw8vfl+QFQJz+4Gx9k/5rL2E3MW8M+WCibehDLRKxnP72X5yyZ2xCaOXTz+tPx36rtLYxwbBt2Au1h7S72nUxsm+0FswkLB8YWxjr7w5wMtJp/Y2R2o8/mP3VScH8PFsgSOPF8sGwhWdsBd6BHmQp5D8EIBzWYrJ/Xzn5EH4q7byWMj7/n9V2FC9+TPcdtWnWGImX0JQnwa4Okswy7kwjvlaMpe98EkQDJFi08nkJj1ESaLX4/LPJEsoMgOZ9zh8HikPW91zRwwaWp7xj+Qo30ZSFr08oG32d1ki7YCiUDwA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=p29A1K8b151fDW3Y4UfHqvIbDkZNU1nwQmdlhtvtRPk=; b=yRN/QKv0S2ylzekigYtyvO9PSuOc7pcjdDFSQ7oqzUwd64k6sNPoIOiYYusEDgpy1mhXBleeOuOkFRZQs5L4noVkYH90knG5B32vB5yWfrCjcXuGRbb3xsoLHDvCGHhcCeEadHhxtNyVHQO/p1qNcm/ihry81v+17QU2hLKWh98= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:06 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:06 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 94/96] cl8k: add wrs.c Date: Tue, 24 May 2022 14:35:00 +0300 Message-Id: <20220524113502.1094459-95-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1fb7b295-35a3-48c9-1503-08da3d7a0185 X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Z224LvELBOdftG6bXEIJwAxXe+5sYOdWPdJSRaRLxbx9n7VjX0To0e93DzEWNhcyIiVMYyV2mXy5gEbe5CXixV0Mwn5hca3gnh/u4KgmtjdRtFgjgKq9aYKahQxUVpAzISjhSmkgdTb10iysG/IjW+ncZiHrQdPVxuVGkGsLdONpFAlOWLC+hT/jQCqv8UJoUwTjvg/urfTKd8ZlVaBjCt7ur7HUlvciLmCd59UaMgmanthF4Fh9hL9hXvyCmqPwifTxurcPFGD7g+R46AZEJCaB12Xn+2pYQ+tNeOBN7T2ICxN16lNY97YhBmq36OoXovApoZ0Ul8KFC4aFUpE18kj2jlEWmgWbabjOX2sKhiuYA25ex3uVnQBfNLqn+PPp1befkQSgiLrVURS8d38le5jq0ZBcjdEpVGXgTDJYIQTVwttSDJ3hdce0NeLU+u5YEQErBQ+/abxDGwgdKKm3j+jGC771dmUvTsyeJ9ELvo5W2cctKCwjX6/7ranGvVaOF+gGPMJJnX8GM0pbBcHVIa3H5eOIvDU2fwIHy9NLK1wfyOp+9IZwNz/j3yCrDl0fHyslPAh2IcNeuRLvh8tbKr9+rlQCaGTi6IlaromgeodPnUMn3nQdrG+YxcIw7o5OtesszXjbkhjzytUyJHkwp5eV/uPkzK3fRlaDdAICizHom/pG4oh2SqyeooB3wB70l84xXqiwJzkkN3Mxl17Bj5AbBZckFl85pVADaQTSs/9lPHzF2+Wf2sNSocHeqQ6p X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(30864003)(107886003)(5660300002)(508600001)(83380400001)(8936002)(186003)(1076003)(41300700001)(6666004)(32563001)(579004)(559001)(309714004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: e/RUopYF8I0V8ytm/MXXNwiqfq2rhTV4J1b4pI/Hpp4Jx7Bt/pNDetTNeQcPqzctivOjUkrMvzYf7XB7FjTOY4GzIvkiFHYHd9FDnrqHB25BnVK17JMPkoYHNNLXjXeegFnst8tiD4FuSWQfXvn6RjvakJJ5QMFFaCpd2uIyQRI0RhsefzKMKAjbvnhkJYULFaW+ahBAfi07Yl4RekVsDKw5E8znsZYh2XCpTY3EF8cpR85hZL0m0hVxakilft/rYd0HGBujU7sPidTsVsrWxD/hdXh5OnYBP1iqVqgwHAo/oy2w8MVoTXO2TI1O4w1T28hARkgY3m6Xk8kMKNvtR3Xevz7FehJlmfrm0T9iAxC75U/KHeMRyDEEQ1Gzx8koRH61lqGXbRVuaVbfiv4hmq3gnGRoB512taPd4Ai/sK7LptHErpomElneKwEkKQ3q2WnEEPQA+E0o017M12l2kfbDySIDtTHlgWpjTrTGICY2YsIPh1MNmBU+K44RZt9Z2bs1nxewaRKB6BIben1vDNn9KRlp7Zz7W0j5cWn2G6CD+0cWKJt+J3pALEmp6WJIB5T3WylJ/YjyW0JzVWvOhDw0HJs92LxuNo8dCZa7xVLsjRBO19sT72AR4PouqoxHqczZIoDW/VAnpsV1hwNVrhGkkgFJt76TMKiLl8ztryjLAt6tb9GvA/KDrmLolyyccMF25yVma8CtPgCvt06aMS/5n7CnvTL9VF7XivTEWiMe4YAo3CLc+B55A9WCoDxtvC2sZIO6kd2eTa/I/tFFdGlpYqEg21ZJv4WtZ5L85twJ6ICU565hknjwx4kgs0Z49eaNXCyUgnDGPfxeliigmmXiROYl5OC+SmAdrAW8oRJFHXw4vfxoXgHNXv72cxLQGHHxJz0i/R2lWlMrf83jNRaMK+RSI4Yj8MnP2rEglUhjd7T9+LWichv/yrXI4Wj2/XVK937HU7SXQ2IoEA0Dqu1tndoVdHOO3p6EnC3Sds2iMC/TqtW5ivy7MnEFlQdS7oSPqcQyoU75x9GVk9B22DneWYRa6rnRCYj+drWslP8EoWdpA5vSuFMiQg/hpKE4/aLSZs7mLVKL2hMWZ3TvnskaLjxeYybYWwI8xcDfljlicwZopsJ6tYLqUFRR9Z6/q5VwJCstakyYMRQDGNiycVFWxTaogWWNSQhO9ba1sRltiBQcqPl541MeCpmhaereHzwmAmdroOmLB9TrOfeBntAhs9U9ROd07Ja9sWSo1klpceEf5Pc7SLqDFIOi2yDHCdXll+1Z3GlQRKQmMhg9I87svjInZy+HAuQ5AYpMJinWt+AknhVQlSOoJYnDTkUtTVYsqUWW94vMEQSbXGFKDXwYaBW9beSC/MTeO5zey0wGZ63DlkvN4Iqhmt5yd4QCeICwHBmAhYa9G3/dq+8pMP3ynJ7ixxsBxs++bnM8xS4rxZTAKei+BKzwIKAaJvFDlJiMAHPPzR1PDBMwHt+TI2FUaXzhQidod4NKRlBVIfaHk/Shn+TKQ1XeBNyspf3rmPCP/cqMyeQEsyNI1HFzfv91jZ9jnJ+aawqlw2xrNgVhDYoPwR24M0K3G0qXlxJu1fybOfUlZhVMGm7f656GkzVk7Suz0oJiBhzY+jwg/me7qcNhUaxcfq3HY8h3iJTn+ccb8gWDk8pR7/cA27Krad04d7P3u1Xz/RP8cIsOs7BrUiZByZFfDiuWlM38GFdQQxXqjWiDg3lo0UTnQq5h43ytRZpeVrELbAfSt1jFvAE= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1fb7b295-35a3-48c9-1503-08da3d7a0185 X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:05.0118 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6vmlRxamBhtHhnSDlZDGt7w8jckffmpl9SpguUZkJVg98F/wAWRn6QYmYI7g89qs2JUWJtnfLqtFzS4/A065Uw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/wrs.c | 3323 ++++++++++++++++++++++++ 1 file changed, 3323 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/wrs.c diff --git a/drivers/net/wireless/celeno/cl8k/wrs.c b/drivers/net/wireless/celeno/cl8k/wrs.c new file mode 100644 index 000000000000..9f6b0d8154da --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/wrs.c @@ -0,0 +1,3323 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include + +#include "rates.h" +#include "chip.h" +#include "utils.h" +#include "hw.h" +#include "reg/reg_defs.h" +#include "debug.h" +#include "radio.h" +#include "wrs.h" + +#define wrs_pr(wrs_db, level, ...) \ + do { \ + if ((level) <= (wrs_db)->debug_level) \ + pr_debug("[WRS]" __VA_ARGS__); \ + } while (0) + +#define wrs_pr_verbose(wrs_db, ...) wrs_pr(wrs_db, DBG_LVL_VERBOSE, ##__VA_ARGS__) +#define wrs_pr_err(wrs_db, ...) wrs_pr(wrs_db, DBG_LVL_ERROR, ##__VA_ARGS__) +#define wrs_pr_warn(wrs_db, ...) wrs_pr(wrs_db, DBG_LVL_WARNING, ##__VA_ARGS__) +#define wrs_pr_trace(wrs_db, ...) wrs_pr(wrs_db, DBG_LVL_TRACE, ##__VA_ARGS__) +#define wrs_pr_info(wrs_db, ...) wrs_pr(wrs_db, DBG_LVL_INFO, ##__VA_ARGS__) + +#define WRS_LOGGER wrs_params->logger[wrs_params->logger_idx] + +static void cl_wrs_reset_params_cntrs(struct cl_wrs_params *wrs_params) +{ + wrs_params->frames_total = 0; + wrs_params->fail_total = 0; + wrs_params->ba_not_rcv_total = 0; + wrs_params->epr_acc = 0; + wrs_params->up_same_time_cnt = 0; + wrs_params->down_time_cnt = 0; +} + +static bool cl_wrs_down_epr_check(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, u8 drop_factor, + enum cl_wrs_decision decision) +{ + u16 curr_rate_idx = wrs_params->rate_idx; + struct cl_wrs_table *curr_rate = &wrs_params->table[curr_rate_idx]; + u64 curr_epr_acc = curr_rate->epr_acc; + u32 curr_total = curr_rate->frames_total; + u16 down_rate_idx = curr_rate->rate_down.rate_idx; + struct cl_wrs_table *down_rate = &wrs_params->table[down_rate_idx]; + u64 down_epr_acc = down_rate->epr_acc; + u32 down_total = down_rate->frames_total; + u16 down_data_rate = 0; + u64 condition1 = 0, condition2 = 0; + bool down_decision = false, allow_penalty = true; + + if (wrs_params->calc_ba_not_rcv) { + curr_total += curr_rate->ba_not_rcv_total; + down_total += down_rate->ba_not_rcv_total; + } + + /* + * In the EPR of down candidate is better than or equal to current EPR => return true + * + * (1) curr_epr <= down_epr * factor(%) + * + * curr_epr_acc down_epr_acc factor + * (2) -------------- <= -------------- * -------- + * curr_total down_total 100 + * + * (3) curr_epr_acc * down_total * 100 <= down_epr_acc * curr_total * factor + * + * (4) conditation1 <= conditation2 + * down_epr_acc + * If (down_total == 0) we use down_data_rate instead of: -------------- + * down_total + */ + if (down_total) { + condition1 = curr_epr_acc * down_total * 100; + condition2 = down_epr_acc * curr_total * drop_factor; + } else { + down_data_rate = cl_data_rates_get_x10(wrs_params->rate_params.mode, + down_rate->rate.bw, + down_rate->rate.nss, + down_rate->rate.mcs, + down_rate->rate.gi); + + condition1 = curr_epr_acc * 100; + condition2 = (u64)down_data_rate * curr_total * drop_factor; + allow_penalty = false; + } + + wrs_params->penalty_decision_dn = wrs_db->step_down; + + if (condition2 && condition1 <= condition2) { + down_decision = true; + + if (allow_penalty) { + /* + * The penalty is calculated as follow: + * + * penalty = MAX_STEP * penalty_factor + * epr_curr + * penalty = MAX_STEP * (100% - 100% * ----------) + * epr_down + * + * conditation1 + * penalty = MAX_STEP * (100% - 100% --------------) + * conditation2 + */ + + u64 penalty_factor = 100 - div64_u64(condition1 * 100, condition2); + u16 max_step = wrs_db->time_th_max_up - wrs_db->step_down; + + wrs_params->penalty_decision_dn += + div64_u64(max_step * penalty_factor, 100); + } + + if (decision != WRS_DECISION_SAME) + wrs_pr_info(wrs_db, + "[%s] EPR check: sta = %u, pkt_curr = %u, " + "pkt_down = %u, epr_curr = %llu, epr_down * %u%% = %llu, " + "penalty = %u\n", + WRS_TYPE_STR(wrs_params->type), + wrs_sta->sta_idx, + curr_total, + down_total, + div64_u64(curr_epr_acc, curr_total * 10), + drop_factor, + down_total ? + div64_u64(down_epr_acc * drop_factor, down_total * 1000) : + (down_data_rate / 10), + wrs_params->penalty_decision_dn); + } + + if (wrs_params->is_logger_en && down_decision) { + WRS_LOGGER.curr_epr = (u16)div64_u64(curr_epr_acc, 10 * curr_total); + WRS_LOGGER.down_epr = down_total ? + (u16)div64_u64(down_epr_acc, down_total * 10) : (down_data_rate / 10), + WRS_LOGGER.down_epr_factorized = WRS_LOGGER.down_epr * drop_factor / 100; + WRS_LOGGER.penalty = wrs_params->penalty_decision_dn; + } + + return down_decision; +} + +static void cl_wrs_time_thr_max_handler(struct cl_wrs_db *wrs_db, + struct cl_wrs_table *table, u8 up_idx) +{ + /* + * Check if there are at least two UP rates, + * and all UP rates reached max time threshold + */ + u8 i = 0; + u8 time_th_max = 0; + + for (i = 0; i < WRS_TABLE_NODE_UP_MAX; i++) { + if (table->rate_up[i].rate_idx == WRS_INVALID_RATE) + continue; + + if (table->rate_up[i].time_th != wrs_db->time_th_max_up) + return; + + time_th_max++; + } + + if (time_th_max < 2) + return; + + /* Find the next max rate, and decrease its time threshold by 1 */ + i = 0; + while (i < WRS_TABLE_NODE_UP_MAX) { + up_idx++; + if (up_idx == WRS_TABLE_NODE_UP_MAX) + up_idx = WRS_TABLE_NODE_UP_MCS; + + if (table->rate_up[up_idx].rate_idx != WRS_INVALID_RATE) { + /* + * If all up rates reached max time threshold,the first up + * rate will always be selected. + * To overcome it, we decrease the time threshold of the next + * up rate by 1 (so it will be samller and selected next time) + */ + table->rate_up[up_idx].time_th--; + break; + } + + i++; + } +} + +static bool cl_wrs_find_up_candidate(struct cl_wrs_db *wrs_db, struct cl_wrs_params *wrs_params, + u16 *up_rate_idx, u32 *up_time_th) +{ + bool up_rate_valid = false; + u8 up_idx = 0; + u8 up_candidate = 0; + u16 rate_idx = 0; + struct cl_wrs_table *table = &wrs_params->table[wrs_params->rate_idx]; + + *up_rate_idx = WRS_INVALID_RATE; + *up_time_th = U32_MAX; + + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + rate_idx = table->rate_up[up_idx].rate_idx; + + if (rate_idx == WRS_INVALID_RATE) + continue; + + if (wrs_db->quick_up_en && table->rate_up[up_idx].quick_up_check) { + *up_rate_idx = rate_idx; + *up_time_th = wrs_db->quick_up_interval; + up_rate_valid = true; + up_candidate = up_idx; + break; + } else if (table->rate_up[up_idx].time_th < *up_time_th) { + *up_rate_idx = rate_idx; + *up_time_th = table->rate_up[up_idx].time_th; + up_rate_valid = true; + up_candidate = up_idx; + } + } + + if (wrs_db->time_th_max_up == *up_time_th) + cl_wrs_time_thr_max_handler(wrs_db, table, up_candidate); + + return up_rate_valid; +} + +static bool cl_wrs_epr_immeidate_down(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u16 down_rate_idx) +{ + if (cl_wrs_down_epr_check(wrs_db, wrs_sta, wrs_params, + wrs_db->immediate_drop_epr_factor, + WRS_DECISION_DOWN_IMMEDIATE)) { + /* + * If there are several immediate drops in a row ignore them, + * because it is probably not realted to bad TX rate + */ + wrs_params->immediate_drop_cntr++; + + if (wrs_params->immediate_drop_cntr > wrs_db->immediate_drop_max_in_row) { + wrs_params->immediate_drop_ignore++; + + cl_wrs_tables_reset(wrs_db, wrs_sta, wrs_params); + cl_wrs_reset_params_cntrs(wrs_params); + + wrs_pr_info(wrs_db, + "[%s] sta %u - ignore immediate down decision (cntr=%u)\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx, + wrs_params->immediate_drop_cntr); + return true; + } + + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN_IMMEDIATE, down_rate_idx); + return true; + } + + return false; +} + +static void cl_wrs_decision_up(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u16 up_rate_idx, u32 up_th) +{ + enum cl_wrs_decision up_decision = (up_th == wrs_db->quick_up_interval) ? + WRS_DECISION_UP_QUICK : WRS_DECISION_UP; + + if (wrs_params->is_logger_en) + WRS_LOGGER.up_time = wrs_params->up_same_time_cnt; + + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, up_decision, up_rate_idx); +} + +static void cl_wrs_decision_same(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u16 rate_idx) +{ + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, WRS_DECISION_SAME, rate_idx); +} + +static void cl_wrs_epr_decision(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + u16 curr_rate_idx = wrs_params->rate_idx; + struct cl_wrs_table *table = &wrs_params->table[curr_rate_idx]; + u16 down_rate_idx = table->rate_down.rate_idx; + u16 up_rate_idx = 0; + u16 down_th = table->rate_down.time_th; + u32 up_th = 0; + bool up_rate_valid = false; + + /* Check if we transmitted enough frames for taking decision */ + if ((wrs_params->frames_total + wrs_params->ba_not_rcv_total) < + wrs_db->min_frames_for_decision) + return; + + if (wrs_params->is_logger_en) { + WRS_LOGGER.timestamp = jiffies_to_msecs(jiffies); + WRS_LOGGER.rate_idx = wrs_params->rate_idx; + WRS_LOGGER.success = wrs_params->frames_total - wrs_params->fail_total; + WRS_LOGGER.fail = wrs_params->fail_total; + WRS_LOGGER.ba_not_rcv = wrs_params->ba_not_rcv_total; + } + + up_rate_valid = cl_wrs_find_up_candidate(wrs_db, wrs_params, &up_rate_idx, &up_th); + + /* RSSI protect */ + if (!WRS_TYPE_IS_TX_MU_MIMO(wrs_params) && wrs_db->rssi_protect_en) + if (cl_wrs_rssi_prot_decision(cl_hw, wrs_db, wrs_sta, wrs_params, + up_rate_valid, up_rate_idx, down_rate_idx)) + return; + + if (down_rate_idx != curr_rate_idx) { + /* Down immediate */ + if (wrs_db->immediate_drop_en) + if (cl_wrs_epr_immeidate_down(cl_hw, wrs_db, wrs_sta, + wrs_params, down_rate_idx)) + return; + + /* Down */ + if (wrs_params->down_time_cnt >= down_th) { + if (cl_wrs_down_epr_check(wrs_db, wrs_sta, wrs_params, + wrs_db->epr_factor, WRS_DECISION_DOWN)) { + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN, down_rate_idx); + return; + } + + wrs_params->down_time_cnt = 0; + } + } + + /* Up-same */ + if (wrs_params->up_same_time_cnt >= up_th) { + if (up_rate_valid) + cl_wrs_decision_up(cl_hw, wrs_db, wrs_sta, wrs_params, up_rate_idx, up_th); + else + cl_wrs_decision_same(cl_hw, wrs_db, wrs_sta, wrs_params, curr_rate_idx); + + return; + } + + /* + * If there is no valid UP rate and the EPR is more + * than EPR down threshold => make a same decision + */ + if (!up_rate_valid && + !cl_wrs_down_epr_check(wrs_db, wrs_sta, wrs_params, + wrs_db->epr_factor, WRS_DECISION_SAME)) + cl_wrs_decision_same(cl_hw, wrs_db, wrs_sta, wrs_params, curr_rate_idx); +} + +static void cl_wrs_divide_weights_by_two(struct cl_wrs_table *table_node) +{ + u8 up_idx = 0; + struct cl_wrs_table_node *rate_up; + + /* + * Converge weights - divide all weights by 2 + * (make sure they do not go below their init value) + */ + if (table_node->rate_down.rate_idx != WRS_INVALID_RATE) + table_node->rate_down.time_th = max(table_node->rate_down.time_th >> 1, + WRS_INIT_MSEC_WEIGHT_DOWN); + + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + rate_up = &table_node->rate_up[up_idx]; + + if (rate_up->rate_idx != WRS_INVALID_RATE) + rate_up->time_th = max(rate_up->time_th >> 1, WRS_INIT_MSEC_WEIGHT_UP); + + if (rate_up->time_th == WRS_INIT_MSEC_WEIGHT_UP) + rate_up->quick_up_check = false; + } +} + +static void cl_wrs_converge_weights(struct cl_wrs_params *wrs_params) +{ + /* + * Converge weights - divide the weights by 2 (except for the current rate), + * and reset PER counters (except for current rate, down rate, and down-down rate). + */ + u16 i; + u16 curr_idx = wrs_params->rate_idx; + u16 down_idx = wrs_params->table[curr_idx].rate_down.rate_idx; + u16 down2_idx = wrs_params->table[down_idx].rate_down.rate_idx; + + for (i = 0; i < wrs_params->table_size; i++) { + if (i == curr_idx) + continue; + + cl_wrs_divide_weights_by_two(&wrs_params->table[i]); + + if (i != down_idx && i != down2_idx) { + wrs_params->table[i].frames_total = 0; + wrs_params->table[i].ba_not_rcv_total = 0; + wrs_params->table[i].epr_acc = 0; + } + } +} + +static void cl_wrs_converge_weights_idle_decision(struct cl_hw *cl_hw, + struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + /* + * Continue normal converge (just like during traffic). + * After 6 seconds reset table, and select rate based on RSSI. + */ + if (!wrs_db->converge_idle_en) + return; + + wrs_params->converge_time_idle += wrs_db->interval; + + if (wrs_params->converge_mode == WRS_CONVERGE_MODE_RESET) { + if (wrs_params->converge_time_idle < wrs_db->converge_idle_interval_reset) { + cl_wrs_converge_weights(wrs_params); + } else { + wrs_params->converge_mode = WRS_CONVERGE_MODE_RSSI; + wrs_params->converge_time_idle = 0; + + wrs_pr_info(wrs_db, "[%s] Converge weights: sta %u - RSSI\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx); + + /* Reset table and choose new rate based on RSSI */ + cl_wrs_tables_reset(wrs_db, wrs_sta, wrs_params); + + if (!WRS_TYPE_IS_TX_MU_MIMO(wrs_params)) + cl_wrs_set_rate_idle(cl_hw, wrs_db, wrs_sta, wrs_params); + } + } else { + if (wrs_params->converge_time_idle < wrs_db->converge_idle_interval_rssi) + return; + + /* Choose new rate */ + if (!WRS_TYPE_IS_TX_MU_MIMO(wrs_params)) { + wrs_params->converge_time_idle = 0; + cl_wrs_set_rate_idle(cl_hw, wrs_db, wrs_sta, wrs_params); + } + } +} + +static void cl_wrs_converge_weights_idle_reset(struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + /* There was traffic in last maintenance interval - reset converge parameteres */ + wrs_params->converge_time_idle = 0; + + if (wrs_params->converge_mode != WRS_CONVERGE_MODE_RESET) { + wrs_params->converge_mode = WRS_CONVERGE_MODE_RESET; + wrs_pr_info(wrs_db, "[%s] Converge weights: sta %u - RESET\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx); + } +} + +static void cl_wrs_converge_weights_trfc_decision(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_db *wrs_db, + struct cl_wrs_params *wrs_params) +{ + u32 converge_interval = 0; + + if (!wrs_db->converge_trfc_en) + return; + + converge_interval = wrs_db->converge_trfc_interval_static; + + if (!cl_motion_sense_is_static(cl_hw, cl_sta)) + converge_interval = wrs_db->converge_trfc_interval_motion; + + wrs_params->converge_time_trfc += wrs_db->interval; + + if (wrs_params->converge_time_trfc >= converge_interval) { + wrs_params->converge_time_trfc = 0; + cl_wrs_converge_weights(wrs_params); + } +} + +static u32 cl_wrs_get_sync_attempts(struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_info *wrs_info = cl_wrs_info_get(cl_sta, wrs_params->type); + + return wrs_info->sync_attempts; +} + +static void cl_wrs_sta_no_sync_handler(struct cl_hw *cl_hw, + struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + unsigned long time_delta = jiffies_to_msecs(jiffies - wrs_params->no_sync_timestamp); + + if (time_delta < wrs_db->sync_timeout) + return; + + if (cl_wrs_get_sync_attempts(wrs_sta, wrs_params) < wrs_db->sync_min_attempts) { + /* + * Rate not synced but there is also hardly no traffic - + * change mode to synced! + */ + wrs_params->sync = true; + wrs_params->sync_timestamp = jiffies; + } else { + struct cl_wrs_table *wrs_table = &wrs_params->table[wrs_params->rate_idx]; + struct cl_wrs_rate *curr_rate = &wrs_table->rate; + + if (IS_REAL_PHY(cl_hw->chip)) + wrs_pr_warn(wrs_db, + "[%s] NO SYNC - sta = %u, bw = %u, nss = %u, mcs = %u, gi = %u\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx, curr_rate->bw, + curr_rate->nss, curr_rate->mcs, curr_rate->gi); + + if (WRS_IS_DECISION_UP(wrs_params->last_decision)) { + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN_NO_SYNC, + wrs_table->rate_down.rate_idx); + } else { + /* If the last decision was DOWN - change state to SYNCED. */ + wrs_params->sync = true; + wrs_params->sync_timestamp = jiffies; + } + } +} + +static void cl_wrs_update_ba_not_rcv(struct cl_wrs_db *wrs_db, struct cl_wrs_params *wrs_params) +{ + unsigned long time_since_sync = jiffies_to_msecs(jiffies - wrs_params->sync_timestamp); + + wrs_params->calc_ba_not_rcv = (wrs_db->ba_not_rcv_force || + (time_since_sync < wrs_db->ba_not_rcv_time_since_sync)); +} + +static void _cl_wrs_cntrs_reset(struct cl_wrs_info *wrs_info) +{ + wrs_info->epr_acc = 0; + wrs_info->success = 0; + wrs_info->fail = 0; + wrs_info->ba_not_rcv = 0; + wrs_info->ba_not_rcv_consecutive_max = 0; +} + +static void cl_wrs_cntrs_read(struct cl_wrs_sta *wrs_sta, + struct cl_wrs_cntrs *cntrs, + u8 type) +{ + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_info *wrs_info = cl_wrs_info_get(cl_sta, type); + + cntrs->epr_acc = wrs_info->epr_acc; + cntrs->total = wrs_info->success + wrs_info->fail; + cntrs->fail = wrs_info->fail; + cntrs->ba_not_rcv = wrs_info->ba_not_rcv; + cntrs->ba_not_rcv_consecutive = wrs_info->ba_not_rcv_consecutive_max; + + _cl_wrs_cntrs_reset(wrs_info); +} + +static void _cl_wrs_sta_maintenance(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + struct cl_wrs_cntrs cntrs = {0}; + + if (wrs_params->is_logger_en) + memset(&WRS_LOGGER, 0, sizeof(struct cl_wrs_logger)); + + if (!wrs_params->sync) { + cl_wrs_sta_no_sync_handler(cl_hw, wrs_db, wrs_sta, wrs_params); + goto end_logger; + } + + if (!WRS_TYPE_IS_RX(wrs_params)) + cl_wrs_update_ba_not_rcv(wrs_db, wrs_params); + + cl_wrs_cntrs_read(wrs_sta, &cntrs, wrs_params->type); + + if (wrs_params->is_fixed_rate) { + cl_wrs_stats_per_update(wrs_db, wrs_sta, wrs_params, &cntrs); + goto end_logger; + } + + wrs_params->down_time_cnt += wrs_db->interval; + wrs_params->up_same_time_cnt += wrs_db->interval; + + if ((cntrs.total + cntrs.ba_not_rcv) < wrs_db->converge_idle_packet_th) { + /* + * Very few frames were sent in last maintenance interval + * Check if weights should be converged + */ + cl_wrs_converge_weights_idle_decision(cl_hw, wrs_db, wrs_sta, wrs_params); + + cl_wrs_stats_per_update(wrs_db, wrs_sta, wrs_params, &cntrs); + + goto end_logger; + } else { + /* There was traffic in last maintenance interval - reset converge parameteres */ + cl_wrs_converge_weights_idle_reset(wrs_db, wrs_sta, wrs_params); + } + + cl_wrs_stats_per_update(wrs_db, wrs_sta, wrs_params, &cntrs); + + wrs_params->quick_up_check = + (cntrs.ba_not_rcv_consecutive >= wrs_db->quick_up_ba_thr); + cl_wrs_epr_decision(cl_hw, wrs_db, wrs_sta, wrs_params); + + cl_wrs_converge_weights_trfc_decision(cl_hw, cl_sta, wrs_db, wrs_params); + +end_logger: + if (wrs_params->is_logger_en && WRS_LOGGER.decision != WRS_DECISION_NONE) + wrs_params->logger_idx = WRS_INC_POW2(wrs_params->logger_idx, + wrs_params->logger_size); +} + +static void cl_wrs_sta_maintenance(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + _cl_wrs_sta_maintenance(cl_hw, cl_sta, &cl_sta->wrs_sta.tx_su_params); + + if (cl_sta->wrs_sta.rx_params) + _cl_wrs_sta_maintenance(cl_hw, cl_sta, cl_sta->wrs_sta.rx_params); +} + +static void cl_wrs_cca_calc(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, u8 max_bw) +{ + u32 cca_primary_new = mac_hw_edca_cca_busy_get(cl_hw); + u32 cca_sec80_new = (max_bw > CHNL_BW_80) ? mac_hw_add_cca_busy_sec_80_get(cl_hw) : 0; + u32 cca_sec40_new = (max_bw > CHNL_BW_40) ? mac_hw_add_cca_busy_sec_40_get(cl_hw) : 0; + u32 cca_sec20_new = mac_hw_add_cca_busy_sec_20_get(cl_hw); + + u32 cca_primary_diff = cca_primary_new - wrs_db->cca_primary; + u32 cca_sec80_diff = cca_sec80_new - wrs_db->cca_sec80; + u32 cca_sec40_diff = cca_sec40_new - wrs_db->cca_sec40; + u32 cca_sec20_diff = cca_sec20_new - wrs_db->cca_sec20; + + wrs_db->cca_primary = cca_primary_new; + wrs_db->cca_sec80 = cca_sec80_new; + wrs_db->cca_sec40 = cca_sec40_new; + wrs_db->cca_sec20 = cca_sec20_new; + wrs_db->cca_timestamp = jiffies; + + /* Increase by 25% */ + cca_primary_diff = cca_primary_diff * WRS_CCA_PRIMARY_FACTOR >> WRS_CCA_PRIMARY_SHIFT; + + /* Adjacent interference - if secondary is higher than primary by 25%. */ + wrs_db->adjacent_interference80 = (cca_sec80_diff > cca_primary_diff); + wrs_db->adjacent_interference40 = (cca_sec40_diff > cca_primary_diff); + wrs_db->adjacent_interference20 = (cca_sec20_diff > cca_primary_diff); +} + +static void cl_wrs_cca_maintenance(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db) +{ + u8 max_bw = wrs_db->max_cap.bw; + + if (max_bw == CHNL_BW_20) + return; + + if (jiffies_to_msecs(jiffies - wrs_db->cca_timestamp) > WRS_CCA_PERIOD_MS) + cl_wrs_cca_calc(cl_hw, wrs_db, max_bw); +} + +static void cl_wrs_maintenance(struct timer_list *t) +{ + struct cl_wrs_db *wrs_db = from_timer(wrs_db, t, timer_maintenance); + struct cl_hw *cl_hw = container_of(wrs_db, struct cl_hw, wrs_db); + + cl_wrs_cca_maintenance(cl_hw, wrs_db); + + cl_wrs_lock(wrs_db); + cl_sta_loop(cl_hw, cl_wrs_sta_maintenance); + cl_wrs_unlock(wrs_db); + + mod_timer(&wrs_db->timer_maintenance, jiffies + msecs_to_jiffies(wrs_db->interval)); +} + +static void cl_wrs_down_decision_weights_update(struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + u16 new_rate_idx, + struct cl_wrs_params *wrs_params) +{ + u16 old_rate_idx = wrs_params->rate_idx; + u8 up_idx = 0; + u16 down_th_min = wrs_db->time_th_min; + u16 step = wrs_db->step_down; + u16 *th_down = &wrs_params->table[old_rate_idx].rate_down.time_th; + u16 *th_up = NULL; + struct cl_wrs_table *table_node = &wrs_params->table[new_rate_idx]; + + /* Decrease the weight from old rate to new rate */ + if (*th_down > (down_th_min + step)) + *th_down -= step; + else + *th_down = down_th_min; + + /* Increase the weight from new rate to old rate */ + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + if (old_rate_idx == table_node->rate_up[up_idx].rate_idx) { + th_up = &table_node->rate_up[up_idx].time_th; + table_node->rate_up[up_idx].quick_up_check = !!wrs_params->quick_up_check; + step = wrs_params->penalty_decision_dn; + *th_up = min_t(u16, *th_up + step, wrs_db->time_th_max_up); + break; + } + } + + wrs_pr_info(wrs_db, + "[%s] Down update - sta = %u, " + "down weight [%u-->%u] = %u, up weight [%u-->%u] = %u\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx, old_rate_idx, new_rate_idx, + *th_down, new_rate_idx, old_rate_idx, th_up ? *th_up : 0); +} + +static void cl_wrs_up_same_decision_weights_update(struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + u16 curr_rate_idx = wrs_params->rate_idx; + u16 down_rate_idx = wrs_params->table[curr_rate_idx].rate_down.rate_idx; + u8 up_idx = 0; + u16 up_th_min = wrs_db->time_th_min; + u16 step = wrs_db->step_up_same; + u16 *th_down = &wrs_params->table[curr_rate_idx].rate_down.time_th; + u16 *th_up = NULL; + u16 th_down_orig = *th_down; + u16 th_up_orig = 0; + struct cl_wrs_table *table_node = &wrs_params->table[down_rate_idx]; + + /* Increase the weight from current rate to down rate */ + *th_down = min_t(u16, *th_down + step, wrs_db->time_th_max_down); + + /* Decrease the weight from down rate to current rate */ + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + if (curr_rate_idx == table_node->rate_up[up_idx].rate_idx) { + th_up = &table_node->rate_up[up_idx].time_th; + table_node->rate_up[up_idx].quick_up_check = false; + + th_up_orig = *th_up; + + if (*th_up > (up_th_min + step)) + *th_up -= step; + else + *th_up = up_th_min; + break; + } + } + + if (th_up && (th_up_orig != *th_up || th_down_orig != *th_down)) + wrs_pr_info(wrs_db, + "[%s] Up/same update - sta = %u, " + "down weight [%u-->%u] = %u, up weight [%u-->%u] = %u\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx, curr_rate_idx, + down_rate_idx, *th_down, down_rate_idx, curr_rate_idx, *th_up); +} + +static bool cl_wrs_is_rate_params_valid(struct cl_wrs_rate *rate_params) +{ + return (*(u16 *)rate_params != U16_MAX); +} + +void cl_wrs_init(struct cl_hw *cl_hw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + /* Default configuration */ + wrs_db->debug_level = DBG_LVL_ERROR; + wrs_db->rssi_protect_en = true; + wrs_db->rssi_protect_mode = WRS_RSSI_PROT_MODE_RSSI; + wrs_db->rssi_protect_up_thr = WRS_RSSI_PROTECT_UP_THR; + wrs_db->rssi_protect_dn_thr = WRS_RSSI_PROTECT_DN_THR; + wrs_db->min_frames_for_decision = WRS_MIN_FRAMES_FOR_DECISION; + wrs_db->epr_factor = WRS_EPR_FACTOR; + wrs_db->converge_idle_en = true; + wrs_db->converge_idle_interval_reset = WRS_CONVERGE_IDLE_INTERVAL_RESET; + wrs_db->converge_idle_interval_rssi = WRS_CONVERGE_IDLE_INTERVAL_RSSI; + wrs_db->converge_idle_packet_th = WRS_CONVERGE_IDLE_PACKET_TH; + wrs_db->converge_trfc_en = true; + wrs_db->converge_trfc_interval_static = WRS_CONVERGE_TRFC_INTERVAL_STATIC; + wrs_db->converge_trfc_interval_motion = WRS_CONVERGE_TRFC_INTERVAL_MOTION; + wrs_db->immediate_drop_en = true; + wrs_db->immediate_drop_epr_factor = WRS_IMMEDIATE_DROP_EPR_FACTOR; + wrs_db->immediate_drop_max_in_row = WRS_IMMEDIATE_DROP_MAX_IN_ROW; + wrs_db->time_th_min = WRS_MSEC_WEIGHT_MIN; + wrs_db->time_th_max_up = WRS_MSEC_WEIGHT_MAX_UP; + wrs_db->time_th_max_down = WRS_MSEC_WEIGHT_MAX_DOWN; + wrs_db->step_down = WRS_MSEC_STEP_DOWN; + wrs_db->step_up_same = WRS_MSEC_STEP_UP_SAME; + wrs_db->interval = msecs_round(WRS_MAINTENANCE_PERIOD_MS); + wrs_db->conservative_mcs_noisy_env = false; + wrs_db->conservative_nss_noisy_env = false; + wrs_db->quick_up_en = true; + wrs_db->quick_up_ba_thr = WRS_QUICK_UP_BA_THR; + wrs_db->quick_up_interval = msecs_round(WRS_QUICK_UP_INTERVAL_MS); + wrs_db->quick_down_en = true; + wrs_db->quick_down_epr_factor = WRS_QUICK_DOWN_EPR_FACTOR; + wrs_db->quick_down_agg_thr = WRS_QUICK_DOWN_AGG_THR; + wrs_db->quick_down_pkt_thr = WRS_QUICK_DOWN_PKT_THR; + wrs_db->ba_not_rcv_collision_filter = true; + /* Environment of 2.4 is much more noisy, so 'BA not received' are ignored. */ + wrs_db->ba_not_rcv_force = cl_band_is_24g(cl_hw) ? false : true; + wrs_db->ba_not_rcv_time_since_sync = WRS_BA_NOT_RCV_TIME_SINCE_SYNC; + wrs_db->sync_timeout = WRS_SYNC_TIMEOUT; + wrs_db->sync_min_attempts = WRS_SYNC_MIN_ATTEMPTS; + + /* Init WRS periodic timer */ + timer_setup(&wrs_db->timer_maintenance, cl_wrs_maintenance, 0); + + if (!cl_hw->chip->conf->ce_production_mode) { + wrs_db->cca_timestamp = jiffies; + mod_timer(&wrs_db->timer_maintenance, + jiffies + msecs_to_jiffies(wrs_db->interval)); + } + + spin_lock_init(&wrs_db->lock); + + if ((cl_hw->conf->ci_wrs_fixed_rate[WRS_FIXED_PARAM_MODE] != -1) && + (cl_hw->conf->ci_wrs_fixed_rate[WRS_FIXED_PARAM_BW] != -1) && + (cl_hw->conf->ci_wrs_fixed_rate[WRS_FIXED_PARAM_NSS] != -1) && + (cl_hw->conf->ci_wrs_fixed_rate[WRS_FIXED_PARAM_MCS] != -1) && + (cl_hw->conf->ci_wrs_fixed_rate[WRS_FIXED_PARAM_GI] != -1)) + wrs_db->is_fixed_rate = WRS_FIXED_FALLBACK_DIS; +} + +inline void cl_wrs_lock_bh(struct cl_wrs_db *wrs_db) +{ + spin_lock_bh(&wrs_db->lock); +} + +inline void cl_wrs_unlock_bh(struct cl_wrs_db *wrs_db) +{ + spin_unlock_bh(&wrs_db->lock); +} + +inline void cl_wrs_lock(struct cl_wrs_db *wrs_db) +{ + spin_lock(&wrs_db->lock); +} + +inline void cl_wrs_unlock(struct cl_wrs_db *wrs_db) +{ + spin_unlock(&wrs_db->lock); +} + +void cl_wrs_rate_param_sync(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + if (wrs_params->sync) + return; + + cl_wrs_cntrs_reset(wrs_sta, wrs_params); + + /* Reset counters */ + cl_wrs_reset_params_cntrs(wrs_params); + + /* Change state to SYNCED */ + wrs_params->sync = true; + wrs_params->sync_timestamp = jiffies; + + wrs_pr_trace(wrs_db, "[%s] Sync - timestamp = %u, sta = %u, rate_idx = %u\n", + WRS_TYPE_STR(wrs_params->type), + jiffies_to_msecs(jiffies), + wrs_sta->sta_idx, + wrs_params->rate_idx); +} + +void cl_wrs_rate_params_update(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u16 new_rate_idx, bool is_sync_required, bool mu_valid) +{ + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + struct cl_wrs_rate *rate = &wrs_params->table[new_rate_idx].rate; + u16 fallback_rate_idx = wrs_params->table[new_rate_idx].rate_down.rate_idx; + struct cl_wrs_rate *rate_fallback = &wrs_params->table[fallback_rate_idx].rate; +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + + if (!WRS_TYPE_IS_RX(wrs_params)) { + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + + cl_dyn_bcast_rate_change(cl_hw, cl_sta, rate_params->mcs, rate->mcs); + } +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + + rate_params->bw = rate->bw; + rate_params->nss = rate->nss; + rate_params->mcs = rate->mcs; + rate_params->gi = rate->gi; + rate_params->mode = wrs_sta->mode; + rate_params->fallback_en = (wrs_params->is_fixed_rate != WRS_FIXED_FALLBACK_DIS); + + wrs_pr_trace(wrs_db, + "[%s] Rate params update - " + "sta = %u, rate_idx = %u, bw = %u, nss = %u, mcs = %u, gi = %u\n", + WRS_TYPE_STR(wrs_params->type), wrs_sta->sta_idx, + new_rate_idx, rate_params->bw, rate_params->nss, + rate_params->mcs, rate_params->gi); + + wrs_params->rate_idx = new_rate_idx; + + /* Converge - restart the time for converging weights of all old rates */ + wrs_params->converge_time_trfc = 0; + + cl_wrs_rate_param_set(cl_hw, wrs_sta, wrs_params, rate_params, + rate_fallback, mu_valid, true); + + if (is_sync_required) { + wrs_params->sync = false; + wrs_params->no_sync_timestamp = jiffies; + } else { + wrs_params->sync = true; + } + + /* Reset Counters */ + cl_wrs_reset_params_cntrs(wrs_params); +} + +void cl_wrs_decision_make(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + enum cl_wrs_decision decision, u16 new_rate_idx) +{ + if (WRS_IS_DECISION_DOWN(decision)) { + cl_wrs_down_decision_weights_update(wrs_db, wrs_sta, new_rate_idx, wrs_params); + } else if (WRS_IS_DECISION_UP(decision)) { + cl_wrs_up_same_decision_weights_update(wrs_db, wrs_sta, wrs_params); + + if (wrs_params->rate_idx != wrs_params->table[new_rate_idx].rate_down.rate_idx) { + /* + * In case the down rate is different from the previous rate, + * update down rate index and reset the thresholds + */ + struct cl_wrs_table_node *rate_down = + &wrs_params->table[new_rate_idx].rate_down; + + rate_down->rate_idx = wrs_params->rate_idx; + rate_down->time_th = WRS_INIT_MSEC_WEIGHT_DOWN; + } + } else if (decision == WRS_DECISION_SAME) { + cl_wrs_up_same_decision_weights_update(wrs_db, wrs_sta, wrs_params); + + /* Reset counters besides down_time_cnt */ + wrs_params->frames_total = 0; + wrs_params->fail_total = 0; + wrs_params->ba_not_rcv_total = 0; + wrs_params->epr_acc = 0; + wrs_params->up_same_time_cnt = 0; + } + + cl_wrs_decision_update(wrs_db, wrs_sta, wrs_params, decision, new_rate_idx); + + if (WRS_IS_DECISION_DOWN(decision) || WRS_IS_DECISION_UP(decision)) + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, wrs_params, + new_rate_idx, true, wrs_params->is_mu_valid); +} + +void cl_wrs_decision_update(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, enum cl_wrs_decision decision, + u16 new_rate_idx) +{ + wrs_params->last_decision = decision; + wrs_params->decision_cnt[decision]++; + + if (decision != WRS_DECISION_DOWN_IMMEDIATE) + wrs_params->immediate_drop_cntr = 0; + + if (wrs_params->is_logger_en) { + WRS_LOGGER.decision = decision; + WRS_LOGGER.new_rate_idx = new_rate_idx; + } + + if (decision == WRS_DECISION_SAME) + return; + + wrs_pr_trace(wrs_db, + "[%s] Decision update - timestamp [%u] sta [%u] decision [%s]\n", + WRS_TYPE_STR(wrs_params->type), + jiffies_to_msecs(jiffies), + wrs_sta->sta_idx, + WRS_DECISION_STR(decision)); +} + +void cl_wrs_fixed_rate_set(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u8 is_fixed_rate, u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi, bool mu_valid) +{ + u16 rate_idx = 0; + u8 type = wrs_params->type; + + if (!is_fixed_rate) { + wrs_params->is_fixed_rate = WRS_AUTO_RATE; + wrs_pr_verbose(wrs_db, "[%s] Station %u was set to auto rate!\n", + WRS_TYPE_STR(type), wrs_sta->sta_idx); + cl_wrs_set_rate_idle(cl_hw, wrs_db, wrs_sta, wrs_params); + return; + } + + if (mode != wrs_sta->mode) { + /* Set fixed rate with a different format-mode */ + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + + if (cl_band_is_6g(cl_hw) && mode != WRS_MODE_HE) { + wrs_pr_verbose(wrs_db, "[%s] Invalid format mode [%u] for 6GHz band\n", + WRS_TYPE_STR(type), mode); + return; + } +#ifdef CONFIG_CL8K_DYN_BCAST_RATE + + if (!WRS_TYPE_IS_RX(wrs_params)) { + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + + cl_dyn_bcast_rate_change(cl_hw, cl_sta, rate_params->mcs, mcs); + } +#endif /* CONFIG_CL8K_DYN_BCAST_RATE */ + + rate_params->bw = bw; + rate_params->nss = nss; + rate_params->mcs = mcs; + rate_params->gi = gi; + rate_params->mode = mode; + rate_params->fallback_en = (wrs_params->is_fixed_rate != WRS_FIXED_FALLBACK_DIS); + + wrs_params->is_fixed_rate = is_fixed_rate; + + cl_wrs_rate_param_set(cl_hw, wrs_sta, wrs_params, rate_params, + NULL, mu_valid, true); + wrs_pr_verbose(wrs_db, + "[%s] Station %u set to %s - " + "mode=%u, bw=%u, nss=%u, mcs=%u, gi=%u\n", + WRS_TYPE_STR(type), wrs_sta->sta_idx, FIXED_RATE_STR(is_fixed_rate), + mode, bw, nss, mcs, gi); + return; + } + + rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, bw, nss, mcs, gi); + + if (rate_idx == WRS_INVALID_RATE) { + wrs_pr_err(wrs_db, + "[%s] Invalid fixed rate - mode=%u, bw=%u, nss=%u, mcs=%u, gi=%u\n", + WRS_TYPE_STR(type), mode, bw, nss, mcs, gi); + return; + } + + wrs_params->is_fixed_rate = is_fixed_rate; + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, wrs_params, rate_idx, false, false); + wrs_pr_verbose(wrs_db, + "[%s] Station %u set to %s - mode=%u, bw=%u, nss=%u, mcs=%u, gi=%u\n", + WRS_TYPE_STR(type), wrs_sta->sta_idx, FIXED_RATE_STR(is_fixed_rate), + mode, bw, nss, mcs, gi); +} + +void cl_wrs_quick_down_check(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_cntrs cntrs = {0}; + struct cl_wrs_table *table = NULL; + u16 curr_rate_idx = 0; + u16 down_rate_idx = 0; + u8 type = wrs_params->type; + + if (!wrs_params->sync || + wrs_params->is_fixed_rate || + !WRS_IS_DECISION_UP(wrs_params->last_decision)) + return; + + if (!WRS_TYPE_IS_RX(wrs_params)) + cl_wrs_update_ba_not_rcv(wrs_db, wrs_params); + + cl_wrs_cntrs_read(wrs_sta, &cntrs, type); + cl_wrs_stats_per_update(wrs_db, wrs_sta, wrs_params, &cntrs); + + curr_rate_idx = wrs_params->rate_idx; + table = &wrs_params->table[curr_rate_idx]; + down_rate_idx = table->rate_down.rate_idx; + + /* Check if we transmitted enough frames for taking decision */ + if (wrs_params->frames_total < wrs_db->min_frames_for_decision) + return; + + if (wrs_params->is_logger_en) { + memset(&WRS_LOGGER, 0, sizeof(struct cl_wrs_logger)); + WRS_LOGGER.timestamp = jiffies_to_msecs(jiffies); + WRS_LOGGER.rate_idx = curr_rate_idx; + WRS_LOGGER.success = wrs_params->frames_total - wrs_params->fail_total; + WRS_LOGGER.fail = wrs_params->fail_total; + WRS_LOGGER.ba_not_rcv = wrs_params->ba_not_rcv_total; + } + + /* Down decision check */ + if (down_rate_idx != curr_rate_idx && + cl_wrs_down_epr_check(wrs_db, wrs_sta, wrs_params, + wrs_db->quick_down_epr_factor, WRS_DECISION_DOWN_QUICK)) + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN_QUICK, down_rate_idx); + + if (wrs_params->is_logger_en && WRS_LOGGER.decision != WRS_DECISION_NONE) + wrs_params->logger_idx = WRS_INC_POW2(wrs_params->logger_idx, + wrs_params->logger_size); +} + +bool cl_wrs_up_mcs1(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + /* + * In case of big packets (4300 in VHT and 5400 in HE) and low + * rate (BW 20, NSS 1, MCS 0), firmware will increase rate to MCS 1, + * and give an indication to driver (set rate_fix_mcs1 in cl_agg_tx_report). + * WRS should also move to MCS 1, and give the maximum time + * penalty time from MCS 0 toMCS 1. + */ + u16 curr_rate_idx = wrs_params->rate_idx; + u16 up_rate_idx = 0; + struct cl_wrs_table *table = &wrs_params->table[curr_rate_idx]; + + if (!table || wrs_params->is_fixed_rate) + return false; + + if (table->rate.bw != CHNL_BW_20 || + table->rate.nss != WRS_SS_1 || + table->rate.mcs != WRS_MCS_0) + return false; + + up_rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, + CHNL_BW_20, WRS_SS_1, WRS_MCS_1, table->rate.gi); + + if (up_rate_idx == WRS_INVALID_RATE) + return false; + + if (wrs_params->is_logger_en) { + memset(&WRS_LOGGER, 0, sizeof(struct cl_wrs_logger)); + WRS_LOGGER.timestamp = jiffies_to_msecs(jiffies); + WRS_LOGGER.rate_idx = curr_rate_idx; + } + + wrs_params->table[up_rate_idx].rate_down.time_th = wrs_db->time_th_max_up; + + cl_wrs_cntrs_reset(wrs_sta, wrs_params); + cl_wrs_decision_update(wrs_db, wrs_sta, wrs_params, WRS_DECISION_UP_MCS1, up_rate_idx); + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, wrs_params, + up_rate_idx, true, wrs_params->is_mu_valid); + + if (wrs_params->is_logger_en) + wrs_params->logger_idx = WRS_INC_POW2(wrs_params->logger_idx, + wrs_params->logger_size); + + return true; +} + +void cl_wrs_rate_param_set(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + struct cl_wrs_rate_params *rate_params, + struct cl_wrs_rate *rate_fallback, + bool mu_mimo_valid, bool set_su) +{ + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_info *wrs_info = NULL; + u8 op_mode = 0; + u8 ltf = 0; + u8 ltf_fallback = 0; + u8 sta_idx = cl_sta->sta_idx; + union cl_rate_ctrl_info rate_ctrl; + union cl_rate_ctrl_info rate_ctrl_fallback; + union cl_rate_ctrl_info_he rate_ctrl_he; + + rate_ctrl_he.word = 0; + wrs_info = cl_wrs_info_get(cl_sta, wrs_params->type); + + wrs_params->data_rate = cl_data_rates_get(rate_params->mode, + rate_params->bw, + rate_params->nss, + rate_params->mcs, + rate_params->gi); + + /* + * Trying to transmit MU-MIMO in bw < bw of sounding (which is STA's max bw) will fail, + * So we prevent it from being transmitted with MU. + */ + if (rate_params->bw != cl_sta->sta->bandwidth) + mu_mimo_valid = false; + + rate_ctrl.word = cl_rate_ctrl_generate(cl_hw, cl_sta, rate_params->mode, + rate_params->bw, rate_params->nss, + rate_params->mcs, rate_params->gi, + rate_params->fallback_en, mu_mimo_valid); + + /* For fallback rate use same mode (if it is NULL use same rate). */ + if (rate_fallback) { + rate_ctrl_fallback.word = cl_rate_ctrl_generate(cl_hw, + cl_sta, + rate_params->mode, + rate_fallback->bw, + rate_fallback->nss, + rate_fallback->mcs, + rate_fallback->gi, + rate_params->fallback_en, + mu_mimo_valid); + ltf_fallback = cl_map_gi_to_ltf(rate_params->mode, rate_fallback->gi); + } else { + rate_ctrl_fallback.word = rate_ctrl.word; + } + + /* Save current BF state and SS for the fallback rate */ + if (WRS_TYPE_IS_TX_SU(wrs_params)) { + struct cl_bf_sta_db *bf_db = &cl_sta->bf_db; + + bf_db->is_on = rate_ctrl.field.tx_bf; + bf_db->is_on_fallback = rate_ctrl_fallback.field.tx_bf; + bf_db->num_ss = rate_params->nss; + bf_db->num_ss_fallback = rate_fallback ? rate_fallback->nss : rate_params->nss; + } + + /* Reset counters */ + wrs_info->success = 0; + wrs_info->fail = 0; + + /* Mark rate as unsynced */ + wrs_info->synced = false; + wrs_info->quick_rate_check = false; + wrs_info->sync_attempts = 0; + ltf = cl_map_gi_to_ltf(rate_params->mode, rate_params->gi); + + if (rate_params->mode == WRS_MODE_HE) + rate_ctrl_he.field.spatial_conf = RATE_CNTRL_HE_SPATIAL_CONF_DEF; + + /* Send new rate to firmware */ + if (set_su) { + if (WRS_TYPE_IS_TX_SU(wrs_params)) { + op_mode = RATE_OP_MODE_STA_SU; + cl_msg_tx_update_rate_dl(cl_hw, sta_idx, rate_ctrl.word, + rate_ctrl_fallback.word, rate_params->bw, + op_mode, wrs_params->group_id, mu_mimo_valid, + ltf, ltf_fallback, rate_ctrl_he.word); + } else if (WRS_TYPE_IS_RX(wrs_params)) { + u8 ul_gi_ltf = CL_TF_GI_TO_GI_LTF(rate_params->gi); + + cl_msg_tx_update_rate_ul(cl_hw, sta_idx, rate_params->bw, + rate_params->nss, rate_params->mcs, ul_gi_ltf); + } + } +} + +s8 cl_wrs_rssi_eq_calc(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + bool read_clear, s8 *sorted_rssi) +{ + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_rssi *wrs_rssi = &cl_sta->wrs_rssi; + int i; + + if (wrs_rssi->cnt == 0) { + memcpy(sorted_rssi, cl_sta->last_rssi, cl_hw->num_antennas); + goto sort; + } + + for (i = 0; i < cl_hw->num_antennas; i++) + sorted_rssi[i] = (s8)(wrs_rssi->sum[i] / wrs_rssi->cnt); + + if (read_clear) + memset(wrs_rssi, 0, sizeof(struct cl_wrs_rssi)); + +sort: + /* Sort RSSI values in descending order */ + cl_rssi_sort_descending(sorted_rssi, cl_hw->num_antennas); + + /* Calc equivalent RSSI */ + return cl_rssi_calc_equivalent(cl_hw, sorted_rssi); +} + +void cl_wrs_cntrs_reset(struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_info *wrs_info = cl_wrs_info_get(cl_sta, wrs_params->type); + + _cl_wrs_cntrs_reset(wrs_info); +} + +struct cl_wrs_info *cl_wrs_info_get(struct cl_sta *cl_sta, u8 type) +{ + if (type == WRS_TYPE_TX_SU) + return &cl_sta->wrs_info_tx_su; + else if (type == WRS_TYPE_RX) + return &cl_sta->wrs_info_rx; + + return NULL; +} + +struct cl_wrs_params *cl_wrs_params_get(struct cl_wrs_sta *wrs_sta, u8 type) +{ + if (type == WRS_TYPE_TX_SU) + return &wrs_sta->tx_su_params; + else if (type == WRS_TYPE_RX) + return wrs_sta->rx_params; + + return NULL; +} + +void cl_wrs_update_rx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct hw_rxhdr *rxhdr) +{ + struct cl_wrs_rate *rate_params = NULL; + + if (!cl_sta || + !cl_sta->wrs_sta.rx_params || + rxhdr->format_mod == FORMATMOD_HE_TRIG) + return; + + rate_params = &cl_sta->wrs_sta.rx_params->rx_rate_idle; + + rate_params->bw = rxhdr->ch_bw; + rate_params->nss = rxhdr->n_sts; + rate_params->mcs = rxhdr->mcs; + rate_params->gi = rxhdr->gi_type; +} + +bool cl_wrs_set_rate_idle(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_rate *rx_rate_idle = &wrs_params->rx_rate_idle; + s8 rssi_sort[MAX_ANTENNAS] = {0}; + u16 new_rate_idx = 0; + u8 decision; + + if (WRS_TYPE_IS_RX(wrs_params) && + cl_wrs_is_rate_params_valid(rx_rate_idle)) { + decision = WRS_DECISION_RX_RATE; + if (wrs_params->initial_rate_idx != WRS_INVALID_RATE) + new_rate_idx = wrs_params->initial_rate_idx; + else + /* Get rate from last data packet */ + new_rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, + rx_rate_idle->bw, + rx_rate_idle->nss, + rx_rate_idle->mcs, + rx_rate_idle->gi); + + cl_wrs_rx_rate_idle_reset(wrs_params); + } else { + /* Get rate from rssi */ + cl_wrs_rssi_eq_calc(cl_hw, wrs_sta, true, rssi_sort); + new_rate_idx = cl_wrs_rssi_find_rate(cl_hw, wrs_db, wrs_sta, wrs_params, rssi_sort); + decision = WRS_DECISION_RSSI_MGMT; + } + + if (new_rate_idx != wrs_params->rate_idx) { + if (wrs_params->is_logger_en) { + memset(&WRS_LOGGER, 0, sizeof(struct cl_wrs_logger)); + WRS_LOGGER.timestamp = jiffies_to_msecs(jiffies); + WRS_LOGGER.rate_idx = wrs_params->rate_idx; + } + + cl_wrs_decision_update(wrs_db, wrs_sta, wrs_params, decision, new_rate_idx); + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, wrs_params, + new_rate_idx, false, false); + } else { + wrs_params->sync = true; + } + + return true; +} + +struct cl_wrs_rate_params *cl_wrs_rx_rate_get(struct cl_sta *cl_sta) +{ + struct cl_wrs_params *rx_params = cl_sta->wrs_sta.rx_params; + + if (rx_params) + return &rx_params->rate_params; + + return NULL; +} + +void cl_wrs_rx_rate_idle_reset(struct cl_wrs_params *rx_params) +{ + struct cl_wrs_rate *rate_idle = &rx_params->rx_rate_idle; + + *(u16 *)rate_idle = U16_MAX; +} + +static void cl_wrs_ap_set_bitmap(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db) +{ + u8 mcs, bw, nss, rate_idx; + + memset(wrs_db->ap_supported_rates, 0, sizeof(wrs_db->ap_supported_rates)); + + for (bw = cl_hw->conf->ci_wrs_min_bw; bw <= wrs_db->max_cap.bw; bw++) + for (nss = 0; nss <= wrs_db->max_cap.nss; nss++) + for (mcs = 0; mcs <= wrs_db->max_cap.mcs; mcs++) { + rate_idx = mcs + (nss * WRS_MCS_MAX); + wrs_db->ap_supported_rates[bw] |= BIT(rate_idx); + } +} + +void cl_wrs_ap_capab_set(struct cl_hw *cl_hw, + u8 bw, + u8 use_sgi) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_rate *max_cap = &wrs_db->max_cap; + u8 conf_nss = cl_hw->conf->ce_tx_nss - 1; + + switch (cl_hw->wireless_mode) { + case WIRELESS_MODE_HE: + case WIRELESS_MODE_HT_VHT_HE: + wrs_db->mode = WRS_MODE_HE; + max_cap->bw = bw; + max_cap->nss = conf_nss; + max_cap->mcs = WRS_MCS_11; + max_cap->gi = use_sgi ? WRS_GI_VSHORT : 0; + break; + case WIRELESS_MODE_HT_VHT: + wrs_db->mode = WRS_MODE_VHT; + max_cap->bw = bw; + max_cap->nss = conf_nss; + max_cap->mcs = WRS_MCS_9; + max_cap->gi = use_sgi ? WRS_GI_SHORT : 0; + break; + case WIRELESS_MODE_HT: + wrs_db->mode = WRS_MODE_HT; + max_cap->bw = min_t(u8, bw, CHNL_BW_80); + max_cap->nss = conf_nss; + max_cap->mcs = WRS_MCS_7; + max_cap->gi = use_sgi ? WRS_GI_SHORT : 0; + break; + case WIRELESS_MODE_LEGACY: + default: + if (cl_hw->hw_mode == HW_MODE_B) { + wrs_db->mode = WRS_MODE_CCK; + max_cap->mcs = WRS_MCS_3; + } else { + wrs_db->mode = WRS_MODE_OFDM; + max_cap->mcs = WRS_MCS_7; + } + + max_cap->bw = CHNL_BW_20; + max_cap->nss = 0; + max_cap->gi = 0; + break; + } + + if (cl_hw->conf->ci_wrs_max_bw < max_cap->bw) { + max_cap->bw = cl_hw->conf->ci_wrs_max_bw; + wrs_pr_warn(wrs_db, "Max BW limited to %uMHz\n", BW_TO_MHZ(max_cap->bw)); + } + + wrs_db->coex_bw = max_t(u8, max_cap->bw, CHNL_BW_40); + + cl_wrs_ap_set_bitmap(cl_hw, wrs_db); +} + +void cl_wrs_ap_capab_modify_bw(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, u8 max_bw) +{ + wrs_db->max_cap.bw = max_bw; + + cl_wrs_ap_set_bitmap(cl_hw, wrs_db); +} + +void cl_wrs_ap_capab_modify_gi(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, u8 use_sgi) +{ + switch (cl_hw->wireless_mode) { + case WIRELESS_MODE_HE: + case WIRELESS_MODE_HT_VHT_HE: + wrs_db->max_cap.gi = use_sgi ? WRS_GI_VSHORT : 0; + break; + case WIRELESS_MODE_HT: + case WIRELESS_MODE_HT_VHT: + wrs_db->max_cap.gi = use_sgi ? WRS_GI_SHORT : 0; + break; + default: + wrs_db->max_cap.gi = 0; + } + + cl_wrs_ap_set_bitmap(cl_hw, wrs_db); +} + +void cl_wrs_api_init(struct cl_hw *cl_hw) +{ + cl_wrs_init(cl_hw); + cl_wrs_ap_capab_set(cl_hw, cl_hw->conf->ci_cap_bandwidth, + cl_hw->conf->ci_short_guard_interval); +} + +void cl_wrs_api_close(struct cl_hw *cl_hw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + del_timer_sync(&wrs_db->timer_maintenance); +} + +void cl_wrs_api_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock_bh(wrs_db); + cl_wrs_sta_add(cl_hw, sta); + + if (sta->he_cap.has_he && cl_hw->conf->ce_wrs_rx_en) + cl_wrs_sta_add_rx(cl_hw, sta); + + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock_bh(wrs_db); + cl_wrs_sta_remove(cl_hw, wrs_db, cl_sta); + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_bss_set_bw(struct cl_hw *cl_hw, u8 bw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock_bh(wrs_db); + cl_wrs_ap_capab_modify_bw(cl_hw, wrs_db, bw); + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_bss_set_sgi(struct cl_hw *cl_hw, u8 use_sgi) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock_bh(wrs_db); + cl_wrs_ap_capab_modify_gi(cl_hw, wrs_db, use_sgi); + cl_wrs_unlock_bh(wrs_db); +} + +bool cl_wrs_api_bss_is_sgi_en(struct cl_hw *cl_hw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + bool ret = false; + + cl_wrs_lock_bh(wrs_db); + ret = wrs_db->max_cap.gi != 0; + cl_wrs_unlock_bh(wrs_db); + + return ret; +} + +void cl_wrs_api_bss_capab_update(struct cl_hw *cl_hw, u8 bw, u8 use_sgi) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock_bh(wrs_db); + cl_wrs_ap_capab_set(cl_hw, bw, use_sgi); + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_nss_or_bw_changed(struct cl_hw *cl_hw, struct ieee80211_sta *sta, u8 nss, u8 bw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + + cl_wrs_lock_bh(wrs_db); + + wrs_sta->max_rate_cap.nss = nss; + wrs_sta->max_rate_cap.bw = bw; + cl_wrs_sta_capabilities_set(wrs_db, sta); + cl_wrs_tables_build(cl_hw, wrs_sta, &wrs_sta->tx_su_params); + + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_he_minrate_changed(struct cl_sta *cl_sta, u8 he_minrate) +{ + struct cl_hw *cl_hw = cl_sta->cl_vif->cl_hw; + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u8 mcs = 0, nss = 0, bw = 0; + u16 data_rate_x10 = 0; + + cl_wrs_lock_bh(wrs_db); + + wrs_sta->he_minrate = he_minrate; + cl_wrs_tables_build(cl_hw, wrs_sta, &wrs_sta->tx_su_params); + + cl_wrs_unlock_bh(wrs_db); + + for (bw = 0; bw < wrs_sta->max_rate_cap.bw; bw++) { + for (nss = 0; nss < wrs_sta->max_rate_cap.nss; nss++) { + for (mcs = 0; mcs < wrs_sta->max_rate_cap.mcs; mcs++) { + data_rate_x10 = cl_data_rates_get_x10(WRS_MODE_HE, bw, + nss, mcs, + WRS_GI_LONG); + if (data_rate_x10 >= (he_minrate * 10)) { + cl_rate_ctrl_set_default_per_he_minrate(cl_hw, bw, + nss, mcs, + WRS_GI_LONG); + return; + } + } + } + } +} + +static void _cl_wrs_api_recovery(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + u16 fallback_rate_idx = wrs_params->table[wrs_params->rate_idx].rate_down.rate_idx; + struct cl_wrs_rate *rate_fallback = &wrs_params->table[fallback_rate_idx].rate; + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + bool is_mu_valid = wrs_params->is_mu_valid; + + cl_wrs_rate_param_set(cl_hw, wrs_sta, wrs_params, rate_params, + rate_fallback, is_mu_valid, true); +} + +void cl_wrs_api_recovery(struct cl_hw *cl_hw) +{ + struct cl_sta *cl_sta = NULL; + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_sta *wrs_sta = NULL; + + cl_wrs_lock_bh(wrs_db); + cl_sta_lock(cl_hw); + + list_for_each_entry(cl_sta, &cl_hw->cl_sta_db.head, list) { + wrs_sta = &cl_sta->wrs_sta; + + _cl_wrs_api_recovery(cl_hw, wrs_sta, &wrs_sta->tx_su_params); + + if (wrs_sta->rx_params) + _cl_wrs_api_recovery(cl_hw, wrs_sta, wrs_sta->rx_params); + } + + cl_sta_unlock(cl_hw); + cl_wrs_unlock_bh(wrs_db); +} + +void cl_wrs_api_beamforming_sync(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_params *wrs_params = &cl_sta->wrs_sta.tx_su_params; + u8 up_idx = 0; + u16 rate_idx = wrs_params->rate_idx; + + cl_wrs_lock(wrs_db); + + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) + wrs_params->table[rate_idx].rate_up[up_idx].time_th = WRS_INIT_MSEC_WEIGHT_UP; + + cl_wrs_unlock(wrs_db); + + wrs_pr_info(wrs_db, "[%s] sta %u - beamforming sync\n", + WRS_TYPE_STR(wrs_params->type), cl_sta->sta_idx); +} + +void cl_wrs_api_quick_down_check(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock(wrs_db); + cl_wrs_quick_down_check(cl_hw, wrs_db, &cl_sta->wrs_sta, wrs_params); + cl_wrs_unlock(wrs_db); +} + +void cl_wrs_api_rate_sync(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + cl_wrs_lock(wrs_db); + cl_wrs_rate_param_sync(wrs_db, &cl_sta->wrs_sta, wrs_params); + cl_wrs_unlock(wrs_db); +} + +bool cl_wrs_api_up_mcs1(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + bool result = false; + + cl_wrs_lock(wrs_db); + result = cl_wrs_up_mcs1(cl_hw, wrs_db, &cl_sta->wrs_sta, wrs_params); + cl_wrs_unlock(wrs_db); + + return result; +} + +void cl_wrs_api_set_smps_mode(struct cl_hw *cl_hw, struct ieee80211_sta *sta, const u8 bw) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u8 min_bw; + + if (sta->smps_mode == IEEE80211_SMPS_STATIC || + sta->smps_mode == IEEE80211_SMPS_DYNAMIC) { + /* If RTS is enabled, there is no need to go down to 1ss */ + if (cl_prot_mode_get(cl_hw) == TXL_PROT_RTS_FW) + return; + + wrs_sta->smps_enable = true; + } else if (sta->smps_mode == IEEE80211_SMPS_OFF && wrs_sta->smps_enable) { + wrs_sta->smps_enable = false; + } + + cl_wrs_lock_bh(wrs_db); + min_bw = min_t(u8, bw, wrs_db->max_cap.bw); + + if (wrs_sta->max_rate_cap.bw != min_bw) { + wrs_sta->max_rate_cap.bw = min_bw; + wrs_pr_trace(wrs_db, "[TX_SU] SMPS mode: sta %u, bw %u\n", + wrs_sta->sta_idx, min_bw); + cl_wrs_tables_build(cl_hw, wrs_sta, &wrs_sta->tx_su_params); + } + + cl_wrs_unlock_bh(wrs_db); +} + +u16 cl_wrs_api_get_tx_sta_data_rate(struct cl_sta *cl_sta) +{ + return cl_sta->wrs_sta.tx_su_params.data_rate; +} + +static enum rate_info_bw cl_wrs_mode_to_nl80211_rateinfo_bw(u8 bw) +{ + switch (bw) { + case CHNL_BW_20: + return RATE_INFO_BW_20; + case CHNL_BW_40: + return RATE_INFO_BW_40; + case CHNL_BW_80: + return RATE_INFO_BW_80; + case CHNL_BW_160: + return RATE_INFO_BW_160; + default: + return RATE_INFO_BW_20; + } +} + +void cl_wrs_fill_sinfo_rates(struct rate_info *rate_info, + const struct cl_wrs_params *wrs_params, + const struct cl_sta *sta) +{ + rate_info->bw = cl_wrs_mode_to_nl80211_rateinfo_bw(wrs_params->rate_params.bw); + rate_info->mcs = wrs_params->rate_params.mcs; + rate_info->nss = wrs_params->rate_params.nss + 1; + rate_info->he_gi = wrs_params->rate_params.gi; + + rate_info->flags = 0; + /* GI = 0.4 us */ + if (wrs_params->rate_params.mode < WRS_MODE_HE && wrs_params->rate_params.gi == 1) + rate_info->flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (wrs_params->rate_params.mode == WRS_MODE_HT) + rate_info->flags |= RATE_INFO_FLAGS_MCS; + + if (wrs_params->rate_params.mode == WRS_MODE_VHT) + rate_info->flags |= RATE_INFO_FLAGS_VHT_MCS; + + if (wrs_params->rate_params.mode == WRS_MODE_HE) { + enum cl_mu_ofdma_ru_type ru_type = sta->rate_ctrl_he.field.ru_type; + + rate_info->flags |= RATE_INFO_FLAGS_HE_MCS; + if (ru_type) { + rate_info->he_ru_alloc = cl_ru_type_to_nl80211_he_ru_alloc(ru_type); + rate_info->bw = RATE_INFO_BW_HE_RU; + } + } +} + +/* + * Section #1: + * rate based on rssi. + */ +static s8 rssi_threshold_he[WRS_MCS_MAX_HE] = { + -35, -40, -45, -50, -55, -60, -65, -70, -75, -80, -85, -90 +}; + +static s8 rssi_threshold_vht[WRS_MCS_MAX_VHT] = { + -36, -42, -48, -54, -60, -66, -72, -78, -84, -90 +}; + +static s8 rssi_threshold_ht[WRS_MCS_MAX_HT] = { + -34, -42, -50, -58, -66, -74, -82, -90 +}; + +static s8 rssi_threshold_ofdm[WRS_MCS_MAX_OFDM] = { + -34, -42, -50, -58, -66, -74, -82, -90 +}; + +static s8 rssi_threshold_cck[WRS_MCS_MAX_CCK] = { + -45, -60, -75, -90 +}; + +static u16 cl_wrs_rssi_find_rate_ht_vht_he(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + s8 *rssi_sort, + s8 *thresholds) +{ + s8 max_ss = (s8)wrs_sta->max_rate_cap.nss; + s8 nss = 0; + u8 max_bw = wrs_sta->max_rate_cap.bw; + u8 bw = 0; + u8 max_mcs = wrs_sta->max_rate_cap.mcs; + u8 mcs = 0; + u8 gi = WRS_GI_LONG; + u8 selected_mcs = 0; + u8 selected_nss = 0; + u8 selected_bw = 0; + u8 i = 0; + u16 rate_idx = 0; + u16 data_rate = 0; + u16 max_data_rate = 0; + + if (max_bw > cl_hw->conf->ci_wrs_max_bw) + max_bw = cl_hw->conf->ci_wrs_max_bw; + + for (i = 0; i <= max_mcs; i++) { + mcs = max_mcs - i; + + for (nss = max_ss; nss >= 0; nss--) { + if (rssi_sort[nss] <= thresholds[i]) + continue; + + /* In last level decrease BW */ + bw = ((i == max_mcs) && (max_bw > CHNL_BW_20)) ? (max_bw - 1) : max_bw; + + if (wrs_sta->mode == WRS_MODE_HE) { + data_rate = data_rate_he_x10[nss][bw][mcs][WRS_GI_LONG]; + } else { + if (wrs_sta->mode == WRS_MODE_VHT) { + /* 160MHz in VHT is valid only for 1/2 SS */ + if (nss >= WRS_SS_3 && bw == CHNL_BW_160) + bw = CHNL_BW_80; + + /* BW 80, 3 SS MCS 6 is invalid in VHT */ + if (bw == CHNL_BW_80 && + nss == WRS_SS_3 && + mcs == WRS_MCS_6) + continue; + } + + data_rate = data_rate_ht_vht_x10[bw][nss][mcs][gi]; + } + + if (data_rate > max_data_rate) { + selected_mcs = mcs; + selected_nss = nss; + selected_bw = bw; + max_data_rate = data_rate; + rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, + bw, nss, mcs, gi); + } + + break; + } + } + + return rate_idx; +} + +static u16 cl_wrs_rssi_find_rate_cck_ofdm(struct cl_wrs_sta *wrs_sta, + s8 *rssi_sort, s8 *thresholds) +{ + struct cl_wrs_params *wrs_params = &wrs_sta->tx_su_params; + u8 max_mcs = wrs_sta->max_rate_cap.mcs; + u8 mcs = 0; + u8 i = 0; + + for (i = 0; i <= max_mcs; i++) { + mcs = max_mcs - i; + + if (rssi_sort[WRS_SS_1] > thresholds[i]) + return cl_wrs_tables_find_rate_idx(wrs_params, + CHNL_BW_20, WRS_SS_1, mcs, WRS_GI_LONG); + } + + return 0; +} + +u16 cl_wrs_rssi_find_rate(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + s8 *rssi_sort) +{ + u16 rate_idx = 0; + + if (wrs_params->initial_rate_idx != WRS_INVALID_RATE) + return wrs_params->initial_rate_idx; + + switch (wrs_sta->mode) { + case WRS_MODE_HE: + rate_idx = cl_wrs_rssi_find_rate_ht_vht_he(cl_hw, wrs_db, wrs_sta, wrs_params, + rssi_sort, rssi_threshold_he); + break; + case WRS_MODE_VHT: + rate_idx = cl_wrs_rssi_find_rate_ht_vht_he(cl_hw, wrs_db, wrs_sta, wrs_params, + rssi_sort, rssi_threshold_vht); + break; + case WRS_MODE_HT: + rate_idx = cl_wrs_rssi_find_rate_ht_vht_he(cl_hw, wrs_db, wrs_sta, wrs_params, + rssi_sort, rssi_threshold_ht); + break; + case WRS_MODE_OFDM: + rate_idx = cl_wrs_rssi_find_rate_cck_ofdm(wrs_sta, rssi_sort, + rssi_threshold_ofdm); + break; + case WRS_MODE_CCK: + rate_idx = cl_wrs_rssi_find_rate_cck_ofdm(wrs_sta, rssi_sort, + rssi_threshold_cck); + break; + default: + break; + } + + if (rate_idx == WRS_INVALID_RATE) + rate_idx = 0; + + wrs_pr_trace(wrs_db, + "[%s] Select rate based rssi - sta=%u, rssi [%d,%d,%d,%d], " + "rate_idx=%u, bw=%u, nss=%u, mcs=%u\n", + WRS_TYPE_STR(wrs_params->type), + wrs_sta->sta_idx, + rssi_sort[0], + rssi_sort[1], + rssi_sort[2], + rssi_sort[3], + rate_idx, + wrs_params->table[rate_idx].rate.bw, + wrs_params->table[rate_idx].rate.nss, + wrs_params->table[rate_idx].rate.mcs); + + return rate_idx; +} + +/* + * Section #2: + * rssi protect. + */ +static void cl_wrs_rssi_prot_set_avg(struct cl_wrs_sta *wrs_sta, s8 avg) +{ + struct cl_wrs_rssi_prot_db *rssi_prot_db = &wrs_sta->rssi_prot_db; + + memset(rssi_prot_db->samples_old, avg, WRS_RSSI_PROTECT_BUF_SZ_OLD); + memset(rssi_prot_db->samples_new, avg, WRS_RSSI_PROTECT_BUF_SZ_NEW); + rssi_prot_db->sum = avg << WRS_RSSI_PROTECT_SHIFT; +} + +static s8 cl_wrs_rssi_prot_add_smpl(struct cl_wrs_sta *wrs_sta, s8 rssi_eq) +{ + struct cl_wrs_rssi_prot_db *rssi_prot_db = &wrs_sta->rssi_prot_db; + u8 curr_idx_old = rssi_prot_db->curr_idx_old; + u8 curr_idx_new = rssi_prot_db->curr_idx_new; + + rssi_prot_db->sum += + rssi_prot_db->samples_new[curr_idx_new] - rssi_prot_db->samples_old[curr_idx_old]; + rssi_prot_db->samples_old[curr_idx_old] = rssi_prot_db->samples_new[curr_idx_new]; + rssi_prot_db->samples_new[curr_idx_new] = rssi_eq; + + rssi_prot_db->curr_idx_old = + WRS_INC_POW2(rssi_prot_db->curr_idx_old, WRS_RSSI_PROTECT_BUF_SZ_OLD); + WRS_INC(rssi_prot_db->curr_idx_new, WRS_RSSI_PROTECT_BUF_SZ_NEW); + + return (s8)(wrs_sta->rssi_prot_db.sum >> WRS_RSSI_PROTECT_SHIFT); +} + +static bool cl_wrs_rssi_prot_decision_up(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + s8 rssi_avg, s8 rssi_eq, + s8 *rssi_sort, u8 up_rate_idx) +{ + /* Decide UP only if all new samples are greater than old average */ + s8 *samples_new = wrs_sta->rssi_prot_db.samples_new; + s8 up_thr = rssi_avg + wrs_db->rssi_protect_up_thr; + u8 i = 0; + + for (i = 0; i < WRS_RSSI_PROTECT_BUF_SZ_NEW; i++) + if (samples_new[i] <= up_thr) + return false; + + if (wrs_db->rssi_protect_mode == WRS_RSSI_PROT_MODE_RSSI) { + u16 rate_idx_old = wrs_params->rate_idx; + u16 rate_idx_new = cl_wrs_rssi_find_rate(cl_hw, wrs_db, wrs_sta, + wrs_params, rssi_sort); + struct cl_wrs_rate *rate_old = &wrs_params->table[rate_idx_old].rate; + struct cl_wrs_rate *rate_new = &wrs_params->table[rate_idx_new].rate; + u16 data_rate_old = cl_data_rates_get_x10(wrs_sta->mode, rate_old->bw, + rate_old->nss, rate_old->mcs, + rate_old->gi); + u16 data_rate_new = cl_data_rates_get_x10(wrs_sta->mode, rate_new->bw, + rate_new->nss, rate_new->mcs, + rate_new->gi); + + if (rate_idx_old == rate_idx_new || data_rate_old >= data_rate_new) + rate_idx_new = up_rate_idx; + + wrs_pr_info(wrs_db, "[%s] Increase rate based on RSSI - old [%u], new [%u]\n", + WRS_TYPE_STR(wrs_params->type), rate_idx_old, rate_idx_new); + cl_wrs_decision_update(wrs_db, wrs_sta, wrs_params, + WRS_DECISION_UP_RSSI, rate_idx_new); + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, + wrs_params, rate_idx_new, true, false); + } else { + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_UP_RSSI, up_rate_idx); + } + + cl_wrs_tables_reset(wrs_db, wrs_sta, wrs_params); + cl_wrs_rssi_prot_set_avg(wrs_sta, rssi_eq); + + return true; +} + +static bool cl_wrs_rssi_prot_decision_down(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + s8 rssi_avg, s8 rssi_eq, + s8 *rssi_sort, u8 down_rate_idx) +{ + /* Decide DOWN only if all new samples are smaller than old average */ + s8 *samples_new = wrs_sta->rssi_prot_db.samples_new; + s8 dn_thr = rssi_avg - wrs_db->rssi_protect_dn_thr; + u8 i = 0; + + if (wrs_params->rate_idx == 0) + return false; + + for (i = 0; i < WRS_RSSI_PROTECT_BUF_SZ_NEW; i++) + if (samples_new[i] >= dn_thr) + return false; + + if (wrs_db->rssi_protect_mode == WRS_RSSI_PROT_MODE_RSSI) { + u16 rate_idx_old = wrs_params->rate_idx; + u16 rate_idx_new = cl_wrs_rssi_find_rate(cl_hw, wrs_db, wrs_sta, + wrs_params, rssi_sort); + struct cl_wrs_rate *rate_old = &wrs_params->table[rate_idx_old].rate; + struct cl_wrs_rate *rate_new = &wrs_params->table[rate_idx_new].rate; + u16 data_rate_old = cl_data_rates_get_x10(wrs_sta->mode, rate_old->bw, + rate_old->nss, rate_old->mcs, + rate_old->gi); + u16 data_rate_new = cl_data_rates_get_x10(wrs_sta->mode, rate_new->bw, + rate_new->nss, rate_new->mcs, + rate_new->gi); + + if (rate_idx_old == rate_idx_new || data_rate_old <= data_rate_new) + rate_idx_new = down_rate_idx; + + wrs_pr_info(wrs_db, "[%s] Decrease rate based on RSSI - old [%u], new [%u]\n", + WRS_TYPE_STR(wrs_params->type), rate_idx_old, rate_idx_new); + cl_wrs_decision_update(wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN_RSSI, rate_idx_new); + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, wrs_params, + rate_idx_new, true, false); + } else { + cl_wrs_decision_make(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_DECISION_DOWN_RSSI, down_rate_idx); + } + + cl_wrs_tables_reset(wrs_db, wrs_sta, wrs_params); + cl_wrs_rssi_prot_set_avg(wrs_sta, rssi_eq); + + return true; +} + +void cl_wrs_rssi_prot_start(struct cl_hw *cl_hw, struct cl_sta *cl_sta) +{ + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + s8 rssi_sort[MAX_ANTENNAS] = {0}; + s8 rssi_eq = 0; + + if (!cl_hw->wrs_db.rssi_protect_en) + return; + + rssi_eq = cl_wrs_rssi_eq_calc(cl_hw, wrs_sta, false, rssi_sort); + cl_wrs_rssi_prot_set_avg(wrs_sta, rssi_eq); +} + +bool cl_wrs_rssi_prot_decision(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + bool up_rate_valid, + u8 up_rate_idx, u8 down_rate_idx) +{ + s8 rssi_avg = 0; + s8 rssi_eq = 0; + s8 rssi_sort[MAX_ANTENNAS] = {0}; + + rssi_eq = cl_wrs_rssi_eq_calc(cl_hw, wrs_sta, true, rssi_sort); + rssi_avg = cl_wrs_rssi_prot_add_smpl(wrs_sta, rssi_eq); + + if (up_rate_valid) + if (cl_wrs_rssi_prot_decision_up(cl_hw, wrs_db, wrs_sta, wrs_params, rssi_avg, + rssi_eq, rssi_sort, up_rate_idx)) + return true; + + return cl_wrs_rssi_prot_decision_down(cl_hw, wrs_db, wrs_sta, wrs_params, rssi_avg, + rssi_eq, rssi_sort, down_rate_idx); +} + +static void cl_wrs_sta_info_set_he(struct cl_wrs_sta *wrs_sta) +{ + wrs_sta->mode = WRS_MODE_HE; + + wrs_sta->gi_cap[CHNL_BW_20] = WRS_GI_VSHORT; + wrs_sta->gi_cap[CHNL_BW_40] = WRS_GI_VSHORT; + wrs_sta->gi_cap[CHNL_BW_80] = WRS_GI_VSHORT; + wrs_sta->gi_cap[CHNL_BW_160] = WRS_GI_VSHORT; +} + +static void cl_wrs_sta_info_set_vht(struct cl_wrs_sta *wrs_sta, + struct ieee80211_sta_vht_cap *vht_cap, + struct ieee80211_sta_ht_cap *ht_cap) +{ + wrs_sta->mode = WRS_MODE_VHT; + + wrs_sta->gi_cap[CHNL_BW_20] = + (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) ? WRS_GI_SHORT : WRS_GI_LONG; + wrs_sta->gi_cap[CHNL_BW_40] = + (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) ? WRS_GI_SHORT : WRS_GI_LONG; + wrs_sta->gi_cap[CHNL_BW_80] = + (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) ? WRS_GI_SHORT : WRS_GI_LONG; + wrs_sta->gi_cap[CHNL_BW_160] = + (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) ? WRS_GI_SHORT : WRS_GI_LONG; +} + +static void cl_wrs_sta_info_set_ht(struct cl_wrs_sta *wrs_sta, + struct ieee80211_sta_ht_cap *ht_cap) +{ + wrs_sta->mode = WRS_MODE_HT; + + wrs_sta->gi_cap[CHNL_BW_20] = + (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) ? WRS_GI_SHORT : WRS_GI_LONG; + wrs_sta->gi_cap[CHNL_BW_40] = + (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) ? WRS_GI_SHORT : WRS_GI_LONG; +} + +static void cl_wrs_sta_info_set_legacy(struct cl_wrs_sta *wrs_sta, + struct ieee80211_sta *sta) +{ + if (sta->supp_rates[NL80211_BAND_5GHZ] || + (sta->supp_rates[NL80211_BAND_2GHZ] & 0xFF0)) + wrs_sta->mode = WRS_MODE_OFDM; + else + wrs_sta->mode = WRS_MODE_CCK; +} + +static void cl_wrs_sta_info_set(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct ieee80211_sta *sta) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + u8 bw = min_t(u8, sta->bandwidth, wrs_db->max_cap.bw); + + if (he_cap->has_he) + cl_wrs_sta_info_set_he(wrs_sta); + else if (vht_cap->vht_supported && ht_cap->ht_supported) + cl_wrs_sta_info_set_vht(wrs_sta, vht_cap, ht_cap); + else if (ht_cap->ht_supported) + cl_wrs_sta_info_set_ht(wrs_sta, ht_cap); + else + cl_wrs_sta_info_set_legacy(wrs_sta, sta); + + wrs_sta->max_rate_cap.nss = min_t(u8, sta->rx_nss, WRS_SS_MAX) - 1; + + if (cl_band_is_24g(cl_hw)) + wrs_sta->max_rate_cap.bw = min(bw, wrs_db->coex_bw); + else + wrs_sta->max_rate_cap.bw = bw; + + wrs_sta->assoc_bw = bw; +} + +#define TWO_BITS_MASK 0x3 + +static u8 cl_wrs_calc_max_nss(u16 rx_mcs, u8 max_nss) +{ + u8 i, nss = 0; + + for (i = 0; i <= max_nss; i++) { + if (((rx_mcs >> (2 * i)) & TWO_BITS_MASK) != IEEE80211_HE_MCS_NOT_SUPPORTED) + nss++; + else + break; + } + + return nss; +} + +static void cl_supported_rates_he_cap(struct cl_wrs_db *wrs_db, struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = (struct cl_sta *)sta->drv_priv; + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + struct ieee80211_he_mcs_nss_supp *mcs_nss = &sta->he_cap.he_mcs_nss_supp; + int mcs = 0; + int supported_mcs = 0; + u16 rx_mcs = 0; + u8 max_nss = wrs_sta->max_rate_cap.nss; + u8 nss = 0, bw = 0; + u8 max_nss_80, max_nss_160; + + for (bw = 0; bw <= wrs_sta->max_rate_cap.bw; bw++) { + if (bw < CHNL_BW_160) { + rx_mcs = le16_to_cpu(mcs_nss->rx_mcs_80); + } else if (bw == CHNL_BW_160) { + max_nss_80 = cl_wrs_calc_max_nss(le16_to_cpu(mcs_nss->rx_mcs_80), + max_nss) + 1; + rx_mcs = le16_to_cpu(mcs_nss->rx_mcs_160); + max_nss_160 = cl_wrs_calc_max_nss(rx_mcs, max_nss) + 1; + max_nss = max_nss * max_nss_160 / max_nss_80; + } else { + wrs_pr_err(wrs_db, "bw %u is not supported\n", bw); + } + + for (nss = 0; nss <= max_nss; nss++) { + switch ((rx_mcs >> (2 * nss)) & TWO_BITS_MASK) { + case IEEE80211_HE_MCS_SUPPORT_0_7: + supported_mcs = WRS_MCS_7; + break; + case IEEE80211_HE_MCS_SUPPORT_0_9: + supported_mcs = WRS_MCS_9; + break; + case IEEE80211_HE_MCS_SUPPORT_0_11: + supported_mcs = WRS_MCS_11; + break; + case IEEE80211_HE_MCS_NOT_SUPPORTED: + supported_mcs = -1; + break; + } + + for (mcs = 0; mcs <= supported_mcs; mcs++) + cl_wrs_sta_set_supported_rate(wrs_sta, bw, nss, mcs); + } + } +} + +static void cl_supported_rates_vht_cap(struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); + u8 bw = 0; + u8 nss = 0; + int mcs = 0; + int supported_mcs = 0; + + for (bw = 0; bw <= wrs_sta->max_rate_cap.bw; bw++) { + for (nss = 0; nss <= wrs_sta->max_rate_cap.nss; nss++) { + switch ((mcs_map >> (2 * nss)) & TWO_BITS_MASK) { + case 0: + supported_mcs = WRS_MCS_7; + break; + case 1: + supported_mcs = WRS_MCS_8; + break; + case 2: + supported_mcs = WRS_MCS_9; + break; + case 3: + supported_mcs = -1; + break; + } + + for (mcs = 0; mcs <= supported_mcs; mcs++) + cl_wrs_sta_set_supported_rate(wrs_sta, bw, nss, mcs); + } + } +} + +static void cl_supported_rates_ht_cap(struct ieee80211_sta *sta) +{ + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u8 bw = 0; + u8 nss = 0; + u8 mcs = 0; + + for (mcs = 0; mcs <= WRS_MCS_7; mcs++) { + for (nss = 0; nss <= wrs_sta->max_rate_cap.nss; nss++) { + if ((ht_cap->mcs.rx_mask[nss] & (1 << mcs)) == 0) + continue; + + for (bw = 0; bw <= wrs_sta->max_rate_cap.bw; bw++) + cl_wrs_sta_set_supported_rate(wrs_sta, bw, nss, mcs); + } + } +} + +static void cl_supported_rates_legacy_cap(struct cl_hw *cl_hw, + struct ieee80211_sta *sta, + u8 max_mcs) +{ + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + u8 mcs = 0; + + for (mcs = 0; mcs < max_mcs; mcs++) + if (rate_supported(sta, cl_hw->nl_band, mcs)) + cl_wrs_sta_set_supported_rate(wrs_sta, CHNL_BW_20, WRS_SS_1, mcs); +} + +void cl_wrs_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + struct cl_wrs_params *wrs_params = &wrs_sta->tx_su_params; + + wrs_params->type = WRS_TYPE_TX_SU; + wrs_params->is_mu_valid = false; + wrs_params->rate_idx = WRS_INVALID_RATE; + wrs_params->initial_rate_idx = WRS_INVALID_RATE; + + wrs_sta->sta_idx = cl_sta->sta_idx; + cl_wrs_rssi_prot_start(cl_hw, cl_sta); + cl_wrs_stats_per_init(wrs_params); + cl_wrs_sta_info_set(cl_hw, wrs_sta, sta); + cl_wrs_sta_capabilities_set(wrs_db, sta); + cl_wrs_tables_build(cl_hw, wrs_sta, wrs_params); + cl_wrs_sta_select_first_rate(cl_hw, wrs_db, wrs_sta, wrs_params); + + wrs_pr_trace(wrs_db, "[%s] Add station %pM to database (sta_idx %u)\n", + WRS_TYPE_STR(wrs_params->type), cl_sta->addr, cl_sta->sta_idx); +} + +void cl_wrs_sta_add_rx(struct cl_hw *cl_hw, struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + struct cl_wrs_params *wrs_params; + + if (wrs_sta->rx_params) { + wrs_pr_warn(wrs_db, "[RX] Params already allocated (sta_idx %u)\n", + wrs_sta->sta_idx); + return; + } + + wrs_params = kzalloc(sizeof(*wrs_params), GFP_ATOMIC); + + if (!wrs_params) + return; + + wrs_sta->rx_params = wrs_params; + wrs_params->type = WRS_TYPE_RX; + wrs_params->is_mu_valid = false; + wrs_params->rate_idx = WRS_INVALID_RATE; + wrs_params->initial_rate_idx = WRS_INVALID_RATE; + + wrs_sta->sta_idx = cl_sta->sta_idx; + + cl_wrs_rssi_prot_start(cl_hw, cl_sta); + cl_wrs_stats_per_init(wrs_params); + cl_wrs_sta_info_set(cl_hw, wrs_sta, sta); + cl_wrs_sta_capabilities_set(wrs_db, sta); + cl_wrs_tables_build(cl_hw, wrs_sta, wrs_params); + cl_wrs_sta_select_first_rate(cl_hw, wrs_db, wrs_sta, wrs_params); + cl_wrs_rx_rate_idle_reset(wrs_params); + + wrs_pr_trace(wrs_db, "[%s] Add station %pM to database (sta_idx %u)\n", + WRS_TYPE_STR(wrs_params->type), cl_sta->addr, cl_sta->sta_idx); +} + +static void _cl_wrs_sta_remove(struct cl_wrs_params *wrs_params) +{ + if (wrs_params->is_logger_en) { + kfree(wrs_params->logger); + wrs_params->logger = NULL; + } + + kfree(wrs_params->table); + wrs_params->table = NULL; + + cl_wrs_stats_per_remove(wrs_params); +} + +static void cl_wrs_sta_remove_rx(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta) +{ + struct cl_wrs_params *wrs_params = wrs_sta->rx_params; + + if (!wrs_params) { + wrs_pr_warn(wrs_db, "[RX] Params already removed (sta_idx %u)\n", + wrs_sta->sta_idx); + return; + } + + _cl_wrs_sta_remove(wrs_params); + + kfree(wrs_params); + wrs_sta->rx_params = NULL; + + wrs_pr_err(wrs_db, "[RX] Remove params (sta_idx %u)\n", wrs_sta->sta_idx); +} + +void cl_wrs_sta_remove(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, struct cl_sta *cl_sta) +{ + struct cl_wrs_sta *wrs_sta = &cl_sta->wrs_sta; + + _cl_wrs_sta_remove(&wrs_sta->tx_su_params); + + if (wrs_sta->rx_params) + cl_wrs_sta_remove_rx(wrs_db, wrs_sta); + wrs_pr_trace(wrs_db, "Remove station %pM from database (sta_idx %u)\n", + cl_sta->addr, cl_sta->sta_idx); +} + +struct cl_wrs_sta *cl_wrs_sta_get(struct cl_hw *cl_hw, u8 sta_idx) +{ + struct cl_sta *cl_sta = cl_sta_get(cl_hw, sta_idx); + + return cl_sta ? &cl_sta->wrs_sta : NULL; +} + +void cl_wrs_sta_select_first_rate(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params) +{ + if (wrs_db->is_fixed_rate) { + s8 *fixed_rate = cl_hw->conf->ci_wrs_fixed_rate; + + cl_wrs_fixed_rate_set(cl_hw, wrs_db, wrs_sta, wrs_params, wrs_db->is_fixed_rate, + fixed_rate[WRS_FIXED_PARAM_MODE], + fixed_rate[WRS_FIXED_PARAM_BW], + fixed_rate[WRS_FIXED_PARAM_NSS], + fixed_rate[WRS_FIXED_PARAM_MCS], + fixed_rate[WRS_FIXED_PARAM_GI], 0); + } else { + struct cl_sta *cl_sta = container_of(wrs_sta, struct cl_sta, wrs_sta); + struct cl_wrs_rate_params *vif_fixed_params = &cl_sta->cl_vif->fixed_params; + + if (vif_fixed_params->is_fixed) + cl_wrs_fixed_rate_set(cl_hw, wrs_db, wrs_sta, wrs_params, + WRS_FIXED_FALLBACK_DIS, + vif_fixed_params->mode, + vif_fixed_params->bw, + vif_fixed_params->nss, + vif_fixed_params->mcs, + vif_fixed_params->gi, 0); + } + + if (!wrs_params->is_fixed_rate) { + bool result = cl_wrs_set_rate_idle(cl_hw, wrs_db, wrs_sta, wrs_params); + + /* + * If new rate wasn't selected according to + * rssi (no samples) or data packets set rate to lowest possible + */ + if (!result) + cl_wrs_rate_params_update(cl_hw, wrs_db, wrs_sta, + wrs_params, 0, false, false); + } +} + +void cl_wrs_sta_capabilities_set(struct cl_wrs_db *wrs_db, struct ieee80211_sta *sta) +{ + struct cl_sta *cl_sta = IEEE80211_STA_TO_CL_STA(sta); + enum cl_wrs_mode mode = cl_sta->wrs_sta.mode; + + if (mode == WRS_MODE_HE) { + cl_supported_rates_he_cap(wrs_db, sta); + } else if (mode == WRS_MODE_VHT) { + cl_supported_rates_vht_cap(sta); + } else if (mode == WRS_MODE_HT) { + cl_supported_rates_ht_cap(sta); + } else { + struct cl_hw *cl_hw = cl_sta->cl_vif->cl_hw; + u8 max_mcs = (mode == WRS_MODE_OFDM) ? WRS_MCS_MAX_OFDM : WRS_MCS_MAX_CCK; + + cl_supported_rates_legacy_cap(cl_hw, sta, max_mcs); + } +} + +void cl_wrs_sta_set_supported_rate(struct cl_wrs_sta *wrs_sta, u8 bw, u8 nss, u8 mcs) +{ + u8 rate_idx = mcs + (nss * WRS_MCS_MAX); + + wrs_sta->supported_rates[bw] |= BIT(rate_idx); +} + +static struct cl_wrs_per_stats *cl_wrs_stats_per_entry(struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_per_stats *per_stats = NULL, *per_stats_new = NULL; + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + struct list_head *list_rates = &wrs_params->list_rates; + u8 bw = rate_params->bw; + u8 nss = rate_params->nss; + u8 mcs = rate_params->mcs; + u8 gi = rate_params->gi; + + list_for_each_entry(per_stats, list_rates, list) { + if (per_stats->bw != bw || + per_stats->nss != nss || + per_stats->mcs != mcs || + per_stats->gi != gi) + continue; + + /* + * Move the entry to the beginning of the list, so that it + * will be faster to find next time. + */ + if (per_stats != list_entry(list_rates->next, struct cl_wrs_per_stats, list)) { + list_del(&per_stats->list); + list_add(&per_stats->list, list_rates); + } + + return per_stats; + } + + /* Entry not found - allocate new entry and add to list */ + per_stats_new = kzalloc(sizeof(*per_stats_new), GFP_ATOMIC); + + if (!per_stats_new) + return NULL; + + per_stats_new->bw = bw; + per_stats_new->nss = nss; + per_stats_new->mcs = mcs; + per_stats_new->gi = gi; + + list_add(&per_stats_new->list, &wrs_params->list_rates); + + return per_stats_new; +} + +void cl_wrs_stats_per_update(struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + struct cl_wrs_cntrs *cntrs) +{ + u16 curr_rate_idx = wrs_params->rate_idx; + struct cl_wrs_table *table_node = &wrs_params->table[curr_rate_idx]; + struct cl_wrs_per_stats *per_stats = cl_wrs_stats_per_entry(wrs_params); + + if (!per_stats) + return; + + wrs_params->frames_total += cntrs->total; + wrs_params->fail_total += cntrs->fail; + wrs_params->ba_not_rcv_total += cntrs->ba_not_rcv; + wrs_params->epr_acc += cntrs->epr_acc; + + per_stats->frames_total += cntrs->total; + per_stats->frames_failed += cntrs->fail; + per_stats->epr_acc += cntrs->epr_acc; + + if (wrs_params->calc_ba_not_rcv) { + per_stats->frames_total += cntrs->ba_not_rcv; + per_stats->frames_failed += cntrs->ba_not_rcv; + } + + table_node->frames_total = wrs_params->frames_total; + table_node->ba_not_rcv_total = wrs_params->ba_not_rcv_total; + table_node->epr_acc = wrs_params->epr_acc; +} + +void cl_wrs_stats_per_init(struct cl_wrs_params *wrs_params) +{ + INIT_LIST_HEAD(&wrs_params->list_rates); +} + +void cl_wrs_stats_per_remove(struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_per_stats *per_stats = NULL, *per_stats_next = NULL; + + list_for_each_entry_safe(per_stats, per_stats_next, &wrs_params->list_rates, list) { + list_del(&per_stats->list); + kfree(per_stats); + } +} + +static struct cl_wrs_table + ap_rate_table_he[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_HE][WRS_GI_MAX_HE]; +static struct cl_wrs_table + ap_rate_table_ht_vht[CHNL_BW_MAX][WRS_SS_MAX][WRS_MCS_MAX_VHT][WRS_GI_MAX_VHT]; + +/* Rate indexes sorted by data rate */ +static u16 rate_idx_sorted_by_data_rate_he[WRS_HE_RATE_TABLE_SIZE] = {0}; +static u16 rate_idx_sorted_by_data_rate_ht_vht[WRS_HT_VHT_RATE_TABLE_SIZE] = {0}; + +static void cl_wrs_extract_rate_idx_vht(u16 idx, u8 *bw, u8 *nss, u8 *mcs, u8 *gi) +{ + *gi = idx % WRS_GI_MAX_VHT; + idx = (idx - *gi) / WRS_GI_MAX_VHT; + *mcs = idx % WRS_MCS_MAX_VHT; + idx = (idx - *mcs) / WRS_MCS_MAX_VHT; + *nss = idx % WRS_SS_MAX; + *bw = (idx - *nss) / CHNL_BW_MAX; +} + +static void cl_wrs_extract_rate_idx_he(u16 idx, u8 *bw, u8 *nss, u8 *mcs, u8 *gi) +{ + *gi = idx % WRS_GI_MAX_HE; + idx = (idx - *gi) / WRS_GI_MAX_HE; + *mcs = idx % WRS_MCS_MAX_HE; + idx = (idx - *mcs) / WRS_MCS_MAX_HE; + *nss = idx % WRS_SS_MAX; + *bw = (idx - *nss) / CHNL_BW_MAX; +} + +static void cl_wrs_tables_build_sorted_ht_vht(void) +{ + /* Sort according to HT/VHT data rate */ + u16 i, j; + u8 bw1, nss1, mcs1, gi1, bw2, nss2, mcs2, gi2; + + for (i = 0; i < WRS_HT_VHT_RATE_TABLE_SIZE; i++) + rate_idx_sorted_by_data_rate_ht_vht[i] = i; + + for (i = 0; i < WRS_HT_VHT_RATE_TABLE_SIZE - 1; i++) { + for (j = 0; j < WRS_HT_VHT_RATE_TABLE_SIZE - i - 1; j++) { + cl_wrs_extract_rate_idx_vht(rate_idx_sorted_by_data_rate_ht_vht[j], + &bw1, &nss1, &mcs1, &gi1); + cl_wrs_extract_rate_idx_vht(rate_idx_sorted_by_data_rate_ht_vht[j + 1], + &bw2, &nss2, &mcs2, &gi2); + + if (data_rate_ht_vht_x10[bw1][nss1][mcs1][gi1] > + data_rate_ht_vht_x10[bw2][nss2][mcs2][gi2]) + swap(rate_idx_sorted_by_data_rate_ht_vht[j], + rate_idx_sorted_by_data_rate_ht_vht[j + 1]); + } + } +} + +static void cl_wrs_tables_build_sorted_he(void) +{ + /* Sort according to HE data rate */ + u16 i, j; + u8 bw1, nss1, mcs1, gi1, bw2, nss2, mcs2, gi2; + + for (i = 0; i < WRS_HE_RATE_TABLE_SIZE; i++) + rate_idx_sorted_by_data_rate_he[i] = i; + + for (i = 0; i < WRS_HE_RATE_TABLE_SIZE - 1; i++) { + for (j = 0; j < WRS_HE_RATE_TABLE_SIZE - i - 1; j++) { + cl_wrs_extract_rate_idx_he(rate_idx_sorted_by_data_rate_he[j], + &bw1, &nss1, &mcs1, &gi1); + cl_wrs_extract_rate_idx_he(rate_idx_sorted_by_data_rate_he[j + 1], + &bw2, &nss2, &mcs2, &gi2); + + if (data_rate_he_x10[nss1][bw1][mcs1][gi1] > + data_rate_he_x10[nss2][bw2][mcs2][gi2]) + swap(rate_idx_sorted_by_data_rate_he[j], + rate_idx_sorted_by_data_rate_he[j + 1]); + } + } +} + +static u16 idx_to_offt_ht_vht(u32 bw, u32 nss, u32 mcs, u32 gi) +{ + if (bw < CHNL_BW_MAX && + nss < WRS_SS_MAX && + mcs < WRS_MCS_MAX_VHT && + gi < WRS_GI_MAX_VHT) + return (gi + WRS_GI_MAX_VHT * (mcs + WRS_MCS_MAX_VHT * (nss + bw * WRS_SS_MAX))); + else + return -1; +} + +static u16 idx_to_offt_he(u32 bw, u32 nss, u32 mcs, u32 gi) +{ + if (bw < CHNL_BW_MAX && + nss < WRS_SS_MAX && + mcs < WRS_MCS_MAX_HE && + gi < WRS_GI_MAX_HE) + return (gi + WRS_GI_MAX_HE * (mcs + WRS_MCS_MAX_HE * (nss + bw * WRS_SS_MAX))); + else + return -1; +} + +static u16 find_down_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, u16 *data_rates, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + u16 idx; + + if (mcs > 0) { + idx = idx_to_offt(bw, nss, mcs - 1, gi); + if (data_rates[idx]) + return idx; + if (mcs > 1) + return idx_to_offt(bw, nss, mcs - 2, gi); + } + + if (bw > 0) { + idx = idx_to_offt(bw - 1, nss, mcs, gi); + if (data_rates[idx]) + return idx; + if (bw > 1) + return idx_to_offt(bw - 2, nss, mcs, gi); + } + + if (nss > 0) { + idx = idx_to_offt(bw, nss - 1, mcs, gi); + if (data_rates[idx]) + return idx; + if (nss > 1) { + idx = idx_to_offt(bw, nss - 2, mcs, gi); + if (data_rates[idx]) + return idx; + } + } + + if (gi > 0) + return idx_to_offt(bw, nss, mcs, gi - 1); + + return 0; +} + +static u16 find_up_mcs_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, u16 *data_rates, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + s16 idx = idx_to_offt(bw, nss, mcs + 1, gi); + + if (idx < 0 || !data_rates[idx]) + idx = idx_to_offt(bw, nss, mcs + 2, gi); + + return (idx < 0) ? WRS_INVALID_RATE : idx; +} + +static u16 find_up_bw_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, + u16 *data_rates, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + s16 cur_data_rate = data_rates[idx_to_offt(bw, nss, mcs, gi)]; + s16 min_idx = WRS_INVALID_RATE; + s16 idx; + s32 min_rate_diff = S32_MAX; + s32 rate_diff; + + for (idx = idx_to_offt(++bw, nss, mcs, gi); !(idx < 0); + idx = idx_to_offt(bw, nss, --mcs, gi)) { + /* + * If data_rates[idx] == 0, the difference will be negative, + * so the condition below will not hold. + * Therefore, no need to check this possiblity specifically. + */ + rate_diff = data_rates[idx] - cur_data_rate; + if (rate_diff > 0 && + rate_diff < min_rate_diff && + (data_rates[idx] * 100) > (cur_data_rate * WRS_EPR_FACTOR)) { + min_rate_diff = rate_diff; + min_idx = idx; + } + } + + return min_idx; +} + +static u16 find_up_nss_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, + u16 *data_rates, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + s16 cur_data_rate = data_rates[idx_to_offt(bw, nss, mcs, gi)]; + s16 min_idx = WRS_INVALID_RATE; + s16 idx; + s32 min_rate_diff = S32_MAX; + s32 rate_diff; + + for (idx = idx_to_offt(bw, ++nss, mcs, gi); !(idx < 0); + idx = idx_to_offt(bw, nss, --mcs, gi)) { + /* + * If data_rates[idx] == 0, the difference will be negative, + * so the condition below will not hold. + * Therefore, no need to check this possiblity specifically. + */ + rate_diff = data_rates[idx] - cur_data_rate; + if (rate_diff > 0 && + rate_diff < min_rate_diff && + (data_rates[idx] * 100) > (cur_data_rate * WRS_EPR_FACTOR)) { + min_rate_diff = rate_diff; + min_idx = idx; + } + } + + return min_idx; +} + +static u16 find_up_bf_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, + u16 *data_rates, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + s16 cur_data_rate = data_rates[idx_to_offt(bw, nss, mcs, gi)]; + s16 min_idx = WRS_INVALID_RATE; + s16 idx; + s32 min_rate_diff = S32_MAX; + s16 rate_diff; + + for (idx = idx_to_offt(bw, --nss, mcs, gi); !(idx < 0); + idx = idx_to_offt(bw, nss, ++mcs, gi)) { + /* + * If data_rates[idx] == 0, the difference will be negative, + * so the condition below will not hold. + * Therefore, no need to check this possiblity specifically. + */ + rate_diff = data_rates[idx] - cur_data_rate; + if (rate_diff > 0 && + rate_diff < min_rate_diff && + (data_rates[idx] * 100) > (cur_data_rate * WRS_EPR_FACTOR)) { + min_rate_diff = rate_diff; + min_idx = idx; + } + } + + return min_idx; +} + +static u16 find_up_gi_rate_idx(u32 bw, u32 nss, u32 mcs, u32 gi, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + s16 idx = idx_to_offt(bw, nss, mcs, gi + 1); + + return (idx < 0) ? WRS_INVALID_RATE : idx; +} + +static void _cl_wrs_tables_init(struct cl_wrs_table *ap_rate_table, + u16 *data_rates, + u32 bw, u32 nss, u32 mcs, u32 gi, + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi)) +{ + struct cl_wrs_table *cur_entry = NULL; + int i = 0; + u16 offt = idx_to_offt(bw, nss, mcs, gi); + + cur_entry = &ap_rate_table[offt]; + cur_entry->rate.bw = bw; + cur_entry->rate.nss = nss; + cur_entry->rate.mcs = mcs; + cur_entry->rate.gi = gi; + + /* If current rate is invalid, mark it as such and skip it. */ + if (!data_rates[offt]) { + cur_entry->rate_down.rate_idx = WRS_INVALID_RATE; + cur_entry->rate_down.time_th = WRS_MSEC_WEIGHT_MAX_DOWN; + + for (i = 0; i < WRS_TABLE_NODE_UP_MAX; i++) { + cur_entry->rate_up[i].rate_idx = WRS_INVALID_RATE; + cur_entry->rate_up[i].time_th = WRS_MSEC_WEIGHT_MAX_UP; + } + + return; + } + + cur_entry->rate_down.rate_idx = + find_down_rate_idx(bw, nss, mcs, gi, data_rates, idx_to_offt); + cur_entry->rate_up[WRS_TABLE_NODE_UP_MCS].rate_idx = + find_up_mcs_rate_idx(bw, nss, mcs, gi, data_rates, idx_to_offt); + cur_entry->rate_up[WRS_TABLE_NODE_UP_BW].rate_idx = + find_up_bw_rate_idx(bw, nss, mcs, gi, data_rates, idx_to_offt); + cur_entry->rate_up[WRS_TABLE_NODE_UP_NSS].rate_idx = + find_up_nss_rate_idx(bw, nss, mcs, gi, data_rates, idx_to_offt); + cur_entry->rate_up[WRS_TABLE_NODE_UP_BF].rate_idx = + find_up_bf_rate_idx(bw, nss, mcs, gi, data_rates, idx_to_offt); + cur_entry->rate_up[WRS_TABLE_NODE_UP_GI].rate_idx = + find_up_gi_rate_idx(bw, nss, mcs, gi, idx_to_offt); + + cur_entry->rate_down.time_th = WRS_INIT_MSEC_WEIGHT_DOWN; + + for (i = 0; i < WRS_TABLE_NODE_UP_MAX; i++) + cur_entry->rate_up[i].time_th = + (cur_entry->rate_up[i].rate_idx == WRS_INVALID_RATE) ? + WRS_MSEC_WEIGHT_MAX_UP : WRS_INIT_MSEC_WEIGHT_UP; +} + +static void cl_wrs_tables_init(u8 mode) +{ + u32 bw, nss, mcs, gi; + u32 max_bw, max_nss, max_mcs, max_gi; + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi); + struct cl_wrs_table *ap_rate_table = NULL; + u16 *data_rates = NULL; + + if (mode == WRS_MODE_HE) { + idx_to_offt = idx_to_offt_he; + max_bw = CHNL_BW_MAX; + max_nss = WRS_SS_MAX; + max_mcs = WRS_MCS_MAX_HE; + max_gi = WRS_GI_MAX_HE; + ap_rate_table = (struct cl_wrs_table *)ap_rate_table_he; + data_rates = (u16 *)data_rate_he_x10; + } else if (mode == WRS_MODE_VHT) { + idx_to_offt = idx_to_offt_ht_vht; + max_bw = CHNL_BW_MAX; + max_nss = WRS_SS_MAX; + max_mcs = WRS_MCS_MAX_VHT; + max_gi = WRS_GI_MAX_VHT; + ap_rate_table = (struct cl_wrs_table *)ap_rate_table_ht_vht; + data_rates = (u16 *)data_rate_ht_vht_x10; + } else { + return; + } + + for (bw = 0; bw < max_bw; bw++) + for (nss = 0; nss < max_nss; nss++) + for (mcs = 0; mcs < max_mcs; mcs++) + for (gi = 0; gi < max_gi; gi++) + _cl_wrs_tables_init(ap_rate_table, + data_rates, + bw, + nss, + mcs, + gi, + idx_to_offt); +} + +void cl_wrs_tables_global_build(void) +{ + cl_wrs_tables_init(WRS_MODE_HE); + cl_wrs_tables_init(WRS_MODE_VHT); + cl_wrs_tables_build_sorted_he(); + cl_wrs_tables_build_sorted_ht_vht(); +} + +void cl_wrs_tables_reset(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_table_node *rate_up; + u16 rate_idx = 0; + u8 up_idx = 0; + + for (rate_idx = 0; rate_idx < wrs_params->table_size; rate_idx++) { + if (wrs_params->table[rate_idx].rate_down.rate_idx != WRS_INVALID_RATE) + wrs_params->table[rate_idx].rate_down.time_th = WRS_INIT_MSEC_WEIGHT_DOWN; + else + wrs_params->table[rate_idx].rate_down.time_th = wrs_db->time_th_max_down; + + wrs_params->table[rate_idx].rate_down.quick_up_check = false; + + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + rate_up = &wrs_params->table[rate_idx].rate_up[up_idx]; + + if (rate_up->rate_idx != WRS_INVALID_RATE) + rate_up->time_th = WRS_INIT_MSEC_WEIGHT_UP; + else + rate_up->time_th = wrs_db->time_th_max_up; + + rate_up->quick_up_check = false; + } + + wrs_params->table[rate_idx].frames_total = 0; + wrs_params->table[rate_idx].ba_not_rcv_total = 0; + wrs_params->table[rate_idx].epr_acc = 0; + } +} + +static bool cl_wrs_is_rate_valid_he(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, u8 bw, + u8 nss, u8 mcs, u8 gi) +{ + /* Disable rates according to ce_he_mcs_nss_supp_tx */ + if ((cl_hw->conf->ce_he_mcs_nss_supp_tx[nss] + 1) <= mcs) + return false; + + /* TB flow doesn't support 0.8us GI */ + if (WRS_TYPE_IS_RX(wrs_params) && gi == WRS_GI_VSHORT) + return false; + + if (data_rate_he_x10[nss][bw][mcs][gi] < (10 * wrs_sta->he_minrate)) + return false; + + return true; +} + +static bool cl_wrs_is_rate_valid_vht(struct cl_hw *cl_hw, u8 bw, u8 nss, u8 mcs) +{ + /* Disable BW160 */ + if (bw == CHNL_BW_160) + return false; + + /* Disable VHT invalid rates (MCS9 20M 1SS, MCS9 20M 2SS, MCS6 80M 3SS, MCS9 20M 4SS) */ + if (bw == CHNL_BW_20 && mcs == WRS_MCS_9) + if (nss == WRS_SS_1 || nss == WRS_SS_2 || nss == WRS_SS_4) + return false; + + if (bw == CHNL_BW_80 && mcs == WRS_MCS_6 && nss == WRS_SS_3) + return false; + + /* Disable rates according to ce_vht_mcs_nss_supp_tx */ + if ((cl_hw->conf->ce_vht_mcs_nss_supp_tx[nss] + 1) <= mcs) + return false; + + return true; +} + +static bool cl_wrs_is_rate_valid(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + if (gi > wrs_db->max_cap.gi || gi > wrs_sta->gi_cap[bw]) + return false; + + if (mode == WRS_MODE_HE) + return cl_wrs_is_rate_valid_he(cl_hw, wrs_sta, wrs_params, bw, nss, mcs, gi); + + if (mode == WRS_MODE_VHT) + return cl_wrs_is_rate_valid_vht(cl_hw, bw, nss, mcs); + + return true; +} + +static bool cl_wrs_is_rate_supported(u64 *rate_bitmap, u8 bw, u8 nss, u8 mcs) +{ + u8 rate_idx = mcs + (nss * WRS_MCS_MAX); + u64 mask = BIT(rate_idx); + + return rate_bitmap[bw] & mask; +} + +static bool cl_wrs_tables_is_up_invalid(struct cl_wrs_table *table) +{ + /* + * The UP_GI is not part of this if condition, because we would + * like to set the same up candidate for LGI & SGI (except the + * up from LGI to SGI). + */ + return ((table->rate_up[WRS_TABLE_NODE_UP_MCS].rate_idx == WRS_INVALID_RATE) && + (table->rate_up[WRS_TABLE_NODE_UP_BW].rate_idx == WRS_INVALID_RATE) && + (table->rate_up[WRS_TABLE_NODE_UP_NSS].rate_idx == WRS_INVALID_RATE) && + (table->rate_up[WRS_TABLE_NODE_UP_BF].rate_idx == WRS_INVALID_RATE) && + (table->rate_up[WRS_TABLE_NODE_UP_GI].rate_idx == WRS_INVALID_RATE)); +} + +static int cl_wrs_tables_max(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + u8 *max_bw, u8 *max_nss, u8 *max_mcs, u8 *max_gi) +{ + *max_bw = wrs_sta->max_rate_cap.bw; + *max_nss = wrs_sta->smps_enable ? WRS_SS_1 : wrs_sta->max_rate_cap.nss; + + switch (wrs_sta->mode) { + case WRS_MODE_CCK: + *max_mcs = WRS_MCS_3; + *max_gi = WRS_GI_LONG; + break; + case WRS_MODE_OFDM: + *max_mcs = WRS_MCS_7; + *max_gi = WRS_GI_LONG; + break; + case WRS_MODE_HT: + *max_mcs = WRS_MCS_7; + *max_gi = WRS_GI_SHORT; + break; + case WRS_MODE_VHT: + *max_mcs = WRS_MCS_9; + *max_gi = WRS_GI_SHORT; + break; + case WRS_MODE_HE: + *max_mcs = WRS_MCS_11; + *max_gi = WRS_GI_VSHORT; + + if (!cl_hw->conf->ce_txldpc_en) { + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + + wrs_pr_verbose(wrs_db, + "TX LDPC disabled: limit BW to 20MHz and MCS to 9\n"); + *max_mcs = WRS_MCS_9; + *max_bw = CHNL_BW_20; + } + break; + default: + return -1; + } + + return 0; +} + +void cl_wrs_tables_build(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params) +{ + struct cl_wrs_db *wrs_db = &cl_hw->wrs_db; + u8 bw = 0; + u8 nss = 0; + u8 mcs = 0; + u8 gi = 0; + u8 max_bw = 0; + u8 max_nss = 0; + u8 max_mcs = 0; + u8 max_gi = 0; + u8 up_idx = 0; + u8 type = wrs_params->type; + u16 rate_idx = 0; + u16 new_rate_idx = 0; + u16 tmp_rate_idx = 0; + u16 max_table_size = 0; + u16 new_table_size = 0; + u16 (*idx_to_offt)(u32 bw, u32 nss, u32 mcs, u32 gi); + u16 *rate_idx_sorted_by_data_rate; + struct cl_wrs_table *ap_rate_table; + struct cl_wrs_table *new_table = NULL; + struct cl_wrs_table_validity *valid_rates = NULL; + + if (cl_wrs_tables_max(cl_hw, wrs_sta, &max_bw, &max_nss, &max_mcs, &max_gi)) + return; + + if (wrs_sta->mode == WRS_MODE_HE) { + max_table_size = WRS_HE_RATE_TABLE_SIZE; + idx_to_offt = idx_to_offt_he; + ap_rate_table = (struct cl_wrs_table *)ap_rate_table_he; + rate_idx_sorted_by_data_rate = rate_idx_sorted_by_data_rate_he; + } else { + max_table_size = WRS_HT_VHT_RATE_TABLE_SIZE; + idx_to_offt = idx_to_offt_ht_vht; + ap_rate_table = (struct cl_wrs_table *)ap_rate_table_ht_vht; + rate_idx_sorted_by_data_rate = rate_idx_sorted_by_data_rate_ht_vht; + } + + valid_rates = kzalloc(max_table_size * sizeof(struct cl_wrs_table_validity), GFP_ATOMIC); + if (!valid_rates) + goto out; + + wrs_sta->max_rate_cap.mcs = WRS_MCS_0; + wrs_sta->max_rate_cap.gi = WRS_GI_LONG; + + for (bw = 0; bw <= max_bw; bw++) { + for (nss = 0; nss <= max_nss; nss++) { + for (mcs = 0; mcs <= max_mcs; mcs++) { + for (gi = 0; gi <= max_gi; gi++) { + rate_idx = idx_to_offt(bw, nss, mcs, gi); + valid_rates[rate_idx].is_valid = + cl_wrs_is_rate_supported(wrs_sta->supported_rates, + bw, nss, mcs) && + cl_wrs_is_rate_supported(wrs_db->ap_supported_rates, + bw, nss, mcs) && + cl_wrs_is_rate_valid(cl_hw, wrs_sta, wrs_params, + wrs_sta->mode, + bw, nss, mcs, gi); + + if (!valid_rates[rate_idx].is_valid) + continue; + + valid_rates[rate_idx].new_rate_idx = new_table_size; + new_table_size++; + + if (WRS_TYPE_IS_TX_MU_MIMO(wrs_params)) + continue; + + if (mcs > wrs_sta->max_rate_cap.mcs) + wrs_sta->max_rate_cap.mcs = mcs; + + if (gi > wrs_sta->max_rate_cap.gi) + wrs_sta->max_rate_cap.gi = gi; + } + } + } + } + + if (new_table_size == 0) { + /* Error - size of table is 0, add single rate (mcs 0, 1 SS, bw 20 Mhz) */ + wrs_pr_err(wrs_db, "[%s] Table build error - Size of table is 0\n", + WRS_TYPE_STR(type)); + cl_wrs_sta_set_supported_rate(wrs_sta, CHNL_BW_20, WRS_SS_1, WRS_MCS_0); + valid_rates[0].new_rate_idx = 0; + valid_rates[0].is_valid = 1; + new_table_size = 1; + } + + new_table = kzalloc(new_table_size * sizeof(struct cl_wrs_table), GFP_ATOMIC); + + if (!new_table) + goto out; + + for (rate_idx = 0; rate_idx < max_table_size; rate_idx++) { + if (!valid_rates[rate_idx].is_valid) + continue; + + memcpy(new_table + new_rate_idx, + ap_rate_table + rate_idx, + sizeof(struct cl_wrs_table)); + + /* Set down rate */ + tmp_rate_idx = ap_rate_table[rate_idx].rate_down.rate_idx; + + while ((!valid_rates[tmp_rate_idx].is_valid) && + (ap_rate_table[tmp_rate_idx].rate_down.rate_idx != tmp_rate_idx)) + tmp_rate_idx = ap_rate_table[tmp_rate_idx].rate_down.rate_idx; + + if (valid_rates[tmp_rate_idx].is_valid) { + new_table[new_rate_idx].rate_down.rate_idx = + valid_rates[tmp_rate_idx].new_rate_idx; + } else { + u16 i = 0; + u16 down_idx = 0; + u16 down_rate_idx = new_rate_idx; + + while (new_table[new_rate_idx].rate_down.rate_idx != + rate_idx_sorted_by_data_rate[i]) { + down_idx = rate_idx_sorted_by_data_rate[i]; + + if (valid_rates[down_idx].is_valid) + down_rate_idx = valid_rates[down_idx].new_rate_idx; + i++; + } + + new_table[new_rate_idx].rate_down.rate_idx = down_rate_idx; + } + + /* Set up rates */ + for (up_idx = 0; up_idx < WRS_TABLE_NODE_UP_MAX; up_idx++) { + tmp_rate_idx = new_table[new_rate_idx].rate_up[up_idx].rate_idx; + + if (tmp_rate_idx != WRS_INVALID_RATE && + valid_rates[tmp_rate_idx].is_valid) + new_table[new_rate_idx].rate_up[up_idx].rate_idx = + valid_rates[tmp_rate_idx].new_rate_idx; + else + new_table[new_rate_idx].rate_up[up_idx].rate_idx = WRS_INVALID_RATE; + } + + /* + * In case all the UP rates are invalid, find one available UP + * rate based on PHY rate + */ + if (cl_wrs_tables_is_up_invalid(&new_table[new_rate_idx])) { + u16 i = 0; + + for (i = 0; i < max_table_size; i++) + if (rate_idx == rate_idx_sorted_by_data_rate[i]) + break; + + i++; + + while (i < max_table_size) { + tmp_rate_idx = rate_idx_sorted_by_data_rate[i]; + if (!valid_rates[tmp_rate_idx].is_valid) { + i++; + continue; + } + + new_table[new_rate_idx].rate_up[WRS_TABLE_NODE_UP_MCS].rate_idx = + valid_rates[tmp_rate_idx].new_rate_idx; + break; + } + } + + new_rate_idx++; + } + + if (wrs_params->table) { + /* + * Copy epr_acc, frames_total and ba_not_rcv_total + * from the old table to the new table. + * Also, if initial_rate_idx is set, find the new + * value in the new table. + */ + u16 old_rate_idx = 0; + struct cl_wrs_rate *initial_old_rate = NULL; + + if (wrs_params->initial_rate_idx != WRS_INVALID_RATE) { + initial_old_rate = &wrs_params->table[wrs_params->initial_rate_idx].rate; + wrs_params->initial_rate_idx = WRS_INVALID_RATE; + } + + for (rate_idx = 0; rate_idx < new_table_size; rate_idx++) { + old_rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, + new_table[rate_idx].rate.bw, + new_table[rate_idx].rate.nss, + new_table[rate_idx].rate.mcs, + new_table[rate_idx].rate.gi); + + if (initial_old_rate && + new_table[rate_idx].rate.bw == initial_old_rate->bw && + new_table[rate_idx].rate.nss == initial_old_rate->nss && + new_table[rate_idx].rate.mcs == initial_old_rate->mcs && + new_table[rate_idx].rate.gi == initial_old_rate->gi) { + wrs_params->initial_rate_idx = rate_idx; + initial_old_rate = NULL; + } + + if (old_rate_idx == WRS_INVALID_RATE) + continue; + + new_table[rate_idx].epr_acc = + wrs_params->table[old_rate_idx].epr_acc; + new_table[rate_idx].frames_total = + wrs_params->table[old_rate_idx].frames_total; + new_table[rate_idx].ba_not_rcv_total = + wrs_params->table[old_rate_idx].ba_not_rcv_total; + } + + kfree(wrs_params->table); + } + + wrs_params->table = new_table; + wrs_params->table_size = new_table_size; + + if (wrs_params->rate_idx != WRS_INVALID_RATE) { + /* + * Check if current rate is included in the new table. + * If not select a rate from the new table accroding to rssi. + */ + struct cl_wrs_rate_params *rate_params = &wrs_params->rate_params; + + rate_idx = cl_wrs_tables_find_rate_idx(wrs_params, + rate_params->bw, rate_params->nss, + rate_params->mcs, rate_params->gi); + + if (rate_idx != WRS_INVALID_RATE) { + wrs_params->rate_idx = rate_idx; + } else { + if (wrs_params->is_fixed_rate) { + wrs_params->is_fixed_rate = false; + wrs_pr_verbose(wrs_db, + "[%s] Disable fixed rate for station %u\n", + WRS_TYPE_STR(type), wrs_sta->sta_idx); + } + + cl_wrs_sta_select_first_rate(cl_hw, wrs_db, wrs_sta, wrs_params); + cl_wrs_cntrs_reset(wrs_sta, wrs_params); + } + } + +out: + kfree(valid_rates); +} + +u16 cl_wrs_tables_find_rate_idx(struct cl_wrs_params *wrs_params, + u8 bw, u8 nss, u8 mcs, u8 gi) +{ + struct cl_wrs_table *table = wrs_params->table; + u16 rate_idx = 0; + + for (rate_idx = 0; rate_idx < wrs_params->table_size; rate_idx++) + if (bw == table[rate_idx].rate.bw && + nss == table[rate_idx].rate.nss && + mcs == table[rate_idx].rate.mcs && + gi == table[rate_idx].rate.gi) + return rate_idx; + + return WRS_INVALID_RATE; +} + From patchwork Tue May 24 11:35:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576830 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 81BE6C433F5 for ; Tue, 24 May 2022 11:41:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236609AbiEXLly (ORCPT ); Tue, 24 May 2022 07:41:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236945AbiEXLlw (ORCPT ); Tue, 24 May 2022 07:41:52 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00078.outbound.protection.outlook.com [40.107.0.78]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17FB7614F for ; Tue, 24 May 2022 04:41:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bcXTaLL6d7vyXs6bySyCzvEPt/t80zB1P+klCspzKHY3LK7cQ7cPHZljxwyQ2TcV/IQ0KkbRDTNmkXzyX+fhiwvRLPJWwokN6rsaafUgPLPR/ko1/JkMoE3qisgjrGcc5CfYcALLr4gZs29kPtbs1njTzMAqNOl7eIF9EPc5WSosBWIQXsanUhzim2zeZIlZzNabXL4aP/HYTMCOMv+/tA15TWvZRL63F168FpWntnK9jPiYr8/gzs/gdkXkFVm6+/3fufei06266gP04arrIHKSy7h4AqROkyldtfUPQ43HG+u4kb2ABClyU+QUopAsqO+T9V9p1jmiUnnji9m1tw== 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=mvsWW9LDg7mrJG0nernJxj5Xn8PXcHvPhbWwo6lXWEk=; b=mtZiOZCG689/VEXIsfCObwdmbbLxx2PQVpUWIWTQ6LmxfKt7EYZBFQ0Y/8bniYSgOdaeX5uDp1b8QlR638/TWe3gk3Ua0isIIAam14u3EiC2wTWqzntSVR7hUoh059EYApuBKbUIR6xyKX+R4dTxFkn0RQgNX2hXj4RFKX0njj3z3GgXn4iMDaPu5foZQBCPgg2Av/aryEIlxlqtpztBOpM+atA7pZpOELnlf4mxGjEC4sPjAnHBvEI7dulzZluf/hQ4MVBByY1llKXHvj9C3ZosYbCDkiwG9qkrehLV05WKzgpqLDprRpESzLj43RCdwW0jBVQqtGa2nqf/P8z1lQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mvsWW9LDg7mrJG0nernJxj5Xn8PXcHvPhbWwo6lXWEk=; b=prP7AWse8sH6HrZkcMBlX71TnZNy8fiQjBuMglltmQJNX4YEd0Nuvw8z4QKIeKxr378AHUHDZ5hpzwNVSjH07fQXL8y5MUsHsVsas07Ql+RwcHUVXuCr5yYls9/DgROG4fT6rjlj+nW+lvilt3TiCa6rwxj3Rz42aM6awK1y7Ws= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:07 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:07 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 95/96] cl8k: add wrs.h Date: Tue, 24 May 2022 14:35:01 +0300 Message-Id: <20220524113502.1094459-96-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ef899d36-d152-433c-c081-08da3d7a020a X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: k5XryspG/xy+oTiikFcIwxLhrCfQmuNjQ7XrZd4NVYfR9yGuRO0P8U5I1rRrFcZt1l1XaLXME4EMgeoKe3jgREVaSTm5vQV517V5mGTvy2B30qKH3A8s/vdStBvyOZa28/0DtE8sk43iP52fc8ID6a9oaz5ZqUIFbfeT5uHWcj84E7RuDzzq4joHVzvXkaSD5JB9qhuuS6FY9o64bpbo0xcvlZ4+yQvMM2mbmBqE+Qk8biKmkIoMv266b3mLaWjL9CXYke1IQ+94NzIhS6ribRm1MWZQIQS5aDM3/j+IF/2h+mLqq/77jBaIIGIUY/itOEvTiC8iHyKBScq458bKvAhvVAPIzS0DxFXk/T53/F0plNfek52MbDHaYnW0OBCP8uA4nt82wHfVcqosYe6JPuqQhw+rUcCeLK+ldPSTywjfEOgCln2o7I9GwWIcNTfx+Y/7VjkibyLIqh7ot7FzuboAWpvxw3AYqiuw7lpjPtqwAmKFpTHzd+8/ux3SvS7dhkC+Twav7vr0cm6exIc6R+ucVvzBAuyMow752XavuIHYjHpY+oVULL+Mu6WvtbrrD7rO035R3CEWttHItllaCfXQArrHXarmg+SyRHoj2QBCjS7CVm6UXWZBWBS7XjIgNcr13p32cWdNP8SnGFn90WmGMNOcE3uBc0xY/Nf13U6OeldVPeW7MT/IVWRM2d5X1TJXF0Wb9nRRtNNaXVHEWNwP6SPQm8P4hUwgAI95VOU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(30864003)(107886003)(5660300002)(508600001)(83380400001)(8936002)(186003)(1076003)(41300700001)(6666004)(32563001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: EMHj+qm5XGBwJfVZ8m6jHJ0WCzaDzxUfPXGocYPsfTRv/OA1Inmo0eILL/USNbrOtEYWlgBdCNZq+YlPhQY4wJm/gllL7KSohaVg/nUo6VdryiNq+HYqNXkK+OJ0oezuV/WsJndKNfaZC06kl8UNg/0sS+q1kIdFXJX/x5FhJZftyefsBtOIuH4N7Tho0fXPQvOQLvt0VUJrN/3jmWFWLOAe6gTVPiSnSceOtu4vMdSylb0Prs887voVVUWmYFXlCkJsw8VKLOJvBQihyz2dOtVxLPwr0erv5GBR+CVSAhmdjEUkSrYFRnKc6BkAIFAi7I/VWEp2jPJCrR6teL0ROBp2ls0MY0J4Vq5qvw/Hu6U9FhvYh2oT5UnY740o/eFUTEXuGj+lUYK+k2hgOOBK9b8cvN61u2euR924ViFaKDzaSHxr48KQ/4I9lX61vSgoI5waUuCCD6hEsHyAWgLIrsHMYr38q28V/UnwoAj+h+1jr83wZ0XUoi9CT7spuja2JJRfjTw3cwAUF8BdMkDUDGgFl3wEZR9/ieVeHfgHVyBwftPa3ZXteuwiMFbkhHQ1e3jklP6B4IN+gwrW5fqfYcmK8bZKrA9XJq9XDnvT9xDiGOp+bo0PesZ27BPpUzgsvW8/hGHNldCmuPEhwzRR+Rq/X/EGpVUoLhgtctTNaHyZfkDeyXvJfkVGcS2pWLJLFoxE8dQiW7PgF+09P+/bgdGj+6K6mFfqKzQVw15RMGNqvpIB37b+8XKGWAAS3Z1+l+NvwBnc9jQfaqJ9A814fL8Vv2kK72hx7tuhasB7M1LOr57V3V63N63bTje42uTelrYp2JLW62rQmUGKfsL3M1tPOiRVQuI69Hce+/N9cZl9hUReKuplCBnWN0jqrqq+/fwSic6PkIOoZCML79uqIHKaMJ8OR/ztFbngZGgDyG2p9PWP/u8lvvx9zd6ATb//mKvlCGK5lovrgF/L4+m+2M+bqbQ/tBPxKx/cgEfcqemFg9cLssnzY5sW3IvmUcjKakzp3oHJxMwdxpD7vJOJNbib7LFxVvffAH70096xVgtWj8A0u7nFff0s8hsfQe1vnVdkc6hpEB+3FqXn+lkeIXXWZenURWui+YOfFRHF8l/6Upn5R0anuXaikKIiAWMSfHBV5w+aDZA8h0U4o/nS8N+fvu1PO3XxHjp/QEAHqJ+U9RqZDa2mTbt54p6WwPEZHHIt7qyBQA52hgoRtz41majm/pRzzA+smbu8KZFSe3eYk5G+ydrAmf407Zz+2wbzcnYLTrlBTAv/qxpLN4IhT6jfEPh4GpisXl4nk1C2SIqnEuM3SPa03L4+Ycs7nvLo5ABtr7e6uC2drjlQAXVsuDmqHtdbvd7ozMfwAjr9VbL+InE63QZHewZgOEMcCGbyeixYzAHYdcxCf7UDi0iSG0s6sXsYI5QmOqi/gAigMs019dhMJO0G0iiPTrTwGFUnzeyrutamurqGt0uMEQOvqYuiQcFIcE2JqPjX7P3R42+ln3ttlvwzATsWHdVIq+sQ5TyDYLVZd5hd0pjun39YVbiNj0EuC5TuS1hKEFu9IJS97s409v7zuMuORwKFNyGgkmoIAke0yBgrcYeQAHQgl5pOzEg577OZItWcQC9kSO5osXz2XnB1PWY1K187TQF6odCOpAlKP1PThyx8oBb5N3oFKu0YrlxPSbCtkkQf68UlXMpKRMPZcF1RWGHfNscwgzme7sih1y5iiI3UKL4Wbj+TUwttNBEQweuG7xJzF0o= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: ef899d36-d152-433c-c081-08da3d7a020a X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:05.7472 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: vhW+kHXjCRWoeJ4GuK6Qg+XAVV062SaYFkj7Pxte8qs0suR9MSJPdw1b6L4Vm/jDmaUn0bEY9ty8CPfbcsblcA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/celeno/cl8k/wrs.h | 565 +++++++++++++++++++++++++ 1 file changed, 565 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/wrs.h diff --git a/drivers/net/wireless/celeno/cl8k/wrs.h b/drivers/net/wireless/celeno/cl8k/wrs.h new file mode 100644 index 000000000000..158d61b92ffc --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/wrs.h @@ -0,0 +1,565 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#ifndef CL_WRS_H +#define CL_WRS_H + +#include + +#include "def.h" +#include "debug.h" +#include "rx.h" + +/** + * WRS (=Weighted Rate Selection) + */ + +struct cl_hw; +struct cl_sta; +struct cl_vif; + +/* Rate Table Size */ +#define WRS_HE_RATE_TABLE_SIZE (WRS_MCS_MAX_HE * WRS_SS_MAX * CHNL_BW_MAX * WRS_GI_MAX_HE) +#define WRS_HT_VHT_RATE_TABLE_SIZE (WRS_MCS_MAX_VHT * WRS_SS_MAX * CHNL_BW_MAX * WRS_GI_MAX_VHT) + +/* Initial Thresholds */ +#define WRS_INIT_MSEC_WEIGHT_DOWN (WRS_MAINTENANCE_PERIOD_MS * 3) /* Msec */ +#define WRS_INIT_MSEC_WEIGHT_UP (WRS_MAINTENANCE_PERIOD_MS * 3) /* Msec */ + +#define WRS_MSEC_WEIGHT_MIN (WRS_MAINTENANCE_PERIOD_MS * 2) /* Msec */ +#define WRS_MSEC_WEIGHT_MAX_UP 30000 /* Msec */ +#define WRS_MSEC_WEIGHT_MAX_DOWN 4000 /* Msec */ +#define WRS_MSEC_STEP_DOWN 5000 /* Msec */ +#define WRS_MSEC_STEP_UP_SAME 1000 /* Msec */ +#define WRS_INVALID_RATE ((u16)(~0)) + +enum cl_wrs_table_node_up { + WRS_TABLE_NODE_UP_MCS, + WRS_TABLE_NODE_UP_BW, + WRS_TABLE_NODE_UP_NSS, + WRS_TABLE_NODE_UP_BF, + WRS_TABLE_NODE_UP_GI, + + WRS_TABLE_NODE_UP_MAX +}; + +struct cl_wrs_table_validity { + bool is_valid; + u16 new_rate_idx; +}; + +struct cl_wrs_table_node { + u16 rate_idx; + u16 time_th; + bool quick_up_check; +}; + +struct cl_wrs_rate { + u16 mcs : 4, + nss : 3, + bw : 2, + gi : 2, + rsv : 2; +}; + +struct cl_wrs_table { + struct cl_wrs_rate rate; + struct cl_wrs_table_node rate_down; + struct cl_wrs_table_node rate_up[WRS_TABLE_NODE_UP_MAX]; + u32 frames_total; + u32 ba_not_rcv_total; + u64 epr_acc; +}; + +#define WRS_MAINTENANCE_PERIOD_MS 40 +#define WRS_DATA_RATE_FACTOR 10 +#define WRS_RSSI_PROTECT_UP_THR 10 +#define WRS_RSSI_PROTECT_DN_THR 10 +#define WRS_MIN_FRAMES_FOR_DECISION 15 +#define WRS_EPR_FACTOR 105 +#define WRS_CONVERGE_IDLE_PACKET_TH 5 +#define WRS_CONVERGE_IDLE_INTERVAL_RESET 6000 /* 6 sec */ +#define WRS_CONVERGE_IDLE_INTERVAL_RSSI 2000 /* 2 sec */ +#define WRS_CONVERGE_TRFC_INTERVAL_STATIC 30000 /* 30 sec */ +#define WRS_CONVERGE_TRFC_INTERVAL_MOTION 1000 /* 1 sec */ +#define WRS_IMMEDIATE_DROP_EPR_FACTOR 70 /* 70% */ +#define WRS_IMMEDIATE_DROP_MAX_IN_ROW U32_MAX +#define WRS_SYNC_MIN_ATTEMPTS 4 +#define WRS_SYNC_TIMEOUT 1000 /* 1 sec */ +#define WRS_QUICK_UP_BA_THR 5 +#define WRS_QUICK_UP_INTERVAL_MS 1000 +#define WRS_QUICK_DOWN_EPR_FACTOR 85 +#define WRS_QUICK_DOWN_AGG_THR 3 +#define WRS_QUICK_DOWN_PKT_THR 60 +#define WRS_RSSI_PROTECT_SHIFT 7 +#define WRS_RSSI_PROTECT_BUF_SZ_OLD BIT(WRS_RSSI_PROTECT_SHIFT) /* 2 ^ 7 = 128 */ +#define WRS_RSSI_PROTECT_BUF_SZ_NEW 3 +#define WRS_BA_NOT_RCV_TIME_SINCE_SYNC 1000 +#define WRS_CCA_PERIOD_MS 1000 +#define WRS_CCA_PRIMARY_SHIFT 7 +#define WRS_CCA_PRIMARY_FACTOR 160 /* 160 / 2^7 = 1.25 = 25% */ + +enum cl_wrs_rssi_prot_mode { + WRS_RSSI_PROT_MODE_RSSI, /* Up/down based on rssi */ + WRS_RSSI_PROT_MODE_NEIGHBOR, /* Up/down based on neighbors */ + + WRS_RSSI_PROTECT_MODE_MAX +}; + +enum cl_wrs_fixed_rate { + WRS_AUTO_RATE, + WRS_FIXED_FALLBACK_EN, + WRS_FIXED_FALLBACK_DIS, + + WRS_FIXED_RATE_MAX +}; + +enum cl_wrs_fixed_param { + WRS_FIXED_PARAM_MODE, + WRS_FIXED_PARAM_BW, + WRS_FIXED_PARAM_NSS, + WRS_FIXED_PARAM_MCS, + WRS_FIXED_PARAM_GI, + + WRS_FIXED_PARAM_MAX +}; + +#define FIXED_RATE_STR(x) \ + (((x) == WRS_AUTO_RATE) ? "auto rate" : \ + (((x) == WRS_FIXED_FALLBACK_EN) ? "fixed rate (fallbacks enabled)" : \ + "fixed rate (fallbacks disabled)")) + +enum cl_wrs_decision { + WRS_DECISION_NONE, + WRS_DECISION_SAME, + WRS_DECISION_UP, + WRS_DECISION_UP_QUICK, + WRS_DECISION_UP_RSSI, + WRS_DECISION_UP_MCS1, + WRS_DECISION_DOWN, + WRS_DECISION_DOWN_RSSI, + WRS_DECISION_DOWN_IMMEDIATE, + WRS_DECISION_DOWN_QUICK, + WRS_DECISION_DOWN_NO_SYNC, + WRS_DECISION_RSSI_MGMT, + WRS_DECISION_RX_RATE, + + WRS_DECISION_MAX, +}; + +enum cl_wrs_mcs { + WRS_MCS_0, + WRS_MCS_1, + WRS_MCS_2, + WRS_MCS_3, + WRS_MCS_4, + WRS_MCS_5, + WRS_MCS_6, + WRS_MCS_7, + WRS_MCS_8, + WRS_MCS_9, + WRS_MCS_10, + WRS_MCS_11, + WRS_MCS_MAX, +}; + +#define WRS_MCS_MAX_CCK WRS_MCS_4 +#define WRS_MCS_MAX_OFDM WRS_MCS_8 +#define WRS_MCS_MAX_HT WRS_MCS_8 +#define WRS_MCS_MAX_VHT WRS_MCS_10 +#define WRS_MCS_MAX_HE WRS_MCS_MAX + +enum cl_wrs_ss { + WRS_SS_1, + WRS_SS_2, + WRS_SS_3, + WRS_SS_4, + + WRS_SS_MAX +}; + +enum cl_wrs_gi { + WRS_GI_LONG, + WRS_GI_SHORT, + WRS_GI_VSHORT, + + WRS_GI_MAX +}; + +#define WRS_GI_MAX_HT WRS_GI_VSHORT +#define WRS_GI_MAX_VHT WRS_GI_VSHORT +#define WRS_GI_MAX_HE WRS_GI_MAX + +enum cl_wrs_ltf { + LTF_X1, + LTF_X2, + LTF_X4, + LTF_MAX +}; + +enum cl_wrs_converge_mode { + WRS_CONVERGE_MODE_RESET, + WRS_CONVERGE_MODE_RSSI, + + WRS_CONVERGE_MODE_MAX, +}; + +enum cl_wrs_mode { + WRS_MODE_CCK, + WRS_MODE_OFDM, + WRS_MODE_HT, + WRS_MODE_VHT, + WRS_MODE_HE, + + WRS_MODE_MAX, +}; + +enum cl_wrs_type { + WRS_TYPE_TX_SU, + WRS_TYPE_TX_MU_MIMO, + WRS_TYPE_RX, + + WRS_TYPE_MAX, +}; + +#define WRS_TYPE_STR(type) \ + ((type) == WRS_TYPE_TX_SU ? "TX_SU" : \ + ((type) == WRS_TYPE_RX ? "RX" : \ + ((type) == WRS_TYPE_TX_MU_MIMO ? "TX_MU-MIMO" : ""))) + +#define WRS_TYPE_IS_TX_SU(wrs_params) ((wrs_params)->type == WRS_TYPE_TX_SU) +#define WRS_TYPE_IS_TX_MU_MIMO(wrs_params) ((wrs_params)->type == WRS_TYPE_TX_MU_MIMO) +#define WRS_TYPE_IS_RX(wrs_params) ((wrs_params)->type == WRS_TYPE_RX) + +/* m MUST be power of 2 ! */ +#define WRS_INC_POW2(c, m) (((c) + 1) & ((m) - 1)) + +#define WRS_INC(c, m) \ + do { \ + (c)++; \ + if ((c) == (m)) \ + (c) = 0; \ + } while (0) + +#define WRS_IS_DECISION_UP(decision) \ + (((decision) >= WRS_DECISION_UP) && ((decision) <= WRS_DECISION_UP_MCS1)) +#define WRS_IS_DECISION_DOWN(decision) \ + (((decision) >= WRS_DECISION_DOWN) && ((decision) <= WRS_DECISION_DOWN_NO_SYNC)) + +#define WRS_DECISION_STR(decision) ( \ + (decision) == WRS_DECISION_NONE ? "NONE" : \ + (decision) == WRS_DECISION_SAME ? "SAME" : \ + (decision) == WRS_DECISION_UP ? "UP" : \ + (decision) == WRS_DECISION_UP_QUICK ? "UP QUICK" : \ + (decision) == WRS_DECISION_UP_RSSI ? "UP RSSI" : \ + (decision) == WRS_DECISION_UP_MCS1 ? "UP MCS1" : \ + (decision) == WRS_DECISION_DOWN ? "DOWN" : \ + (decision) == WRS_DECISION_DOWN_RSSI ? "DOWN RSSI" : \ + (decision) == WRS_DECISION_DOWN_IMMEDIATE ? "DOWN IMMEDIATE" : \ + (decision) == WRS_DECISION_DOWN_QUICK ? "DOWN QUICK" : \ + (decision) == WRS_DECISION_DOWN_NO_SYNC ? "DOWN NO_SYNC" : \ + (decision) == WRS_DECISION_RSSI_MGMT ? "RSSI MGMT" : \ + (decision) == WRS_DECISION_RX_RATE ? "RX_RATE" : \ + "ERROR") + +struct cl_wrs_cntrs { + u64 epr_acc; + u32 total; + u32 fail; + u32 ba_not_rcv; + u32 ba_not_rcv_consecutive; +}; + +struct cl_wrs_rate_params { + u16 mode : 3, /* Mode - 0 = CCK, 1 = OFDM, 2 = HT, 3 = VHT, 4 = HE. */ + gi : 2, /* GI - O = Long, 1 = Short, 2 = Very short. */ + bw : 2, /* Bandwidth - 0 = 20M, 1 = 40M, 2 = 80M, 3 = 160M. */ + nss : 3, /* Spatial Streams - 0 = 1SS, 1 = 2SS, .. 7 = 8SS. */ + mcs : 4, /* MCS - CCK (0 - 3), OFDM/HT (0 - 7), VHT (0 - 9), HE (0 - 11). */ + fallback_en : 1, + is_fixed : 1; +}; + +struct cl_wrs_logger { + unsigned long timestamp; + u16 rate_idx; + u32 success; + u32 fail; + u32 ba_not_rcv; + u16 down_rate_idx; + u16 up_rate_idx; + u16 curr_epr; + u16 down_epr; + u16 down_epr_factorized; + u16 penalty; + u16 up_time; + enum cl_wrs_decision decision; + u16 new_rate_idx; +}; + +struct cl_wrs_per_stats { + struct list_head list; + u8 mcs; + u8 bw; + u8 nss; + u8 gi; + u32 frames_total; + u32 frames_failed; + u64 epr_acc; +}; + +struct cl_wrs_rssi_prot_db { + s8 samples_old[WRS_RSSI_PROTECT_BUF_SZ_OLD]; + s8 samples_new[WRS_RSSI_PROTECT_BUF_SZ_NEW]; + u8 curr_idx_old; + u8 curr_idx_new; + s32 sum; +}; + +struct cl_wrs_params { + u8 group_id; + u8 is_mu_valid : 1, + is_fixed_rate : 2, + is_logger_en : 1, + quick_up_check : 1, + type : 2, + rsv : 1; + u32 up_same_time_cnt; + u32 down_time_cnt; + enum cl_wrs_converge_mode converge_mode; + u32 converge_time_idle; + u32 converge_time_trfc; + u16 data_rate; + u16 rate_idx; + u16 initial_rate_idx; + struct cl_wrs_table *table; + u16 table_size; + u16 penalty_decision_dn; + struct cl_wrs_rate_params rate_params; + struct cl_wrs_rate rx_rate_idle; + enum cl_wrs_decision last_decision; + u32 decision_cnt[WRS_DECISION_MAX]; + struct list_head list_rates; + u32 frames_total; + u32 fail_total; + u32 ba_not_rcv_total; + u64 epr_acc; + bool calc_ba_not_rcv; + bool sync; + unsigned long sync_timestamp; + unsigned long no_sync_timestamp; + struct cl_wrs_logger *logger; + u16 logger_idx; + u16 logger_size; + u32 immediate_drop_cntr; + u32 immediate_drop_ignore; +}; + +struct cl_wrs_sta { + u8 sta_idx; + bool smps_enable; + u8 assoc_bw; + u8 he_minrate; + u8 gi_cap[CHNL_BW_MAX]; + u64 supported_rates[CHNL_BW_MAX]; + enum cl_wrs_mode mode; + struct cl_wrs_rate max_rate_cap; + struct cl_wrs_rssi_prot_db rssi_prot_db; + struct cl_wrs_params tx_su_params; + struct cl_wrs_params *rx_params; +}; + +struct cl_wrs_db { + /* General */ + spinlock_t lock; + enum cl_dbg_level debug_level; + /* Timer */ + struct timer_list timer_maintenance; + u32 interval; + /* Fixed rate */ + u8 is_fixed_rate; + /* Conservative initial rate */ + bool conservative_mcs_noisy_env; + bool conservative_nss_noisy_env; + /* Immediate drop */ + bool immediate_drop_en; + u8 immediate_drop_epr_factor; + u32 immediate_drop_max_in_row; + /* Converge idle */ + bool converge_idle_en; + u32 converge_idle_interval_reset; + u32 converge_idle_interval_rssi; + u32 converge_idle_packet_th; + /* Converge traffic */ + bool converge_trfc_en; + u32 converge_trfc_interval_static; + u32 converge_trfc_interval_motion; + /* Supported rates */ + u8 mode; + u64 ap_supported_rates[CHNL_BW_MAX]; /* Bit array for each bw */ + struct cl_wrs_rate max_cap; + u8 coex_bw; + /* RSSI protect */ + bool rssi_protect_en; + u8 rssi_protect_mode; + s8 rssi_protect_up_thr; + s8 rssi_protect_dn_thr; + /* Time + step thresholds */ + u16 time_th_min; + u16 time_th_max_up; + u16 time_th_max_down; + u16 step_down; + u16 step_up_same; + /* Quick up */ + bool quick_up_en; + u8 quick_up_ba_thr; + u16 quick_up_interval; + /* Quick down */ + bool quick_down_en; + u8 quick_down_epr_factor; + u8 quick_down_agg_thr; + u16 quick_down_pkt_thr; + /* BA not received */ + bool ba_not_rcv_collision_filter; + bool ba_not_rcv_force; + u32 ba_not_rcv_time_since_sync; + /* Sync */ + u16 sync_timeout; + u8 sync_min_attempts; + /* CCA counters */ + unsigned long cca_timestamp; + u32 cca_primary; + u32 cca_sec80; + u32 cca_sec40; + u32 cca_sec20; + bool adjacent_interference20; + bool adjacent_interference40; + bool adjacent_interference80; + /* All the rest */ + u32 min_frames_for_decision; + u8 epr_factor; +}; + +struct cl_wrs_info { + u64 epr_acc; + u32 success; + u32 fail; + u32 fail_prev; + u32 ba_not_rcv; + u8 ba_not_rcv_consecutive; + u8 ba_not_rcv_consecutive_max; + bool synced; + u32 sync_attempts; + u8 quick_rate_agg_cntr; + u16 quick_rate_pkt_cntr; + bool quick_rate_check; +}; + +struct cl_wrs_rssi { + s32 sum[MAX_ANTENNAS]; + s32 cnt; +}; + +bool cl_wrs_rssi_set_rate(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta); +void cl_wrs_rssi_prot_start(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +bool cl_wrs_rssi_prot_decision(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + bool up_rate_valid, + u8 up_rate_idx, u8 down_rate_idx); +u16 cl_wrs_rssi_find_rate(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + s8 *rssi_sort); +void cl_wrs_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta); +bool cl_wrs_sta_add_mu(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, u8 group_id); +void cl_wrs_sta_add_rx(struct cl_hw *cl_hw, struct ieee80211_sta *sta); +void cl_wrs_sta_remove(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, struct cl_sta *cl_sta); +bool cl_wrs_sta_remove_mu(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta); +struct cl_wrs_sta *cl_wrs_sta_get(struct cl_hw *cl_hw, u8 sta_idx); +void cl_wrs_sta_select_first_rate(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params); +void cl_wrs_sta_capabilities_set(struct cl_wrs_db *wrs_db, struct ieee80211_sta *sta); +void cl_wrs_sta_set_supported_rate(struct cl_wrs_sta *wrs_sta, u8 bw, u8 nss, u8 mcs); +void cl_wrs_stats_per_update(struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + struct cl_wrs_cntrs *cntrs); +void cl_wrs_stats_per_init(struct cl_wrs_params *wrs_params); +void cl_wrs_stats_per_remove(struct cl_wrs_params *wrs_params); +void cl_wrs_tables_global_build(void); +void cl_wrs_tables_reset(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params); +void cl_wrs_tables_build(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params); +u16 cl_wrs_tables_find_rate_idx(struct cl_wrs_params *wrs_params, + u8 bw, u8 nss, u8 mcs, u8 gi); +void cl_wrs_init(struct cl_hw *cl_hw); +void cl_wrs_lock_bh(struct cl_wrs_db *wrs_db); +void cl_wrs_unlock_bh(struct cl_wrs_db *wrs_db); +void cl_wrs_lock(struct cl_wrs_db *wrs_db); +void cl_wrs_unlock(struct cl_wrs_db *wrs_db); +void cl_wrs_fixed_rate_set(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u8 is_fixed_rate, u8 mode, u8 bw, u8 nss, u8 mcs, u8 gi, bool mu_valid); +void cl_wrs_rate_param_sync(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params); +void cl_wrs_rate_params_update(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + u16 new_rate_idx, bool is_sync_required, bool mu_valid); +void cl_wrs_decision_make(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params, + enum cl_wrs_decision decision, u16 new_rate_idx); +void cl_wrs_decision_update(struct cl_wrs_db *wrs_db, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, enum cl_wrs_decision decision, + u16 new_rate_idx); +void cl_wrs_quick_down_check(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params); +bool cl_wrs_up_mcs1(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params); +void cl_wrs_rate_param_set(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + struct cl_wrs_params *wrs_params, + struct cl_wrs_rate_params *rate_params, + struct cl_wrs_rate *rate_fallback, + bool mu_mimo_valid, bool set_su); +s8 cl_wrs_rssi_eq_calc(struct cl_hw *cl_hw, struct cl_wrs_sta *wrs_sta, + bool read_clear, s8 *sorted_rssi); +void cl_wrs_cntrs_reset(struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params); +struct cl_wrs_info *cl_wrs_info_get(struct cl_sta *cl_sta, u8 type); +struct cl_wrs_params *cl_wrs_params_get(struct cl_wrs_sta *wrs_sta, u8 type); +void cl_wrs_update_rx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta, struct hw_rxhdr *rxhdr); +bool cl_wrs_set_rate_idle(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, + struct cl_wrs_sta *wrs_sta, struct cl_wrs_params *wrs_params); +struct cl_wrs_rate_params *cl_wrs_rx_rate_get(struct cl_sta *cl_sta); +void cl_wrs_rx_rate_idle_reset(struct cl_wrs_params *rx_params); +void cl_wrs_ap_capab_set(struct cl_hw *cl_hw, u8 bw, u8 use_sgi); +void cl_wrs_ap_capab_modify_bw(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, u8 max_bw); +void cl_wrs_ap_capab_modify_gi(struct cl_hw *cl_hw, struct cl_wrs_db *wrs_db, u8 use_sgi); +void cl_wrs_ap_capab_update(struct cl_hw *cl_hw, u8 bw, u8 use_sgi); + +/* Driver --> WRS */ +void cl_wrs_api_init(struct cl_hw *cl_hw); +void cl_wrs_api_close(struct cl_hw *cl_hw); +void cl_wrs_api_sta_add(struct cl_hw *cl_hw, struct ieee80211_sta *sta); +void cl_wrs_api_sta_remove(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_wrs_api_bss_set_bw(struct cl_hw *cl_hw, u8 bw); +void cl_wrs_api_bss_set_sgi(struct cl_hw *cl_hw, u8 use_sgi); +bool cl_wrs_api_bss_is_sgi_en(struct cl_hw *cl_hw); +void cl_wrs_api_nss_or_bw_changed(struct cl_hw *cl_hw, struct ieee80211_sta *sta, u8 nss, u8 bw); +void cl_wrs_api_he_minrate_changed(struct cl_sta *cl_sta, u8 he_minrate); +void cl_wrs_api_recovery(struct cl_hw *cl_hw); +void cl_wrs_api_beamforming_sync(struct cl_hw *cl_hw, struct cl_sta *cl_sta); +void cl_wrs_api_quick_down_check(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params); +void cl_wrs_api_rate_sync(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params); +bool cl_wrs_api_up_mcs1(struct cl_hw *cl_hw, struct cl_sta *cl_sta, + struct cl_wrs_params *wrs_params); +void cl_wrs_api_set_smps_mode(struct cl_hw *cl_hw, struct ieee80211_sta *sta, const u8 bw); +u16 cl_wrs_api_get_tx_sta_data_rate(struct cl_sta *cl_sta); +void cl_wrs_api_bss_capab_update(struct cl_hw *cl_hw, u8 bw, u8 use_sgi); +void cl_wrs_fill_sinfo_rates(struct rate_info *rate_info, + const struct cl_wrs_params *wrs_params, + const struct cl_sta *sta); + +#endif /* CL_WRS_H */ From patchwork Tue May 24 11:35:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Barna X-Patchwork-Id: 576835 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 EFD53C4332F for ; Tue, 24 May 2022 11:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236937AbiEXLl2 (ORCPT ); Tue, 24 May 2022 07:41:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237057AbiEXLlM (ORCPT ); Tue, 24 May 2022 07:41:12 -0400 Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00080.outbound.protection.outlook.com [40.107.0.80]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E95879548B for ; Tue, 24 May 2022 04:40:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YKUbRMWddtiCtijym/SD800e3K+6JfKZOWBvrLoC3hre2eF4NULDZitEAwQ9+7FEoQnvuYZkoxy4pcc8jVvO5odBKt7e184GbCp78/9sVhXGC6ucDZDKHf5qCQBZjEuTXlonMqOkXI3IvO3FKdhI1vdQTdC79B5stk1JGYE3Wwc+3Wg+ytJ4hydAOrnXMLmeeSXR03mr/rx3EFtz1B8OmQZuyQ0Qg+aSw7j5Kak85DNKsB3YROx8qS+Ne0G6u+0piB+yQ5uc2WmcvazqnXkeDKatUJTNBhhI3W9EkPMQCMqmbE//whgWm9Pz1QXXK0dSEdrgD3f+jutMG8uVmjkBDQ== 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=LjM1EzjCY3utdspDCfRR4v0P+u37DxPkAT/q/cJvYtA=; b=XJWxIU+VKq11BViszlLqmbjVKJe6Oxb4YV+nBzkwnieSXnoDIXauIXwEwxztSO1qJZmhWa42cf0yH5J+gPFluk3vacVj04fXdpwonm2DkBDmAbvWaxU9ETxaOQSzc/jowHQM+j107cD38A/W2If2yyPDYqq13D60EfxlBRPL0/8RGUq1ju928twAXtIeUzkg3alMj9e5Qcw3/SkDvDEpUORGkb6H1nr7tPTCqHSuMG+Anxequar0um0x/Srlvwe90yP8EgqA61Zp+oA2Z4qI3V2q7KtkCi7DrrcpZszGbOqO+deHSAXYdnlEjNvwFlT10Cgvxi5y+r6KAKwDFmWb8w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=celeno.com; dmarc=pass action=none header.from=celeno.com; dkim=pass header.d=celeno.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=celeno.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LjM1EzjCY3utdspDCfRR4v0P+u37DxPkAT/q/cJvYtA=; b=xsAL0uMB3+TLcud+XjKjmxdGjWBuBvoSbJWwqgiDsrCp561pBDhg1S/E2X7kDH+8nyjmUgV7JjhhI0bEvqLsUE98ddf3FaMjl4ZG3sMJ/Xh/0K/EsHAAVlzY08rg1J1fMVCxjS0C6lmm9hFPkm3Y9K6g6wPowQjej/Gr2GZA5y8= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=celeno.com; Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) by DBAP192MB1033.EURP192.PROD.OUTLOOK.COM (2603:10a6:10:1b4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.13; Tue, 24 May 2022 11:40:07 +0000 Received: from AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb]) by AM9P192MB1412.EURP192.PROD.OUTLOOK.COM ([fe80::6c57:2d13:9162:cbbb%8]) with mapi id 15.20.5293.013; Tue, 24 May 2022 11:40:07 +0000 From: viktor.barna@celeno.com To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "David S . Miller" , Jakub Kicinski , Aviad Brikman , Eliav Farber , Maksym Kokhan , Oleksandr Savchenko , Shay Bar , Viktor Barna Subject: [RFC v2 96/96] wireless: add Celeno vendor Date: Tue, 24 May 2022 14:35:02 +0300 Message-Id: <20220524113502.1094459-97-viktor.barna@celeno.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220524113502.1094459-1-viktor.barna@celeno.com> References: <20220524113502.1094459-1-viktor.barna@celeno.com> X-ClientProxiedBy: AM6PR10CA0092.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:8c::33) To AM9P192MB1412.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:38b::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: fecaddf6-17e7-458d-2bce-08da3d7a027d X-MS-TrafficTypeDiagnostic: DBAP192MB1033:EE_ X-LD-Processed: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8,ExtFwd X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 3gxnpxvrqdipqEZi7+TcBIaWMOQprFhv7/6lconKRD/CnuEt6vBg6mxCfjijm27JUsckwZgtOXF+5eix838wGAF5+bwS26NTM5RCy8xhKszL+gkgZvHQPYAJXWu2Kwcv9GsOnLjRM0IL1tF7rcPr3hI4n8TURXiL+f6ysCDP7hvdjQQHhTmMWRDhb3DA5fEvxQbBrV1wawKmrTkMeGoWzDnD96uMc47oXZGWYaARHyZSrygB5aMQWx6BNfxNMomjb6LbjWaIHkns6hFPDtoxoaRba9xEbNPSurq6Kg/6tRqvff8jJLgg+8ieiql4lwVafj2z3IJ/jzAlDiXBWf77nFawAn4hKXzPiQ3pQq0modFaTe4ZU0jfDG3je1ENWGCYwgkOwkwLUChiJSlOak2yUcZksBJ5uPQFRLJj230lwLl11RcGPixG9ggVY3C5wdm1Aebgj8rEE14CjGsW/Bt7IyBJfK46UMxpOCziNhjnCzx25Djk4FpzA1NjRmgTXJWzeWTa/2Fxxer5xX0yoNQghYPaO/o5R5vDsMSgZ/AYQayMZdWm6e7FQEsV8jqgEV/WW71Me7QXdAs6bkrPkkAJJ/36ahiabxyuMLldQn7OwQ00YXjItAA60426Ml9Ry4pjQ0cpi+qsZjgkQR3e/jx+iJP6ylvgZbYcdZSlmc0EKIQid3W1iL4iWXAexd/W8U7lomgmJTsR1Kxy/QH8BC+cMw== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM9P192MB1412.EURP192.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230001)(346002)(376002)(366004)(136003)(396003)(39850400004)(2906002)(4326008)(6916009)(38350700002)(8676002)(86362001)(316002)(54906003)(38100700002)(66476007)(66556008)(26005)(2616005)(52116002)(9686003)(36756003)(6486002)(66946007)(6512007)(6506007)(107886003)(5660300002)(508600001)(8936002)(186003)(1076003)(41300700001)(6666004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: V2YhkOIfMetucgA3iNVz8yYiFooehRU5BpXxk8YwAHysDYQS4YxT8i3FmAlb/+FCRcTZcXeHeZTyimw4drPNHEgGkA/iJrJiBXVX3ye/51OrUcMgBGBEooe142eoQpCUnMhv02WsvEpWHdcb64gJYSZXXtcE0b46GroptCUy3F8Y2pCMQAbbso/hCOCq4yT84w4ACWn8Ok1dPy0dueInesecpE2MD1zLARcw+AaIqE/7mBGu/jSVT/mteykOg+NvYQTEfwaYCtuwfGsxrFd0r9FDqquUWDcGx47t09ipTwy4HL5Id8ddZk8G98Djy89bqCZKzRweq5uaBpaOgqs9KpbRoepTJK0Umwl0qLXLNzCcnCxnhRdv6BVAZI2F6AvVhCYXaZ6JIUIbju+YemyonCtnTe6w3TQFa/mbXyooU8lP3XHJeZ0SJr8LmMo6cFkbqUHYmCfu5WhVPgDgoRVDip5Z8ieCQraq54gNgMgwHi5T8gFoKBt51iCt6ZL04h/ieJ7A3wde3DfF2oC7N0+Yd7lDmh/5FZWN34FMgj1zkEeYzcTqwF6e8J+FXvIE5KYrOEsQKdgLIPgb/8Bh8vXatBYoydURSLmAhF2lGa+sl0ah/zLK0PkZCjo8s6I8lRUesJOHOhoK4CAdNu7fpcadSWV+bOnSBnqYOI8e45Ca0tP6/D4CKm2bBz9MHA+gk9r3+mEMHdM6J0BO6viBt+aCfr7B0CymD0AGojQ0MMwrMUakW9lT5HqESCAhOw+e6nXd9coZwWeHRYefS5uSU5B1SbIiWqMbQxpqRxfJbLAe8Vwu7e/P9mBjj0tRQmFFKVgYL5dZpAQFWlGcTlK0GoRI+8oXKIKtk+7n2brIjWns6equGQwRpd71YXzIbnyWFk0z19s4wYNQc03INY3exgJZPpUGGw20hRB0CLYbVfl8e/W7fV5WfeVP+bZQBgfD4y+GiD3o8TfZFF97eMOudJAWnvPzStg66PCMp29l0HYa6YMPpbMA0sCBK6SiATSSzWt2rnCZj4Rp8x96ZBIgWiv8AE1m5/bwRxmnrhCOBS2DsjMu/DPgInSpxm0LhY6OKcO7AOhLi9NbzQyttm+uB1pI8FpQvNYS3qDWiAmQ4p/2TMXfAqPaC2PWpHi8D367MxjEXBAO6jjWP0ff+1sVH4sGwVpP7FsFRukcKMoy7AtdHdJQLDKQ9M4k7enNH6UOZ2JgGxDV/j8soHA1egutXdMSwM6Y3H+8MzOQ5JaL3EMikPiFdbX1FB9lLrwGZekBMz8nlr8mLV7fZImOTOVTTk3+9yXLlq/Gv6UDzPdY21CbwMwF7JgMAFWHTDOIrD3W0mdMOWL4I3dOL2W/v8Pdw38xYVUfIfZUEouaMLQyQ01ZPWjPx+oFtUBaHupXcPi8plWoM9E4btqIHuMAqEAOC70Gogic85zByJVU5dCw06+1gam7ovSEXbplUlcnBgEpqKqarnoFVZFXad/Rl9djLRSN1Mqq9kTYLfaMesLd3gqAXtsz4kqbztfjZ6ZdUgPuAHt1uguF60nbMxQTNXKubxF2nXGwqn2c55gbrgiDYlsUtFHDUeuoJbF+xUCXx5DBDuEak0ws/Kw7Gp0lPR9oLJ0NmmpLZPvlfkCrC1BEu5TP5hDQtHb4eCS4wugdtPC5EfCFOEUxbMWiNTyIFogEU1NZZlGEfidFX5jFby20bHcOxpYTNvwsYz+QHqXBwKEhyCqpr1UgNZTGb8pYBIAvvrS5qZrGYC7FwkacY7ULkWH+2CY= X-OriginatorOrg: celeno.com X-MS-Exchange-CrossTenant-Network-Message-Id: fecaddf6-17e7-458d-2bce-08da3d7a027d X-MS-Exchange-CrossTenant-AuthSource: AM9P192MB1412.EURP192.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2022 11:39:06.4814 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f313103b-4c9f-4fd3-b5cf-b97f91c4afa8 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ov8kJ3WUDgZBwONkW6HnWv1C1mBQnU5/KJ4LW4x/zFO45SegayKrMCbZJomnsy7JvVOhGAa5VY7Q/JXGlDXGbw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAP192MB1033 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Viktor Barna (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7add2002ff4c..444c81e3da06 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -35,6 +35,7 @@ source "drivers/net/wireless/st/Kconfig" source "drivers/net/wireless/ti/Kconfig" source "drivers/net/wireless/zydas/Kconfig" source "drivers/net/wireless/quantenna/Kconfig" +source "drivers/net/wireless/celeno/Kconfig" config PCMCIA_RAYCS tristate "Aviator/Raytheon 2.4GHz wireless support" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 80b324499786..3eb57351d0e5 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_WLAN_VENDOR_ST) += st/ obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ obj-$(CONFIG_WLAN_VENDOR_QUANTENNA) += quantenna/ +obj-$(CONFIG_WLAN_VENDOR_CELENO) += celeno/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o