From patchwork Thu May 28 15:12:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadym Kochan X-Patchwork-Id: 218318 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 465B5C433DF for ; Thu, 28 May 2020 15:13:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1641B2075F for ; Thu, 28 May 2020 15:13:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=plvision.eu header.i=@plvision.eu header.b="BGDkQ0sf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404207AbgE1PNf (ORCPT ); Thu, 28 May 2020 11:13:35 -0400 Received: from mail-vi1eur05on2129.outbound.protection.outlook.com ([40.107.21.129]:54914 "EHLO EUR05-VI1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404135AbgE1PNa (ORCPT ); Thu, 28 May 2020 11:13:30 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WKq8s+39iKmpmjtqWH3WUcHJ3duPxvK2lx0QuHIVXEfQYcv2Hc6ZZAIq5lOecOrHJusitlTeNLG/FlYa3SbSj/wgOATBnl17nJMVHl5THyIXBf44zyw1Fcv0rXaEpTsen7GcCi+nm+ZvyTl4zIGSju9ZxevcV+TNwjFpiA9pFmUbpf6GHXfIUoRHeiWELayb0SCySXUhG+Uymu4EpGNhw92vE56sWkhvvWPhf93uuYur7lvIG6TkqDzHWoCUVItLupnpJfs0hX/6JiJB5VLD9JeO4YlAopXzh43or8/DrGN4bDJFTbqvqMVmIuqzcfUUI7WJ6CD+7NfXUz4bnVMgBw== 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-SenderADCheck; bh=994SHS2O/PrS95cifgOXEnIBINDE1NPAkDDi9LRTbSc=; b=ZI/ukS3mLxV4LDN6WIgwDD9aYIMJMLgbm5XtVoT87z4XaVx2zgDwIfMe2bTFMHo7jbFAfN3/IUpMVAe2eb+m8XRWU1kGm5OPPcr0j/ZlheC/3+J5py5UrzIxUJQjRwFRcX+RTu3qgq2jL9HJ+Va3I1oeoanTkhOO6IOrQrFkFdQa0F7D6Rv88q2EG9siD3k+CzYfNe19KG6LRv8zMzPU0i/YonHibiE0F+nVJjMV2TWPRQpy85KKP4Vf1vu1wPevrMtsIexlyszAoDIBgz8kFkalhdOhpJde9Byrw8fx5AXijLAWaxo0EJvaQByCFC3v4SMCgvBVCeUOC3MNAELajQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=plvision.eu; dmarc=pass action=none header.from=plvision.eu; dkim=pass header.d=plvision.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=plvision.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=994SHS2O/PrS95cifgOXEnIBINDE1NPAkDDi9LRTbSc=; b=BGDkQ0sfPY2uhojmrTBsC/4Yb6Yd4RhkLdZowmrBUB09KXWQTTAHwuc2CXJkSQOWmBXQ83Ai2Rz9Ft/hHK3TAUrWEAFs0j3FZMdb33XDEyECOv7A+9/E3glUC1bRnOL4DeKtu/mIxNcJLW+Obn3k4hgciWFnwY2AWqmynGZEEI8= Authentication-Results: davemloft.net; dkim=none (message not signed) header.d=none; davemloft.net; dmarc=none action=none header.from=plvision.eu; Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) by VI1P190MB0224.EURP190.PROD.OUTLOOK.COM (2603:10a6:800:a4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23; Thu, 28 May 2020 15:13:09 +0000 Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f]) by VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f%7]) with mapi id 15.20.3045.018; Thu, 28 May 2020 15:13:09 +0000 From: Vadym Kochan To: "David S. Miller" , Jakub Kicinski , Jiri Pirko , Ido Schimmel , Andrew Lunn , Oleksandr Mazur , Serhiy Boiko , Serhiy Pshyk , Volodymyr Mytnyk , Taras Chornyi , Andrii Savka , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Mickey Rachamim , Vadym Kochan Subject: [net-next 3/6] net: marvell: prestera: Add basic devlink support Date: Thu, 28 May 2020 18:12:42 +0300 Message-Id: <20200528151245.7592-4-vadym.kochan@plvision.eu> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528151245.7592-1-vadym.kochan@plvision.eu> References: <20200528151245.7592-1-vadym.kochan@plvision.eu> X-ClientProxiedBy: AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) To VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from pc60716vkochan.x.ow.s (217.20.186.93) by AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.19 via Frontend Transport; Thu, 28 May 2020 15:13:08 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [217.20.186.93] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8b0792fc-b380-4361-0cc2-08d80319a1a7 X-MS-TrafficTypeDiagnostic: VI1P190MB0224: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:428; X-Forefront-PRVS: 0417A3FFD2 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: UqwgVTBgzkkhl8wzTvVKyKYv5mg5YVWF1O9O3LDJiaK2XXYG8QXb+rFui+g5aDaBCPkGtsk6W7qaZTi5KUmVFPl0EUDWsOWfUnI/tHVwAyJCH/zTbSpGgIdO7r0ihj1jcL61RdzgGC+UCTz+mKhnCQkv/dVX+yndUuIOaM85klsf4rF2Fp/2V0u/IysRcOx2vRRGotjCh4DCxU3NXvsUxb6OIlD+nld3dqDj7gu2Y/YiKCvbuo3hCRRgSpiDxY7DeJ+2XRZA2hHw2k00IcNJ5vCpvHvz7oDLAficnD6Eq1gCn+wR3O4sppZDgE+nWfaCG/fiqS/PFaOt8ImC8HMOUxzcyRwPSEZOkfIOncuukV5Dpxy+pVFbzw3pW6WtSHFP X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1P190MB0399.EURP190.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFTY:; SFS:(136003)(39830400003)(376002)(366004)(346002)(396003)(66476007)(316002)(66556008)(107886003)(5660300002)(6512007)(2616005)(508600001)(186003)(956004)(4326008)(1076003)(2906002)(16526019)(52116002)(26005)(6486002)(44832011)(54906003)(6506007)(66946007)(8936002)(8676002)(110136005)(86362001)(83380400001)(36756003)(6666004)(921003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData: tSxg6mT0DH/npIscwsvcOZ7wgCg2d/aRnHibbchaMcaQ+FpCLd/bKkoCKkj8Q4IDvfBneF125/By0ibQDJYyS50IcpxwMT8GDChjAxKbYyOvAvYJQvGHRsPrwcmSiyyNUV3c373EGXUfSwhsXryq613aizxob4Mm0amRt80M4AKzZtRfx6jL+nGG3FD+E980Ur/E5FPKxFXNy2Qb0KL9ypLsd+yXJikyidmaWEKGv5R3pNWFO/ngqphsdKm2uN8UYE6feyuLQDcF3gClkFNorZ2f4N0OENwS8pLaZjnr17p88UwTkF1G+PNk0xEVOBJpRzvNYhMdV1bOHss55ZW9dGOg7otRzqW/35vfU3cabKJitLqnglhr8rCuOLQh8r9XUBss+HWPbYaAAbllpzw68Vcln+i8GB5w3GeyC5uoWotJ9yt9ofm+dd4r8Wbn+JanM45HEX+LfJdyKpI0dcfbWhZ0Y9tfhNepOY/Q33BYUFw= X-OriginatorOrg: plvision.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 8b0792fc-b380-4361-0cc2-08d80319a1a7 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 May 2020 15:13:09.6898 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 03707b74-30f3-46b6-a0e0-ff0a7438c9c4 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 05xedvf0ldLbrpGrLCadfMZRzkq78X0Fu0Hd5sgKt2aI1Pmhi8W6N/pRM1Oh7nzsZttm91YA++Wgh5utoq2+r2cJAEoXDj3sMW7rcE0mXCo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P190MB0224 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add very basic support for devlink interface: - driver name - fw version - devlink ports Signed-off-by: Vadym Kochan --- drivers/net/ethernet/marvell/prestera/Kconfig | 1 + .../net/ethernet/marvell/prestera/Makefile | 2 +- .../net/ethernet/marvell/prestera/prestera.h | 4 + .../marvell/prestera/prestera_devlink.c | 111 ++++++++++++++++++ .../marvell/prestera/prestera_devlink.h | 25 ++++ .../ethernet/marvell/prestera/prestera_main.c | 27 ++++- 6 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_devlink.c create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_devlink.h diff --git a/drivers/net/ethernet/marvell/prestera/Kconfig b/drivers/net/ethernet/marvell/prestera/Kconfig index 0848edb272a5..dfd5174d0568 100644 --- a/drivers/net/ethernet/marvell/prestera/Kconfig +++ b/drivers/net/ethernet/marvell/prestera/Kconfig @@ -6,6 +6,7 @@ config PRESTERA tristate "Marvell Prestera Switch ASICs support" depends on NET_SWITCHDEV && VLAN_8021Q + select NET_DEVLINK help This driver supports Marvell Prestera Switch ASICs family. diff --git a/drivers/net/ethernet/marvell/prestera/Makefile b/drivers/net/ethernet/marvell/prestera/Makefile index 2146714eab21..babd71fba809 100644 --- a/drivers/net/ethernet/marvell/prestera/Makefile +++ b/drivers/net/ethernet/marvell/prestera/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PRESTERA) += prestera.o prestera-objs := prestera_main.o prestera_hw.o prestera_dsa.o \ - prestera_rxtx.o + prestera_rxtx.o prestera_devlink.o obj-$(CONFIG_PRESTERA_PCI) += prestera_pci.o diff --git a/drivers/net/ethernet/marvell/prestera/prestera.h b/drivers/net/ethernet/marvell/prestera/prestera.h index 5079d872e18a..f8abaaff5f21 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera.h +++ b/drivers/net/ethernet/marvell/prestera/prestera.h @@ -11,6 +11,9 @@ #include #include #include +#include + +#define PRESTERA_DRV_NAME "prestera" struct prestera_fw_rev { u16 maj; @@ -63,6 +66,7 @@ struct prestera_port_caps { struct prestera_port { struct net_device *dev; struct prestera_switch *sw; + struct devlink_port dl_port; u32 id; u32 hw_id; u32 dev_id; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c new file mode 100644 index 000000000000..58021057981b --- /dev/null +++ b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */ + +#include + +#include "prestera.h" +#include "prestera_devlink.h" + +static int prestera_dl_info_get(struct devlink *dl, + struct devlink_info_req *req, + struct netlink_ext_ack *extack) +{ + struct prestera_switch *sw = devlink_priv(dl); + char buf[16]; + int err = 0; + + err = devlink_info_driver_name_put(req, PRESTERA_DRV_NAME); + if (err) + return err; + + snprintf(buf, sizeof(buf), "%d.%d.%d", + sw->dev->fw_rev.maj, + sw->dev->fw_rev.min, + sw->dev->fw_rev.sub); + + err = devlink_info_version_running_put(req, + DEVLINK_INFO_VERSION_GENERIC_FW, + buf); + if (err) + return err; + + return 0; +} + +static const struct devlink_ops prestera_dl_ops = { + .info_get = prestera_dl_info_get, +}; + +struct prestera_switch *prestera_devlink_alloc(void) +{ + struct devlink *dl; + + dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch)); + + return devlink_priv(dl); +} + +void prestera_devlink_free(struct prestera_switch *sw) +{ + struct devlink *dl = priv_to_devlink(sw); + + devlink_free(dl); +} + +int prestera_devlink_register(struct prestera_switch *sw) +{ + struct devlink *dl = priv_to_devlink(sw); + int err; + + err = devlink_register(dl, sw->dev->dev); + if (err) { + dev_warn(sw->dev->dev, "devlink_register failed: %d\n", err); + return err; + } + + return 0; +} + +void prestera_devlink_unregister(struct prestera_switch *sw) +{ + struct devlink *dl = priv_to_devlink(sw); + + devlink_unregister(dl); +} + +int prestera_devlink_port_register(struct prestera_port *port) +{ + struct devlink *dl = priv_to_devlink(port->sw); + struct prestera_switch *sw; + int err; + + sw = port->sw; + dl = priv_to_devlink(sw); + + devlink_port_attrs_set(&port->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL, + port->fp_id, false, 0, + &port->sw->id, sizeof(port->sw->id)); + + err = devlink_port_register(dl, &port->dl_port, port->fp_id); + if (err) + dev_err(sw->dev->dev, "devlink_port_register failed: %d\n", err); + + return 0; +} + +void prestera_devlink_port_unregister(struct prestera_port *port) +{ + devlink_port_unregister(&port->dl_port); +} + +void prestera_devlink_port_type_set(struct prestera_port *port) +{ + devlink_port_type_eth_set(&port->dl_port, port->dev); +} + +struct devlink_port *prestera_devlink_get_port(struct net_device *dev) +{ + struct prestera_port *port = netdev_priv(dev); + + return &port->dl_port; +} diff --git a/drivers/net/ethernet/marvell/prestera/prestera_devlink.h b/drivers/net/ethernet/marvell/prestera/prestera_devlink.h new file mode 100644 index 000000000000..b46441d1e758 --- /dev/null +++ b/drivers/net/ethernet/marvell/prestera/prestera_devlink.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 + * + * Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. + * + */ + +#ifndef _PRESTERA_DEVLINK_H_ +#define _PRESTERA_DEVLINK_H_ + +#include "prestera.h" + +struct prestera_switch *prestera_devlink_alloc(void); +void prestera_devlink_free(struct prestera_switch *sw); + +int prestera_devlink_register(struct prestera_switch *sw); +void prestera_devlink_unregister(struct prestera_switch *sw); + +int prestera_devlink_port_register(struct prestera_port *port); +void prestera_devlink_port_unregister(struct prestera_port *port); + +void prestera_devlink_port_type_set(struct prestera_port *port); + +struct devlink_port *prestera_devlink_get_port(struct net_device *dev); + +#endif /* _PRESTERA_DEVLINK_H_ */ diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c index b5241e9b784a..ddab9422fe5e 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_main.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c @@ -14,6 +14,7 @@ #include "prestera.h" #include "prestera_hw.h" #include "prestera_rxtx.h" +#include "prestera_devlink.h" #define PRESTERA_MTU_DEFAULT 1536 @@ -185,6 +186,7 @@ static const struct net_device_ops netdev_ops = { .ndo_change_mtu = prestera_port_change_mtu, .ndo_get_stats64 = prestera_port_get_stats64, .ndo_set_mac_address = prestera_port_set_mac_address, + .ndo_get_devlink_port = prestera_devlink_get_port, }; static int prestera_port_autoneg_set(struct prestera_port *port, bool enable, @@ -234,9 +236,13 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id) &port->hw_id, &port->dev_id); if (err) { dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id); - goto err_port_init; + goto err_port_info_get; } + err = prestera_devlink_port_register(port); + if (err) + goto err_dl_port_register; + dev->features |= NETIF_F_NETNS_LOCAL; dev->netdev_ops = &netdev_ops; @@ -295,11 +301,16 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id) if (err) goto err_register_netdev; + prestera_devlink_port_type_set(port); + return 0; err_register_netdev: list_del_rcu(&port->list); err_port_init: + prestera_devlink_port_unregister(port); +err_dl_port_register: +err_port_info_get: free_netdev(dev); return err; } @@ -313,6 +324,7 @@ static void prestera_port_destroy(struct prestera_port *port) list_del_rcu(&port->list); + prestera_devlink_port_unregister(port); free_netdev(dev); } @@ -435,6 +447,10 @@ static int prestera_switch_init(struct prestera_switch *sw) if (err) return err; + err = prestera_devlink_register(sw); + if (err) + goto err_dl_register; + err = prestera_create_ports(sw); if (err) goto err_ports_create; @@ -442,6 +458,8 @@ static int prestera_switch_init(struct prestera_switch *sw) return 0; err_ports_create: + prestera_devlink_unregister(sw); +err_dl_register: prestera_event_handlers_unregister(sw); return err; @@ -450,6 +468,7 @@ static int prestera_switch_init(struct prestera_switch *sw) static void prestera_switch_fini(struct prestera_switch *sw) { prestera_destroy_ports(sw); + prestera_devlink_unregister(sw); prestera_event_handlers_unregister(sw); prestera_rxtx_switch_fini(sw); } @@ -459,7 +478,7 @@ int prestera_device_register(struct prestera_device *dev) struct prestera_switch *sw; int err; - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = prestera_devlink_alloc(); if (!sw) return -ENOMEM; @@ -468,7 +487,7 @@ int prestera_device_register(struct prestera_device *dev) err = prestera_switch_init(sw); if (err) { - kfree(sw); + prestera_devlink_free(sw); return err; } @@ -481,7 +500,7 @@ void prestera_device_unregister(struct prestera_device *dev) struct prestera_switch *sw = dev->priv; prestera_switch_fini(sw); - kfree(sw); + prestera_devlink_free(sw); } EXPORT_SYMBOL(prestera_device_unregister); From patchwork Thu May 28 15:12:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadym Kochan X-Patchwork-Id: 218317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EC47C433DF for ; Thu, 28 May 2020 15:14:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 604F02075F for ; Thu, 28 May 2020 15:14:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=plvision.eu header.i=@plvision.eu header.b="S6H9wzUc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404226AbgE1PNq (ORCPT ); Thu, 28 May 2020 11:13:46 -0400 Received: from mail-vi1eur05on2129.outbound.protection.outlook.com ([40.107.21.129]:54914 "EHLO EUR05-VI1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2403787AbgE1PNl (ORCPT ); Thu, 28 May 2020 11:13:41 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GQ2pN69vOnbbhByZP5FWenK+Ifzpkx2opHk7FJKRlsenfaiLgV87xrBWn+P421yGNx9ZKoe3HTuXWuV2aALwX4wUvrCdgFjZY0ZqKlz0YHPCSpG/3iJpLc4zuor1e6DmhHXH7DC2BAt+dJmJVDs3X/JN9NuGOqNyD2a971giBQPH+MtskPBkwerPtsd6Zqa5Uru2nh2HBpSXtfWwAb4AmUOxBBSi5FgctAxVTfGKbTNF0qvYEt91uyUHINxWAR49lEP2YQWv/mZWquseqxmZmBvmhrcVnSaoHwS2ItadhUAk7Xw5ln2vy9RlDiJmlBQF0NG6b2LcURh7bc4+vK1skg== 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-SenderADCheck; bh=kFxKxPCGHHh624tdoZPKQRfQF+nbs+tDEJSCw/ZfpN4=; b=aqiU+o0uShwgK1awB4izN/Qz0q/KAy4v4Fr36u4B91ni52hiK9eChRLa3xt4HqMUShm7U+KcpbPY0GhlLJ7yL72epX+4Mpqw5LkUYzCUXIFDKUzwbpvNBu9xQ6e3MYFLfSsEgKoKBiItZPcazeQMphexuXpC4gdq8AXfJO9n+wTyFkLagMW7/hB5SIzuimP7m1VAsK3pi53WBLR7xSZZrjmW2bE6LPVT4Vqv/BXp3rJ7izsTffG1aQkbVA1VgR+I04gtFCt75lsaI8logpfIckkpeXzaz8Yz+Dgv/dKSR2fUFrNEeFiqHrcckeSu+J/jjJphiZOnv8WaylIu+NBQKA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=plvision.eu; dmarc=pass action=none header.from=plvision.eu; dkim=pass header.d=plvision.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=plvision.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=kFxKxPCGHHh624tdoZPKQRfQF+nbs+tDEJSCw/ZfpN4=; b=S6H9wzUcAYnmWwZCEySNaVGTWWf6EWIr1nVa2iQWpUr1kUnhR3XiMZGM6nD1UzAEbjU2H/BV7MyJYNYNajukt70nxPXgSCQoBskWXmY6z/CrcL6gfGTtKweFa8IyPylEOoDaunaI+j13eoTxe7RJNJ5KFfHbNW9xy1JXOUAcmMI= Authentication-Results: davemloft.net; dkim=none (message not signed) header.d=none; davemloft.net; dmarc=none action=none header.from=plvision.eu; Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) by VI1P190MB0224.EURP190.PROD.OUTLOOK.COM (2603:10a6:800:a4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23; Thu, 28 May 2020 15:13:11 +0000 Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f]) by VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f%7]) with mapi id 15.20.3045.018; Thu, 28 May 2020 15:13:11 +0000 From: Vadym Kochan To: "David S. Miller" , Jakub Kicinski , Jiri Pirko , Ido Schimmel , Andrew Lunn , Oleksandr Mazur , Serhiy Boiko , Serhiy Pshyk , Volodymyr Mytnyk , Taras Chornyi , Andrii Savka , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Mickey Rachamim , Vadym Kochan Subject: [net-next 4/6] net: marvell: prestera: Add ethtool interface support Date: Thu, 28 May 2020 18:12:43 +0300 Message-Id: <20200528151245.7592-5-vadym.kochan@plvision.eu> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528151245.7592-1-vadym.kochan@plvision.eu> References: <20200528151245.7592-1-vadym.kochan@plvision.eu> X-ClientProxiedBy: AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) To VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from pc60716vkochan.x.ow.s (217.20.186.93) by AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.19 via Frontend Transport; Thu, 28 May 2020 15:13:09 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [217.20.186.93] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d60abaee-92f6-4335-13a7-08d80319a2a0 X-MS-TrafficTypeDiagnostic: VI1P190MB0224: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:972; X-Forefront-PRVS: 0417A3FFD2 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: owNCkjY7wSVbPEwuL4ct4NSf55zIDglVP0RG8NRWXYq3FukUdQLnulSVrYzXof9AgB+ccMfRUMY/O06916Ld++M/uhdlj8nnbBjNPeojHBjk/MkbQNj1vE+uf26YgYwMmI8ISFjk4r+77qt6eDdFwwKMUudQR1sRTA9l68bMJMoSVV3X6hP8q5fi7s3TmmEqZa0Jm1IAOwpvsmrd/IyzoUPh5Q8Va9qCyUjEftaWIGg0JJD7+5xUK0lbO3VaBbOKo+uBQLOwWEnmTUxZIASaKhVnhcD8JbNBoBXjKapLZk1iT5Le58A7AqxlUuUDpM8OmU/tyl+Z2WvmhGLIqtHzRB5HOLTKnRmkVNsJDMr1OFbwh63akoE55xXGHt8dKmoH X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1P190MB0399.EURP190.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFTY:; SFS:(136003)(39830400003)(376002)(366004)(346002)(396003)(66476007)(316002)(66556008)(107886003)(5660300002)(6512007)(2616005)(508600001)(186003)(956004)(4326008)(1076003)(2906002)(16526019)(52116002)(26005)(6486002)(44832011)(54906003)(30864003)(6506007)(66946007)(8936002)(8676002)(110136005)(86362001)(83380400001)(36756003)(6666004)(921003)(579004); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData: 1R4dZeHVcRnegyTU8LIgEBrPGekcus0FjuPQHOBlVbHkQM1AVa+FrIyLJVDWE48T9cI6BlrhbQ1QeDOaeHJyVu/rC6cLjl73UksCtK81NkRVM0bvvnr/eG0eeWiuzeSV2COwIs45UcDor4UNIAr8bjZ4Y03I5t+qeimuJdrhYt+nkkrbV1c8F7i5rDsIO8R8XYZEOBlEmNdPhEcvQi93P6+UibzBjscKULzSO6CL+UXynj8yJlJeQKjQ5fwxidhuGKtmlt+yfu2vqXmFUAmV3GW/9z2RWZQ8HYCW+z8WpVvNPIKAFvPLogJITN82+NrMWpgyq1PzPwmzocUxBhfEXXACPn/lwvK2p4/ASWZ0VcqojrQ8xDHYygdtvW+SBCTBuzpGzeX2omFrx5qgpK7RSOgPUxBcgjUOdCh9pF+fO9vDMnVaBqvlqp/05meSXaKrGjDzXIP8xA+GzNBaXKMdvj+9Cb8/qNNc+siaBhzq6aU= X-OriginatorOrg: plvision.eu X-MS-Exchange-CrossTenant-Network-Message-Id: d60abaee-92f6-4335-13a7-08d80319a2a0 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 May 2020 15:13:11.3758 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 03707b74-30f3-46b6-a0e0-ff0a7438c9c4 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KAmtXl2ZdpLOcMOzJ32qZL4VCSk5J4sOE76aqN11Dwc8Z3DzhA53ccA9VScvXwiM/MmdiU/ISsL1uMw4ikRwdf5NJHWc68Tem8Bxb5SpwjU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P190MB0224 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The ethtool API provides support for the configuration of the following features: speed and duplex, auto-negotiation, MDI-x, forward error correction, port media type. The API also provides information about the port status, hardware and software statistic. The following limitation exists: - port media type should be configured before speed setting - ethtool -m option is not supported - ethtool -p option is not supported - ethtool -r option is supported for RJ45 port only - the following combination of parameters is not supported: ethtool -s sw1pX port XX autoneg on - forward error correction feature is supported only on SFP ports, 10G speed - auto-negotiation and MDI-x features are not supported on Copper-to-Fiber SFP module Signed-off-by: Andrii Savka Signed-off-by: Serhiy Boiko Signed-off-by: Vadym Kochan --- .../net/ethernet/marvell/prestera/Makefile | 2 +- .../net/ethernet/marvell/prestera/prestera.h | 3 + .../marvell/prestera/prestera_ethtool.c | 737 ++++++++++++++++++ .../marvell/prestera/prestera_ethtool.h | 37 + .../ethernet/marvell/prestera/prestera_hw.c | 293 +++++++ .../ethernet/marvell/prestera/prestera_hw.h | 65 +- .../ethernet/marvell/prestera/prestera_main.c | 42 +- 7 files changed, 1171 insertions(+), 8 deletions(-) create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_ethtool.c create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_ethtool.h diff --git a/drivers/net/ethernet/marvell/prestera/Makefile b/drivers/net/ethernet/marvell/prestera/Makefile index babd71fba809..7684e7047562 100644 --- a/drivers/net/ethernet/marvell/prestera/Makefile +++ b/drivers/net/ethernet/marvell/prestera/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PRESTERA) += prestera.o prestera-objs := prestera_main.o prestera_hw.o prestera_dsa.o \ - prestera_rxtx.o prestera_devlink.o + prestera_rxtx.o prestera_devlink.o prestera_ethtool.o obj-$(CONFIG_PRESTERA_PCI) += prestera_pci.o diff --git a/drivers/net/ethernet/marvell/prestera/prestera.h b/drivers/net/ethernet/marvell/prestera/prestera.h index f8abaaff5f21..ee834e824521 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera.h +++ b/drivers/net/ethernet/marvell/prestera/prestera.h @@ -173,4 +173,7 @@ void prestera_device_unregister(struct prestera_device *dev); struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw, u32 dev_id, u32 hw_id); +int prestera_port_autoneg_set(struct prestera_port *port, bool enable, + u64 adver_link_modes, u8 adver_fec); + #endif /* _PRESTERA_H_ */ diff --git a/drivers/net/ethernet/marvell/prestera/prestera_ethtool.c b/drivers/net/ethernet/marvell/prestera/prestera_ethtool.c new file mode 100644 index 000000000000..c99d91f2bf62 --- /dev/null +++ b/drivers/net/ethernet/marvell/prestera/prestera_ethtool.c @@ -0,0 +1,737 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */ + +#include +#include +#include + +#include "prestera.h" +#include "prestera_hw.h" +#include "prestera_ethtool.h" + +#define PRESTERA_STATS_CNT \ + (sizeof(struct prestera_port_stats) / sizeof(u64)) +#define PRESTERA_STATS_IDX(name) \ + (offsetof(struct prestera_port_stats, name) / sizeof(u64)) +#define PRESTERA_STATS_FIELD(name) \ + [PRESTERA_STATS_IDX(name)] = __stringify(name) + +static const char driver_kind[] = "prestera"; + +static const struct prestera_link_mode { + enum ethtool_link_mode_bit_indices eth_mode; + u32 speed; + u64 pr_mask; + u8 duplex; + u8 port_type; +} port_link_modes[PRESTERA_LINK_MODE_MAX] = { + [PRESTERA_LINK_MODE_10baseT_Half] = { + .eth_mode = ETHTOOL_LINK_MODE_10baseT_Half_BIT, + .speed = 10, + .pr_mask = 1 << PRESTERA_LINK_MODE_10baseT_Half, + .duplex = PRESTERA_PORT_DUPLEX_HALF, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_10baseT_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_10baseT_Full_BIT, + .speed = 10, + .pr_mask = 1 << PRESTERA_LINK_MODE_10baseT_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_100baseT_Half] = { + .eth_mode = ETHTOOL_LINK_MODE_100baseT_Half_BIT, + .speed = 100, + .pr_mask = 1 << PRESTERA_LINK_MODE_100baseT_Half, + .duplex = PRESTERA_PORT_DUPLEX_HALF, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_100baseT_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_100baseT_Full_BIT, + .speed = 100, + .pr_mask = 1 << PRESTERA_LINK_MODE_100baseT_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_1000baseT_Half] = { + .eth_mode = ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + .speed = 1000, + .pr_mask = 1 << PRESTERA_LINK_MODE_1000baseT_Half, + .duplex = PRESTERA_PORT_DUPLEX_HALF, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_1000baseT_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + .speed = 1000, + .pr_mask = 1 << PRESTERA_LINK_MODE_1000baseT_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_1000baseX_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_1000baseX_Full_BIT, + .speed = 1000, + .pr_mask = 1 << PRESTERA_LINK_MODE_1000baseX_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_1000baseKX_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + .speed = 1000, + .pr_mask = 1 << PRESTERA_LINK_MODE_1000baseKX_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_2500baseX_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + .speed = 2500, + .pr_mask = 1 << PRESTERA_LINK_MODE_2500baseX_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + }, + [PRESTERA_LINK_MODE_10GbaseKR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + .speed = 10000, + .pr_mask = 1 << PRESTERA_LINK_MODE_10GbaseKR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_10GbaseSR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, + .speed = 10000, + .pr_mask = 1 << PRESTERA_LINK_MODE_10GbaseSR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_10GbaseLR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, + .speed = 10000, + .pr_mask = 1 << PRESTERA_LINK_MODE_10GbaseLR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_20GbaseKR2_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, + .speed = 20000, + .pr_mask = 1 << PRESTERA_LINK_MODE_20GbaseKR2_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_25GbaseCR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, + .speed = 25000, + .pr_mask = 1 << PRESTERA_LINK_MODE_25GbaseCR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_DA, + }, + [PRESTERA_LINK_MODE_25GbaseKR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, + .speed = 25000, + .pr_mask = 1 << PRESTERA_LINK_MODE_25GbaseKR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_25GbaseSR_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, + .speed = 25000, + .pr_mask = 1 << PRESTERA_LINK_MODE_25GbaseSR_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_40GbaseKR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, + .speed = 40000, + .pr_mask = 1 << PRESTERA_LINK_MODE_40GbaseKR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_40GbaseCR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, + .speed = 40000, + .pr_mask = 1 << PRESTERA_LINK_MODE_40GbaseCR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_DA, + }, + [PRESTERA_LINK_MODE_40GbaseSR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, + .speed = 40000, + .pr_mask = 1 << PRESTERA_LINK_MODE_40GbaseSR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_50GbaseCR2_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, + .speed = 50000, + .pr_mask = 1 << PRESTERA_LINK_MODE_50GbaseCR2_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_DA, + }, + [PRESTERA_LINK_MODE_50GbaseKR2_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, + .speed = 50000, + .pr_mask = 1 << PRESTERA_LINK_MODE_50GbaseKR2_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_50GbaseSR2_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, + .speed = 50000, + .pr_mask = 1 << PRESTERA_LINK_MODE_50GbaseSR2_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_100GbaseKR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + .speed = 100000, + .pr_mask = 1 << PRESTERA_LINK_MODE_100GbaseKR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_TP, + }, + [PRESTERA_LINK_MODE_100GbaseSR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, + .speed = 100000, + .pr_mask = 1 << PRESTERA_LINK_MODE_100GbaseSR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_FIBRE, + }, + [PRESTERA_LINK_MODE_100GbaseCR4_Full] = { + .eth_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, + .speed = 100000, + .pr_mask = 1 << PRESTERA_LINK_MODE_100GbaseCR4_Full, + .duplex = PRESTERA_PORT_DUPLEX_FULL, + .port_type = PRESTERA_PORT_TYPE_DA, + } +}; + +static const struct prestera_fec { + u32 eth_fec; + enum ethtool_link_mode_bit_indices eth_mode; + u8 pr_fec; +} port_fec_caps[PRESTERA_PORT_FEC_MAX] = { + [PRESTERA_PORT_FEC_OFF] = { + .eth_fec = ETHTOOL_FEC_OFF, + .eth_mode = ETHTOOL_LINK_MODE_FEC_NONE_BIT, + .pr_fec = 1 << PRESTERA_PORT_FEC_OFF, + }, + [PRESTERA_PORT_FEC_BASER] = { + .eth_fec = ETHTOOL_FEC_BASER, + .eth_mode = ETHTOOL_LINK_MODE_FEC_BASER_BIT, + .pr_fec = 1 << PRESTERA_PORT_FEC_BASER, + }, + [PRESTERA_PORT_FEC_RS] = { + .eth_fec = ETHTOOL_FEC_RS, + .eth_mode = ETHTOOL_LINK_MODE_FEC_RS_BIT, + .pr_fec = 1 << PRESTERA_PORT_FEC_RS, + } +}; + +static const struct prestera_port_type { + enum ethtool_link_mode_bit_indices eth_mode; + u8 eth_type; +} port_types[PRESTERA_PORT_TYPE_MAX] = { + [PRESTERA_PORT_TYPE_NONE] = { + .eth_mode = __ETHTOOL_LINK_MODE_MASK_NBITS, + .eth_type = PORT_NONE, + }, + [PRESTERA_PORT_TYPE_TP] = { + .eth_mode = ETHTOOL_LINK_MODE_TP_BIT, + .eth_type = PORT_TP, + }, + [PRESTERA_PORT_TYPE_AUI] = { + .eth_mode = ETHTOOL_LINK_MODE_AUI_BIT, + .eth_type = PORT_AUI, + }, + [PRESTERA_PORT_TYPE_MII] = { + .eth_mode = ETHTOOL_LINK_MODE_MII_BIT, + .eth_type = PORT_MII, + }, + [PRESTERA_PORT_TYPE_FIBRE] = { + .eth_mode = ETHTOOL_LINK_MODE_FIBRE_BIT, + .eth_type = PORT_FIBRE, + }, + [PRESTERA_PORT_TYPE_BNC] = { + .eth_mode = ETHTOOL_LINK_MODE_BNC_BIT, + .eth_type = PORT_BNC, + }, + [PRESTERA_PORT_TYPE_DA] = { + .eth_mode = ETHTOOL_LINK_MODE_TP_BIT, + .eth_type = PORT_TP, + }, + [PRESTERA_PORT_TYPE_OTHER] = { + .eth_mode = __ETHTOOL_LINK_MODE_MASK_NBITS, + .eth_type = PORT_OTHER, + } +}; + +static const char prestera_cnt_name[PRESTERA_STATS_CNT][ETH_GSTRING_LEN] = { + PRESTERA_STATS_FIELD(good_octets_received), + PRESTERA_STATS_FIELD(bad_octets_received), + PRESTERA_STATS_FIELD(mac_trans_error), + PRESTERA_STATS_FIELD(broadcast_frames_received), + PRESTERA_STATS_FIELD(multicast_frames_received), + PRESTERA_STATS_FIELD(frames_64_octets), + PRESTERA_STATS_FIELD(frames_65_to_127_octets), + PRESTERA_STATS_FIELD(frames_128_to_255_octets), + PRESTERA_STATS_FIELD(frames_256_to_511_octets), + PRESTERA_STATS_FIELD(frames_512_to_1023_octets), + PRESTERA_STATS_FIELD(frames_1024_to_max_octets), + PRESTERA_STATS_FIELD(excessive_collision), + PRESTERA_STATS_FIELD(multicast_frames_sent), + PRESTERA_STATS_FIELD(broadcast_frames_sent), + PRESTERA_STATS_FIELD(fc_sent), + PRESTERA_STATS_FIELD(fc_received), + PRESTERA_STATS_FIELD(buffer_overrun), + PRESTERA_STATS_FIELD(undersize), + PRESTERA_STATS_FIELD(fragments), + PRESTERA_STATS_FIELD(oversize), + PRESTERA_STATS_FIELD(jabber), + PRESTERA_STATS_FIELD(rx_error_frame_received), + PRESTERA_STATS_FIELD(bad_crc), + PRESTERA_STATS_FIELD(collisions), + PRESTERA_STATS_FIELD(late_collision), + PRESTERA_STATS_FIELD(unicast_frames_received), + PRESTERA_STATS_FIELD(unicast_frames_sent), + PRESTERA_STATS_FIELD(sent_multiple), + PRESTERA_STATS_FIELD(sent_deferred), + PRESTERA_STATS_FIELD(good_octets_sent), +}; + +void prestera_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) +{ + struct prestera_port *port = netdev_priv(dev); + struct prestera_switch *sw = port->sw; + + strlcpy(drvinfo->driver, driver_kind, sizeof(drvinfo->driver)); + strlcpy(drvinfo->bus_info, dev_name(prestera_dev(sw)), + sizeof(drvinfo->bus_info)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", + sw->dev->fw_rev.maj, + sw->dev->fw_rev.min, + sw->dev->fw_rev.sub); +} + +static u8 prestera_port_type_get(struct prestera_port *port) +{ + if (port->caps.type < PRESTERA_PORT_TYPE_MAX) + return port_types[port->caps.type].eth_type; + return PORT_OTHER; +} + +static int prestera_port_type_set(const struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + u32 new_mode = PRESTERA_LINK_MODE_MAX; + u32 type, mode; + int err; + + for (type = 0; type < PRESTERA_PORT_TYPE_MAX; type++) { + if (port_types[type].eth_type == ecmd->base.port && + test_bit(port_types[type].eth_mode, + ecmd->link_modes.supported)) { + break; + } + } + + if (type == port->caps.type) + return 0; + if (type != port->caps.type && ecmd->base.autoneg == AUTONEG_ENABLE) + return -EINVAL; + if (type == PRESTERA_PORT_TYPE_MAX) + return -EOPNOTSUPP; + + for (mode = 0; mode < PRESTERA_LINK_MODE_MAX; mode++) { + if ((port_link_modes[mode].pr_mask & + port->caps.supp_link_modes) && + type == port_link_modes[mode].port_type) { + new_mode = mode; + } + } + + if (new_mode < PRESTERA_LINK_MODE_MAX) + err = prestera_hw_port_link_mode_set(port, new_mode); + else + err = -EINVAL; + + if (!err) { + port->caps.type = type; + port->autoneg = false; + } + + return err; +} + +static void prestera_modes_to_eth(unsigned long *eth_modes, u64 link_modes, + u8 fec, u8 type) +{ + u32 mode; + + for (mode = 0; mode < PRESTERA_LINK_MODE_MAX; mode++) { + if ((port_link_modes[mode].pr_mask & link_modes) == 0) + continue; + if (type != PRESTERA_PORT_TYPE_NONE && + port_link_modes[mode].port_type != type) + continue; + __set_bit(port_link_modes[mode].eth_mode, eth_modes); + } + + for (mode = 0; mode < PRESTERA_PORT_FEC_MAX; mode++) { + if ((port_fec_caps[mode].pr_fec & fec) == 0) + continue; + __set_bit(port_fec_caps[mode].eth_mode, eth_modes); + } +} + +static void prestera_modes_from_eth(const unsigned long *eth_modes, + u64 *link_modes, u8 *fec, u8 type) +{ + u32 mode; + + for (mode = 0; mode < PRESTERA_LINK_MODE_MAX; mode++) { + if (!test_bit(port_link_modes[mode].eth_mode, eth_modes)) + continue; + if (port_link_modes[mode].port_type != type) + continue; + *link_modes |= port_link_modes[mode].pr_mask; + } + + for (mode = 0; mode < PRESTERA_PORT_FEC_MAX; mode++) { + if (!test_bit(port_fec_caps[mode].eth_mode, eth_modes)) + continue; + *fec |= port_fec_caps[mode].pr_fec; + } +} + +static void prestera_port_supp_types_get(struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + u32 mode; + u8 ptype; + + for (mode = 0; mode < PRESTERA_LINK_MODE_MAX; mode++) { + if ((port_link_modes[mode].pr_mask & + port->caps.supp_link_modes) == 0) + continue; + ptype = port_link_modes[mode].port_type; + __set_bit(port_types[ptype].eth_mode, + ecmd->link_modes.supported); + } +} + +static void prestera_port_remote_cap_get(struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + bool asym_pause; + bool pause; + u64 bitmap; + + if (!prestera_hw_port_remote_cap_get(port, &bitmap)) { + prestera_modes_to_eth(ecmd->link_modes.lp_advertising, + bitmap, 0, PRESTERA_PORT_TYPE_NONE); + + if (!bitmap_empty(ecmd->link_modes.lp_advertising, + __ETHTOOL_LINK_MODE_MASK_NBITS)) { + ethtool_link_ksettings_add_link_mode(ecmd, + lp_advertising, + Autoneg); + } + } + + if (prestera_hw_port_remote_fc_get(port, &pause, &asym_pause)) + return; + if (pause) + ethtool_link_ksettings_add_link_mode(ecmd, + lp_advertising, + Pause); + if (asym_pause) + ethtool_link_ksettings_add_link_mode(ecmd, + lp_advertising, + Asym_Pause); +} + +static void prestera_port_speed_get(struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + u32 speed; + int err; + + err = prestera_hw_port_speed_get(port, &speed); + ecmd->base.speed = !err ? speed : SPEED_UNKNOWN; +} + +static void prestera_port_duplex_get(struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + u8 duplex; + + if (!prestera_hw_port_duplex_get(port, &duplex)) { + ecmd->base.duplex = duplex == PRESTERA_PORT_DUPLEX_FULL ? + DUPLEX_FULL : DUPLEX_HALF; + } else { + ecmd->base.duplex = DUPLEX_UNKNOWN; + } +} + +int prestera_ethtool_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *ecmd) +{ + struct prestera_port *port = netdev_priv(dev); + + ethtool_link_ksettings_zero_link_mode(ecmd, supported); + ethtool_link_ksettings_zero_link_mode(ecmd, advertising); + ethtool_link_ksettings_zero_link_mode(ecmd, lp_advertising); + + ecmd->base.autoneg = port->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; + + if (port->caps.type == PRESTERA_PORT_TYPE_TP) { + ethtool_link_ksettings_add_link_mode(ecmd, supported, Autoneg); + + if (netif_running(dev) && + (port->autoneg || + port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER)) + ethtool_link_ksettings_add_link_mode(ecmd, advertising, + Autoneg); + } + + prestera_modes_to_eth(ecmd->link_modes.supported, + port->caps.supp_link_modes, + port->caps.supp_fec, + port->caps.type); + + prestera_port_supp_types_get(ecmd, port); + + if (netif_carrier_ok(dev)) { + prestera_port_speed_get(ecmd, port); + prestera_port_duplex_get(ecmd, port); + } else { + ecmd->base.speed = SPEED_UNKNOWN; + ecmd->base.duplex = DUPLEX_UNKNOWN; + } + + ecmd->base.port = prestera_port_type_get(port); + + if (port->autoneg) { + if (netif_running(dev)) + prestera_modes_to_eth(ecmd->link_modes.advertising, + port->adver_link_modes, + port->adver_fec, + port->caps.type); + + if (netif_carrier_ok(dev) && + port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER) + prestera_port_remote_cap_get(ecmd, port); + } + + if (port->caps.type == PRESTERA_PORT_TYPE_TP && + port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER) + prestera_hw_port_mdix_get(port, &ecmd->base.eth_tp_mdix, + &ecmd->base.eth_tp_mdix_ctrl); + + return 0; +} + +static int prestera_port_mdix_set(const struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + if (ecmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_INVALID && + port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER && + port->caps.type == PRESTERA_PORT_TYPE_TP) + return prestera_hw_port_mdix_set(port, + ecmd->base.eth_tp_mdix_ctrl); + + return 0; +} + +static int prestera_port_link_mode_set(struct prestera_port *port, + u32 speed, u8 duplex, u8 type) +{ + u32 new_mode = PRESTERA_LINK_MODE_MAX; + u32 mode; + + for (mode = 0; mode < PRESTERA_LINK_MODE_MAX; mode++) { + if (speed != port_link_modes[mode].speed) + continue; + if (duplex != port_link_modes[mode].duplex) + continue; + if (!(port_link_modes[mode].pr_mask & + port->caps.supp_link_modes)) + continue; + if (type != port_link_modes[mode].port_type) + continue; + + new_mode = mode; + break; + } + + if (new_mode == PRESTERA_LINK_MODE_MAX) + return -EOPNOTSUPP; + + return prestera_hw_port_link_mode_set(port, new_mode); +} + +static int +prestera_port_speed_duplex_set(const struct ethtool_link_ksettings *ecmd, + struct prestera_port *port) +{ + u32 curr_mode; + u8 duplex; + u32 speed; + int err; + + err = prestera_hw_port_link_mode_get(port, &curr_mode); + if (err || curr_mode >= PRESTERA_LINK_MODE_MAX) + return -EINVAL; + + if (ecmd->base.duplex != DUPLEX_UNKNOWN) + duplex = ecmd->base.duplex == DUPLEX_FULL ? + PRESTERA_PORT_DUPLEX_FULL : PRESTERA_PORT_DUPLEX_HALF; + else + duplex = port_link_modes[curr_mode].duplex; + + if (ecmd->base.speed != SPEED_UNKNOWN) + speed = ecmd->base.speed; + else + speed = port_link_modes[curr_mode].speed; + + return prestera_port_link_mode_set(port, speed, duplex, + port->caps.type); +} + +int prestera_ethtool_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *ecmd) +{ + struct prestera_port *port = netdev_priv(dev); + u64 adver_modes = 0; + u8 adver_fec = 0; + int err; + + err = prestera_port_type_set(ecmd, port); + if (err) + return err; + + if (port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER) { + err = prestera_port_mdix_set(ecmd, port); + if (err) + return err; + } + + prestera_modes_from_eth(ecmd->link_modes.advertising, &adver_modes, + &adver_fec, port->caps.type); + + err = prestera_port_autoneg_set(port, + ecmd->base.autoneg == AUTONEG_ENABLE, + adver_modes, adver_fec); + if (err) + return err; + + if (ecmd->base.autoneg == AUTONEG_DISABLE) { + err = prestera_port_speed_duplex_set(ecmd, port); + if (err) + return err; + } + + return 0; +} + +int prestera_ethtool_get_fecparam(struct net_device *dev, + struct ethtool_fecparam *fecparam) +{ + struct prestera_port *port = netdev_priv(dev); + u32 mode; + u8 active; + int err; + + err = prestera_hw_port_fec_get(port, &active); + if (err) + return err; + + fecparam->fec = 0; + for (mode = 0; mode < PRESTERA_PORT_FEC_MAX; mode++) { + if ((port_fec_caps[mode].pr_fec & port->caps.supp_fec) == 0) + continue; + fecparam->fec |= port_fec_caps[mode].eth_fec; + } + + if (active < PRESTERA_PORT_FEC_MAX) + fecparam->active_fec = port_fec_caps[active].eth_fec; + else + fecparam->active_fec = ETHTOOL_FEC_AUTO; + + return 0; +} + +int prestera_ethtool_set_fecparam(struct net_device *dev, + struct ethtool_fecparam *fecparam) +{ + struct prestera_port *port = netdev_priv(dev); + u8 fec, active; + u32 mode; + int err; + + if (port->autoneg) { + netdev_err(dev, "FEC set is not allowed while autoneg is on\n"); + return -EINVAL; + } + + err = prestera_hw_port_fec_get(port, &active); + if (err) + return err; + + fec = PRESTERA_PORT_FEC_MAX; + for (mode = 0; mode < PRESTERA_PORT_FEC_MAX; mode++) { + if ((port_fec_caps[mode].eth_fec & fecparam->fec) && + (port_fec_caps[mode].pr_fec & port->caps.supp_fec)) { + fec = mode; + break; + } + } + + if (fec == active) + return 0; + + if (fec == PRESTERA_PORT_FEC_MAX) + return -EOPNOTSUPP; + + return prestera_hw_port_fec_set(port, fec); +} + +int prestera_ethtool_get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return PRESTERA_STATS_CNT; + default: + return -EOPNOTSUPP; + } +} + +void prestera_ethtool_get_strings(struct net_device *dev, + u32 stringset, u8 *data) +{ + if (stringset != ETH_SS_STATS) + return; + + memcpy(data, *prestera_cnt_name, sizeof(prestera_cnt_name)); +} + +void prestera_ethtool_get_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct prestera_port *port = netdev_priv(dev); + struct prestera_port_stats *port_stats; + + port_stats = &port->cached_hw_stats.stats; + + memcpy((u8 *)data, port_stats, sizeof(*port_stats)); +} + +int prestera_ethtool_nway_reset(struct net_device *dev) +{ + struct prestera_port *port = netdev_priv(dev); + + if (netif_running(dev) && + port->caps.transceiver == PRESTERA_PORT_TCVR_COPPER && + port->caps.type == PRESTERA_PORT_TYPE_TP) + return prestera_hw_port_autoneg_restart(port); + + return -EINVAL; +} diff --git a/drivers/net/ethernet/marvell/prestera/prestera_ethtool.h b/drivers/net/ethernet/marvell/prestera/prestera_ethtool.h new file mode 100644 index 000000000000..e6a51e9020a4 --- /dev/null +++ b/drivers/net/ethernet/marvell/prestera/prestera_ethtool.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 + * + * Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. + * + */ +#ifndef __PRESTERA_ETHTOOL_H_ +#define __PRESTERA_ETHTOOL_H_ + +#include +#include + +void prestera_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo); + +int prestera_ethtool_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *ecmd); + +int prestera_ethtool_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *ecmd); + +int prestera_ethtool_get_fecparam(struct net_device *dev, + struct ethtool_fecparam *fecparam); + +int prestera_ethtool_set_fecparam(struct net_device *dev, + struct ethtool_fecparam *fecparam); + +int prestera_ethtool_get_sset_count(struct net_device *dev, int sset); + +void prestera_ethtool_get_strings(struct net_device *dev, u32 stringset, + u8 *data); + +void prestera_ethtool_get_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data); + +int prestera_ethtool_nway_reset(struct net_device *dev); + +#endif /* _PRESTERA_ETHTOOL_H_ */ diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c index 3aa3974f957a..ba87279e16e1 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c @@ -31,9 +31,18 @@ enum { PRESTERA_CMD_PORT_ATTR_ADMIN_STATE = 1, PRESTERA_CMD_PORT_ATTR_MTU = 3, PRESTERA_CMD_PORT_ATTR_MAC = 4, + PRESTERA_CMD_PORT_ATTR_SPEED = 5, PRESTERA_CMD_PORT_ATTR_CAPABILITY = 9, + PRESTERA_CMD_PORT_ATTR_REMOTE_CAPABILITY = 10, + PRESTERA_CMD_PORT_ATTR_REMOTE_FC = 11, + PRESTERA_CMD_PORT_ATTR_LINK_MODE = 12, + PRESTERA_CMD_PORT_ATTR_TYPE = 13, + PRESTERA_CMD_PORT_ATTR_FEC = 14, PRESTERA_CMD_PORT_ATTR_AUTONEG = 15, + PRESTERA_CMD_PORT_ATTR_DUPLEX = 16, PRESTERA_CMD_PORT_ATTR_STATS = 17, + PRESTERA_CMD_PORT_ATTR_MDIX = 18, + PRESTERA_CMD_PORT_ATTR_AUTONEG_RESTART = 19, }; enum { @@ -47,6 +56,13 @@ enum { PRESTERA_CMD_ACK_MAX }; +enum { + PRESTERA_PORT_TP_NA, + PRESTERA_PORT_TP_MDI, + PRESTERA_PORT_TP_MDIX, + PRESTERA_PORT_TP_AUTO +}; + enum { PRESTERA_PORT_GOOD_OCTETS_RCV_CNT, PRESTERA_PORT_BAD_OCTETS_RCV_CNT, @@ -82,6 +98,13 @@ enum { PRESTERA_PORT_CNT_MAX, }; +enum { + PRESTERA_FC_NONE, + PRESTERA_FC_SYMMETRIC, + PRESTERA_FC_ASYMMETRIC, + PRESTERA_FC_SYMM_ASYMM, +}; + struct prestera_fw_event_handler { struct list_head list; enum prestera_event_type type; @@ -136,11 +159,23 @@ struct prestera_msg_port_cap_param { u8 transceiver; }; +struct prestera_msg_port_mdix_param { + u8 status; + u8 admin_mode; +}; + union prestera_msg_port_param { u8 admin_state; u8 oper_state; u32 mtu; u8 mac[ETH_ALEN]; + u32 speed; + u32 link_mode; + u8 type; + u8 duplex; + u8 fec; + u8 fc; + struct prestera_msg_port_mdix_param mdix; struct prestera_msg_port_autoneg_param autoneg; struct prestera_msg_port_cap_param cap; }; @@ -472,6 +507,232 @@ int prestera_hw_port_cap_get(const struct prestera_port *port, return err; } +int prestera_hw_port_remote_cap_get(const struct prestera_port *port, + u64 *link_mode_bitmap) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_REMOTE_CAPABILITY, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *link_mode_bitmap = resp.param.cap.link_mode; + + return err; +} + +int prestera_hw_port_remote_fc_get(const struct prestera_port *port, + bool *pause, bool *asym_pause) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_REMOTE_FC, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + switch (resp.param.fc) { + case PRESTERA_FC_SYMMETRIC: + *pause = true; + *asym_pause = false; + break; + case PRESTERA_FC_ASYMMETRIC: + *pause = false; + *asym_pause = true; + break; + case PRESTERA_FC_SYMM_ASYMM: + *pause = true; + *asym_pause = true; + break; + default: + *pause = false; + *asym_pause = false; + }; + + return err; +} + +int prestera_hw_port_type_get(const struct prestera_port *port, u8 *type) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_TYPE, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *type = resp.param.type; + + return err; +} + +int prestera_hw_port_fec_get(const struct prestera_port *port, u8 *fec) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_FEC, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *fec = resp.param.fec; + + return err; +} + +int prestera_hw_port_fec_set(const struct prestera_port *port, u8 fec) +{ + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_FEC, + .port = port->hw_id, + .dev = port->dev_id, + .param = {.fec = fec} + }; + + return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, + &req.cmd, sizeof(req)); +} + +static u8 prestera_hw_mdix_to_eth(u8 mode) +{ + switch (mode) { + case PRESTERA_PORT_TP_MDI: + return ETH_TP_MDI; + case PRESTERA_PORT_TP_MDIX: + return ETH_TP_MDI_X; + case PRESTERA_PORT_TP_AUTO: + return ETH_TP_MDI_AUTO; + } + + return ETH_TP_MDI_INVALID; +} + +static u8 prestera_hw_mdix_from_eth(u8 mode) +{ + switch (mode) { + case ETH_TP_MDI: + return PRESTERA_PORT_TP_MDI; + case ETH_TP_MDI_X: + return PRESTERA_PORT_TP_MDIX; + case ETH_TP_MDI_AUTO: + return PRESTERA_PORT_TP_AUTO; + } + + return PRESTERA_PORT_TP_NA; +} + +int prestera_hw_port_mdix_get(const struct prestera_port *port, u8 *status, + u8 *admin_mode) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_MDIX, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *status = prestera_hw_mdix_to_eth(resp.param.mdix.status); + *admin_mode = prestera_hw_mdix_to_eth(resp.param.mdix.admin_mode); + + return 0; +} + +int prestera_hw_port_mdix_set(const struct prestera_port *port, u8 mode) +{ + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_MDIX, + .port = port->hw_id, + .dev = port->dev_id + }; + + req.param.mdix.admin_mode = prestera_hw_mdix_from_eth(mode); + + return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, + &req.cmd, sizeof(req)); +} + +int prestera_hw_port_link_mode_set(const struct prestera_port *port, u32 mode) +{ + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_LINK_MODE, + .port = port->hw_id, + .dev = port->dev_id, + .param = {.link_mode = mode} + }; + + return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, + &req.cmd, sizeof(req)); +} + +int prestera_hw_port_link_mode_get(const struct prestera_port *port, u32 *mode) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_LINK_MODE, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + + *mode = resp.param.link_mode; + + return err; +} + +int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_SPEED, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *speed = resp.param.speed; + + return err; +} + int prestera_hw_port_autoneg_set(const struct prestera_port *port, bool autoneg, u64 link_modes, u8 fec) { @@ -489,6 +750,38 @@ int prestera_hw_port_autoneg_set(const struct prestera_port *port, &req.cmd, sizeof(req)); } +int prestera_hw_port_autoneg_restart(struct prestera_port *port) +{ + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_AUTONEG_RESTART, + .port = port->hw_id, + .dev = port->dev_id, + }; + + return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, + &req.cmd, sizeof(req)); +} + +int prestera_hw_port_duplex_get(const struct prestera_port *port, u8 *duplex) +{ + struct prestera_msg_port_attr_resp resp; + struct prestera_msg_port_attr_req req = { + .attr = PRESTERA_CMD_PORT_ATTR_DUPLEX, + .port = port->hw_id, + .dev = port->dev_id + }; + int err; + + err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, + &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); + if (err) + return err; + + *duplex = resp.param.duplex; + + return err; +} + int prestera_hw_port_stats_get(const struct prestera_port *port, struct prestera_port_stats *st) { diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h index acb0e31d6684..af2141834bbf 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h +++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h @@ -9,19 +9,65 @@ #include +enum { + PRESTERA_LINK_MODE_10baseT_Half, + PRESTERA_LINK_MODE_10baseT_Full, + PRESTERA_LINK_MODE_100baseT_Half, + PRESTERA_LINK_MODE_100baseT_Full, + PRESTERA_LINK_MODE_1000baseT_Half, + PRESTERA_LINK_MODE_1000baseT_Full, + PRESTERA_LINK_MODE_1000baseX_Full, + PRESTERA_LINK_MODE_1000baseKX_Full, + PRESTERA_LINK_MODE_2500baseX_Full, + PRESTERA_LINK_MODE_10GbaseKR_Full, + PRESTERA_LINK_MODE_10GbaseSR_Full, + PRESTERA_LINK_MODE_10GbaseLR_Full, + PRESTERA_LINK_MODE_20GbaseKR2_Full, + PRESTERA_LINK_MODE_25GbaseCR_Full, + PRESTERA_LINK_MODE_25GbaseKR_Full, + PRESTERA_LINK_MODE_25GbaseSR_Full, + PRESTERA_LINK_MODE_40GbaseKR4_Full, + PRESTERA_LINK_MODE_40GbaseCR4_Full, + PRESTERA_LINK_MODE_40GbaseSR4_Full, + PRESTERA_LINK_MODE_50GbaseCR2_Full, + PRESTERA_LINK_MODE_50GbaseKR2_Full, + PRESTERA_LINK_MODE_50GbaseSR2_Full, + PRESTERA_LINK_MODE_100GbaseKR4_Full, + PRESTERA_LINK_MODE_100GbaseSR4_Full, + PRESTERA_LINK_MODE_100GbaseCR4_Full, + PRESTERA_LINK_MODE_MAX, +}; + enum { PRESTERA_PORT_TYPE_NONE, PRESTERA_PORT_TYPE_TP, - + PRESTERA_PORT_TYPE_AUI, + PRESTERA_PORT_TYPE_MII, + PRESTERA_PORT_TYPE_FIBRE, + PRESTERA_PORT_TYPE_BNC, + PRESTERA_PORT_TYPE_DA, + PRESTERA_PORT_TYPE_OTHER, PRESTERA_PORT_TYPE_MAX, }; enum { - PRESTERA_PORT_FEC_OFF, + PRESTERA_PORT_TCVR_COPPER, + PRESTERA_PORT_TCVR_SFP, + PRESTERA_PORT_TCVR_MAX, +}; +enum { + PRESTERA_PORT_FEC_OFF, + PRESTERA_PORT_FEC_BASER, + PRESTERA_PORT_FEC_RS, PRESTERA_PORT_FEC_MAX, }; +enum { + PRESTERA_PORT_DUPLEX_HALF, + PRESTERA_PORT_DUPLEX_FULL +}; + struct prestera_switch; struct prestera_port; struct prestera_port_stats; @@ -49,10 +95,25 @@ int prestera_hw_port_mac_set(const struct prestera_port *port, char *mac); int prestera_hw_port_mac_get(const struct prestera_port *port, char *mac); int prestera_hw_port_cap_get(const struct prestera_port *port, struct prestera_port_caps *caps); +int prestera_hw_port_remote_cap_get(const struct prestera_port *port, + u64 *link_mode_bitmap); +int prestera_hw_port_remote_fc_get(const struct prestera_port *port, + bool *pause, bool *asym_pause); +int prestera_hw_port_type_get(const struct prestera_port *port, u8 *type); +int prestera_hw_port_fec_get(const struct prestera_port *port, u8 *fec); +int prestera_hw_port_fec_set(const struct prestera_port *port, u8 fec); int prestera_hw_port_autoneg_set(const struct prestera_port *port, bool autoneg, u64 link_modes, u8 fec); +int prestera_hw_port_autoneg_restart(struct prestera_port *port); +int prestera_hw_port_duplex_get(const struct prestera_port *port, u8 *duplex); int prestera_hw_port_stats_get(const struct prestera_port *port, struct prestera_port_stats *stats); +int prestera_hw_port_link_mode_set(const struct prestera_port *port, u32 mode); +int prestera_hw_port_link_mode_get(const struct prestera_port *port, u32 *mode); +int prestera_hw_port_mdix_get(const struct prestera_port *port, u8 *status, + u8 *admin_mode); +int prestera_hw_port_mdix_set(const struct prestera_port *port, u8 mode); +int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed); /* Event handlers */ int prestera_hw_event_handler_register(struct prestera_switch *sw, diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c index ddab9422fe5e..e536f87724fd 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_main.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,7 @@ #include "prestera_hw.h" #include "prestera_rxtx.h" #include "prestera_devlink.h" +#include "prestera_ethtool.h" #define PRESTERA_MTU_DEFAULT 1536 @@ -189,22 +191,38 @@ static const struct net_device_ops netdev_ops = { .ndo_get_devlink_port = prestera_devlink_get_port, }; -static int prestera_port_autoneg_set(struct prestera_port *port, bool enable, - u64 link_modes, u8 fec) +int prestera_port_autoneg_set(struct prestera_port *port, bool enable, + u64 adver_link_modes, u8 adver_fec) { bool refresh = false; + u64 link_modes; int err = 0; + u8 fec; if (port->caps.type != PRESTERA_PORT_TYPE_TP) return enable ? -EINVAL : 0; - if (port->adver_link_modes != link_modes || port->adver_fec != fec) { - port->adver_fec = fec ?: BIT(PRESTERA_PORT_FEC_OFF); + if (!enable) + goto set_autoneg; + + link_modes = port->caps.supp_link_modes & adver_link_modes; + fec = port->caps.supp_fec & adver_fec; + + if (!link_modes && !fec) + return -EOPNOTSUPP; + + if (link_modes && port->adver_link_modes != link_modes) { port->adver_link_modes = link_modes; refresh = true; } - if (port->autoneg == enable && !(port->autoneg && refresh)) + if (fec && port->adver_fec != fec) { + port->adver_fec = fec; + refresh = true; + } + +set_autoneg: + if (port->autoneg == enable && !refresh) return 0; err = prestera_hw_port_autoneg_set(port, enable, port->adver_link_modes, @@ -216,6 +234,19 @@ static int prestera_port_autoneg_set(struct prestera_port *port, bool enable, return 0; } +static const struct ethtool_ops ethtool_ops = { + .get_drvinfo = prestera_ethtool_get_drvinfo, + .get_link_ksettings = prestera_ethtool_get_link_ksettings, + .set_link_ksettings = prestera_ethtool_set_link_ksettings, + .get_fecparam = prestera_ethtool_get_fecparam, + .set_fecparam = prestera_ethtool_set_fecparam, + .get_sset_count = prestera_ethtool_get_sset_count, + .get_strings = prestera_ethtool_get_strings, + .get_ethtool_stats = prestera_ethtool_get_stats, + .get_link = ethtool_op_get_link, + .nway_reset = prestera_ethtool_nway_reset +}; + static int prestera_port_create(struct prestera_switch *sw, u32 id) { struct prestera_port *port; @@ -245,6 +276,7 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id) dev->features |= NETIF_F_NETNS_LOCAL; dev->netdev_ops = &netdev_ops; + dev->ethtool_ops = ðtool_ops; netif_carrier_off(dev); From patchwork Thu May 28 15:12:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadym Kochan X-Patchwork-Id: 218316 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77AE4C433E1 for ; Thu, 28 May 2020 15:14:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4E2D62075F for ; Thu, 28 May 2020 15:14:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=plvision.eu header.i=@plvision.eu header.b="hh+as38N" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404254AbgE1POG (ORCPT ); Thu, 28 May 2020 11:14:06 -0400 Received: from mail-vi1eur05on2129.outbound.protection.outlook.com ([40.107.21.129]:54914 "EHLO EUR05-VI1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404214AbgE1PNq (ORCPT ); Thu, 28 May 2020 11:13:46 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Lc4caU6+ksjRwYqJG4lXONwuG40whT6ctnM02JbeZXUzLsIy7i7K5Lcf7eAUJd4VzgjbTpj+cF9XfxAFljfwhjeTLywSXWuEfIMmD0Y+srLlkP0zE/p+DWtSacPYFxx6saiPz9g2L0zfHKjJgsPFx1QXdeGX9QF5vN1EAUW1VsPOiooEfV3rQNbgwf/RT8y6EtzVK3sdkBp3PATgNk3/P3LHAEzYgE6AC6tGX56t3cJsevwGtU4oW/fN6Oy0tFhvj20eeAQG1j16o//JYuwp31KcNK9cJHZrJTPFZJT3NsDichpkzmpztplMIfhSl7QfBACOvI5Y17jNDcJxpb9xuw== 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-SenderADCheck; bh=OUm1aS9UUuseD4nWcf7QHncYBRxQA+2Hm6PztoMAtIA=; b=OsKpZ2BhMxdmLPbg1fM5Q2ZLsUiamjYp2i7hwRG9cE1tRiTZaP5EE5k1qTAgZNoV2ojiB2xIze1HhKm5e8c4NQd52Hn03Dh5p90giwFY304Fo5BRO6MZyUO32fLSmruCGNHKZ08x1fouflgyY/ZJqbBX/2BsqSlI3lmUKG7SUM60jYYTZlrPtilyn+cV/FftdAU/0Sns4sZB+SjNWCU8ftGGB49YefnczBzX7yLQQ5Yef+WME5UKTqXi0y8q7ged9MJYGED0y9U1Q7X1qzzkQmfJ1Mu6wJc8tDvlIgmV86+dXX8X86cfUlqaZv+N1AV7jSdus/0dtHDZV+6wA9bELA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=plvision.eu; dmarc=pass action=none header.from=plvision.eu; dkim=pass header.d=plvision.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=plvision.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OUm1aS9UUuseD4nWcf7QHncYBRxQA+2Hm6PztoMAtIA=; b=hh+as38NkpgckOWD9L9JPDHsWfCXSwzhenATypifTW05dwwO9PN7UoGxKJlNOo1viY0lqji4dU3GHJebvtUHAyQsFbpOyxQAd5dJwcPW4SruypzU278HBj022irEpXQG+FOSRs6I9+/0wGfF9gaYPs+KJsgrSC2ydovCouhp0y8= Authentication-Results: davemloft.net; dkim=none (message not signed) header.d=none; davemloft.net; dmarc=none action=none header.from=plvision.eu; Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) by VI1P190MB0224.EURP190.PROD.OUTLOOK.COM (2603:10a6:800:a4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23; Thu, 28 May 2020 15:13:14 +0000 Received: from VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f]) by VI1P190MB0399.EURP190.PROD.OUTLOOK.COM ([fe80::8149:8652:3746:574f%7]) with mapi id 15.20.3045.018; Thu, 28 May 2020 15:13:14 +0000 From: Vadym Kochan To: "David S. Miller" , Jakub Kicinski , Jiri Pirko , Ido Schimmel , Andrew Lunn , Oleksandr Mazur , Serhiy Boiko , Serhiy Pshyk , Volodymyr Mytnyk , Taras Chornyi , Andrii Savka , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Mickey Rachamim , Vadym Kochan Subject: [net-next 6/6] dt-bindings: marvell, prestera: Add description for device-tree bindings Date: Thu, 28 May 2020 18:12:45 +0300 Message-Id: <20200528151245.7592-7-vadym.kochan@plvision.eu> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200528151245.7592-1-vadym.kochan@plvision.eu> References: <20200528151245.7592-1-vadym.kochan@plvision.eu> X-ClientProxiedBy: AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) To VI1P190MB0399.EURP190.PROD.OUTLOOK.COM (2603:10a6:802:35::10) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from pc60716vkochan.x.ow.s (217.20.186.93) by AM6P191CA0094.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.19 via Frontend Transport; Thu, 28 May 2020 15:13:13 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [217.20.186.93] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1da91ead-d9ff-403d-69ad-08d80319a4a6 X-MS-TrafficTypeDiagnostic: VI1P190MB0224: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6790; X-Forefront-PRVS: 0417A3FFD2 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rUSo5Z70lUIYvj1Vqkd04fcB62ZdsylLLrj9BmG1nUl6ZKOAlPBH1yrqnKca7gUev8HHymMjYT/B/qT+/6enzDLfqfZW/jaDo0oOALJT5yQgCUZZsxNygLSU4wxEHnLHQ39/SZlnXaokjZHTtAUNjuKKUBV7E9gHuRJaCbtVOB8lZPXg36dmP2YgzVMQmRL+bxVfqZFdklCq5WwGCZgbgC5DguIrcUHZPqlobjPEFaEOho1u0q9vrlHiiIjNyOpq7RvCB6qo1gE1wU2EgHimSgHD/+Ng9wM6IkgZz/OWSXNCFVw2rTpPnbGoqE81qtA+nJjhN2yNBiBBTfOdXlVwz2d8c1VMiiptKQPPKXGt8aBk/zwsLSTvTBWVEcZJDbXbdNokguLx+ll8XB3Gpv6p0A== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1P190MB0399.EURP190.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFTY:; SFS:(136003)(39830400003)(376002)(366004)(346002)(396003)(66476007)(316002)(66556008)(107886003)(5660300002)(6512007)(2616005)(508600001)(186003)(956004)(4326008)(1076003)(2906002)(16526019)(52116002)(26005)(6486002)(44832011)(54906003)(6506007)(66946007)(8936002)(8676002)(110136005)(86362001)(83380400001)(36756003)(6666004)(921003)(142933001); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData: rcI3ZVjViPDK9wb3SXECKCFhdURAt7dHoM6E3cAt75RKJD2BrAQydCC/483WFD5UpuEhm6ULJZbheZhcHcIu1tZOndC2gvnya0lA5+Ko8LhpBT6mM3OhK5v+KN4COUMKIHwUdiJpzFeC1s1p2ERy8FiSCTW67z16n4EJMNTtw0Be5PfF5r6KvWqlEatlSvQoDil4/yLnMy46idv4OmLsY9c+2QneDcKnlTdOX4yybJONg4SSLTMWdppG9neNuLi8isrJHlAbV08kNpX9Pn3DsgxdJuIPVTXMMG3sWJLJaMhVVn8Kks08FfFhoiyL5PEwdPbjLBWMcdbT9Q1Vc+W34+pvWZuNIZqD23e91N27GB/4JyBQLk4KYOfKd/LFCL2FHaADnRB/WbwLOBueQWMIgD96qDvP7rApvLuWy6zBtfgXPofKeyMPu8p4Y6ePZq599u2dn09/032f+emW1uIAj4w0UuM4AiSbbWyyWen6I1U= X-OriginatorOrg: plvision.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 1da91ead-d9ff-403d-69ad-08d80319a4a6 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 May 2020 15:13:14.7408 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 03707b74-30f3-46b6-a0e0-ff0a7438c9c4 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 12YBW8nlu53F+WVfai7s3vRKdWl1s0LtZYBbmPqdadU55ntPlEXuRsQlulKHkC/YPXWaxrh+pVGZ5N2fGNPKx/C79ib5We+02t4LAeAlEGc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1P190MB0224 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add brief description how to configure base mac address binding in device-tree. Describe requirement for the PCI port which is connected to the ASIC, to allow access to the firmware related registers. Signed-off-by: Vadym Kochan --- .../bindings/net/marvell,prestera.txt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/net/marvell,prestera.txt b/Documentation/devicetree/bindings/net/marvell,prestera.txt index 83370ebf5b89..e28938ddfdf5 100644 --- a/Documentation/devicetree/bindings/net/marvell,prestera.txt +++ b/Documentation/devicetree/bindings/net/marvell,prestera.txt @@ -45,3 +45,37 @@ dfx-server { ranges = <0 MBUS_ID(0x08, 0x00) 0 0x100000>; reg = ; }; + +Marvell Prestera SwitchDev bindings +----------------------------------- +Optional properties: +- compatible: must be "marvell,prestera" +- base-mac-provider: describes handle to node which provides base mac address, + might be a static base mac address or nvme cell provider. + +Example: + +eeprom_mac_addr: eeprom-mac-addr { + compatible = "eeprom,mac-addr-cell"; + status = "okay"; + + nvmem = <&eeprom_at24>; +}; + +prestera { + compatible = "marvell,prestera"; + status = "okay"; + + base-mac-provider = <&eeprom_mac_addr>; +}; + +The current implementation of Prestera Switchdev PCI interface driver requires +that BAR2 is assigned to 0xf6000000 as base address from the PCI IO range: + +&cp0_pcie0 { + ranges = <0x81000000 0x0 0xfb000000 0x0 0xfb000000 0x0 0xf0000 + 0x82000000 0x0 0xf6000000 0x0 0xf6000000 0x0 0x2000000 + 0x82000000 0x0 0xf9000000 0x0 0xf9000000 0x0 0x100000>; + phys = <&cp0_comphy0 0>; + status = "okay"; +};