Commit 73cfe264 authored by Giuseppe CAVALLARO's avatar Giuseppe CAVALLARO Committed by David S. Miller

stmmac: do not fail when the timer cannot be used.

If the external timer cannot be used the driver
will continue to work without mitigation.
Signed-off-by: default avatarGiuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e6e3625f
...@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev) ...@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev)
unsigned int txsize = priv->dma_tx_size; unsigned int txsize = priv->dma_tx_size;
unsigned int rxsize = priv->dma_rx_size; unsigned int rxsize = priv->dma_rx_size;
unsigned int bfsize = priv->dma_buf_sz; unsigned int bfsize = priv->dma_buf_sz;
int buff2_needed = 0; int buff2_needed = 0, dis_ic = 0;
int dis_ic = 0;
#ifdef CONFIG_STMMAC_TIMER
/* Using Timers disable interrupts on completion for the reception */
dis_ic = 1;
#endif
/* Set the Buffer size according to the MTU; /* Set the Buffer size according to the MTU;
* indeed, in case of jumbo we need to bump-up the buffer sizes. * indeed, in case of jumbo we need to bump-up the buffer sizes.
*/ */
...@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev) ...@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev)
else else
bfsize = DMA_BUFFER_SIZE; bfsize = DMA_BUFFER_SIZE;
#ifdef CONFIG_STMMAC_TIMER
/* Disable interrupts on completion for the reception if timer is on */
if (likely(priv->tm->enable))
dis_ic = 1;
#endif
/* If the MTU exceeds 8k so use the second buffer in the chain */ /* If the MTU exceeds 8k so use the second buffer in the chain */
if (bfsize >= BUF_SIZE_8KiB) if (bfsize >= BUF_SIZE_8KiB)
buff2_needed = 1; buff2_needed = 1;
...@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv) ...@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv)
static inline void stmmac_enable_irq(struct stmmac_priv *priv) static inline void stmmac_enable_irq(struct stmmac_priv *priv)
{ {
#ifndef CONFIG_STMMAC_TIMER #ifdef CONFIG_STMMAC_TIMER
writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); if (likely(priv->tm->enable))
#else
priv->tm->timer_start(tmrate); priv->tm->timer_start(tmrate);
else
#endif #endif
writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
} }
static inline void stmmac_disable_irq(struct stmmac_priv *priv) static inline void stmmac_disable_irq(struct stmmac_priv *priv)
{ {
#ifndef CONFIG_STMMAC_TIMER #ifdef CONFIG_STMMAC_TIMER
writel(0, priv->dev->base_addr + DMA_INTR_ENA); if (likely(priv->tm->enable))
#else
priv->tm->timer_stop(); priv->tm->timer_stop();
else
#endif #endif
writel(0, priv->dev->base_addr + DMA_INTR_ENA);
} }
static int stmmac_has_work(struct stmmac_priv *priv) static int stmmac_has_work(struct stmmac_priv *priv)
...@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev) ...@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev)
} }
#ifdef CONFIG_STMMAC_TIMER #ifdef CONFIG_STMMAC_TIMER
priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
if (unlikely(priv->tm == NULL)) { if (unlikely(priv->tm == NULL)) {
pr_err("%s: ERROR: timer memory alloc failed \n", __func__); pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
return -ENOMEM; return -ENOMEM;
} }
priv->tm->freq = tmrate; priv->tm->freq = tmrate;
/* Test if the HW timer can be actually used. /* Test if the external timer can be actually used.
* In case of failure continue with no timer. */ * In case of failure continue without timer. */
if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
pr_warning("stmmaceth: cannot attach the HW timer\n"); pr_warning("stmmaceth: cannot attach the external timer.\n");
tmrate = 0; tmrate = 0;
priv->tm->freq = 0; priv->tm->freq = 0;
priv->tm->timer_start = stmmac_no_timer_started; priv->tm->timer_start = stmmac_no_timer_started;
priv->tm->timer_stop = stmmac_no_timer_stopped; priv->tm->timer_stop = stmmac_no_timer_stopped;
} } else
priv->tm->enable = 1;
#endif #endif
/* Create and initialize the TX/RX descriptors chains. */ /* Create and initialize the TX/RX descriptors chains. */
...@@ -1322,8 +1325,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1322,8 +1325,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
/* Interrupt on completition only for the latest segment */ /* Interrupt on completition only for the latest segment */
priv->mac_type->ops->close_tx_desc(desc); priv->mac_type->ops->close_tx_desc(desc);
#ifdef CONFIG_STMMAC_TIMER #ifdef CONFIG_STMMAC_TIMER
/* Clean IC while using timers */ /* Clean IC while using timer */
if (likely(priv->tm->enable))
priv->mac_type->ops->clear_tx_ic(desc); priv->mac_type->ops->clear_tx_ic(desc);
#endif #endif
/* To avoid raise condition */ /* To avoid raise condition */
...@@ -2028,6 +2033,7 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) ...@@ -2028,6 +2033,7 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
#ifdef CONFIG_STMMAC_TIMER #ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_stop(); priv->tm->timer_stop();
if (likely(priv->tm->enable))
dis_ic = 1; dis_ic = 1;
#endif #endif
napi_disable(&priv->napi); napi_disable(&priv->napi);
......
...@@ -26,6 +26,7 @@ struct stmmac_timer { ...@@ -26,6 +26,7 @@ struct stmmac_timer {
void (*timer_start) (unsigned int new_freq); void (*timer_start) (unsigned int new_freq);
void (*timer_stop) (void); void (*timer_stop) (void);
unsigned int freq; unsigned int freq;
unsigned int enable;
}; };
/* Open the HW timer device and return 0 in case of success */ /* Open the HW timer device and return 0 in case of success */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment