From patchwork Mon Mar 23 23:42:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222005 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 63CC0C43331 for ; Mon, 23 Mar 2020 23:43:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 43BE8206F9 for ; Mon, 23 Mar 2020 23:43:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727113AbgCWXn3 (ORCPT ); Mon, 23 Mar 2020 19:43:29 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:33972 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727032AbgCWXn2 (ORCPT ); Mon, 23 Mar 2020 19:43:28 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWCv2YQdz1rwKW; Tue, 24 Mar 2020 00:43:23 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWCv1dHtz1qyDv; Tue, 24 Mar 2020 00:43:23 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id gFXmskgbu8Pe; Tue, 24 Mar 2020 00:43:21 +0100 (CET) X-Auth-Info: Ag6Ea6yffQJJB33aW+AbDFoKxTRVkyXPDh1c3+4JH+A= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:21 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 01/14] net: ks8851: Factor out spi->dev in probe()/remove() Date: Tue, 24 Mar 2020 00:42:50 +0100 Message-Id: <20200323234303.526748-2-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Pull out the spi->dev into one common place in the function instead of having it repeated over and over again. This is done in preparation for unifying ks8851 and ks8851-mll drivers. No functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 33305c9c5a62..d1e0116c9728 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1413,6 +1413,7 @@ static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); static int ks8851_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct net_device *ndev; struct ks8851_net *ks; int ret; @@ -1431,7 +1432,7 @@ static int ks8851_probe(struct spi_device *spi) ks->spidev = spi; ks->tx_space = 6144; - gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios", + gpio = of_get_named_gpio_flags(dev->of_node, "reset-gpios", 0, NULL); if (gpio == -EPROBE_DEFER) { ret = gpio; @@ -1440,15 +1441,15 @@ static int ks8851_probe(struct spi_device *spi) ks->gpio = gpio; if (gpio_is_valid(gpio)) { - ret = devm_gpio_request_one(&spi->dev, gpio, + ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW, "ks8851_rst_n"); if (ret) { - dev_err(&spi->dev, "reset gpio request failed\n"); + dev_err(dev, "reset gpio request failed\n"); goto err_gpio; } } - ks->vdd_io = devm_regulator_get(&spi->dev, "vdd-io"); + ks->vdd_io = devm_regulator_get(dev, "vdd-io"); if (IS_ERR(ks->vdd_io)) { ret = PTR_ERR(ks->vdd_io); goto err_reg_io; @@ -1456,12 +1457,12 @@ static int ks8851_probe(struct spi_device *spi) ret = regulator_enable(ks->vdd_io); if (ret) { - dev_err(&spi->dev, "regulator vdd_io enable fail: %d\n", + dev_err(dev, "regulator vdd_io enable fail: %d\n", ret); goto err_reg_io; } - ks->vdd_reg = devm_regulator_get(&spi->dev, "vdd"); + ks->vdd_reg = devm_regulator_get(dev, "vdd"); if (IS_ERR(ks->vdd_reg)) { ret = PTR_ERR(ks->vdd_reg); goto err_reg; @@ -1469,7 +1470,7 @@ static int ks8851_probe(struct spi_device *spi) ret = regulator_enable(ks->vdd_reg); if (ret) { - dev_err(&spi->dev, "regulator vdd enable fail: %d\n", + dev_err(dev, "regulator vdd enable fail: %d\n", ret); goto err_reg; } @@ -1509,7 +1510,7 @@ static int ks8851_probe(struct spi_device *spi) ks->mii.mdio_read = ks8851_phy_read; ks->mii.mdio_write = ks8851_phy_write; - dev_info(&spi->dev, "message enable is %d\n", msg_enable); + dev_info(dev, "message enable is %d\n", msg_enable); /* set the default message enable */ ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | @@ -1519,7 +1520,7 @@ static int ks8851_probe(struct spi_device *spi) skb_queue_head_init(&ks->txq); ndev->ethtool_ops = &ks8851_ethtool_ops; - SET_NETDEV_DEV(ndev, &spi->dev); + SET_NETDEV_DEV(ndev, dev); spi_set_drvdata(spi, ks); @@ -1534,7 +1535,7 @@ static int ks8851_probe(struct spi_device *spi) /* simple check for a valid chip being connected to the bus */ cider = ks8851_rdreg16(ks, KS_CIDER); if ((cider & ~CIDER_REV_MASK) != CIDER_ID) { - dev_err(&spi->dev, "failed to read device ID\n"); + dev_err(dev, "failed to read device ID\n"); ret = -ENODEV; goto err_id; } @@ -1547,7 +1548,7 @@ static int ks8851_probe(struct spi_device *spi) ret = register_netdev(ndev); if (ret) { - dev_err(&spi->dev, "failed to register network device\n"); + dev_err(dev, "failed to register network device\n"); goto err_netdev; } @@ -1573,9 +1574,10 @@ static int ks8851_probe(struct spi_device *spi) static int ks8851_remove(struct spi_device *spi) { struct ks8851_net *priv = spi_get_drvdata(spi); + struct device *dev = &spi->dev; if (netif_msg_drv(priv)) - dev_info(&spi->dev, "remove\n"); + dev_info(dev, "remove\n"); unregister_netdev(priv->netdev); if (gpio_is_valid(priv->gpio)) From patchwork Mon Mar 23 23:42:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 221999 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 C7FD7C43331 for ; Mon, 23 Mar 2020 23:43:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A6CEA206F9 for ; Mon, 23 Mar 2020 23:43:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727268AbgCWXn5 (ORCPT ); Mon, 23 Mar 2020 19:43:57 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:49437 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727031AbgCWXna (ORCPT ); Mon, 23 Mar 2020 19:43:30 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWCx53vLz1rwKg; Tue, 24 Mar 2020 00:43:25 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWCx4WZ7z1qyDk; Tue, 24 Mar 2020 00:43:25 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id 1f9_B7AHyVM0; Tue, 24 Mar 2020 00:43:24 +0100 (CET) X-Auth-Info: zRkzvFW+D/3Ed8YfEl2QYYWsTojuLHcLGe+KOvx9/Ls= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:24 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 03/14] net: ks8851: Pass device pointer into ks8851_init_mac() Date: Tue, 24 Mar 2020 00:42:52 +0100 Message-Id: <20200323234303.526748-4-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Since the driver probe function already has a struct device *dev pointer, pass it as a parameter to ks8851_init_mac() to avoid fishing it out via ks->spidev. This is the only reference to spidev in the function, so get rid of it. This is done in preparation for unifying the KS8851 SPI and parallel drivers. No functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 8f4d7c0af723..601a74d750b2 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -409,6 +409,7 @@ static void ks8851_read_mac_addr(struct net_device *dev) /** * ks8851_init_mac - initialise the mac address * @ks: The device structure + * @ddev: The device structure pointer * * Get or create the initial mac address for the device and then set that * into the station address register. A mac address supplied in the device @@ -416,12 +417,12 @@ static void ks8851_read_mac_addr(struct net_device *dev) * we try that. If no valid mac address is found we use eth_random_addr() * to create a new one. */ -static void ks8851_init_mac(struct ks8851_net *ks) +static void ks8851_init_mac(struct ks8851_net *ks, struct device *ddev) { struct net_device *dev = ks->netdev; const u8 *mac_addr; - mac_addr = of_get_mac_address(ks->spidev->dev.of_node); + mac_addr = of_get_mac_address(ddev->of_node); if (!IS_ERR(mac_addr)) { ether_addr_copy(dev->dev_addr, mac_addr); ks8851_write_mac_addr(dev); @@ -1544,7 +1545,7 @@ static int ks8851_probe(struct spi_device *spi) ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR); ks8851_read_selftest(ks); - ks8851_init_mac(ks); + ks8851_init_mac(ks, dev); ret = register_netdev(ndev); if (ret) { From patchwork Mon Mar 23 23:42:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222004 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 EBEF6C54FCF for ; Mon, 23 Mar 2020 23:43:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C19FD20719 for ; Mon, 23 Mar 2020 23:43:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727132AbgCWXnb (ORCPT ); Mon, 23 Mar 2020 19:43:31 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:48230 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727118AbgCWXna (ORCPT ); Mon, 23 Mar 2020 19:43:30 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWD11hKFz1qs4J; Tue, 24 Mar 2020 00:43:27 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWCz6Q0tz1qyDk; Tue, 24 Mar 2020 00:43:27 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id CFa0orQjWAdK; Tue, 24 Mar 2020 00:43:26 +0100 (CET) X-Auth-Info: Yn2T1H3Wv7svxLAL4lpM6wws+kBsUDDJRTp5A/paUt4= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:26 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 05/14] net: ks8851: Use dev_{get,set}_drvdata() Date: Tue, 24 Mar 2020 00:42:54 +0100 Message-Id: <20200323234303.526748-6-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Replace spi_{get,set}_drvdata() with dev_{get,set}_drvdata(), which works for both SPI and platform drivers. This is done in preparation for unifying the KS8851 SPI and parallel bus drivers. There should be no functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index cc1137be3d8f..1c0a0364b047 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1521,7 +1521,7 @@ static int ks8851_probe(struct spi_device *spi) ndev->ethtool_ops = &ks8851_ethtool_ops; SET_NETDEV_DEV(ndev, dev); - spi_set_drvdata(spi, ks); + dev_set_drvdata(dev, ks); netif_carrier_off(ks->netdev); ndev->if_port = IF_PORT_100BASET; @@ -1570,8 +1570,8 @@ static int ks8851_probe(struct spi_device *spi) static int ks8851_remove(struct spi_device *spi) { - struct ks8851_net *priv = spi_get_drvdata(spi); struct device *dev = &spi->dev; + struct ks8851_net *priv = dev_get_drvdata(dev); if (netif_msg_drv(priv)) dev_info(dev, "remove\n"); From patchwork Mon Mar 23 23:42:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222000 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 3A1F5C54FCF for ; Mon, 23 Mar 2020 23:43:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 18ADD206F9 for ; Mon, 23 Mar 2020 23:43:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727240AbgCWXnu (ORCPT ); Mon, 23 Mar 2020 19:43:50 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:49437 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727116AbgCWXnc (ORCPT ); Mon, 23 Mar 2020 19:43:32 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWD23lsWz1rwbJ; Tue, 24 Mar 2020 00:43:30 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWD23YW2z1qyDk; Tue, 24 Mar 2020 00:43:30 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id jygw9deID8g6; Tue, 24 Mar 2020 00:43:29 +0100 (CET) X-Auth-Info: 6w+jmY3Rupbj4ZK88chaNr73jf3526AKFZGJ1BQtcdc= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:29 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 07/14] net: ks8851: Use 16-bit writes to program MAC address Date: Tue, 24 Mar 2020 00:42:56 +0100 Message-Id: <20200323234303.526748-8-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On the SPI variant of KS8851, the MAC address can be programmed with either 8/16/32-bit writes. To make it easier to support the 16-bit parallel option of KS8851 too, switch both the MAC address programming and readout to 16-bit operations. Remove ks8851_wrreg8() as it is not used anywhere anymore. There should be no functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 47 ++++++++-------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index be9478f39009..3150f1b928c0 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -185,36 +185,6 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) netdev_err(ks->netdev, "spi_sync() failed\n"); } -/** - * ks8851_wrreg8 - write 8bit register value to chip - * @ks: The chip state - * @reg: The register address - * @val: The value to write - * - * Issue a write to put the value @val into the register specified in @reg. - */ -static void ks8851_wrreg8(struct ks8851_net *ks, unsigned reg, unsigned val) -{ - struct spi_transfer *xfer = &ks->spi_xfer1; - struct spi_message *msg = &ks->spi_msg1; - __le16 txb[2]; - int ret; - int bit; - - bit = 1 << (reg & 3); - - txb[0] = cpu_to_le16(MK_OP(bit, reg) | KS_SPIOP_WR); - txb[1] = val; - - xfer->tx_buf = txb; - xfer->rx_buf = NULL; - xfer->len = 3; - - ret = spi_sync(ks->spidev, msg); - if (ret < 0) - netdev_err(ks->netdev, "spi_sync() failed\n"); -} - /** * ks8851_rdreg - issue read register command and return the data * @ks: The device state @@ -349,6 +319,7 @@ static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode) static int ks8851_write_mac_addr(struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); + u16 val; int i; mutex_lock(&ks->lock); @@ -358,8 +329,12 @@ static int ks8851_write_mac_addr(struct net_device *dev) * the first write to the MAC address does not take effect. */ ks8851_set_powermode(ks, PMECR_PM_NORMAL); - for (i = 0; i < ETH_ALEN; i++) - ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]); + + for (i = 0; i < ETH_ALEN; i += 2) { + val = (dev->dev_addr[i] << 8) | dev->dev_addr[i + 1]; + ks8851_wrreg16(ks, KS_MAR(i + 1), val); + } + if (!netif_running(dev)) ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); @@ -377,12 +352,16 @@ static int ks8851_write_mac_addr(struct net_device *dev) static void ks8851_read_mac_addr(struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); + u16 reg; int i; mutex_lock(&ks->lock); - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = ks8851_rdreg8(ks, KS_MAR(i)); + for (i = 0; i < ETH_ALEN; i += 2) { + reg = ks8851_rdreg16(ks, KS_MAR(i + 1)); + dev->dev_addr[i] = reg & 0xff; + dev->dev_addr[i + 1] = reg >> 8; + } mutex_unlock(&ks->lock); } From patchwork Mon Mar 23 23:42:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222003 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 3A4A8C4332B for ; Mon, 23 Mar 2020 23:43:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 084F4206F9 for ; Mon, 23 Mar 2020 23:43:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727176AbgCWXnf (ORCPT ); Mon, 23 Mar 2020 19:43:35 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:42130 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727144AbgCWXnd (ORCPT ); Mon, 23 Mar 2020 19:43:33 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWD35DQ5z1qs38; Tue, 24 Mar 2020 00:43:31 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWD34ldDz1qyDk; Tue, 24 Mar 2020 00:43:31 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id MimTWd_wfcxA; Tue, 24 Mar 2020 00:43:30 +0100 (CET) X-Auth-Info: p3+rQ/EUYr6hm3Nitjg0qk9iPRE3P6a46m3roBj73aU= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:30 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 08/14] net: ks8851: Use 16-bit read of RXFC register Date: Tue, 24 Mar 2020 00:42:57 +0100 Message-Id: <20200323234303.526748-9-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The RXFC register is the only one being read using 8-bit accessors. To make it easier to support the 16-bit accesses used by the parallel bus variant of KS8851, use 16-bit accessor to read RXFC register as well as neighboring RXFCTR register. Remove ks8851_rdreg8() as it is not used anywhere anymore. There should be no functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 3150f1b928c0..03d349208794 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -236,21 +236,6 @@ static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, memcpy(rxb, trx + 2, rxl); } -/** - * ks8851_rdreg8 - read 8 bit register from device - * @ks: The chip information - * @reg: The register address - * - * Read a 8bit register from the chip, returning the result -*/ -static unsigned ks8851_rdreg8(struct ks8851_net *ks, unsigned reg) -{ - u8 rxb[1]; - - ks8851_rdreg(ks, MK_OP(1 << (reg & 3), reg), rxb, 1); - return rxb[0]; -} - /** * ks8851_rdreg16 - read 16 bit register from device * @ks: The chip information @@ -470,7 +455,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) unsigned rxstat; u8 *rxpkt; - rxfc = ks8851_rdreg8(ks, KS_RXFC); + rxfc = (ks8851_rdreg16(ks, KS_RXFCTR) >> 8) & 0xff; netif_dbg(ks, rx_status, ks->netdev, "%s: %d packets\n", __func__, rxfc); From patchwork Mon Mar 23 23:42:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222002 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 2B6E7C43331 for ; Mon, 23 Mar 2020 23:43:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 01583206F9 for ; Mon, 23 Mar 2020 23:43:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727213AbgCWXnl (ORCPT ); Mon, 23 Mar 2020 19:43:41 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:43822 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727150AbgCWXnh (ORCPT ); Mon, 23 Mar 2020 19:43:37 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWD50hz1z1qsZp; Tue, 24 Mar 2020 00:43:33 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWD50TrHz1qyDk; Tue, 24 Mar 2020 00:43:33 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id WMIw1WP8tAPJ; Tue, 24 Mar 2020 00:43:31 +0100 (CET) X-Auth-Info: FY+VI67u3vU4671drz9ajvejfklWEsBAIhvt+Auj/r8= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:31 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 09/14] net: ks8851: Split out SPI specific entries in struct ks8851_net Date: Tue, 24 Mar 2020 00:42:58 +0100 Message-Id: <20200323234303.526748-10-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a new struct ks8851_net_spi, which embeds the original struct ks8851_net and contains the entries specific only to the SPI variant of KS8851. There should be no functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/ks8851.c | 76 +++++++++++++++++----------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 03d349208794..56f505ae6458 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -102,7 +102,6 @@ union ks8851_tx_hdr { */ struct ks8851_net { struct net_device *netdev; - struct spi_device *spidev; struct mutex lock; spinlock_t statelock; @@ -126,17 +125,30 @@ struct ks8851_net { struct sk_buff_head txq; - struct spi_message spi_msg1; - struct spi_message spi_msg2; - struct spi_transfer spi_xfer1; - struct spi_transfer spi_xfer2[2]; - struct eeprom_93cx6 eeprom; struct regulator *vdd_reg; struct regulator *vdd_io; int gpio; }; +/** + * struct ks8851_net_spi - KS8851 SPI driver private data + * @ks8851: KS8851 driver common private data + * @spidev: The spi device we're bound to. + * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. + * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. + */ +struct ks8851_net_spi { + struct ks8851_net ks8851; /* Must be first */ + struct spi_device *spidev; + struct spi_message spi_msg1; + struct spi_message spi_msg2; + struct spi_transfer spi_xfer1; + struct spi_transfer spi_xfer2[2]; +}; + +#define to_ks8851_spi(ks) container_of((ks), struct ks8851_net_spi, ks8851) + static int msg_enable; /* SPI frame opcodes */ @@ -168,8 +180,9 @@ static int msg_enable; */ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) { - struct spi_transfer *xfer = &ks->spi_xfer1; - struct spi_message *msg = &ks->spi_msg1; + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = &kss->spi_xfer1; + struct spi_message *msg = &kss->spi_msg1; __le16 txb[2]; int ret; @@ -180,7 +193,7 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) xfer->rx_buf = NULL; xfer->len = 4; - ret = spi_sync(ks->spidev, msg); + ret = spi_sync(kss->spidev, msg); if (ret < 0) netdev_err(ks->netdev, "spi_sync() failed\n"); } @@ -198,6 +211,7 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, u8 *rxb, unsigned rxl) { + struct ks8851_net_spi *kss = to_ks8851_spi(ks); struct spi_transfer *xfer; struct spi_message *msg; __le16 *txb = (__le16 *)ks->txd; @@ -206,9 +220,9 @@ static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, txb[0] = cpu_to_le16(op | KS_SPIOP_RD); - if (ks->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) { - msg = &ks->spi_msg2; - xfer = ks->spi_xfer2; + if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) { + msg = &kss->spi_msg2; + xfer = kss->spi_xfer2; xfer->tx_buf = txb; xfer->rx_buf = NULL; @@ -219,18 +233,18 @@ static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, xfer->rx_buf = trx; xfer->len = rxl; } else { - msg = &ks->spi_msg1; - xfer = &ks->spi_xfer1; + msg = &kss->spi_msg1; + xfer = &kss->spi_xfer1; xfer->tx_buf = txb; xfer->rx_buf = trx; xfer->len = rxl + 2; } - ret = spi_sync(ks->spidev, msg); + ret = spi_sync(kss->spidev, msg); if (ret < 0) netdev_err(ks->netdev, "read: spi_sync() failed\n"); - else if (ks->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) + else if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) memcpy(rxb, trx, rxl); else memcpy(rxb, trx + 2, rxl); @@ -398,8 +412,9 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device *ddev) */ static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) { - struct spi_transfer *xfer = ks->spi_xfer2; - struct spi_message *msg = &ks->spi_msg2; + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = kss->spi_xfer2; + struct spi_message *msg = &kss->spi_msg2; u8 txb[1]; int ret; @@ -418,7 +433,7 @@ static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) xfer->tx_buf = NULL; xfer->len = len; - ret = spi_sync(ks->spidev, msg); + ret = spi_sync(kss->spidev, msg); if (ret < 0) netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); } @@ -642,8 +657,9 @@ static inline unsigned calc_txlen(unsigned len) */ static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) { - struct spi_transfer *xfer = ks->spi_xfer2; - struct spi_message *msg = &ks->spi_msg2; + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = kss->spi_xfer2; + struct spi_message *msg = &kss->spi_msg2; unsigned fid = 0; int ret; @@ -670,7 +686,7 @@ static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) xfer->rx_buf = NULL; xfer->len = ALIGN(txp->len, 4); - ret = spi_sync(ks->spidev, msg); + ret = spi_sync(kss->spidev, msg); if (ret < 0) netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); } @@ -1358,22 +1374,24 @@ static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); static int ks8851_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct ks8851_net_spi *kss; struct net_device *ndev; struct ks8851_net *ks; int ret; unsigned cider; int gpio; - ndev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net)); + ndev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); if (!ndev) return -ENOMEM; spi->bits_per_word = 8; ks = netdev_priv(ndev); + kss = to_ks8851_spi(ks); ks->netdev = ndev; - ks->spidev = spi; + kss->spidev = spi; ks->tx_space = 6144; gpio = of_get_named_gpio_flags(dev->of_node, "reset-gpios", @@ -1430,12 +1448,12 @@ static int ks8851_probe(struct spi_device *spi) /* initialise pre-made spi transfer messages */ - spi_message_init(&ks->spi_msg1); - spi_message_add_tail(&ks->spi_xfer1, &ks->spi_msg1); + spi_message_init(&kss->spi_msg1); + spi_message_add_tail(&kss->spi_xfer1, &kss->spi_msg1); - spi_message_init(&ks->spi_msg2); - spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2); - spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2); + spi_message_init(&kss->spi_msg2); + spi_message_add_tail(&kss->spi_xfer2[0], &kss->spi_msg2); + spi_message_add_tail(&kss->spi_xfer2[1], &kss->spi_msg2); /* setup EEPROM state */ From patchwork Mon Mar 23 23:43:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 222001 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=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, 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 233BEC10DCE for ; Mon, 23 Mar 2020 23:43:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DB954206F9 for ; Mon, 23 Mar 2020 23:43:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727228AbgCWXnn (ORCPT ); Mon, 23 Mar 2020 19:43:43 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:43822 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727163AbgCWXnl (ORCPT ); Mon, 23 Mar 2020 19:43:41 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 48mWDB5nkdz1qsbL; Tue, 24 Mar 2020 00:43:38 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 48mWDB5ch0z1qyDk; Tue, 24 Mar 2020 00:43:38 +0100 (CET) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id jfoBuTTb1ywY; Tue, 24 Mar 2020 00:43:36 +0100 (CET) X-Auth-Info: raxlEOcX3oIqOHA2344WnP0f9MsTcGF5ZdUl84vPtr0= Received: from desktop.lan (ip-86-49-35-8.net.upcbroadband.cz [86.49.35.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 24 Mar 2020 00:43:35 +0100 (CET) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH 12/14] net: ks8851: Separate SPI operations into separate file Date: Tue, 24 Mar 2020 00:43:01 +0100 Message-Id: <20200323234303.526748-13-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323234303.526748-1-marex@denx.de> References: <20200323234303.526748-1-marex@denx.de> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Pull all the SPI bus specific code into a separate file, so that it is not mixed with the common code. No functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- drivers/net/ethernet/micrel/Makefile | 2 +- drivers/net/ethernet/micrel/ks8851.c | 404 +---------------------- drivers/net/ethernet/micrel/ks8851.h | 123 +++++++ drivers/net/ethernet/micrel/ks8851_spi.c | 311 +++++++++++++++++ 4 files changed, 439 insertions(+), 401 deletions(-) create mode 100644 drivers/net/ethernet/micrel/ks8851_spi.c diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile index 6d8ac5527aef..bb5c6c53fa02 100644 --- a/drivers/net/ethernet/micrel/Makefile +++ b/drivers/net/ethernet/micrel/Makefile @@ -4,6 +4,6 @@ # obj-$(CONFIG_KS8842) += ks8842.o -obj-$(CONFIG_KS8851) += ks8851.o +obj-$(CONFIG_KS8851) += ks8851.o ks8851_spi.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o obj-$(CONFIG_KSZ884X_PCI) += ksz884x.o diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index d5bdbd9122bf..dd8d8a88c7e9 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -22,192 +22,14 @@ #include #include -#include #include #include #include #include "ks8851.h" -/** - * struct ks8851_rxctrl - KS8851 driver rx control - * @mchash: Multicast hash-table data. - * @rxcr1: KS_RXCR1 register setting - * @rxcr2: KS_RXCR2 register setting - * - * Representation of the settings needs to control the receive filtering - * such as the multicast hash-filter and the receive register settings. This - * is used to make the job of working out if the receive settings change and - * then issuing the new settings to the worker that will send the necessary - * commands. - */ -struct ks8851_rxctrl { - u16 mchash[4]; - u16 rxcr1; - u16 rxcr2; -}; - -/** - * union ks8851_tx_hdr - tx header data - * @txb: The header as bytes - * @txw: The header as 16bit, little-endian words - * - * A dual representation of the tx header data to allow - * access to individual bytes, and to allow 16bit accesses - * with 16bit alignment. - */ -union ks8851_tx_hdr { - u8 txb[6]; - __le16 txw[3]; -}; - -/** - * struct ks8851_net - KS8851 driver private data - * @netdev: The network device we're bound to - * @spidev: The spi device we're bound to. - * @lock: Lock to ensure that the device is not accessed when busy. - * @statelock: Lock on this structure for tx list. - * @mii: The MII state information for the mii calls. - * @rxctrl: RX settings for @rxctrl_work. - * @tx_work: Work queue for tx packets - * @rxctrl_work: Work queue for updating RX mode and multicast lists - * @txq: Queue of packets for transmission. - * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. - * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. - * @txh: Space for generating packet TX header in DMA-able data - * @rxd: Space for receiving SPI data, in DMA-able space. - * @txd: Space for transmitting SPI data, in DMA-able space. - * @msg_enable: The message flags controlling driver output (see ethtool). - * @fid: Incrementing frame id tag. - * @rc_ier: Cached copy of KS_IER. - * @rc_ccr: Cached copy of KS_CCR. - * @rc_rxqcr: Cached copy of KS_RXQCR. - * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. - * @vdd_reg: Optional regulator supplying the chip - * @vdd_io: Optional digital power supply for IO - * @gpio: Optional reset_n gpio - * - * The @lock ensures that the chip is protected when certain operations are - * in progress. When the read or write packet transfer is in progress, most - * of the chip registers are not ccessible until the transfer is finished and - * the DMA has been de-asserted. - * - * The @statelock is used to protect information in the structure which may - * need to be accessed via several sources, such as the network driver layer - * or one of the work queues. - * - * We align the buffers we may use for rx/tx to ensure that if the SPI driver - * wants to DMA map them, it will not have any problems with data the driver - * modifies. - */ -struct ks8851_net { - struct net_device *netdev; - struct mutex lock; - spinlock_t statelock; - - union ks8851_tx_hdr txh ____cacheline_aligned; - u8 rxd[8]; - u8 txd[8]; - - u32 msg_enable ____cacheline_aligned; - u16 tx_space; - u8 fid; - - u16 rc_ier; - u16 rc_rxqcr; - u16 rc_ccr; - - struct mii_if_info mii; - struct ks8851_rxctrl rxctrl; - - struct work_struct tx_work; - struct work_struct rxctrl_work; - - struct sk_buff_head txq; - - struct eeprom_93cx6 eeprom; - struct regulator *vdd_reg; - struct regulator *vdd_io; - int gpio; - - unsigned int (*rdreg16)(struct ks8851_net *ks, - unsigned int reg); - void (*wrreg16)(struct ks8851_net *ks, - unsigned int reg, unsigned int val); - void (*rdfifo)(struct ks8851_net *ks, u8 *buff, - unsigned int len); - void (*wrfifo)(struct ks8851_net *ks, - struct sk_buff *txp, bool irq); -}; - -/** - * struct ks8851_net_spi - KS8851 SPI driver private data - * @ks8851: KS8851 driver common private data - * @spidev: The spi device we're bound to. - * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. - * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. - */ -struct ks8851_net_spi { - struct ks8851_net ks8851; /* Must be first */ - struct spi_device *spidev; - struct spi_message spi_msg1; - struct spi_message spi_msg2; - struct spi_transfer spi_xfer1; - struct spi_transfer spi_xfer2[2]; -}; - -#define to_ks8851_spi(ks) container_of((ks), struct ks8851_net_spi, ks8851) - static int msg_enable; -/* SPI frame opcodes */ -#define KS_SPIOP_RD (0x00) -#define KS_SPIOP_WR (0x40) -#define KS_SPIOP_RXFIFO (0x80) -#define KS_SPIOP_TXFIFO (0xC0) - -/* shift for byte-enable data */ -#define BYTE_EN(_x) ((_x) << 2) - -/* turn register number and byte-enable mask into data for start of packet */ -#define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) - -/* SPI register read/write calls. - * - * All these calls issue SPI transactions to access the chip's registers. They - * all require that the necessary lock is held to prevent accesses when the - * chip is busy transferring packet data (RX/TX FIFO accesses). - */ - -/** - * ks8851_wrreg16_spi - write 16bit register value to chip via SPI - * @ks: The chip state - * @reg: The register address - * @val: The value to write - * - * Issue a write to put the value @val into the register specified in @reg. - */ -static void ks8851_wrreg16_spi(struct ks8851_net *ks, unsigned int reg, - unsigned int val) -{ - struct ks8851_net_spi *kss = to_ks8851_spi(ks); - struct spi_transfer *xfer = &kss->spi_xfer1; - struct spi_message *msg = &kss->spi_msg1; - __le16 txb[2]; - int ret; - - txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); - txb[1] = cpu_to_le16(val); - - xfer->tx_buf = txb; - xfer->rx_buf = NULL; - xfer->len = 4; - - ret = spi_sync(kss->spidev, msg); - if (ret < 0) - netdev_err(ks->netdev, "spi_sync() failed\n"); -} - /** * ks8851_wrreg16 - write 16bit register value to chip * @ks: The chip state @@ -222,74 +44,6 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned int reg, ks->wrreg16(ks, reg, val); } -/** - * ks8851_rdreg - issue read register command and return the data - * @ks: The device state - * @op: The register address and byte enables in message format. - * @rxb: The RX buffer to return the result into - * @rxl: The length of data expected. - * - * This is the low level read call that issues the necessary spi message(s) - * to read data from the register specified in @op. - */ -static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, - u8 *rxb, unsigned rxl) -{ - struct ks8851_net_spi *kss = to_ks8851_spi(ks); - struct spi_transfer *xfer; - struct spi_message *msg; - __le16 *txb = (__le16 *)ks->txd; - u8 *trx = ks->rxd; - int ret; - - txb[0] = cpu_to_le16(op | KS_SPIOP_RD); - - if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) { - msg = &kss->spi_msg2; - xfer = kss->spi_xfer2; - - xfer->tx_buf = txb; - xfer->rx_buf = NULL; - xfer->len = 2; - - xfer++; - xfer->tx_buf = NULL; - xfer->rx_buf = trx; - xfer->len = rxl; - } else { - msg = &kss->spi_msg1; - xfer = &kss->spi_xfer1; - - xfer->tx_buf = txb; - xfer->rx_buf = trx; - xfer->len = rxl + 2; - } - - ret = spi_sync(kss->spidev, msg); - if (ret < 0) - netdev_err(ks->netdev, "read: spi_sync() failed\n"); - else if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) - memcpy(rxb, trx, rxl); - else - memcpy(rxb, trx + 2, rxl); -} - -/** - * ks8851_rdreg16_spi - read 16 bit register from device via SPI - * @ks: The chip information - * @reg: The register address - * - * Read a 16bit register from the chip, returning the result -*/ -static unsigned int ks8851_rdreg16_spi(struct ks8851_net *ks, - unsigned int reg) -{ - __le16 rx = 0; - - ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); - return le16_to_cpu(rx); -} - /** * ks8851_rdreg16 - read 16 bit register from device * @ks: The chip information @@ -439,44 +193,6 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device *ddev) ks8851_write_mac_addr(dev); } -/** - * ks8851_rdfifo_spi - read data from the receive fifo via SPI - * @ks: The device state. - * @buff: The buffer address - * @len: The length of the data to read - * - * Issue an RXQ FIFO read command and read the @len amount of data from - * the FIFO into the buffer specified by @buff. - */ -static void ks8851_rdfifo_spi(struct ks8851_net *ks, u8 *buff, - unsigned int len) -{ - struct ks8851_net_spi *kss = to_ks8851_spi(ks); - struct spi_transfer *xfer = kss->spi_xfer2; - struct spi_message *msg = &kss->spi_msg2; - u8 txb[1]; - int ret; - - netif_dbg(ks, rx_status, ks->netdev, - "%s: %d@%p\n", __func__, len, buff); - - /* set the operation we're issuing */ - txb[0] = KS_SPIOP_RXFIFO; - - xfer->tx_buf = txb; - xfer->rx_buf = NULL; - xfer->len = 1; - - xfer++; - xfer->rx_buf = buff; - xfer->tx_buf = NULL; - xfer->len = len; - - ret = spi_sync(kss->spidev, msg); - if (ret < 0) - netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); -} - /** * ks8851_dbg_dumpkkt - dump initial packet contents to debug * @ks: The device state @@ -683,54 +399,6 @@ static inline unsigned calc_txlen(unsigned len) return ALIGN(len + 4, 4); } -/** - * ks8851_wrpkt_spi - write packet to TX FIFO via SPI - * @ks: The device state. - * @txp: The sk_buff to transmit. - * @irq: IRQ on completion of the packet. - * - * Send the @txp to the chip. This means creating the relevant packet header - * specifying the length of the packet and the other information the chip - * needs, such as IRQ on completion. Send the header and the packet data to - * the device. - */ -static void ks8851_wrpkt_spi(struct ks8851_net *ks, struct sk_buff *txp, - bool irq) -{ - struct ks8851_net_spi *kss = to_ks8851_spi(ks); - struct spi_transfer *xfer = kss->spi_xfer2; - struct spi_message *msg = &kss->spi_msg2; - unsigned fid = 0; - int ret; - - netif_dbg(ks, tx_queued, ks->netdev, "%s: skb %p, %d@%p, irq %d\n", - __func__, txp, txp->len, txp->data, irq); - - fid = ks->fid++; - fid &= TXFR_TXFID_MASK; - - if (irq) - fid |= TXFR_TXIC; /* irq on completion */ - - /* start header at txb[1] to align txw entries */ - ks->txh.txb[1] = KS_SPIOP_TXFIFO; - ks->txh.txw[1] = cpu_to_le16(fid); - ks->txh.txw[2] = cpu_to_le16(txp->len); - - xfer->tx_buf = &ks->txh.txb[1]; - xfer->rx_buf = NULL; - xfer->len = 5; - - xfer++; - xfer->tx_buf = txp->data; - xfer->rx_buf = NULL; - xfer->len = ALIGN(txp->len, 4); - - ret = spi_sync(kss->spidev, msg); - if (ret < 0) - netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); -} - /** * ks8851_done_tx - update and then free skbuff after transmitting * @ks: The device state @@ -1382,7 +1050,7 @@ static int ks8851_read_selftest(struct ks8851_net *ks) #ifdef CONFIG_PM_SLEEP -static int ks8851_suspend(struct device *dev) +int ks8851_suspend(struct device *dev) { struct ks8851_net *ks = dev_get_drvdata(dev); struct net_device *netdev = ks->netdev; @@ -1395,7 +1063,7 @@ static int ks8851_suspend(struct device *dev) return 0; } -static int ks8851_resume(struct device *dev) +int ks8851_resume(struct device *dev) { struct ks8851_net *ks = dev_get_drvdata(dev); struct net_device *netdev = ks->netdev; @@ -1409,9 +1077,7 @@ static int ks8851_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); - -static int ks8851_probe_common(struct net_device *ndev, struct device *dev) +int ks8851_probe_common(struct net_device *ndev, struct device *dev) { struct ks8851_net *ks = netdev_priv(ndev); unsigned cider; @@ -1545,7 +1211,7 @@ static int ks8851_probe_common(struct net_device *ndev, struct device *dev) return ret; } -static int ks8851_remove_common(struct device *dev) +int ks8851_remove_common(struct device *dev) { struct ks8851_net *priv = dev_get_drvdata(dev); @@ -1561,68 +1227,6 @@ static int ks8851_remove_common(struct device *dev) return 0; } -static int ks8851_probe(struct spi_device *spi) -{ - struct device *dev = &spi->dev; - struct ks8851_net_spi *kss; - struct net_device *ndev; - struct ks8851_net *ks; - - ndev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); - if (!ndev) - return -ENOMEM; - - spi->bits_per_word = 8; - - ks = netdev_priv(ndev); - ks->rdreg16 = ks8851_rdreg16_spi; - ks->wrreg16 = ks8851_wrreg16_spi; - ks->rdfifo = ks8851_rdfifo_spi; - ks->wrfifo = ks8851_wrpkt_spi; - - kss = to_ks8851_spi(ks); - - kss->spidev = spi; - - /* initialise pre-made spi transfer messages */ - spi_message_init(&kss->spi_msg1); - spi_message_add_tail(&kss->spi_xfer1, &kss->spi_msg1); - - spi_message_init(&kss->spi_msg2); - spi_message_add_tail(&kss->spi_xfer2[0], &kss->spi_msg2); - spi_message_add_tail(&kss->spi_xfer2[1], &kss->spi_msg2); - - ndev->irq = spi->irq; - - return ks8851_probe_common(ndev, dev); -} - -static int ks8851_remove(struct spi_device *spi) -{ - return ks8851_remove_common(&spi->dev); -} - -static const struct of_device_id ks8851_match_table[] = { - { .compatible = "micrel,ks8851" }, - { } -}; -MODULE_DEVICE_TABLE(of, ks8851_match_table); - -static struct spi_driver ks8851_driver = { - .driver = { - .name = "ks8851", - .of_match_table = ks8851_match_table, - .pm = &ks8851_pm_ops, - }, - .probe = ks8851_probe, - .remove = ks8851_remove, -}; -module_spi_driver(ks8851_driver); - -MODULE_DESCRIPTION("KS8851 Network driver"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL"); - module_param_named(message, msg_enable, int, 0); MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); MODULE_ALIAS("spi:ks8851"); diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index 8f834aef8e32..8b2acbc06f15 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -7,6 +7,9 @@ * KS8851 register definitions */ +#ifndef __KS8851_H__ +#define __KS8851_H__ + #define KS_CCR 0x08 #define CCR_LE (1 << 10) /* KSZ8851-16MLL */ #define CCR_EEPROM (1 << 9) @@ -300,3 +303,123 @@ #define TXFR_TXIC (1 << 15) #define TXFR_TXFID_MASK (0x3f << 0) #define TXFR_TXFID_SHIFT (0) + +/** + * struct ks8851_rxctrl - KS8851 driver rx control + * @mchash: Multicast hash-table data. + * @rxcr1: KS_RXCR1 register setting + * @rxcr2: KS_RXCR2 register setting + * + * Representation of the settings needs to control the receive filtering + * such as the multicast hash-filter and the receive register settings. This + * is used to make the job of working out if the receive settings change and + * then issuing the new settings to the worker that will send the necessary + * commands. + */ +struct ks8851_rxctrl { + u16 mchash[4]; + u16 rxcr1; + u16 rxcr2; +}; + +/** + * union ks8851_tx_hdr - tx header data + * @txb: The header as bytes + * @txw: The header as 16bit, little-endian words + * + * A dual representation of the tx header data to allow + * access to individual bytes, and to allow 16bit accesses + * with 16bit alignment. + */ +union ks8851_tx_hdr { + u8 txb[6]; + __le16 txw[3]; +}; + +/** + * struct ks8851_net - KS8851 driver private data + * @netdev: The network device we're bound to + * @spidev: The spi device we're bound to. + * @lock: Lock to ensure that the device is not accessed when busy. + * @statelock: Lock on this structure for tx list. + * @mii: The MII state information for the mii calls. + * @rxctrl: RX settings for @rxctrl_work. + * @tx_work: Work queue for tx packets + * @rxctrl_work: Work queue for updating RX mode and multicast lists + * @txq: Queue of packets for transmission. + * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. + * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. + * @txh: Space for generating packet TX header in DMA-able data + * @rxd: Space for receiving SPI data, in DMA-able space. + * @txd: Space for transmitting SPI data, in DMA-able space. + * @msg_enable: The message flags controlling driver output (see ethtool). + * @fid: Incrementing frame id tag. + * @rc_ier: Cached copy of KS_IER. + * @rc_ccr: Cached copy of KS_CCR. + * @rc_rxqcr: Cached copy of KS_RXQCR. + * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. + * @vdd_reg: Optional regulator supplying the chip + * @vdd_io: Optional digital power supply for IO + * @gpio: Optional reset_n gpio + * + * The @lock ensures that the chip is protected when certain operations are + * in progress. When the read or write packet transfer is in progress, most + * of the chip registers are not ccessible until the transfer is finished and + * the DMA has been de-asserted. + * + * The @statelock is used to protect information in the structure which may + * need to be accessed via several sources, such as the network driver layer + * or one of the work queues. + * + * We align the buffers we may use for rx/tx to ensure that if the SPI driver + * wants to DMA map them, it will not have any problems with data the driver + * modifies. + */ +struct ks8851_net { + struct net_device *netdev; + struct mutex lock; + spinlock_t statelock; + + union ks8851_tx_hdr txh ____cacheline_aligned; + u8 rxd[8]; + u8 txd[8]; + + u32 msg_enable ____cacheline_aligned; + u16 tx_space; + u8 fid; + + u16 rc_ier; + u16 rc_rxqcr; + u16 rc_ccr; + + struct mii_if_info mii; + struct ks8851_rxctrl rxctrl; + + struct work_struct tx_work; + struct work_struct rxctrl_work; + + struct sk_buff_head txq; + + struct eeprom_93cx6 eeprom; + struct regulator *vdd_reg; + struct regulator *vdd_io; + int gpio; + + unsigned int (*rdreg16)(struct ks8851_net *ks, + unsigned int reg); + void (*wrreg16)(struct ks8851_net *ks, + unsigned int reg, unsigned int val); + void (*rdfifo)(struct ks8851_net *ks, u8 *buff, + unsigned int len); + void (*wrfifo)(struct ks8851_net *ks, + struct sk_buff *txp, bool irq); +}; + +int ks8851_probe_common(struct net_device *ndev, struct device *dev); +int ks8851_remove_common(struct device *dev); +int ks8851_suspend(struct device *dev); +int ks8851_resume(struct device *dev); + +static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); + +#endif diff --git a/drivers/net/ethernet/micrel/ks8851_spi.c b/drivers/net/ethernet/micrel/ks8851_spi.c new file mode 100644 index 000000000000..07f1b8f09fc0 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8851_spi.c @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* drivers/net/ethernet/micrel/ks8851.c + * + * Copyright 2009 Simtec Electronics + * http://www.simtec.co.uk/ + * Ben Dooks + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ks8851.h" + +/** + * struct ks8851_net_spi - KS8851 SPI driver private data + * @ks8851: KS8851 driver common private data + * @spidev: The spi device we're bound to. + * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. + * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. + */ +struct ks8851_net_spi { + struct ks8851_net ks8851; /* Must be first */ + struct spi_device *spidev; + struct spi_message spi_msg1; + struct spi_message spi_msg2; + struct spi_transfer spi_xfer1; + struct spi_transfer spi_xfer2[2]; +}; + +#define to_ks8851_spi(ks) container_of((ks), struct ks8851_net_spi, ks8851) + +/* SPI frame opcodes */ +#define KS_SPIOP_RD 0x00 +#define KS_SPIOP_WR 0x40 +#define KS_SPIOP_RXFIFO 0x80 +#define KS_SPIOP_TXFIFO 0xC0 + +/* shift for byte-enable data */ +#define BYTE_EN(_x) ((_x) << 2) + +/* turn register number and byte-enable mask into data for start of packet */ +#define MK_OP(_byteen, _reg) \ + (BYTE_EN(_byteen) | (_reg) << (8 + 2) | (_reg) >> 6) + +/* SPI register read/write calls. + * + * All these calls issue SPI transactions to access the chip's registers. They + * all require that the necessary lock is held to prevent accesses when the + * chip is busy transferring packet data (RX/TX FIFO accesses). + */ + +/** + * ks8851_wrreg16_spi - write 16bit register value to chip via SPI + * @ks: The chip state + * @reg: The register address + * @val: The value to write + * + * Issue a write to put the value @val into the register specified in @reg. + */ +static void ks8851_wrreg16_spi(struct ks8851_net *ks, unsigned int reg, + unsigned int val) +{ + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = &kss->spi_xfer1; + struct spi_message *msg = &kss->spi_msg1; + __le16 txb[2]; + int ret; + + txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); + txb[1] = cpu_to_le16(val); + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 4; + + ret = spi_sync(kss->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "spi_sync() failed\n"); +} + +/** + * ks8851_rdreg - issue read register command and return the data + * @ks: The device state + * @op: The register address and byte enables in message format. + * @rxb: The RX buffer to return the result into + * @rxl: The length of data expected. + * + * This is the low level read call that issues the necessary spi message(s) + * to read data from the register specified in @op. + */ +static void ks8851_rdreg(struct ks8851_net *ks, unsigned int op, + u8 *rxb, unsigned int rxl) +{ + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer; + struct spi_message *msg; + __le16 *txb = (__le16 *)ks->txd; + u8 *trx = ks->rxd; + int ret; + + txb[0] = cpu_to_le16(op | KS_SPIOP_RD); + + if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) { + msg = &kss->spi_msg2; + xfer = kss->spi_xfer2; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 2; + + xfer++; + xfer->tx_buf = NULL; + xfer->rx_buf = trx; + xfer->len = rxl; + } else { + msg = &kss->spi_msg1; + xfer = &kss->spi_xfer1; + + xfer->tx_buf = txb; + xfer->rx_buf = trx; + xfer->len = rxl + 2; + } + + ret = spi_sync(kss->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "read: spi_sync() failed\n"); + else if (kss->spidev->master->flags & SPI_MASTER_HALF_DUPLEX) + memcpy(rxb, trx, rxl); + else + memcpy(rxb, trx + 2, rxl); +} + +/** + * ks8851_rdreg16_spi - read 16 bit register from device via SPI + * @ks: The chip information + * @reg: The register address + * + * Read a 16bit register from the chip, returning the result + */ +static unsigned int ks8851_rdreg16_spi(struct ks8851_net *ks, unsigned int reg) +{ + __le16 rx = 0; + + ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); + return le16_to_cpu(rx); +} + +/** + * ks8851_rdfifo_spi - read data from the receive fifo via SPI + * @ks: The device state. + * @buff: The buffer address + * @len: The length of the data to read + * + * Issue an RXQ FIFO read command and read the @len amount of data from + * the FIFO into the buffer specified by @buff. + */ +static void ks8851_rdfifo_spi(struct ks8851_net *ks, u8 *buff, unsigned int len) +{ + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = kss->spi_xfer2; + struct spi_message *msg = &kss->spi_msg2; + u8 txb[1]; + int ret; + + netif_dbg(ks, rx_status, ks->netdev, + "%s: %d@%p\n", __func__, len, buff); + + /* set the operation we're issuing */ + txb[0] = KS_SPIOP_RXFIFO; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 1; + + xfer++; + xfer->rx_buf = buff; + xfer->tx_buf = NULL; + xfer->len = len; + + ret = spi_sync(kss->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); +} + +/** + * ks8851_wrpkt_spi - write packet to TX FIFO via SPI + * @ks: The device state. + * @txp: The sk_buff to transmit. + * @irq: IRQ on completion of the packet. + * + * Send the @txp to the chip. This means creating the relevant packet header + * specifying the length of the packet and the other information the chip + * needs, such as IRQ on completion. Send the header and the packet data to + * the device. + */ +static void ks8851_wrpkt_spi(struct ks8851_net *ks, struct sk_buff *txp, + bool irq) +{ + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + struct spi_transfer *xfer = kss->spi_xfer2; + struct spi_message *msg = &kss->spi_msg2; + unsigned int fid = 0; + int ret; + + netif_dbg(ks, tx_queued, ks->netdev, "%s: skb %p, %d@%p, irq %d\n", + __func__, txp, txp->len, txp->data, irq); + + fid = ks->fid++; + fid &= TXFR_TXFID_MASK; + + if (irq) + fid |= TXFR_TXIC; /* irq on completion */ + + /* start header at txb[1] to align txw entries */ + ks->txh.txb[1] = KS_SPIOP_TXFIFO; + ks->txh.txw[1] = cpu_to_le16(fid); + ks->txh.txw[2] = cpu_to_le16(txp->len); + + xfer->tx_buf = &ks->txh.txb[1]; + xfer->rx_buf = NULL; + xfer->len = 5; + + xfer++; + xfer->tx_buf = txp->data; + xfer->rx_buf = NULL; + xfer->len = ALIGN(txp->len, 4); + + ret = spi_sync(kss->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); +} + +static int ks8851_probe_spi(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct ks8851_net_spi *kss; + struct net_device *ndev; + struct ks8851_net *ks; + + ndev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); + if (!ndev) + return -ENOMEM; + + spi->bits_per_word = 8; + + ks = netdev_priv(ndev); + ks->rdreg16 = ks8851_rdreg16_spi; + ks->wrreg16 = ks8851_wrreg16_spi; + ks->rdfifo = ks8851_rdfifo_spi; + ks->wrfifo = ks8851_wrpkt_spi; + + kss = to_ks8851_spi(ks); + + kss->spidev = spi; + + /* initialise pre-made spi transfer messages */ + spi_message_init(&kss->spi_msg1); + spi_message_add_tail(&kss->spi_xfer1, &kss->spi_msg1); + + spi_message_init(&kss->spi_msg2); + spi_message_add_tail(&kss->spi_xfer2[0], &kss->spi_msg2); + spi_message_add_tail(&kss->spi_xfer2[1], &kss->spi_msg2); + + ndev->irq = spi->irq; + + return ks8851_probe_common(ndev, dev); +} + +static int ks8851_remove_spi(struct spi_device *spi) +{ + return ks8851_remove_common(&spi->dev); +} + +static const struct of_device_id ks8851_match_table[] = { + { .compatible = "micrel,ks8851" }, + { } +}; +MODULE_DEVICE_TABLE(of, ks8851_match_table); + +static struct spi_driver ks8851_driver = { + .driver = { + .name = "ks8851", + .of_match_table = ks8851_match_table, + .pm = &ks8851_pm_ops, + }, + .probe = ks8851_probe_spi, + .remove = ks8851_remove_spi, +}; +module_spi_driver(ks8851_driver); + +MODULE_DESCRIPTION("KS8851 Network driver"); +MODULE_AUTHOR("Ben Dooks "); +MODULE_LICENSE("GPL");