From patchwork Thu May 14 00:07:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219303 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.7 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 47408C433DF for ; Thu, 14 May 2020 00:08:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 53F4C205ED for ; Thu, 14 May 2020 00:08:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732885AbgENAIJ (ORCPT ); Wed, 13 May 2020 20:08:09 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:39633 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732871AbgENAII (ORCPT ); Wed, 13 May 2020 20:08:08 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsLv0L4wz1qs3X; Thu, 14 May 2020 02:08:07 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsLv03nvz1shf6; Thu, 14 May 2020 02:08:07 +0200 (CEST) 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 xqK_-SaRpSNU; Thu, 14 May 2020 02:08:05 +0200 (CEST) X-Auth-Info: 21pPsPo6yAe+NISyElRZNwE1W6zOplvuYjThvxpp4v8= 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; Thu, 14 May 2020 02:08:05 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , Andrew Lunn , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 03/19] net: ks8851: Replace dev_err() with netdev_err() in IRQ handler Date: Thu, 14 May 2020 02:07:31 +0200 Message-Id: <20200514000747.159320-4-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 Use netdev_err() instead of dev_err() to avoid accessing the spidev->dev in the interrupt handler. This is the only place which uses the spidev in this function, so replace it with netdev_err() to get rid of it. This is done in preparation for unifying the KS8851 SPI and parallel drivers. Reviewed-by: Andrew Lunn Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V2: Add RB from Andrew V3: No change V4: No change V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 2b85072993c5..0088df970ad6 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -631,7 +631,7 @@ static irqreturn_t ks8851_irq(int irq, void *_ks) handled |= IRQ_RXI; if (status & IRQ_SPIBEI) { - dev_err(&ks->spidev->dev, "%s: spi bus error\n", __func__); + netdev_err(ks->netdev, "%s: spi bus error\n", __func__); handled |= IRQ_SPIBEI; } From patchwork Thu May 14 00:07:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219300 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.7 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 94518C433E0 for ; Thu, 14 May 2020 00:08:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A40DF205ED for ; Thu, 14 May 2020 00:08:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732960AbgENAIU (ORCPT ); Wed, 13 May 2020 20:08:20 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:48448 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732924AbgENAIQ (ORCPT ); Wed, 13 May 2020 20:08:16 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsLy5yr1z1rt4X; Thu, 14 May 2020 02:08:08 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsLw1Xpcz1shf6; Thu, 14 May 2020 02:08:08 +0200 (CEST) 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 q6CidvovG4Wo; Thu, 14 May 2020 02:08:07 +0200 (CEST) X-Auth-Info: wLgD2FzJQPjhxGBWhgj3XTbbWFJLzSQ35Zkn+ReH06w= 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; Thu, 14 May 2020 02:08:07 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 04/19] net: ks8851: Pass device node into ks8851_init_mac() Date: Thu, 14 May 2020 02:07:32 +0200 Message-Id: <20200514000747.159320-5-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 and can easily derive of_node pointer from it, pass the of_node pointer as a parameter to ks8851_init_mac() to avoid fishing it out from 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 bus drivers. No functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V2: Pass in of_node instead of the entire device pointer V3: No change V4: No change V5: No change --- 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 0088df970ad6..942e694c750a 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_node *np) { 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(np); if (!IS_ERR(mac_addr)) { ether_addr_copy(dev->dev_addr, mac_addr); ks8851_write_mac_addr(dev); @@ -1541,7 +1542,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->of_node); ret = register_netdev(netdev); if (ret) { From patchwork Thu May 14 00:07:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219301 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.7 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 35D8AC433E1 for ; Thu, 14 May 2020 00:08:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5CBBA2065C for ; Thu, 14 May 2020 00:08:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732926AbgENAIP (ORCPT ); Wed, 13 May 2020 20:08:15 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:56745 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732871AbgENAIN (ORCPT ); Wed, 13 May 2020 20:08:13 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsLz5m3Yz1rtMv; Thu, 14 May 2020 02:08:11 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsLz5ZyGz1shf5; Thu, 14 May 2020 02:08:11 +0200 (CEST) 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 B2TOt7cKjPSy; Thu, 14 May 2020 02:08:10 +0200 (CEST) X-Auth-Info: OrJVdgo4c6YAb2a3YwB6InNvtkJvrRcwn9n4hF2QwK8= 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; Thu, 14 May 2020 02:08:10 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 07/19] net: ks8851: Remove ks8851_rdreg32() Date: Thu, 14 May 2020 02:07:35 +0200 Message-Id: <20200514000747.159320-8-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 ks8851_rdreg32() is used only in one place, to read two registers using a single read. To make it easier to support 16-bit accesses via parallel bus later on, replace this single read with two 16-bit reads from each of the registers and drop the ks8851_rdreg32() altogether. If this has noticeable performance impact on the SPI variant of KS8851, then we should consider using regmap to abstract the SPI and parallel bus options and in case of SPI, permit regmap to merge register reads of neighboring registers into single, longer, read. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V2: No change V3: No change V4: Drop the NOTE from the comment, the performance is OK V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index c2f381a7b3f3..8f1cc05dc3c8 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -296,25 +296,6 @@ static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) return le16_to_cpu(rx); } -/** - * ks8851_rdreg32 - read 32 bit register from device - * @ks: The chip information - * @reg: The register address - * - * Read a 32bit register from the chip. - * - * Note, this read requires the address be aligned to 4 bytes. -*/ -static unsigned ks8851_rdreg32(struct ks8851_net *ks, unsigned reg) -{ - __le32 rx = 0; - - WARN_ON(reg & 3); - - ks8851_rdreg(ks, MK_OP(0xf, reg), (u8 *)&rx, 4); - return le32_to_cpu(rx); -} - /** * ks8851_soft_reset - issue one of the soft reset to the device * @ks: The device state. @@ -508,7 +489,6 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) unsigned rxfc; unsigned rxlen; unsigned rxstat; - u32 rxh; u8 *rxpkt; rxfc = ks8851_rdreg8(ks, KS_RXFC); @@ -527,9 +507,8 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) */ for (; rxfc != 0; rxfc--) { - rxh = ks8851_rdreg32(ks, KS_RXFHSR); - rxstat = rxh & 0xffff; - rxlen = (rxh >> 16) & 0xfff; + rxstat = ks8851_rdreg16(ks, KS_RXFHSR); + rxlen = ks8851_rdreg16(ks, KS_RXFHBCR) & RXFHBCR_CNT_MASK; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); From patchwork Thu May 14 00:07:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219294 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.7 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 D9574C433E0 for ; Thu, 14 May 2020 00:08:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F22AA205ED for ; Thu, 14 May 2020 00:08:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733043AbgENAIu (ORCPT ); Wed, 13 May 2020 20:08:50 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:53668 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732936AbgENAIT (ORCPT ); Wed, 13 May 2020 20:08:19 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsM10w0kz1rtZ9; Thu, 14 May 2020 02:08:13 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsM10hTsz1qql9; Thu, 14 May 2020 02:08:13 +0200 (CEST) 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 RD4_FhAfuhLM; Thu, 14 May 2020 02:08:11 +0200 (CEST) X-Auth-Info: k3vUkBZe157bFy4p7nNQTJ8fJVJc4RLKPzvdUr0+um4= 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; Thu, 14 May 2020 02:08:11 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 08/19] net: ks8851: Use 16-bit writes to program MAC address Date: Thu, 14 May 2020 02:07:36 +0200 Message-Id: <20200514000747.159320-9-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 --- V2: Get rid of the KS_MAR(i + 1) by adjusting KS_MAR(x) macro V3: Swap MARx MSB and LSB in ks8851_read_mac_addr() V4: No change V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 47 ++++++++-------------------- drivers/net/ethernet/micrel/ks8851.h | 2 +- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 8f1cc05dc3c8..bb2f0dc8214d 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), 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)); + dev->dev_addr[i] = reg >> 8; + dev->dev_addr[i + 1] = reg & 0xff; + } mutex_unlock(&ks->lock); } diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index 8f834aef8e32..f210d18a10b5 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -19,7 +19,7 @@ #define CCR_32PIN (1 << 0) /* KSZ8851SNL */ /* MAC address registers */ -#define KS_MAR(_m) (0x15 - (_m)) +#define KS_MAR(_m) (0x14 - (_m)) #define KS_MARL 0x10 #define KS_MARM 0x12 #define KS_MARH 0x14 From patchwork Thu May 14 00:07:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219299 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.7 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 A2456C433E0 for ; Thu, 14 May 2020 00:08:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B12732065C for ; Thu, 14 May 2020 00:08:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732983AbgENAI1 (ORCPT ); Wed, 13 May 2020 20:08:27 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:45154 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732943AbgENAIU (ORCPT ); Wed, 13 May 2020 20:08:20 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsM50cqpz1rqfr; Thu, 14 May 2020 02:08:17 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsM50Nmvz1qql9; Thu, 14 May 2020 02:08:17 +0200 (CEST) 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 DVECI9z0TOCr; Thu, 14 May 2020 02:08:16 +0200 (CEST) X-Auth-Info: 131G/r5MZP4UB6HVD4W532WdCWEtSRFr8bOrSKomjes= 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; Thu, 14 May 2020 02:08:16 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 11/19] net: ks8851: Factor out SKB receive function Date: Thu, 14 May 2020 02:07:39 +0200 Message-Id: <20200514000747.159320-12-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 Factor out this netif_rx_ni(), so it could be overridden by the parallel bus variant of the KS8851 driver. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V3: New patch V4: No change V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index b05cb9e0c5cd..01b00c81a928 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -465,6 +465,15 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); } +/** + * ks8851_rx_skb - receive skbuff + * @skb: The skbuff + */ +static void ks8851_rx_skb(struct sk_buff *skb) +{ + netif_rx_ni(skb); +} + /** * ks8851_rx_pkts - receive packets from the host * @ks: The device information. @@ -533,7 +542,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) ks8851_dbg_dumpkkt(ks, rxpkt); skb->protocol = eth_type_trans(skb, ks->netdev); - netif_rx_ni(skb); + ks8851_rx_skb(skb); ks->netdev->stats.rx_packets++; ks->netdev->stats.rx_bytes += rxlen; From patchwork Thu May 14 00:07:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219297 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.7 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 D1F53C433DF for ; Thu, 14 May 2020 00:08:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0BB6205ED for ; Thu, 14 May 2020 00:08:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733005AbgENAId (ORCPT ); Wed, 13 May 2020 20:08:33 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:42993 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732957AbgENAIW (ORCPT ); Wed, 13 May 2020 20:08:22 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsM81CPpz1qskT; Thu, 14 May 2020 02:08:20 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsM81280z1qql9; Thu, 14 May 2020 02:08:20 +0200 (CEST) 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 XMHm_N0uJqbN; Thu, 14 May 2020 02:08:18 +0200 (CEST) X-Auth-Info: euxHdU+uRDbvrL8YVZFGQVaK+p/NtFXlVptJQ5v5uDk= 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; Thu, 14 May 2020 02:08:18 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 13/19] net: ks8851: Split out SPI specific code from probe() and remove() Date: Thu, 14 May 2020 02:07:41 +0200 Message-Id: <20200514000747.159320-14-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 Factor out common code into ks8851_probe_common() and ks8851_remove_common() to permit both SPI and parallel bus driver variants to use the common code path for both probing and removal. There should be no functional change. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V2: - Add RB from Andrew - Rework on top of locking patches, drop RB V3: No change V4: No change V5: Pass message enable as parameter to common probe function, so the MODULE_* bits can be per-driver --- drivers/net/ethernet/micrel/ks8851.c | 86 ++++++++++++++++------------ 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 440ddd5cafbd..791b2f14dd9d 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1431,27 +1431,15 @@ static int ks8851_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); -static int ks8851_probe(struct spi_device *spi) +static int ks8851_probe_common(struct net_device *netdev, struct device *dev, + int msg_en) { - struct device *dev = &spi->dev; - struct ks8851_net_spi *kss; - struct net_device *netdev; - struct ks8851_net *ks; - int ret; + struct ks8851_net *ks = netdev_priv(netdev); unsigned cider; int gpio; - - netdev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); - if (!netdev) - return -ENOMEM; - - spi->bits_per_word = 8; - - ks = netdev_priv(netdev); - kss = to_ks8851_spi(ks); + int ret; ks->netdev = netdev; - kss->spidev = spi; ks->tx_space = 6144; gpio = of_get_named_gpio_flags(dev->of_node, "reset-gpios", 0, NULL); @@ -1497,23 +1485,11 @@ static int ks8851_probe(struct spi_device *spi) gpio_set_value(gpio, 1); } - mutex_init(&kss->lock); spin_lock_init(&ks->statelock); - INIT_WORK(&kss->tx_work, ks8851_tx_work); INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); - /* 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); - /* setup EEPROM state */ - ks->eeprom.data = ks; ks->eeprom.width = PCI_EEPROM_WIDTH_93C46; ks->eeprom.register_read = ks8851_eeprom_regread; @@ -1527,12 +1503,12 @@ static int ks8851_probe(struct spi_device *spi) ks->mii.mdio_read = ks8851_phy_read; ks->mii.mdio_write = ks8851_phy_write; - dev_info(dev, "message enable is %d\n", msg_enable); + dev_info(dev, "message enable is %d\n", msg_en); /* set the default message enable */ - ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | - NETIF_MSG_PROBE | - NETIF_MSG_LINK)); + ks->msg_enable = netif_msg_init(msg_en, NETIF_MSG_DRV | + NETIF_MSG_PROBE | + NETIF_MSG_LINK); skb_queue_head_init(&ks->txq); @@ -1544,7 +1520,6 @@ static int ks8851_probe(struct spi_device *spi) netif_carrier_off(ks->netdev); netdev->if_port = IF_PORT_100BASET; netdev->netdev_ops = &ks8851_netdev_ops; - netdev->irq = spi->irq; /* issue a global soft reset to reset the device. */ ks8851_soft_reset(ks, GRR_GSR); @@ -1586,12 +1561,9 @@ static int ks8851_probe(struct spi_device *spi) return ret; } -static int ks8851_remove(struct spi_device *spi) +static int ks8851_remove_common(struct device *dev) { - struct device *dev = &spi->dev; - struct ks8851_net *priv; - - priv = dev_get_drvdata(dev); + struct ks8851_net *priv = dev_get_drvdata(dev); if (netif_msg_drv(priv)) dev_info(dev, "remove\n"); @@ -1605,6 +1577,44 @@ static int ks8851_remove(struct spi_device *spi) return 0; } +static int ks8851_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct ks8851_net_spi *kss; + struct net_device *netdev; + struct ks8851_net *ks; + + netdev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_spi)); + if (!netdev) + return -ENOMEM; + + spi->bits_per_word = 8; + + ks = netdev_priv(netdev); + kss = to_ks8851_spi(ks); + + kss->spidev = spi; + mutex_init(&kss->lock); + INIT_WORK(&kss->tx_work, ks8851_tx_work); + + /* 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); + + netdev->irq = spi->irq; + + return ks8851_probe_common(netdev, dev, msg_enable); +} + +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" }, { } From patchwork Thu May 14 00:07:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219298 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.7 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 9A493C433E0 for ; Thu, 14 May 2020 00:08:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B9FEE205ED for ; Thu, 14 May 2020 00:08:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732990AbgENAI3 (ORCPT ); Wed, 13 May 2020 20:08:29 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:44253 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732962AbgENAIW (ORCPT ); Wed, 13 May 2020 20:08:22 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsM92dT5z1qskW; Thu, 14 May 2020 02:08:21 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsM92QDyz1qql9; Thu, 14 May 2020 02:08:21 +0200 (CEST) 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 Ka3lnohhXUiW; Thu, 14 May 2020 02:08:20 +0200 (CEST) X-Auth-Info: XhkDrTnURg12NmffhMKSYmqX9NnI5kUVJ0Z+Ydo8yfQ= 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; Thu, 14 May 2020 02:08:20 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 14/19] net: ks8851: Factor out TX work flush function Date: Thu, 14 May 2020 02:07:42 +0200 Message-Id: <20200514000747.159320-15-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 While the SPI version of the KS8851 requires a TX worker thread to pump data via SPI, the parallel bus version can write data into the TX FIFO directly in .ndo_start_xmit, as the parallel bus access is much faster and does not sleep. Factor out this TX work flush part, so it can be overridden by the parallel bus driver. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V3: New patch V4: No change V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 791b2f14dd9d..20c07e229e12 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -781,6 +781,17 @@ static void ks8851_tx_work(struct work_struct *work) ks8851_unlock(ks, &flags); } +/** + * ks8851_flush_tx_work - flush outstanding TX work + * @ks: The device state + */ +static void ks8851_flush_tx_work(struct ks8851_net *ks) +{ + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + + flush_work(&kss->tx_work); +} + /** * ks8851_net_open - open network device * @dev: The network device being opened. @@ -880,11 +891,8 @@ static int ks8851_net_open(struct net_device *dev) static int ks8851_net_stop(struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); - struct ks8851_net_spi *kss; unsigned long flags; - kss = to_ks8851_spi(ks); - netif_info(ks, ifdown, dev, "shutting down\n"); netif_stop_queue(dev); @@ -896,7 +904,7 @@ static int ks8851_net_stop(struct net_device *dev) ks8851_unlock(ks, &flags); /* stop any outstanding work */ - flush_work(&kss->tx_work); + ks8851_flush_tx_work(ks); flush_work(&ks->rxctrl_work); ks8851_lock(ks, &flags); From patchwork Thu May 14 00:07:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219296 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.7 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 8AE32C433DF for ; Thu, 14 May 2020 00:08:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A5C05205ED for ; Thu, 14 May 2020 00:08:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733017AbgENAIh (ORCPT ); Wed, 13 May 2020 20:08:37 -0400 Received: from mail-out.m-online.net ([212.18.0.10]:45848 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732971AbgENAI0 (ORCPT ); Wed, 13 May 2020 20:08:26 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsMD1sPmz1rtMv; Thu, 14 May 2020 02:08:24 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsMD1gHGz1qql9; Thu, 14 May 2020 02:08:24 +0200 (CEST) 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 KnRG3wbI_P-v; Thu, 14 May 2020 02:08:22 +0200 (CEST) X-Auth-Info: YY3R3fi4m/+6RIQQ937afwhj9CQ7/4Um60Acfp1BZ5o= 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; Thu, 14 May 2020 02:08:22 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 16/19] net: ks8851: Implement register, FIFO, lock accessor callbacks Date: Thu, 14 May 2020 02:07:44 +0200 Message-Id: <20200514000747.159320-17-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 register and FIFO accessors are bus specific, so is locking. Implement callbacks so that each variant of the KS8851 can implement matching accessors and locking, and use the rest of the common code. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V4: New patch V5: No change --- drivers/net/ethernet/micrel/ks8851.c | 167 +++++++++++++++++++++++---- 1 file changed, 145 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 2d3cc4a9c426..7bf2f102c942 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -117,6 +117,24 @@ struct ks8851_net { struct regulator *vdd_reg; struct regulator *vdd_io; int gpio; + + void (*lock)(struct ks8851_net *ks, + unsigned long *flags); + void (*unlock)(struct ks8851_net *ks, + unsigned long *flags); + 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); + netdev_tx_t (*start_xmit)(struct sk_buff *skb, + struct net_device *dev); + void (*rx_skb)(struct ks8851_net *ks, + struct sk_buff *skb); + void (*flush_tx_work)(struct ks8851_net *ks); }; /** @@ -161,13 +179,13 @@ static int msg_enable; #define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) /** - * ks8851_lock - register access lock + * ks8851_lock_spi - register access lock for SPI * @ks: The chip state * @flags: Spinlock flags * * Claim chip register access lock */ -static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags) +static void ks8851_lock_spi(struct ks8851_net *ks, unsigned long *flags) { struct ks8851_net_spi *kss = to_ks8851_spi(ks); @@ -175,19 +193,43 @@ static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags) } /** - * ks8851_unlock - register access unlock + * ks8851_unlock_spi - register access unlock for SPI * @ks: The chip state * @flags: Spinlock flags * * Release chip register access lock */ -static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags) +static void ks8851_unlock_spi(struct ks8851_net *ks, unsigned long *flags) { struct ks8851_net_spi *kss = to_ks8851_spi(ks); mutex_unlock(&kss->lock); } +/** + * ks8851_lock - register access lock + * @ks: The chip state + * @flags: Spinlock flags + * + * Claim chip register access lock + */ +static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags) +{ + ks->lock(ks, flags); +} + +/** + * ks8851_unlock - register access unlock + * @ks: The chip state + * @flags: Spinlock flags + * + * Release chip register access lock + */ +static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags) +{ + ks->unlock(ks, flags); +} + /* SPI register read/write calls. * * All these calls issue SPI transactions to access the chip's registers. They @@ -196,14 +238,15 @@ static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags) */ /** - * ks8851_wrreg16 - write 16bit register value to chip + * 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(struct ks8851_net *ks, unsigned reg, unsigned val) +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; @@ -223,6 +266,20 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) netdev_err(ks->netdev, "spi_sync() failed\n"); } +/** + * ks8851_wrreg16 - write 16bit 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_wrreg16(struct ks8851_net *ks, unsigned int reg, + unsigned int val) +{ + ks->wrreg16(ks, reg, val); +} + /** * ks8851_rdreg - issue read register command and return the data * @ks: The device state @@ -276,13 +333,14 @@ static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, } /** - * ks8851_rdreg16 - read 16 bit register from device + * 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 ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) +static unsigned int ks8851_rdreg16_spi(struct ks8851_net *ks, + unsigned int reg) { __le16 rx = 0; @@ -290,6 +348,19 @@ static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) return le16_to_cpu(rx); } +/** + * ks8851_rdreg16 - read 16 bit register from device + * @ks: The chip information + * @reg: The register address + * + * Read a 16bit register from the chip, returning the result + */ +static unsigned int ks8851_rdreg16(struct ks8851_net *ks, + unsigned int reg) +{ + return ks->rdreg16(ks, reg); +} + /** * ks8851_soft_reset - issue one of the soft reset to the device * @ks: The device state. @@ -429,7 +500,7 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np) } /** - * ks8851_rdfifo - read data from the receive fifo + * 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 @@ -437,7 +508,8 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np) * 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(struct ks8851_net *ks, u8 *buff, unsigned len) +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; @@ -482,14 +554,23 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) } /** - * ks8851_rx_skb - receive skbuff + * ks8851_rx_skb_spi - receive skbuff for SPI * @skb: The skbuff */ -static void ks8851_rx_skb(struct sk_buff *skb) +static void ks8851_rx_skb_spi(struct ks8851_net *ks, struct sk_buff *skb) { netif_rx_ni(skb); } +/** + * ks8851_rx_skb - receive skbuff + * @skb: The skbuff + */ +static void ks8851_rx_skb(struct ks8851_net *ks, struct sk_buff *skb) +{ + ks->rx_skb(ks, skb); +} + /** * ks8851_rx_pkts - receive packets from the host * @ks: The device information. @@ -552,13 +633,13 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) rxpkt = skb_put(skb, rxlen) - 8; - ks8851_rdfifo(ks, rxpkt, rxalign + 8); + ks->rdfifo(ks, rxpkt, rxalign + 8); if (netif_msg_pktdata(ks)) ks8851_dbg_dumpkkt(ks, rxpkt); skb->protocol = eth_type_trans(skb, ks->netdev); - ks8851_rx_skb(skb); + ks8851_rx_skb(ks, skb); ks->netdev->stats.rx_packets++; ks->netdev->stats.rx_bytes += rxlen; @@ -682,7 +763,7 @@ static inline unsigned calc_txlen(unsigned len) } /** - * ks8851_wrpkt - write packet to TX FIFO + * 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. @@ -692,7 +773,8 @@ static inline unsigned calc_txlen(unsigned len) * needs, such as IRQ on completion. Send the header and the packet data to * the device. */ -static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) +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; @@ -770,7 +852,7 @@ static void ks8851_tx_work(struct work_struct *work) if (txb != NULL) { ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); - ks8851_wrpkt(ks, txb, last); + ks->wrfifo(ks, txb, last); ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); @@ -782,16 +864,26 @@ static void ks8851_tx_work(struct work_struct *work) } /** - * ks8851_flush_tx_work - flush outstanding TX work + * ks8851_flush_tx_work_spi - flush outstanding TX work for SPI * @ks: The device state */ -static void ks8851_flush_tx_work(struct ks8851_net *ks) +static void ks8851_flush_tx_work_spi(struct ks8851_net *ks) { struct ks8851_net_spi *kss = to_ks8851_spi(ks); flush_work(&kss->tx_work); } +/** + * ks8851_flush_tx_work - flush outstanding TX work + * @ks: The device state + */ +static void ks8851_flush_tx_work(struct ks8851_net *ks) +{ + if (ks->flush_tx_work) + ks->flush_tx_work(ks); +} + /** * ks8851_net_open - open network device * @dev: The network device being opened. @@ -925,7 +1017,7 @@ static int ks8851_net_stop(struct net_device *dev) } /** - * ks8851_start_xmit - transmit packet + * ks8851_start_xmit_spi - transmit packet using SPI * @skb: The buffer to transmit * @dev: The device used to transmit the packet. * @@ -937,8 +1029,8 @@ static int ks8851_net_stop(struct net_device *dev) * and secondly so we can round up more than one packet to transmit which * means we can try and avoid generating too many transmit done interrupts. */ -static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t ks8851_start_xmit_spi(struct sk_buff *skb, + struct net_device *dev) { struct ks8851_net *ks = netdev_priv(dev); unsigned needed = calc_txlen(skb->len); @@ -966,6 +1058,27 @@ static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb, return ret; } +/** + * ks8851_start_xmit - transmit packet + * @skb: The buffer to transmit + * @dev: The device used to transmit the packet. + * + * Called by the network layer to transmit the @skb. Queue the packet for + * the device and schedule the necessary work to transmit the packet when + * it is free. + * + * We do this to firstly avoid sleeping with the network device locked, + * and secondly so we can round up more than one packet to transmit which + * means we can try and avoid generating too many transmit done interrupts. + */ +static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + + return ks->start_xmit(skb, dev); +} + /** * ks8851_rxctrl_work - work handler to change rx mode * @work: The work structure this belongs to. @@ -1591,6 +1704,16 @@ static int ks8851_probe(struct spi_device *spi) ks = netdev_priv(netdev); + ks->lock = ks8851_lock_spi; + ks->unlock = ks8851_unlock_spi; + ks->rdreg16 = ks8851_rdreg16_spi; + ks->wrreg16 = ks8851_wrreg16_spi; + ks->rdfifo = ks8851_rdfifo_spi; + ks->wrfifo = ks8851_wrpkt_spi; + ks->start_xmit = ks8851_start_xmit_spi; + ks->rx_skb = ks8851_rx_skb_spi; + ks->flush_tx_work = ks8851_flush_tx_work_spi; + #define STD_IRQ (IRQ_LCI | /* Link Change */ \ IRQ_TXI | /* TX done */ \ IRQ_RXI | /* RX done */ \ From patchwork Thu May 14 00:07:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 219295 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.7 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 B49C0C433DF for ; Thu, 14 May 2020 00:08:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C56B1205ED for ; Thu, 14 May 2020 00:08:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733030AbgENAIm (ORCPT ); Wed, 13 May 2020 20:08:42 -0400 Received: from mail-out.m-online.net ([212.18.0.9]:39251 "EHLO mail-out.m-online.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732995AbgENAId (ORCPT ); Wed, 13 May 2020 20:08:33 -0400 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 49MsML2FkTz1qskX; Thu, 14 May 2020 02:08:30 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 49MsML1jWVz1qql9; Thu, 14 May 2020 02:08:30 +0200 (CEST) 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 kia76-sYRn0h; Thu, 14 May 2020 02:08:27 +0200 (CEST) X-Auth-Info: /T5MHWOCOHAWJSYdYza09bfNW8RoY4vGnKp6F9r8KYo= 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; Thu, 14 May 2020 02:08:27 +0200 (CEST) From: Marek Vasut To: netdev@vger.kernel.org Cc: Marek Vasut , "David S . Miller" , Lukas Wunner , Petr Stetiar , YueHaibing Subject: [PATCH V5 18/19] net: ks8851: Implement Parallel bus operations Date: Thu, 14 May 2020 02:07:46 +0200 Message-Id: <20200514000747.159320-19-marex@denx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200514000747.159320-1-marex@denx.de> References: <20200514000747.159320-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 Implement accessors for KS8851-16MLL/MLLI/MLLU parallel bus variant of the KS8851. This is based off the ks8851_mll.c , which is a driver for exactly the same hardware, however the ks8851.c code is much higher quality. Hence, this patch pulls out the relevant information from the ks8851_mll.c on how to access the bus, but uses the common ks8851.c code. To make this patch reviewable, instead of rewriting ks8851_mll.c, ks8851_mll.c is removed in a separate subsequent patch. Signed-off-by: Marek Vasut Cc: David S. Miller Cc: Lukas Wunner Cc: Petr Stetiar Cc: YueHaibing --- V2: - Drop 'must be first' comment on the embedded struct ks8851_net - Add missing Kconfig 'select's to match the KS8851 SPI driver - Get rid of the pointer indirection - Repair the endian handling and add endian check V3: - Adjust Makefile to permit build as a module - Enable only RX and LCx interrupts V4: No change V5: - Move msg_enable module param to ks8851_par.c --- drivers/net/ethernet/micrel/Kconfig | 2 + drivers/net/ethernet/micrel/Makefile | 1 + drivers/net/ethernet/micrel/ks8851_par.c | 348 +++++++++++++++++++++++ 3 files changed, 351 insertions(+) create mode 100644 drivers/net/ethernet/micrel/ks8851_par.c diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig index b9c4d48e28e4..09f35209d43d 100644 --- a/drivers/net/ethernet/micrel/Kconfig +++ b/drivers/net/ethernet/micrel/Kconfig @@ -38,6 +38,8 @@ config KS8851_MLL tristate "Micrel KS8851 MLL" depends on HAS_IOMEM select MII + select CRC32 + select EEPROM_93CX6 ---help--- This platform driver is for Micrel KS8851 Address/data bus multiplexed network chip. diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile index c7a4725c2e95..5cc00d22c708 100644 --- a/drivers/net/ethernet/micrel/Makefile +++ b/drivers/net/ethernet/micrel/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_KS8842) += ks8842.o obj-$(CONFIG_KS8851) += ks8851.o ks8851-objs = ks8851_common.o ks8851_spi.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o +ks8851_mll-objs = ks8851_common.o ks8851_par.o obj-$(CONFIG_KSZ884X_PCI) += ksz884x.o diff --git a/drivers/net/ethernet/micrel/ks8851_par.c b/drivers/net/ethernet/micrel/ks8851_par.c new file mode 100644 index 000000000000..90fffacb1695 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8851_par.c @@ -0,0 +1,348 @@ +// 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 "ks8851.h" + +static int msg_enable; + +#define BE3 0x8000 /* Byte Enable 3 */ +#define BE2 0x4000 /* Byte Enable 2 */ +#define BE1 0x2000 /* Byte Enable 1 */ +#define BE0 0x1000 /* Byte Enable 0 */ + +/** + * struct ks8851_net_par - KS8851 Parallel driver private data + * @ks8851: KS8851 driver common private data + * @lock: Lock to ensure that the device is not accessed when busy. + * @hw_addr : start address of data register. + * @hw_addr_cmd : start address of command register. + * @cmd_reg_cache : command register cached. + * + * 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. + */ +struct ks8851_net_par { + struct ks8851_net ks8851; + spinlock_t lock; + void __iomem *hw_addr; + void __iomem *hw_addr_cmd; + u16 cmd_reg_cache; +}; + +#define to_ks8851_par(ks) container_of((ks), struct ks8851_net_par, ks8851) + +/** + * ks8851_lock_par - register access lock + * @ks: The chip state + * @flags: Spinlock flags + * + * Claim chip register access lock + */ +static void ks8851_lock_par(struct ks8851_net *ks, unsigned long *flags) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + + spin_lock_irqsave(&ksp->lock, *flags); +} + +/** + * ks8851_unlock_par - register access unlock + * @ks: The chip state + * @flags: Spinlock flags + * + * Release chip register access lock + */ +static void ks8851_unlock_par(struct ks8851_net *ks, unsigned long *flags) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + + spin_unlock_irqrestore(&ksp->lock, *flags); +} + +/** + * ks_check_endian - Check whether endianness of the bus is correct + * @ks : The chip information + * + * The KS8851-16MLL EESK pin allows selecting the endianness of the 16bit + * bus. To maintain optimum performance, the bus endianness should be set + * such that it matches the endianness of the CPU. + */ +static int ks_check_endian(struct ks8851_net *ks) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + u16 cider; + + /* + * Read CIDER register first, however read it the "wrong" way around. + * If the endian strap on the KS8851-16MLL in incorrect and the chip + * is operating in different endianness than the CPU, then the meaning + * of BE[3:0] byte-enable bits is also swapped such that: + * BE[3,2,1,0] becomes BE[1,0,3,2] + * + * Luckily for us, the byte-enable bits are the top four MSbits of + * the address register and the CIDER register is at offset 0xc0. + * Hence, by reading address 0xc0c0, which is not impacted by endian + * swapping, we assert either BE[3:2] or BE[1:0] while reading the + * CIDER register. + * + * If the bus configuration is correct, reading 0xc0c0 asserts + * BE[3:2] and this read returns 0x0000, because to read register + * with bottom two LSbits of address set to 0, BE[1:0] must be + * asserted. + * + * If the bus configuration is NOT correct, reading 0xc0c0 asserts + * BE[1:0] and this read returns non-zero 0x8872 value. + */ + iowrite16(BE3 | BE2 | KS_CIDER, ksp->hw_addr_cmd); + cider = ioread16(ksp->hw_addr); + if (!cider) + return 0; + + netdev_err(ks->netdev, "incorrect EESK endian strap setting\n"); + + return -EINVAL; +} + +/** + * ks8851_wrreg16_par - write 16bit 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_wrreg16_par(struct ks8851_net *ks, unsigned int reg, + unsigned int val) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + + ksp->cmd_reg_cache = (u16)reg | ((BE1 | BE0) << (reg & 0x02)); + iowrite16(ksp->cmd_reg_cache, ksp->hw_addr_cmd); + iowrite16(val, ksp->hw_addr); +} + +/** + * ks8851_rdreg16_par - read 16 bit register from chip + * @ks: The chip information + * @reg: The register address + * + * Read a 16bit register from the chip, returning the result + */ +static unsigned int ks8851_rdreg16_par(struct ks8851_net *ks, unsigned int reg) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + + ksp->cmd_reg_cache = (u16)reg | ((BE1 | BE0) << (reg & 0x02)); + iowrite16(ksp->cmd_reg_cache, ksp->hw_addr_cmd); + return ioread16(ksp->hw_addr); +} + +/** + * ks8851_rdfifo_par - read data from the receive fifo + * @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_par(struct ks8851_net *ks, u8 *buff, unsigned int len) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + + netif_dbg(ks, rx_status, ks->netdev, + "%s: %d@%p\n", __func__, len, buff); + + ioread16_rep(ksp->hw_addr, (u16 *)buff + 1, len / 2); +} + +/** + * ks8851_wrfifo_par - write packet to TX FIFO + * @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_wrfifo_par(struct ks8851_net *ks, struct sk_buff *txp, + bool irq) +{ + struct ks8851_net_par *ksp = to_ks8851_par(ks); + unsigned int len = ALIGN(txp->len, 4); + unsigned int fid = 0; + + 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 */ + + iowrite16(fid, ksp->hw_addr); + iowrite16(txp->len, ksp->hw_addr); + + iowrite16_rep(ksp->hw_addr, txp->data, len / 2); +} + +/** + * ks8851_rx_skb_par - receive skbuff + * @skb: The skbuff + */ +static void ks8851_rx_skb_par(struct ks8851_net *ks, struct sk_buff *skb) +{ + netif_rx(skb); +} + +/** + * ks8851_start_xmit_par - transmit packet + * @skb: The buffer to transmit + * @dev: The device used to transmit the packet. + * + * Called by the network layer to transmit the @skb. Queue the packet for + * the device and schedule the necessary work to transmit the packet when + * it is free. + * + * We do this to firstly avoid sleeping with the network device locked, + * and secondly so we can round up more than one packet to transmit which + * means we can try and avoid generating too many transmit done interrupts. + */ +static netdev_tx_t ks8851_start_xmit_par(struct sk_buff *skb, + struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + netdev_tx_t ret = NETDEV_TX_OK; + unsigned long flags; + u16 txmir; + + netif_dbg(ks, tx_queued, ks->netdev, + "%s: skb %p, %d@%p\n", __func__, skb, skb->len, skb->data); + + ks8851_lock_par(ks, &flags); + + txmir = ks8851_rdreg16_par(ks, KS_TXMIR) & 0x1fff; + + if (likely(txmir >= skb->len + 12)) { + ks8851_wrreg16_par(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); + ks8851_wrfifo_par(ks, skb, false); + ks8851_wrreg16_par(ks, KS_RXQCR, ks->rc_rxqcr); + ks8851_wrreg16_par(ks, KS_TXQCR, TXQCR_METFE); + while (ks8851_rdreg16_par(ks, KS_TXQCR) & TXQCR_METFE) + ; + ks8851_done_tx(ks, skb); + } else { + ret = NETDEV_TX_BUSY; + } + + ks8851_unlock_par(ks, &flags); + + return ret; +} + +static int ks8851_probe_par(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ks8851_net_par *ksp; + struct net_device *netdev; + struct ks8851_net *ks; + int ret; + + netdev = devm_alloc_etherdev(dev, sizeof(struct ks8851_net_par)); + if (!netdev) + return -ENOMEM; + + ks = netdev_priv(netdev); + + ks->lock = ks8851_lock_par; + ks->unlock = ks8851_unlock_par; + ks->rdreg16 = ks8851_rdreg16_par; + ks->wrreg16 = ks8851_wrreg16_par; + ks->rdfifo = ks8851_rdfifo_par; + ks->wrfifo = ks8851_wrfifo_par; + ks->start_xmit = ks8851_start_xmit_par; + ks->rx_skb = ks8851_rx_skb_par; + +#define STD_IRQ (IRQ_LCI | /* Link Change */ \ + IRQ_RXI | /* RX done */ \ + IRQ_RXPSI) /* RX process stop */ + ks->rc_ier = STD_IRQ; + + ksp = to_ks8851_par(ks); + spin_lock_init(&ksp->lock); + + ksp->hw_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ksp->hw_addr)) + return PTR_ERR(ksp->hw_addr); + + ksp->hw_addr_cmd = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(ksp->hw_addr_cmd)) + return PTR_ERR(ksp->hw_addr_cmd); + + ret = ks_check_endian(ks); + if (ret) + return ret; + + netdev->irq = platform_get_irq(pdev, 0); + + return ks8851_probe_common(netdev, dev, msg_enable); +} + +static int ks8851_remove_par(struct platform_device *pdev) +{ + return ks8851_remove_common(&pdev->dev); +} + +static const struct of_device_id ks8851_match_table[] = { + { .compatible = "micrel,ks8851-mll" }, + { } +}; +MODULE_DEVICE_TABLE(of, ks8851_match_table); + +static struct platform_driver ks8851_driver = { + .driver = { + .name = "ks8851", + .of_match_table = ks8851_match_table, + .pm = &ks8851_pm_ops, + }, + .probe = ks8851_probe_par, + .remove = ks8851_remove_par, +}; +module_platform_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)");