From patchwork Fri May 5 13:50:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 98639 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp133570qge; Fri, 5 May 2017 06:51:31 -0700 (PDT) X-Received: by 10.98.44.148 with SMTP id s142mr17573548pfs.251.1493992291525; Fri, 05 May 2017 06:51:31 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 81si5335101pfn.32.2017.05.05.06.51.31; Fri, 05 May 2017 06:51:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754371AbdEENup (ORCPT + 25 others); Fri, 5 May 2017 09:50:45 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:59969 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752607AbdEENun (ORCPT ); Fri, 5 May 2017 09:50:43 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id 076C6212DF; Fri, 5 May 2017 15:50:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id BBEB6207E1; Fri, 5 May 2017 15:50:41 +0200 (CEST) From: Quentin Schulz To: wg@grandegger.com, mkl@pengutronix.de, mario.huettel@gmx.net, socketcan@hartkopp.net Cc: Quentin Schulz , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, thomas.petazzoni@free-electrons.com Subject: [PATCH v4 1/4] can: m_can: move Message RAM initialization to function Date: Fri, 5 May 2017 15:50:30 +0200 Message-Id: <20170505135033.8349-1-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To avoid possible ECC/parity checksum errors when reading an uninitialized buffer, the entire Message RAM is initialized when probing the driver. This initialization is done in the same function reading the Device Tree properties. This patch moves the RAM initialization to a separate function so it can be called separately from device initialization from Device Tree. Signed-off-by: Quentin Schulz --- v4: - remove unused variables from m_can_of_parse_mram, drivers/net/can/m_can/m_can.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) -- 2.11.0 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index bf8fdaeb955e..5da1bdb202a3 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1489,11 +1489,23 @@ static int register_m_can_dev(struct net_device *dev) return register_candev(dev); } +static void m_can_init_ram(struct m_can_priv *priv) +{ + int end, i, start; + + /* initialize the entire Message RAM in use to avoid possible + * ECC/parity checksum errors when reading an uninitialized buffer + */ + start = priv->mcfg[MRAM_SIDF].off; + end = priv->mcfg[MRAM_TXB].off + + priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; + for (i = start; i < end; i += 4) + writel(0x0, priv->mram_base + i); +} + static void m_can_of_parse_mram(struct m_can_priv *priv, const u32 *mram_config_vals) { - int i, start, end; - priv->mcfg[MRAM_SIDF].off = mram_config_vals[0]; priv->mcfg[MRAM_SIDF].num = mram_config_vals[1]; priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off + @@ -1529,15 +1541,7 @@ static void m_can_of_parse_mram(struct m_can_priv *priv, priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); - /* initialize the entire Message RAM in use to avoid possible - * ECC/parity checksum errors when reading an uninitialized buffer - */ - start = priv->mcfg[MRAM_SIDF].off; - end = priv->mcfg[MRAM_TXB].off + - priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; - for (i = start; i < end; i += 4) - writel(0x0, priv->mram_base + i); - + m_can_init_ram(priv); } static int m_can_plat_probe(struct platform_device *pdev) From patchwork Fri May 5 13:50:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 98638 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp133563qge; Fri, 5 May 2017 06:51:31 -0700 (PDT) X-Received: by 10.99.119.76 with SMTP id s73mr3417826pgc.215.1493992290976; Fri, 05 May 2017 06:51:30 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 81si5335101pfn.32.2017.05.05.06.51.30; Fri, 05 May 2017 06:51:30 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754709AbdEENuq (ORCPT + 25 others); Fri, 5 May 2017 09:50:46 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:59978 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752631AbdEENuo (ORCPT ); Fri, 5 May 2017 09:50:44 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id 36FD1212E0; Fri, 5 May 2017 15:50:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id F2B8B20829; Fri, 5 May 2017 15:50:41 +0200 (CEST) From: Quentin Schulz To: wg@grandegger.com, mkl@pengutronix.de, mario.huettel@gmx.net, socketcan@hartkopp.net Cc: Quentin Schulz , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, thomas.petazzoni@free-electrons.com Subject: [PATCH v4 2/4] can: m_can: make m_can_start and m_can_stop symmetric Date: Fri, 5 May 2017 15:50:31 +0200 Message-Id: <20170505135033.8349-2-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170505135033.8349-1-quentin.schulz@free-electrons.com> References: <20170505135033.8349-1-quentin.schulz@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This moves clocks gating outside of the m_can_stop function as the m_can_start function does not (and cannot, at least in current implementation) ungate clocks. This way, both functions can now be used symmetrically. Signed-off-by: Quentin Schulz --- added in v4 drivers/net/can/m_can/m_can.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) -- 2.11.0 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 5da1bdb202a3..6115dede671e 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1324,9 +1324,6 @@ static void m_can_stop(struct net_device *dev) /* disable all interrupts */ m_can_disable_all_interrupts(priv); - clk_disable_unprepare(priv->hclk); - clk_disable_unprepare(priv->cclk); - /* set the state as STOPPED */ priv->can.state = CAN_STATE_STOPPED; } @@ -1338,6 +1335,8 @@ static int m_can_close(struct net_device *dev) netif_stop_queue(dev); napi_disable(&priv->napi); m_can_stop(dev); + clk_disable_unprepare(priv->hclk); + clk_disable_unprepare(priv->cclk); free_irq(dev->irq, dev); close_candev(dev); can_led_event(dev, CAN_LED_EVENT_STOP); From patchwork Fri May 5 13:50:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 98637 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp133383qge; Fri, 5 May 2017 06:51:03 -0700 (PDT) X-Received: by 10.98.152.65 with SMTP id q62mr7881619pfd.256.1493992263699; Fri, 05 May 2017 06:51:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1493992263; cv=none; d=google.com; s=arc-20160816; b=tXX1mpnV4GqN/VCo4wvxFfWwz6N6KYW1Y0z6TgBBtztx1WpQY9Wo+kc1R6/vEUB3To wfoOG7PcPU5+TU9Y6WN3CDVVyekz2lhmkCHQo1wEnhasN7ZGS5krOwwNs16qmaRRbRiL eXfJAGEGl/e3tqW4rWuvinq1EH5ZUxyNxeUc2ndncrZptzarkgAmqIHQhZwniHChQ1eT A0ZmxC97htlMxZPwTQfZhVfrH+Ez0S/6oqFW5O/w9TaajAmwTeXaQf7uR6nN96Fy6XLb H7UQc4waVJSiitIUwBzCbbOTMABGHokgTfGZ+znT77y6n9Zy2NjTbSbDVfMas4MnniKl EAyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=yjtFrFwJGkEXM5Ib3LON0/kcd3exB5K+3arJbS3Oo1Q=; b=Injeq8vHpPZGZ2FN6iN2ReUnrTD8QZkjeYvnOrWhP729oPsYYZtmqkwh3HUCIc1qKG 3EgiDqQxPtm48aiWXf4OkP7t+BeBP71DDolJb0i4kp3jNk2yoQHQxIxnVj0kBoYUPFqe WwFCLBBhe75d+fKIJPbLD2A/TsRZiqdY4+rvBl9kymh8A2yWWs0Kl6v0Snl3Yus01U9A m/hRXJY12BZToLs5ehbXHJG9iPnyQ+qxSs4hVSNqT/QaPSIh9bORloppQEdajt/oMZ7v 9AZWTxSqTpkUNjTrgwLaAnep+yYDSLISBX8pekoZBe5E/Dvhvzc3GpIMVPBOmVWrrS+Y iP3Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b12si5826158plm.77.2017.05.05.06.51.03; Fri, 05 May 2017 06:51:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754870AbdEENus (ORCPT + 25 others); Fri, 5 May 2017 09:50:48 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:59982 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752699AbdEENuo (ORCPT ); Fri, 5 May 2017 09:50:44 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id 71B0E212E7; Fri, 5 May 2017 15:50:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 33CD8207E1; Fri, 5 May 2017 15:50:42 +0200 (CEST) From: Quentin Schulz To: wg@grandegger.com, mkl@pengutronix.de, mario.huettel@gmx.net, socketcan@hartkopp.net Cc: Quentin Schulz , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, thomas.petazzoni@free-electrons.com Subject: [PATCH v4 3/4] can: m_can: factorize clock gating and ungating Date: Fri, 5 May 2017 15:50:32 +0200 Message-Id: <20170505135033.8349-3-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170505135033.8349-1-quentin.schulz@free-electrons.com> References: <20170505135033.8349-1-quentin.schulz@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This creates a function to ungate M_CAN clocks and another to gate the same clocks, then swaps all gating/ungating code with their respective function. Signed-off-by: Quentin Schulz --- added in v4 drivers/net/can/m_can/m_can.c | 45 +++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 19 deletions(-) -- 2.11.0 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 6115dede671e..653b304d7091 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -621,10 +621,8 @@ static int __m_can_get_berr_counter(const struct net_device *dev, return 0; } -static int m_can_get_berr_counter(const struct net_device *dev, - struct can_berr_counter *bec) +static int m_can_clk_start(struct m_can_priv *priv) { - struct m_can_priv *priv = netdev_priv(dev); int err; err = clk_prepare_enable(priv->hclk); @@ -632,15 +630,31 @@ static int m_can_get_berr_counter(const struct net_device *dev, return err; err = clk_prepare_enable(priv->cclk); - if (err) { + if (err) clk_disable_unprepare(priv->hclk); - return err; - } - __m_can_get_berr_counter(dev, bec); + return err; +} +static void m_can_clk_stop(struct m_can_priv *priv) +{ clk_disable_unprepare(priv->cclk); clk_disable_unprepare(priv->hclk); +} + +static int m_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct m_can_priv *priv = netdev_priv(dev); + int err; + + err = m_can_clk_start(priv); + if (err) + return err; + + __m_can_get_berr_counter(dev, bec); + + m_can_clk_stop(priv); return 0; } @@ -1276,19 +1290,15 @@ static int m_can_open(struct net_device *dev) struct m_can_priv *priv = netdev_priv(dev); int err; - err = clk_prepare_enable(priv->hclk); + err = m_can_clk_start(priv); if (err) return err; - err = clk_prepare_enable(priv->cclk); - if (err) - goto exit_disable_hclk; - /* open the can device */ err = open_candev(dev); if (err) { netdev_err(dev, "failed to open can device\n"); - goto exit_disable_cclk; + goto exit_disable_clks; } /* register interrupt handler */ @@ -1310,10 +1320,8 @@ static int m_can_open(struct net_device *dev) exit_irq_fail: close_candev(dev); -exit_disable_cclk: - clk_disable_unprepare(priv->cclk); -exit_disable_hclk: - clk_disable_unprepare(priv->hclk); +exit_disable_clks: + m_can_clk_stop(priv); return err; } @@ -1335,8 +1343,7 @@ static int m_can_close(struct net_device *dev) netif_stop_queue(dev); napi_disable(&priv->napi); m_can_stop(dev); - clk_disable_unprepare(priv->hclk); - clk_disable_unprepare(priv->cclk); + m_can_clk_stop(priv); free_irq(dev->irq, dev); close_candev(dev); can_led_event(dev, CAN_LED_EVENT_STOP); From patchwork Fri May 5 13:50:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 98636 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp133381qge; Fri, 5 May 2017 06:51:03 -0700 (PDT) X-Received: by 10.99.42.199 with SMTP id q190mr3385464pgq.13.1493992263361; Fri, 05 May 2017 06:51:03 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b12si5826158plm.77.2017.05.05.06.51.03; Fri, 05 May 2017 06:51:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755090AbdEENut (ORCPT + 25 others); Fri, 5 May 2017 09:50:49 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:59989 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753297AbdEENuo (ORCPT ); Fri, 5 May 2017 09:50:44 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id ABC5720F67; Fri, 5 May 2017 15:50:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 6B74520829; Fri, 5 May 2017 15:50:42 +0200 (CEST) From: Quentin Schulz To: wg@grandegger.com, mkl@pengutronix.de, mario.huettel@gmx.net, socketcan@hartkopp.net Cc: Quentin Schulz , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, thomas.petazzoni@free-electrons.com Subject: [PATCH v4 4/4] can: m_can: add deep Suspend/Resume support Date: Fri, 5 May 2017 15:50:33 +0200 Message-Id: <20170505135033.8349-4-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170505135033.8349-1-quentin.schulz@free-electrons.com> References: <20170505135033.8349-1-quentin.schulz@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This adds Power Management deep Suspend/Resume support for Bosch M_CAN chip. When entering deep sleep, the clocks are gated, the interrupts are disabled. When resuming from deep sleep, the chip needs to be reinitialized, the clocks ungated and the interrupts enabled. Signed-off-by: Quentin Schulz --- v4: - added a TODO comment for efficient runtime PM support, - used m_can_clk_start/stop functions added in v4 to have symmetric suspend and resume functions. v3: - do not close/reopen the can interface (which was previously done when calling m_can_close), basically do the same routine as in probe but it does not close/open the can device, - update commit log, v2: - fix erroneous commit log, drivers/net/can/m_can/m_can.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) -- 2.11.0 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 653b304d7091..f4947a74b65f 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1668,6 +1668,8 @@ static int m_can_plat_probe(struct platform_device *pdev) return ret; } +/* TODO: runtime PM with power down or sleep mode */ + static __maybe_unused int m_can_suspend(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); @@ -1676,10 +1678,10 @@ static __maybe_unused int m_can_suspend(struct device *dev) if (netif_running(ndev)) { netif_stop_queue(ndev); netif_device_detach(ndev); + m_can_stop(ndev); + m_can_clk_stop(priv); } - /* TODO: enter low power */ - priv->can.state = CAN_STATE_SLEEPING; return 0; @@ -1690,11 +1692,18 @@ static __maybe_unused int m_can_resume(struct device *dev) struct net_device *ndev = dev_get_drvdata(dev); struct m_can_priv *priv = netdev_priv(ndev); - /* TODO: exit low power */ + m_can_init_ram(priv); priv->can.state = CAN_STATE_ERROR_ACTIVE; if (netif_running(ndev)) { + int ret; + + ret = m_can_clk_start(priv); + if (ret) + return ret; + + m_can_start(ndev); netif_device_attach(ndev); netif_start_queue(ndev); }