* [net-next.git 1/7] stmmac: remove dead code for TIMER
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
@ 2012-09-03 7:46 ` Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 2/7] stmmac: manage tx clean out of rx_poll Giuseppe CAVALLARO
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:46 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
TIMER option is not longer supported and this
code can be considered dead for this driver in
the new kernel series.
In fact, It was not updated at all and never used.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 25 ----
drivers/net/ethernet/stmicro/stmmac/Makefile | 1 -
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 -
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 101 +--------------
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c | 134 --------------------
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h | 46 -------
6 files changed, 3 insertions(+), 310 deletions(-)
delete mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
delete mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 9f44827..1164930 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -54,31 +54,6 @@ config STMMAC_DA
By default, the DMA arbitration scheme is based on Round-robin
(rx:tx priority is 1:1).
-config STMMAC_TIMER
- bool "STMMAC Timer optimisation"
- default n
- depends on RTC_HCTOSYS_DEVICE
- ---help---
- Use an external timer for mitigating the number of network
- interrupts. Currently, for SH architectures, it is possible
- to use the TMU channel 2 and the SH-RTC device.
-
-choice
- prompt "Select Timer device"
- depends on STMMAC_TIMER
-
-config STMMAC_TMU_TIMER
- bool "TMU channel 2"
- depends on CPU_SH4
- ---help---
-
-config STMMAC_RTC_TIMER
- bool "Real time clock"
- depends on RTC_CLASS
- ---help---
-
-endchoice
-
choice
prompt "Select the DMA TX/RX descriptor operating modes"
depends on STMMAC_ETH
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index bc965ac..c8e8ea6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -1,5 +1,4 @@
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
-stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o
stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o
stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index e872e1d..9f35769 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -31,9 +31,6 @@
#include <linux/phy.h>
#include <linux/pci.h>
#include "common.h"
-#ifdef CONFIG_STMMAC_TIMER
-#include "stmmac_timer.h"
-#endif
struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
@@ -78,9 +75,6 @@ struct stmmac_priv {
spinlock_t tx_lock;
int wolopts;
int wol_irq;
-#ifdef CONFIG_STMMAC_TIMER
- struct stmmac_timer *tm;
-#endif
struct plat_stmmacenet_data *plat;
struct stmmac_counters mmc;
struct dma_features dma_cap;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c136162..c8985f3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -115,16 +115,6 @@ static int tc = TC_DEFAULT;
module_param(tc, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(tc, "DMA threshold control value");
-/* Pay attention to tune this parameter; take care of both
- * hardware capability and network stabitily/performance impact.
- * Many tests showed that ~4ms latency seems to be good enough. */
-#ifdef CONFIG_STMMAC_TIMER
-#define DEFAULT_PERIODIC_RATE 256
-static int tmrate = DEFAULT_PERIODIC_RATE;
-module_param(tmrate, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
-#endif
-
#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
static int buf_sz = DMA_BUFFER_SIZE;
module_param(buf_sz, int, S_IRUGO | S_IWUSR);
@@ -536,12 +526,6 @@ static void init_dma_desc_rings(struct net_device *dev)
else
bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
-#ifdef CONFIG_STMMAC_TIMER
- /* Disable interrupts on completion for the reception if timer is on */
- if (likely(priv->tm->enable))
- dis_ic = 1;
-#endif
-
DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
txsize, rxsize, bfsize);
@@ -786,22 +770,12 @@ static void stmmac_tx(struct stmmac_priv *priv)
static inline void stmmac_enable_irq(struct stmmac_priv *priv)
{
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
- priv->tm->timer_start(tmrate);
- else
-#endif
- priv->hw->dma->enable_dma_irq(priv->ioaddr);
+ priv->hw->dma->enable_dma_irq(priv->ioaddr);
}
static inline void stmmac_disable_irq(struct stmmac_priv *priv)
{
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
- priv->tm->timer_stop();
- else
-#endif
- priv->hw->dma->disable_dma_irq(priv->ioaddr);
+ priv->hw->dma->disable_dma_irq(priv->ioaddr);
}
static int stmmac_has_work(struct stmmac_priv *priv)
@@ -829,25 +803,6 @@ static inline void _stmmac_schedule(struct stmmac_priv *priv)
}
}
-#ifdef CONFIG_STMMAC_TIMER
-void stmmac_schedule(struct net_device *dev)
-{
- struct stmmac_priv *priv = netdev_priv(dev);
-
- priv->xstats.sched_timer_n++;
-
- _stmmac_schedule(priv);
-}
-
-static void stmmac_no_timer_started(unsigned int x)
-{;
-};
-
-static void stmmac_no_timer_stopped(void)
-{;
-};
-#endif
-
/**
* stmmac_tx_err:
* @priv: pointer to the private device structure
@@ -1049,23 +1004,6 @@ static int stmmac_open(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
int ret;
-#ifdef CONFIG_STMMAC_TIMER
- priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
- if (unlikely(priv->tm == NULL))
- return -ENOMEM;
-
- priv->tm->freq = tmrate;
-
- /* Test if the external timer can be actually used.
- * In case of failure continue without timer. */
- if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
- pr_warning("stmmaceth: cannot attach the external timer.\n");
- priv->tm->freq = 0;
- priv->tm->timer_start = stmmac_no_timer_started;
- priv->tm->timer_stop = stmmac_no_timer_stopped;
- } else
- priv->tm->enable = 1;
-#endif
clk_enable(priv->stmmac_clk);
stmmac_check_ether_addr(priv);
@@ -1152,10 +1090,6 @@ static int stmmac_open(struct net_device *dev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
-#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_start(tmrate);
-#endif
-
/* Dump DMA/MAC registers */
if (netif_msg_hw(priv)) {
priv->hw->mac->dump_regs(priv->ioaddr);
@@ -1182,9 +1116,6 @@ open_error_wolirq:
free_irq(dev->irq, dev);
open_error:
-#ifdef CONFIG_STMMAC_TIMER
- kfree(priv->tm);
-#endif
if (priv->phydev)
phy_disconnect(priv->phydev);
@@ -1215,12 +1146,6 @@ static int stmmac_release(struct net_device *dev)
netif_stop_queue(dev);
-#ifdef CONFIG_STMMAC_TIMER
- /* Stop and release the timer */
- stmmac_close_ext_timer();
- if (priv->tm != NULL)
- kfree(priv->tm);
-#endif
napi_disable(&priv->napi);
skb_queue_purge(&priv->rx_recycle);
@@ -1336,12 +1261,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
/* Interrupt on completition only for the latest segment */
priv->hw->desc->close_tx_desc(desc);
-#ifdef CONFIG_STMMAC_TIMER
- /* Clean IC while using timer */
- if (likely(priv->tm->enable))
- priv->hw->desc->clear_tx_ic(desc);
-#endif
-
wmb();
/* To avoid raise condition */
@@ -1539,7 +1458,7 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
* stmmac_tx_timeout
* @dev : Pointer to net device structure
* Description: this function is called when a packet transmission fails to
- * complete within a reasonable tmrate. The driver will mark the error in the
+ * complete within a reasonable time. The driver will mark the error in the
* netdev structure and arrange for the device to be reset to a sane state
* in order to transmit a new packet.
*/
@@ -2157,11 +2076,6 @@ int stmmac_suspend(struct net_device *ndev)
netif_device_detach(ndev);
netif_stop_queue(ndev);
-#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_stop();
- if (likely(priv->tm->enable))
- dis_ic = 1;
-#endif
napi_disable(&priv->napi);
/* Stop TX/RX DMA */
@@ -2212,10 +2126,6 @@ int stmmac_resume(struct net_device *ndev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
- priv->tm->timer_start(tmrate);
-#endif
napi_enable(&priv->napi);
netif_start_queue(ndev);
@@ -2311,11 +2221,6 @@ static int __init stmmac_cmdline_opt(char *str)
} else if (!strncmp(opt, "eee_timer:", 6)) {
if (kstrtoint(opt + 10, 0, &eee_timer))
goto err;
-#ifdef CONFIG_STMMAC_TIMER
- } else if (!strncmp(opt, "tmrate:", 7)) {
- if (kstrtoint(opt + 7, 0, &tmrate))
- goto err;
-#endif
}
}
return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
deleted file mode 100644
index 2a0e1ab..0000000
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*******************************************************************************
- STMMAC external timer support.
-
- Copyright (C) 2007-2009 STMicroelectronics Ltd
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/etherdevice.h>
-#include "stmmac_timer.h"
-
-static void stmmac_timer_handler(void *data)
-{
- struct net_device *dev = (struct net_device *)data;
-
- stmmac_schedule(dev);
-}
-
-#define STMMAC_TIMER_MSG(timer, freq) \
-printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
-
-#if defined(CONFIG_STMMAC_RTC_TIMER)
-#include <linux/rtc.h>
-static struct rtc_device *stmmac_rtc;
-static rtc_task_t stmmac_task;
-
-static void stmmac_rtc_start(unsigned int new_freq)
-{
- rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
-}
-
-static void stmmac_rtc_stop(void)
-{
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
-}
-
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
-{
- stmmac_task.private_data = dev;
- stmmac_task.func = stmmac_timer_handler;
-
- stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
- if (stmmac_rtc == NULL) {
- pr_err("open rtc device failed\n");
- return -ENODEV;
- }
-
- rtc_irq_register(stmmac_rtc, &stmmac_task);
-
- /* Periodic mode is not supported */
- if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
- pr_err("set periodic failed\n");
- rtc_irq_unregister(stmmac_rtc, &stmmac_task);
- rtc_class_close(stmmac_rtc);
- return -1;
- }
-
- STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
-
- tm->timer_start = stmmac_rtc_start;
- tm->timer_stop = stmmac_rtc_stop;
-
- return 0;
-}
-
-int stmmac_close_ext_timer(void)
-{
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
- rtc_irq_unregister(stmmac_rtc, &stmmac_task);
- rtc_class_close(stmmac_rtc);
- return 0;
-}
-
-#elif defined(CONFIG_STMMAC_TMU_TIMER)
-#include <linux/clk.h>
-#define TMU_CHANNEL "tmu2_clk"
-static struct clk *timer_clock;
-
-static void stmmac_tmu_start(unsigned int new_freq)
-{
- clk_set_rate(timer_clock, new_freq);
- clk_enable(timer_clock);
-}
-
-static void stmmac_tmu_stop(void)
-{
- clk_disable(timer_clock);
-}
-
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
-{
- timer_clock = clk_get(NULL, TMU_CHANNEL);
-
- if (timer_clock == NULL)
- return -1;
-
- if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
- timer_clock = NULL;
- return -1;
- }
-
- STMMAC_TIMER_MSG("TMU2", tm->freq);
- tm->timer_start = stmmac_tmu_start;
- tm->timer_stop = stmmac_tmu_stop;
-
- return 0;
-}
-
-int stmmac_close_ext_timer(void)
-{
- clk_disable(timer_clock);
- tmu2_unregister_user();
- clk_put(timer_clock);
- return 0;
-}
-#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
deleted file mode 100644
index aea9b14..0000000
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- STMMAC external timer Header File.
-
- Copyright (C) 2007-2009 STMicroelectronics Ltd
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-#ifndef __STMMAC_TIMER_H__
-#define __STMMAC_TIMER_H__
-
-struct stmmac_timer {
- void (*timer_start) (unsigned int new_freq);
- void (*timer_stop) (void);
- unsigned int freq;
- unsigned int enable;
-};
-
-/* Open the HW timer device and return 0 in case of success */
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
-/* Stop the timer and release it */
-int stmmac_close_ext_timer(void);
-/* Function used for scheduling task within the stmmac */
-void stmmac_schedule(struct net_device *dev);
-
-#if defined(CONFIG_STMMAC_TMU_TIMER)
-extern int tmu2_register_user(void *fnt, void *data);
-extern void tmu2_unregister_user(void);
-#endif
-
-#endif /* __STMMAC_TIMER_H__ */
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [net-next.git 2/7] stmmac: manage tx clean out of rx_poll
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 1/7] stmmac: remove dead code for TIMER Giuseppe CAVALLARO
@ 2012-09-03 7:46 ` Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 3/7] stmmac: add the initial tx coalesce schema Giuseppe CAVALLARO
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:46 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch is to invoke the stmmac_tx (tx handler)
out of the NAPI poll method.
This will make easier the next step to add the new
mitigation schema.
Also the patch enhances the ethtool to report some
stats for normal TX and RX IRQs.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 13 +++++++----
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 7 +++--
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 4 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++++++-----
4 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 719be39..bd32fe6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -95,7 +95,9 @@ struct stmmac_extra_stats {
unsigned long threshold;
unsigned long tx_pkt_n;
unsigned long rx_pkt_n;
- unsigned long poll_n;
+ unsigned long rx_napi_poll;
+ unsigned long rx_normal_irq_n;
+ unsigned long tx_normal_irq_n;
unsigned long sched_timer_n;
unsigned long normal_irq_n;
unsigned long mmc_tx_irq_n;
@@ -169,10 +171,11 @@ enum rx_frame_status { /* IPC status */
llc_snap = 4,
};
-enum tx_dma_irq_status {
- tx_hard_error = 1,
- tx_hard_error_bump_tc = 2,
- handle_tx_rx = 3,
+enum dma_irq_status {
+ tx_hard_error = 0x1,
+ tx_hard_error_bump_tc = 0x2,
+ handle_rx = 0x4,
+ handle_tx = 0x8,
};
enum core_specific_irq_mask {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 4e0e18a..73766e6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -206,9 +206,10 @@ int dwmac_dma_interrupt(void __iomem *ioaddr,
/* TX/RX NORMAL interrupts */
if (intr_status & DMA_STATUS_NIS) {
x->normal_irq_n++;
- if (likely((intr_status & DMA_STATUS_RI) ||
- (intr_status & (DMA_STATUS_TI))))
- ret = handle_tx_rx;
+ if (likely(intr_status & DMA_STATUS_RI))
+ ret |= handle_rx;
+ if (intr_status & (DMA_STATUS_TI))
+ ret |= handle_tx;
}
/* Optional hardware blocks, interrupts should be disabled */
if (unlikely(intr_status &
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 76fd61a..505fe71 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -90,7 +90,9 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
STMMAC_STAT(threshold),
STMMAC_STAT(tx_pkt_n),
STMMAC_STAT(rx_pkt_n),
- STMMAC_STAT(poll_n),
+ STMMAC_STAT(rx_napi_poll),
+ STMMAC_STAT(rx_normal_irq_n),
+ STMMAC_STAT(tx_normal_irq_n),
STMMAC_STAT(sched_timer_n),
STMMAC_STAT(normal_irq_n),
STMMAC_STAT(normal_irq_n),
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c8985f3..b247c39 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -824,16 +824,27 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
netif_wake_queue(priv->dev);
}
+static inline void stmmac_rx_schedule(struct stmmac_priv *priv)
+{
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ stmmac_disable_irq(priv);
+ __napi_schedule(&priv->napi);
+ }
+}
static void stmmac_dma_interrupt(struct stmmac_priv *priv)
{
int status;
status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
- if (likely(status == handle_tx_rx))
- _stmmac_schedule(priv);
-
- else if (unlikely(status == tx_hard_error_bump_tc)) {
+ if (likely(status == handle_rx)) {
+ priv->xstats.rx_normal_irq_n++;
+ stmmac_rx_schedule(priv);
+ }
+ if (likely(status == handle_tx)) {
+ priv->xstats.tx_normal_irq_n++;
+ stmmac_tx(priv);
+ } else if (unlikely(status == tx_hard_error_bump_tc)) {
/* Try to bump up the dma threshold on this failure */
if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
tc += 64;
@@ -1443,8 +1454,7 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
int work_done = 0;
- priv->xstats.poll_n++;
- stmmac_tx(priv);
+ priv->xstats.rx_napi_poll++;
work_done = stmmac_rx(priv, budget);
if (work_done < budget) {
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [net-next.git 3/7] stmmac: add the initial tx coalesce schema
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 1/7] stmmac: remove dead code for TIMER Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 2/7] stmmac: manage tx clean out of rx_poll Giuseppe CAVALLARO
@ 2012-09-03 7:46 ` Giuseppe CAVALLARO
2012-09-03 7:46 ` [net-next.git 4/7] stmmac: add Rx watchdog optimization to mitigate the DMA irqs Giuseppe CAVALLARO
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:46 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch adds a new schema used for mitigating the
number of transmit interrupts.
It is based on a sw timer and a threshold value.
The timer is used to periodically call the stmmac_tx
function that can be invoked by the ISR but only for
the descriptors where the interrupt on completion
field has been set. This is tuned by a threshold.
Next step is to add the ability to tune these coalesce
values by ethtool.
Till now I have put a default that showed a real gain
on all the platforms ARM/SH4 where I performed benchmarks.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 8 +-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 9 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 86 +++++++++++++-------
4 files changed, 72 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index bd32fe6..1d6bd3e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -95,11 +95,13 @@ struct stmmac_extra_stats {
unsigned long threshold;
unsigned long tx_pkt_n;
unsigned long rx_pkt_n;
- unsigned long rx_napi_poll;
+ unsigned long normal_irq_n;
unsigned long rx_normal_irq_n;
+ unsigned long rx_napi_poll;
unsigned long tx_normal_irq_n;
- unsigned long sched_timer_n;
- unsigned long normal_irq_n;
+ unsigned long txtimer;
+ unsigned long tx_clean;
+ unsigned long tx_reset_ic_bit;
unsigned long mmc_tx_irq_n;
unsigned long mmc_rx_irq_n;
unsigned long mmc_rx_csum_offload_irq_n;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 9f35769..0f5ab28 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -88,6 +88,10 @@ struct stmmac_priv {
int eee_enabled;
int eee_active;
int tx_lpi_timer;
+ struct timer_list txtimer;
+ u32 tx_count_frames;
+ u32 tx_coal_frames;
+ u32 tx_coal_timer;
};
extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 505fe71..48ad0bc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -90,12 +90,13 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
STMMAC_STAT(threshold),
STMMAC_STAT(tx_pkt_n),
STMMAC_STAT(rx_pkt_n),
- STMMAC_STAT(rx_napi_poll),
+ STMMAC_STAT(normal_irq_n),
STMMAC_STAT(rx_normal_irq_n),
+ STMMAC_STAT(rx_napi_poll),
STMMAC_STAT(tx_normal_irq_n),
- STMMAC_STAT(sched_timer_n),
- STMMAC_STAT(normal_irq_n),
- STMMAC_STAT(normal_irq_n),
+ STMMAC_STAT(txtimer),
+ STMMAC_STAT(tx_clean),
+ STMMAC_STAT(tx_reset_ic_bit),
STMMAC_STAT(mmc_tx_irq_n),
STMMAC_STAT(mmc_rx_irq_n),
STMMAC_STAT(mmc_rx_csum_offload_irq_n),
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b247c39..d7f5482 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -77,6 +77,8 @@
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
#define JUMBO_LEN 9000
+#define STMMAC_TX_TM 40000
+#define STMMAC_TX_MAX_FRAMES 64 /* Max coalesced frame */
/* Module parameters */
#define TX_TIMEO 5000 /* default 5 seconds */
@@ -695,8 +697,11 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
static void stmmac_tx(struct stmmac_priv *priv)
{
unsigned int txsize = priv->dma_tx_size;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->tx_lock, flags);
- spin_lock(&priv->tx_lock);
+ priv->xstats.tx_clean++;
while (priv->dirty_tx != priv->cur_tx) {
int last;
@@ -765,7 +770,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
stmmac_enable_eee_mode(priv);
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
}
- spin_unlock(&priv->tx_lock);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
}
static inline void stmmac_enable_irq(struct stmmac_priv *priv)
@@ -778,29 +783,16 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv)
priv->hw->dma->disable_dma_irq(priv->ioaddr);
}
-static int stmmac_has_work(struct stmmac_priv *priv)
+static void stmmac_txtimer(unsigned long data)
{
- unsigned int has_work = 0;
- int rxret, tx_work = 0;
+ struct stmmac_priv *priv = (struct stmmac_priv *)data;
- rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
- (priv->cur_rx % priv->dma_rx_size));
+ priv->xstats.txtimer++;
if (priv->dirty_tx != priv->cur_tx)
- tx_work = 1;
-
- if (likely(!rxret || tx_work))
- has_work = 1;
+ stmmac_tx(priv);
- return has_work;
-}
-
-static inline void _stmmac_schedule(struct stmmac_priv *priv)
-{
- if (likely(stmmac_has_work(priv))) {
- stmmac_disable_irq(priv);
- napi_schedule(&priv->napi);
- }
+ return;
}
/**
@@ -824,7 +816,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
netif_wake_queue(priv->dev);
}
-static inline void stmmac_rx_schedule(struct stmmac_priv *priv)
+static void stmmac_rx_schedule(struct stmmac_priv *priv)
{
if (likely(napi_schedule_prep(&priv->napi))) {
stmmac_disable_irq(priv);
@@ -1001,6 +993,36 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
priv->dma_rx_phy);
}
+static int stmmac_check_coal(int size, int max_coal_frames)
+{
+ int ret = 0;
+
+ if (max_coal_frames >= size)
+ return ret;
+
+ return max_coal_frames;
+}
+
+static int stmmac_init_tx_coalesce(struct stmmac_priv *priv)
+{
+ int ret = -EOPNOTSUPP;
+
+ priv->tx_coal_frames = stmmac_check_coal(priv->dma_tx_size,
+ STMMAC_TX_MAX_FRAMES);
+ if (priv->tx_coal_frames) {
+ /* Set Tx coalesce parameters and timers */
+ priv->tx_coal_timer = jiffies + usecs_to_jiffies(STMMAC_TX_TM);
+ init_timer(&priv->txtimer);
+ priv->txtimer.expires = priv->tx_coal_timer;
+ priv->txtimer.data = (unsigned long)priv;
+ priv->txtimer.function = stmmac_txtimer;
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
/**
* stmmac_open - open entry point of the driver
* @dev : pointer to the device structure.
@@ -1113,6 +1135,10 @@ static int stmmac_open(struct net_device *dev)
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
priv->eee_enabled = stmmac_eee_init(priv);
+ ret = stmmac_init_tx_coalesce(priv);
+ if (!ret)
+ add_timer(&priv->txtimer);
+
napi_enable(&priv->napi);
skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
@@ -1202,6 +1228,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
int nfrags = skb_shinfo(skb)->nr_frags;
struct dma_desc *desc, *first;
unsigned int nopaged_len = skb_headlen(skb);
+ unsigned long flags;
if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
if (!netif_queue_stopped(dev)) {
@@ -1213,10 +1240,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- spin_lock(&priv->tx_lock);
-
- if (priv->tx_path_in_lpi_mode)
- stmmac_disable_eee_mode(priv);
+ spin_lock_irqsave(&priv->tx_lock, flags);
entry = priv->cur_tx % txsize;
@@ -1272,7 +1296,14 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
/* Interrupt on completition only for the latest segment */
priv->hw->desc->close_tx_desc(desc);
- wmb();
+ /* Do not set the IC according to the coalesce patameters */
+ priv->tx_count_frames++;
+ if (priv->tx_coal_frames > priv->tx_count_frames) {
+ priv->hw->desc->clear_tx_ic(desc);
+ priv->xstats.tx_reset_ic_bit++;
+ mod_timer(&priv->txtimer, priv->tx_coal_timer);
+ } else
+ priv->tx_count_frames = 0;
/* To avoid raise condition */
priv->hw->desc->set_tx_owner(first);
@@ -1302,7 +1333,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
priv->hw->dma->enable_dma_transmission(priv->ioaddr);
- spin_unlock(&priv->tx_lock);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -1447,7 +1478,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
* all interfaces.
* Description :
* This function implements the the reception process.
- * Also it runs the TX completion thread
*/
static int stmmac_poll(struct napi_struct *napi, int budget)
{
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [net-next.git 4/7] stmmac: add Rx watchdog optimization to mitigate the DMA irqs
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
` (2 preceding siblings ...)
2012-09-03 7:46 ` [net-next.git 3/7] stmmac: add the initial tx coalesce schema Giuseppe CAVALLARO
@ 2012-09-03 7:46 ` Giuseppe CAVALLARO
2012-09-03 7:47 ` [net-next.git 5/7] stmmac: add sysFs support Giuseppe CAVALLARO
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:46 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
New GMAC devices (3.50 and newer) have an embedded timer
that can be used for mitigating the number of interrupts.
So this patch adds this optimizations.
Old MAC will continue to use NAPI.
In this implementation the rx timer stored in the Reg9 is fixed
to the max value.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 7 ++
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 3 -
.../net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 6 ++
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 3 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 +++++++++++++------
5 files changed, 61 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1d6bd3e..63d4bad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -48,6 +48,10 @@
#define CHIP_DBG(fmt, args...) do { } while (0)
#endif
+/* Synopsys Core versions */
+#define DWMAC_CORE_3_40 0x34
+#define DWMAC_CORE_3_50 0x35
+
#undef FRAME_FILTER_DEBUG
/* #define FRAME_FILTER_DEBUG */
@@ -165,6 +169,7 @@ struct stmmac_extra_stats {
#define DMA_HW_FEAT_SAVLANINS 0x08000000 /* Source Addr or VLAN Insertion */
#define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY interface */
#define DEFAULT_DMA_PBL 8
+#define DEFAULT_DMA_RIWT 0xff /* Max RI Watchdog Timer count */
enum rx_frame_status { /* IPC status */
good_frame = 0,
@@ -301,6 +306,8 @@ struct stmmac_dma_ops {
struct stmmac_extra_stats *x);
/* If supported then get the optional core features */
unsigned int (*get_hw_feature) (void __iomem *ioaddr);
+ /* Manage HW RX Watchdog*/
+ void (*rx_watchdog) (void __iomem *ioaddr, u8 timer);
};
struct stmmac_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 0e4cace..7ad56af 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -230,8 +230,5 @@ enum rtc_control {
#define GMAC_MMC_TX_INTR 0x108
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
-/* Synopsys Core versions */
-#define DWMAC_CORE_3_40 0x34
-
extern const struct stmmac_dma_ops dwmac1000_dma_ops;
#endif /* __DWMAC1000_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 0335000..e2c9431 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -174,6 +174,11 @@ static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr)
return readl(ioaddr + DMA_HW_FEATURE);
}
+static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u8 timer)
+{
+ writel(timer, ioaddr + DMA_RX_WATCHDOG);
+}
+
const struct stmmac_dma_ops dwmac1000_dma_ops = {
.init = dwmac1000_dma_init,
.dump_regs = dwmac1000_dump_dma_regs,
@@ -187,4 +192,5 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
.stop_rx = dwmac_dma_stop_rx,
.dma_interrupt = dwmac_dma_interrupt,
.get_hw_feature = dwmac1000_get_hw_feature,
+ .rx_watchdog = dwmac1000_rx_watchdog,
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index e49c9a0..4eeff5d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -35,7 +35,8 @@
#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
-#define DMA_AXI_BUS_MODE 0x00001028 /* AXI Bus Mode */
+#define DMA_RX_WATCHDOG 0x00001024 /* Receive Int Watchdog Timer */
+#define DMA_AXI_BUS_MODE 0x00001028 /* AXI Bus Mode */
#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d7f5482..bafe694 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -133,6 +133,7 @@ MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
#define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
+static int stmmac_rx(struct stmmac_priv *priv, int limit);
#ifdef CONFIG_STMMAC_DEBUG_FS
static int stmmac_init_fs(struct net_device *dev);
@@ -481,7 +482,6 @@ static void display_ring(struct dma_desc *p, int size)
i, (unsigned int)virt_to_phys(&p[i]),
(unsigned int)(x->a), (unsigned int)((x->a) >> 32),
x->b, x->c);
- pr_info("\n");
}
}
@@ -516,7 +516,7 @@ static void init_dma_desc_rings(struct net_device *dev)
unsigned int txsize = priv->dma_tx_size;
unsigned int rxsize = priv->dma_rx_size;
unsigned int bfsize;
- int dis_ic = 0;
+ int dis_ic = 1;
int des3_as_data_buf = 0;
/* Set the max buffer size according to the DESC mode
@@ -603,6 +603,8 @@ static void init_dma_desc_rings(struct net_device *dev)
priv->dirty_tx = 0;
priv->cur_tx = 0;
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ dis_ic = 0;
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
@@ -746,7 +748,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
skb_recycle_check(skb, priv->dma_buf_sz))
__skb_queue_head(&priv->rx_recycle, skb);
else
- dev_kfree_skb(skb);
+ dev_kfree_skb_any(skb);
priv->tx_skbuff[entry] = NULL;
}
@@ -816,12 +818,15 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
netif_wake_queue(priv->dev);
}
-static void stmmac_rx_schedule(struct stmmac_priv *priv)
+static void stmmac_rx_work(struct stmmac_priv *priv)
{
- if (likely(napi_schedule_prep(&priv->napi))) {
- stmmac_disable_irq(priv);
- __napi_schedule(&priv->napi);
- }
+ if (priv->synopsys_id < DWMAC_CORE_3_50) {
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ stmmac_disable_irq(priv);
+ __napi_schedule(&priv->napi);
+ }
+ } else
+ stmmac_rx(priv, priv->dma_rx_size);
}
static void stmmac_dma_interrupt(struct stmmac_priv *priv)
@@ -831,7 +836,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
if (likely(status == handle_rx)) {
priv->xstats.rx_normal_irq_n++;
- stmmac_rx_schedule(priv);
+ stmmac_rx_work(priv);
}
if (likely(status == handle_tx)) {
priv->xstats.tx_normal_irq_n++;
@@ -1139,7 +1144,17 @@ static int stmmac_open(struct net_device *dev)
if (!ret)
add_timer(&priv->txtimer);
- napi_enable(&priv->napi);
+ /* Enable NAPI on chip older than the 3.50 where the Rx watchdog
+ * is not supported.
+ */
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ napi_enable(&priv->napi);
+ else if (priv->hw->dma->rx_watchdog)
+ /* Program RX Watchdog register to the default values
+ * FIXME: provide user value for RIWT
+ */
+ priv->hw->dma->rx_watchdog(priv->ioaddr, DEFAULT_DMA_RIWT);
+
skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
@@ -1183,7 +1198,8 @@ static int stmmac_release(struct net_device *dev)
netif_stop_queue(dev);
- napi_disable(&priv->napi);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ napi_disable(&priv->napi);
skb_queue_purge(&priv->rx_recycle);
/* Free the IRQ lines */
@@ -1448,14 +1464,15 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
#endif
skb->protocol = eth_type_trans(skb, priv->dev);
- if (unlikely(!priv->plat->rx_coe)) {
- /* No RX COE for old mac10/100 devices */
+ if (unlikely(!priv->plat->rx_coe))
skb_checksum_none_assert(skb);
- netif_receive_skb(skb);
- } else {
+ else
skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
napi_gro_receive(&priv->napi, skb);
- }
+ else
+ netif_rx(skb);
priv->dev->stats.rx_packets++;
priv->dev->stats.rx_bytes += frame_len;
@@ -2025,7 +2042,10 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
if (flow_ctrl)
priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
- netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
+ else
+ pr_info(" Enable Mitigation via HW RX_Watchdog Timer\n");
spin_lock_init(&priv->lock);
spin_lock_init(&priv->tx_lock);
@@ -2068,7 +2088,8 @@ error_mdio_register:
error_clk_get:
unregister_netdev(ndev);
error_netdev_register:
- netif_napi_del(&priv->napi);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ netif_napi_del(&priv->napi);
free_netdev(ndev);
return NULL;
@@ -2102,7 +2123,7 @@ int stmmac_dvr_remove(struct net_device *ndev)
int stmmac_suspend(struct net_device *ndev)
{
struct stmmac_priv *priv = netdev_priv(ndev);
- int dis_ic = 0;
+ int dis_ic = 1;
unsigned long flags;
if (!ndev || !netif_running(ndev))
@@ -2116,11 +2137,14 @@ int stmmac_suspend(struct net_device *ndev)
netif_device_detach(ndev);
netif_stop_queue(ndev);
- napi_disable(&priv->napi);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ napi_disable(&priv->napi);
/* Stop TX/RX DMA */
priv->hw->dma->stop_tx(priv->ioaddr);
priv->hw->dma->stop_rx(priv->ioaddr);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ dis_ic = 0;
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
dis_ic);
@@ -2166,7 +2190,8 @@ int stmmac_resume(struct net_device *ndev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
- napi_enable(&priv->napi);
+ if (priv->synopsys_id < DWMAC_CORE_3_50)
+ napi_enable(&priv->napi);
netif_start_queue(ndev);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
` (3 preceding siblings ...)
2012-09-03 7:46 ` [net-next.git 4/7] stmmac: add Rx watchdog optimization to mitigate the DMA irqs Giuseppe CAVALLARO
@ 2012-09-03 7:47 ` Giuseppe CAVALLARO
2012-09-03 12:44 ` Ben Hutchings
2012-09-03 7:47 ` [net-next.git 6/7] stmmac: add mitigation and sysfs info in the doc Giuseppe CAVALLARO
2012-09-03 7:47 ` [net-next.git 7/7] stmmac: update the driver version to August_2012 Giuseppe CAVALLARO
6 siblings, 1 reply; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:47 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch adds the sysFs support.
Some internal driver parameters can be tuned by using some
entries exposed via sysFS. There parameter currently are,
for example, for internal timers used to mitigate the rx/tx
interrupts or for EEE.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 8 +-
drivers/net/ethernet/stmicro/stmmac/stmmac-sysfs.c | 157 ++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 36 ++---
5 files changed, 185 insertions(+), 21 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac-sysfs.c
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index c8e8ea6..4450fc6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -6,4 +6,4 @@ stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
- mmc_core.o $(stmmac-y)
+ mmc_core.o stmmac-sysfs.o $(stmmac-y)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 63d4bad..b0b08bc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -169,7 +169,13 @@ struct stmmac_extra_stats {
#define DMA_HW_FEAT_SAVLANINS 0x08000000 /* Source Addr or VLAN Insertion */
#define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY interface */
#define DEFAULT_DMA_PBL 8
-#define DEFAULT_DMA_RIWT 0xff /* Max RI Watchdog Timer count */
+#define MAX_DMA_RIWT 0xff /* Max RI Watchdog Timer count */
+
+#define STMMAC_COAL_TX_TIMER 40000
+#define STMMAC_MAX_COAL_TX_TIMER 100000
+#define STMMAC_TX_MAX_FRAMES 64
+#define STMMAC_DEFAULT_LPI_TIMER 1000
+#define STMMAC_MAX_LPI_TIMER 5000
enum rx_frame_status { /* IPC status */
good_frame = 0,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac-sysfs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac-sysfs.c
new file mode 100644
index 0000000..92537a0
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac-sysfs.c
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ STMMAC sysfs module
+
+ Copyright(C) 2012 STMicroelectronics Ltd
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/sysfs.h>
+
+#include "stmmac.h"
+
+/* EEE Timer attribute */
+static ssize_t eee_timer_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ return snprintf(buf, PAGE_SIZE, "%u", (u32) priv->eee_timer);
+}
+
+static ssize_t eee_timer_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ int eee_timer;
+
+ sscanf(buf, "%u", &eee_timer);
+
+ if ((eee_timer <= 0) || (eee_timer > STMMAC_MAX_LPI_TIMER))
+ pr_err("stmmac: invalid EEE timer value\n");
+ else
+ priv->eee_timer = eee_timer;
+
+ return count;
+}
+
+/* TX coalesce parameters */
+static ssize_t tx_coal_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ return snprintf(buf, PAGE_SIZE, "%u", (u32) priv->tx_coal_timer);
+}
+
+static ssize_t tx_coal_timer_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ int tx_coal_timer;
+
+ sscanf(buf, "%u", &tx_coal_timer);
+
+ if ((tx_coal_timer <= 0) || (tx_coal_timer > STMMAC_MAX_COAL_TX_TIMER))
+ pr_err("stmmac: Tx coalesce timer value\n");
+ else
+ priv->tx_coal_timer = tx_coal_timer;
+
+ return count;
+}
+
+static ssize_t tx_coal_frames_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ return snprintf(buf, PAGE_SIZE, "%u", (u32) priv->tx_coal_frames);
+}
+
+static ssize_t tx_coal_frames_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ int tx_coal_frames;
+
+ sscanf(buf, "%u", &tx_coal_frames);
+
+ if ((tx_coal_frames <= 0) || (tx_coal_frames >= STMMAC_TX_MAX_FRAMES))
+ pr_err("stmmac: invalid Tx coalesce value\n");
+ else
+ priv->tx_coal_frames = tx_coal_frames;
+
+ return count;
+}
+
+/* RX coalesce parameters */
+static ssize_t rx_riwt_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ return snprintf(buf, PAGE_SIZE, "%u", (u16) priv->rx_riwt);
+}
+
+static ssize_t rx_riwt_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stmmac_priv *priv = netdev_priv(to_net_dev(dev));
+
+ int rx_riwt;
+
+ sscanf(buf, "%u", &rx_riwt);
+
+ if ((rx_riwt <= 0) || (rx_riwt >= MAX_DMA_RIWT)) {
+ pr_err("stmmac: invalid RX WDT timer value\n");
+ } else {
+ priv->rx_riwt = rx_riwt;
+ priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt);
+ }
+
+ return count;
+}
+
+DEVICE_ATTR(eee_timer, 0644, eee_timer_show, eee_timer_store);
+DEVICE_ATTR(tx_coal_timer, 0644, tx_coal_timer_show,
+ tx_coal_timer_store);
+DEVICE_ATTR(tx_coal_frames, 0644, tx_coal_frames_show,
+ tx_coal_frames_store);
+DEVICE_ATTR(rx_riwt, 0644, rx_riwt_show, rx_riwt_store);
+
+void stmmac_create_sysfs(struct net_device *dev)
+{
+ int rc;
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ rc = device_create_file(&dev->dev, &dev_attr_tx_coal_timer);
+ rc |= device_create_file(&dev->dev, &dev_attr_tx_coal_frames);
+ if (priv->synopsys_id >= DWMAC_CORE_3_50)
+ rc |= device_create_file(&dev->dev, &dev_attr_rx_riwt);
+ if (priv->eee_enabled)
+ rc |= device_create_file(&dev->dev, &dev_attr_eee_timer);
+ if (rc)
+ pr_err("%s: failed to create the sysfs entries\n", __func__);
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 0f5ab28..05f17184 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -87,11 +87,13 @@ struct stmmac_priv {
int lpi_irq;
int eee_enabled;
int eee_active;
+ int eee_timer;
int tx_lpi_timer;
struct timer_list txtimer;
u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
+ u16 rx_riwt;
};
extern int phyaddr;
@@ -111,6 +113,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
void __iomem *addr);
void stmmac_disable_eee_mode(struct stmmac_priv *priv);
bool stmmac_eee_init(struct stmmac_priv *priv);
+void stmmac_create_sysfs(struct net_device *dev);
#ifdef CONFIG_STMMAC_PLATFORM
extern struct platform_driver stmmac_pltfr_driver;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bafe694..1895130 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -77,8 +77,6 @@
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
#define JUMBO_LEN 9000
-#define STMMAC_TX_TM 40000
-#define STMMAC_TX_MAX_FRAMES 64 /* Max coalesced frame */
/* Module parameters */
#define TX_TIMEO 5000 /* default 5 seconds */
@@ -126,11 +124,8 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_LINK | NETIF_MSG_IFUP |
NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
-#define STMMAC_DEFAULT_LPI_TIMER 1000
-static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
-module_param(eee_timer, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
#define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
+#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
static int stmmac_rx(struct stmmac_priv *priv, int limit);
@@ -161,8 +156,6 @@ static void stmmac_verify_args(void)
flow_ctrl = FLOW_OFF;
if (unlikely((pause < 0) || (pause > 0xffff)))
pause = PAUSE_TIME;
- if (eee_timer < 0)
- eee_timer = STMMAC_DEFAULT_LPI_TIMER;
}
static void stmmac_clk_csr_set(struct stmmac_priv *priv)
@@ -254,7 +247,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
struct stmmac_priv *priv = (struct stmmac_priv *)arg;
stmmac_enable_eee_mode(priv);
- mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
+ mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(priv->eee_timer));
}
/**
@@ -280,7 +273,8 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
init_timer(&priv->eee_ctrl_timer);
priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
priv->eee_ctrl_timer.data = (unsigned long)priv;
- priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer);
+ priv->eee_ctrl_timer.expires =
+ STMMAC_LPI_TIMER(priv->eee_timer);
add_timer(&priv->eee_ctrl_timer);
priv->hw->mac->set_eee_timer(priv->ioaddr,
@@ -770,7 +764,8 @@ static void stmmac_tx(struct stmmac_priv *priv)
if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
stmmac_enable_eee_mode(priv);
- mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
+ mod_timer(&priv->eee_ctrl_timer,
+ STMMAC_LPI_TIMER(priv->eee_timer));
}
spin_unlock_irqrestore(&priv->tx_lock, flags);
}
@@ -1016,9 +1011,9 @@ static int stmmac_init_tx_coalesce(struct stmmac_priv *priv)
STMMAC_TX_MAX_FRAMES);
if (priv->tx_coal_frames) {
/* Set Tx coalesce parameters and timers */
- priv->tx_coal_timer = jiffies + usecs_to_jiffies(STMMAC_TX_TM);
+ priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
init_timer(&priv->txtimer);
- priv->txtimer.expires = priv->tx_coal_timer;
+ priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);
priv->txtimer.data = (unsigned long)priv;
priv->txtimer.function = stmmac_txtimer;
@@ -1138,6 +1133,7 @@ static int stmmac_open(struct net_device *dev)
phy_start(priv->phydev);
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
+ priv->eee_timer = STMMAC_DEFAULT_LPI_TIMER;
priv->eee_enabled = stmmac_eee_init(priv);
ret = stmmac_init_tx_coalesce(priv);
@@ -1149,11 +1145,13 @@ static int stmmac_open(struct net_device *dev)
*/
if (priv->synopsys_id < DWMAC_CORE_3_50)
napi_enable(&priv->napi);
- else if (priv->hw->dma->rx_watchdog)
+ else if (priv->hw->dma->rx_watchdog) {
+ priv->rx_riwt = MAX_DMA_RIWT;
/* Program RX Watchdog register to the default values
* FIXME: provide user value for RIWT
*/
- priv->hw->dma->rx_watchdog(priv->ioaddr, DEFAULT_DMA_RIWT);
+ priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt);
+ }
skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
@@ -1317,7 +1315,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
if (priv->tx_coal_frames > priv->tx_count_frames) {
priv->hw->desc->clear_tx_ic(desc);
priv->xstats.tx_reset_ic_bit++;
- mod_timer(&priv->txtimer, priv->tx_coal_timer);
+ mod_timer(&priv->txtimer,
+ STMMAC_COAL_TIMER(priv->tx_coal_timer));
} else
priv->tx_count_frames = 0;
@@ -2081,6 +2080,8 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
goto error_mdio_register;
}
+ stmmac_create_sysfs(ndev);
+
return priv;
error_mdio_register:
@@ -2283,9 +2284,6 @@ static int __init stmmac_cmdline_opt(char *str)
} else if (!strncmp(opt, "pause:", 6)) {
if (kstrtoint(opt + 6, 0, &pause))
goto err;
- } else if (!strncmp(opt, "eee_timer:", 6)) {
- if (kstrtoint(opt + 10, 0, &eee_timer))
- goto err;
}
}
return 0;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 7:47 ` [net-next.git 5/7] stmmac: add sysFs support Giuseppe CAVALLARO
@ 2012-09-03 12:44 ` Ben Hutchings
2012-09-03 13:36 ` Giuseppe CAVALLARO
2012-09-03 17:20 ` David Miller
0 siblings, 2 replies; 13+ messages in thread
From: Ben Hutchings @ 2012-09-03 12:44 UTC (permalink / raw)
To: Giuseppe CAVALLARO; +Cc: netdev
On Mon, 2012-09-03 at 09:47 +0200, Giuseppe CAVALLARO wrote:
> This patch adds the sysFs support.
> Some internal driver parameters can be tuned by using some
> entries exposed via sysFS. There parameter currently are,
> for example, for internal timers used to mitigate the rx/tx
> interrupts or for EEE.
[...]
Why are you not exposing these through the standard ethtool operations?
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 12:44 ` Ben Hutchings
@ 2012-09-03 13:36 ` Giuseppe CAVALLARO
2012-09-03 15:09 ` Ben Hutchings
2012-09-03 17:20 ` David Miller
1 sibling, 1 reply; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 13:36 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev
Hello Ben,
On 9/3/2012 2:44 PM, Ben Hutchings wrote:
> On Mon, 2012-09-03 at 09:47 +0200, Giuseppe CAVALLARO wrote:
>> This patch adds the sysFs support.
>> Some internal driver parameters can be tuned by using some
>> entries exposed via sysFS. There parameter currently are,
>> for example, for internal timers used to mitigate the rx/tx
>> interrupts or for EEE.
> [...]
>
> Why are you not exposing these through the standard ethtool operations?
>
> Ben.
yes I want to expose them via ethtool and I'll do this as soon as I have
clear with ethtool parameters have to be used (
http://marc.info/?l=linux-netdev&m=134561966226677&w=2 ).
For the reception side, I have the RI Watchdog Timer count field and I
do not know what is the appropriate ethtool parameter to use.
>From the Synopsys databook, the RI Watchdog Timer count indicates the
number of system clock cycles. When the it runs out, the receive
interrupt bit is set and the timer is stopped.
No idea if it can be actually covered, for example, with
rx_coalesce_usecs_irq.
For the transmission I have a SW timer that periodically calls the tx
function (stmmac_tx) and a threshold to also set the "Interrupt on
completion" bit in the TDES when a frame is transmitted.
I wonder (but not sure) if in this case I could be: tx_coalesce_usec and
tx_mac_coalesced_frames.
>From the kernel documentation IIUC these seem to have other meaning.
No problem, to extend ethtool to cover these kind of parameters if
necessary.
Welcome advice,
Peppe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 13:36 ` Giuseppe CAVALLARO
@ 2012-09-03 15:09 ` Ben Hutchings
2012-09-04 6:35 ` Giuseppe CAVALLARO
0 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2012-09-03 15:09 UTC (permalink / raw)
To: Giuseppe CAVALLARO; +Cc: netdev
On Mon, 2012-09-03 at 15:36 +0200, Giuseppe CAVALLARO wrote:
> Hello Ben,
>
> On 9/3/2012 2:44 PM, Ben Hutchings wrote:
> > On Mon, 2012-09-03 at 09:47 +0200, Giuseppe CAVALLARO wrote:
> >> This patch adds the sysFs support.
> >> Some internal driver parameters can be tuned by using some
> >> entries exposed via sysFS. There parameter currently are,
> >> for example, for internal timers used to mitigate the rx/tx
> >> interrupts or for EEE.
> > [...]
> >
> > Why are you not exposing these through the standard ethtool operations?
> >
> > Ben.
>
> yes I want to expose them via ethtool and I'll do this as soon as I have
> clear with ethtool parameters have to be used (
> http://marc.info/?l=linux-netdev&m=134561966226677&w=2 ).
Sorry, I meant to reply to that but didn't get round to it.
> For the reception side, I have the RI Watchdog Timer count field and I
> do not know what is the appropriate ethtool parameter to use.
> From the Synopsys databook, the RI Watchdog Timer count indicates the
> number of system clock cycles. When the it runs out, the receive
> interrupt bit is set and the timer is stopped.
> No idea if it can be actually covered, for example, with
> rx_coalesce_usecs_irq.
As I understand it, interrupt moderation time is supposed to be the
minimum time between completion IRQs, not a minimum delay from
completion-with-IRQ-armed to assertion of the IRQ. The timer should
start running again immediately after the associated IRQ is asserted.
But I don't know whether it's universally implemented this way.
The field names including '_irq' are to be used if the hardware can use
a different moderation time while the IRQ is still masked (i.e. NAPI or
hard interrupt handler is still running). I think most hardware doesn't
support this.
> For the transmission I have a SW timer that periodically calls the tx
> function (stmmac_tx) and a threshold to also set the "Interrupt on
> completion" bit in the TDES when a frame is transmitted.
> I wonder (but not sure) if in this case I could be: tx_coalesce_usec and
> tx_mac_coalesced_frames.
> From the kernel documentation IIUC these seem to have other meaning.
The semantics don't seem to match the documentation exactly but I think
this is probably close enough.
Ben.
> No problem, to extend ethtool to cover these kind of parameters if
> necessary.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 15:09 ` Ben Hutchings
@ 2012-09-04 6:35 ` Giuseppe CAVALLARO
0 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-04 6:35 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, David S. Miller
Hello Ben
On 9/3/2012 5:09 PM, Ben Hutchings wrote:
> On Mon, 2012-09-03 at 15:36 +0200, Giuseppe CAVALLARO wrote:
>> Hello Ben,
>>
>> On 9/3/2012 2:44 PM, Ben Hutchings wrote:
>>> On Mon, 2012-09-03 at 09:47 +0200, Giuseppe CAVALLARO wrote:
>>>> This patch adds the sysFs support.
>>>> Some internal driver parameters can be tuned by using some
>>>> entries exposed via sysFS. There parameter currently are,
>>>> for example, for internal timers used to mitigate the rx/tx
>>>> interrupts or for EEE.
>>> [...]
>>>
>>> Why are you not exposing these through the standard ethtool operations?
>>>
>>> Ben.
>>
>> yes I want to expose them via ethtool and I'll do this as soon as I have
>> clear with ethtool parameters have to be used (
>> http://marc.info/?l=linux-netdev&m=134561966226677&w=2 ).
>
> Sorry, I meant to reply to that but didn't get round to it.
No problem at all :-) ... we are discussing about that in the thread.
>
>> For the reception side, I have the RI Watchdog Timer count field and I
>> do not know what is the appropriate ethtool parameter to use.
>> From the Synopsys databook, the RI Watchdog Timer count indicates the
>> number of system clock cycles. When the it runs out, the receive
>> interrupt bit is set and the timer is stopped.
>> No idea if it can be actually covered, for example, with
>> rx_coalesce_usecs_irq.
>
> As I understand it, interrupt moderation time is supposed to be the
> minimum time between completion IRQs, not a minimum delay from
> completion-with-IRQ-armed to assertion of the IRQ. The timer should
> start running again immediately after the associated IRQ is asserted.
> But I don't know whether it's universally implemented this way.
Yes this is the point and my initial doubt.
> The field names including '_irq' are to be used if the hardware can use
> a different moderation time while the IRQ is still masked (i.e. NAPI or
> hard interrupt handler is still running). I think most hardware doesn't
> support this.
Indeed, the watchdog represents the number of system clock cycles to
delay the RX interrupt after a packet arrives so IIUC I can use the
rx_coalesce_usecs.
>> For the transmission I have a SW timer that periodically calls the tx
>> function (stmmac_tx) and a threshold to also set the "Interrupt on
>> completion" bit in the TDES when a frame is transmitted.
>> I wonder (but not sure) if in this case I could be: tx_coalesce_usec and
>> tx_mac_coalesced_frames.
>> From the kernel documentation IIUC these seem to have other meaning.
>
> The semantics don't seem to match the documentation exactly but I think
> this is probably close enough.
So IIUC I can use the ethtool coalesce parameters above for the stmmac.
I mean: tx_coalesce_usec and tx_mac_coalesced_frames.
Anyway I'm happy to remove the sysFS (rightly rejected by David) and use
the standard ethtool. So I'll provide new patches after testing all.
Thanks again for your feedback, and let me know if I missed something.
Regards
Peppe
>
> Ben.
>
>> No problem, to extend ethtool to cover these kind of parameters if
>> necessary.
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [net-next.git 5/7] stmmac: add sysFs support
2012-09-03 12:44 ` Ben Hutchings
2012-09-03 13:36 ` Giuseppe CAVALLARO
@ 2012-09-03 17:20 ` David Miller
1 sibling, 0 replies; 13+ messages in thread
From: David Miller @ 2012-09-03 17:20 UTC (permalink / raw)
To: bhutchings; +Cc: peppe.cavallaro, netdev
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 3 Sep 2012 13:44:27 +0100
> On Mon, 2012-09-03 at 09:47 +0200, Giuseppe CAVALLARO wrote:
>> This patch adds the sysFs support.
>> Some internal driver parameters can be tuned by using some
>> entries exposed via sysFS. There parameter currently are,
>> for example, for internal timers used to mitigate the rx/tx
>> interrupts or for EEE.
> [...]
>
> Why are you not exposing these through the standard ethtool operations?
Guiseppe, I'm not appyling driver patches that add sysfs crap like
this. Either use existing ethtool interfaces or create new ones that
provide the necessary functionality.
Adding unique configuration mechanisms to a device driver is always a
bug.
And I'm getting real fed up with driver writers simply not getting the
message. Every time someone adds sysfs or ioctl crap, we push back,
so just don't do it and stop wasting our time.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [net-next.git 6/7] stmmac: add mitigation and sysfs info in the doc
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
` (4 preceding siblings ...)
2012-09-03 7:47 ` [net-next.git 5/7] stmmac: add sysFs support Giuseppe CAVALLARO
@ 2012-09-03 7:47 ` Giuseppe CAVALLARO
2012-09-03 7:47 ` [net-next.git 7/7] stmmac: update the driver version to August_2012 Giuseppe CAVALLARO
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:47 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch updates the stmmac.txt addinf some information
about the new rx/tx mitigation schema and the sysFs support.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 34 +++++++++++++++++++++-------------
1 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index ef9ee71..67eaa35 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -29,11 +29,9 @@ The kernel configuration option is STMMAC_ETH:
dma_txsize: DMA tx ring size;
buf_sz: DMA buffer size;
tc: control the HW FIFO threshold;
- tx_coe: Enable/Disable Tx Checksum Offload engine;
watchdog: transmit timeout (in milliseconds);
flow_ctrl: Flow control ability [on/off];
pause: Flow Control Pause Time;
- tmrate: timer period (only if timer optimisation is configured).
3) Command line options
Driver parameters can be also passed in command line by using:
@@ -60,17 +58,21 @@ Then the poll method will be scheduled at some future point.
The incoming packets are stored, by the DMA, in a list of pre-allocated socket
buffers in order to avoid the memcpy (Zero-copy).
-4.3) Timer-Driver Interrupt
-Instead of having the device that asynchronously notifies the frame receptions,
-the driver configures a timer to generate an interrupt at regular intervals.
-Based on the granularity of the timer, the frames that are received by the
-device will experience different levels of latency. Some NICs have dedicated
-timer device to perform this task. STMMAC can use either the RTC device or the
-TMU channel 2 on STLinux platforms.
-The timers frequency can be passed to the driver as parameter; when change it,
-take care of both hardware capability and network stability/performance impact.
-Several performance tests on STM platforms showed this optimisation allows to
-spare the CPU while having the maximum throughput.
+4.3) Interrupt Mitigation
+The driver is able to mitigate the number of its DMA interrupts
+using NAPI for the reception on chips older than the 3.50.
+New chips have an HW RX-Watchdog used for this mitigation.
+
+User can tune (also via sysfs) a parameter that is the RI Watchdog
+Timer count. It indicates the number of system clock cycles.
+
+On Tx-side, the mitigation schema is based on a SW timer that calls the
+tx function (stmmac_tx) to reclaim the resource after transmitting the
+frames.
+Also there is another parameter (like a threshold) used to program
+the descriptors avoiding to set the interrupt on completion bit in
+when the frame is sent (xmit).
+These parameters can be tuned by sysfs entries.
4.4) WOL
Wake up on Lan feature through Magic and Unicast frames are supported for the
@@ -324,6 +326,12 @@ To enter in Tx LPI mode the driver needs to have a software timer
that enable and disable the LPI mode when there is nothing to be
transmitted.
+7) sys FS interface
+Some internal driver parameters can be tuned by using some
+entries exposed via sysFS. There parameter currently are,
+for example, for internal timers used to mitigate the rx/tx
+interrupts or for EEE.
+
7) TODO:
o XGMAC is not supported.
o Add the PTP - precision time protocol
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [net-next.git 7/7] stmmac: update the driver version to August_2012
2012-09-03 7:46 [net-next.git 0/7] stmmac: remove dead code for STMMAC_TIMER and add new mitigation schema Giuseppe CAVALLARO
` (5 preceding siblings ...)
2012-09-03 7:47 ` [net-next.git 6/7] stmmac: add mitigation and sysfs info in the doc Giuseppe CAVALLARO
@ 2012-09-03 7:47 ` Giuseppe CAVALLARO
6 siblings, 0 replies; 13+ messages in thread
From: Giuseppe CAVALLARO @ 2012-09-03 7:47 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
Many new feautures have been introduced in the driver:
sysFS, Rx HW watchdog... so this patch updates the
driver's version.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 05f17184..ad95f26 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -24,7 +24,7 @@
#define __STMMAC_H__
#define STMMAC_RESOURCE_NAME "stmmaceth"
-#define DRV_MODULE_VERSION "March_2012"
+#define DRV_MODULE_VERSION "August_2012"
#include <linux/clk.h>
#include <linux/stmmac.h>
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread