Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: arch/mips/net/bpf_jit.c drivers/net/can/flexcan.c Both the flexcan and MIPS bpf_jit conflicts were cases of simple overlapping changes. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -27,6 +27,17 @@
|
||||
#include "emac.h"
|
||||
|
||||
|
||||
/**
|
||||
* arc_emac_tx_avail - Return the number of available slots in the tx ring.
|
||||
* @priv: Pointer to ARC EMAC private data structure.
|
||||
*
|
||||
* returns: the number of slots available for transmission in tx the ring.
|
||||
*/
|
||||
static inline int arc_emac_tx_avail(struct arc_emac_priv *priv)
|
||||
{
|
||||
return (priv->txbd_dirty + TX_BD_NUM - priv->txbd_curr - 1) % TX_BD_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_emac_adjust_link - Adjust the PHY link duplex.
|
||||
* @ndev: Pointer to the net_device structure.
|
||||
@@ -182,10 +193,15 @@ static void arc_emac_tx_clean(struct net_device *ndev)
|
||||
txbd->info = 0;
|
||||
|
||||
*txbd_dirty = (*txbd_dirty + 1) % TX_BD_NUM;
|
||||
|
||||
if (netif_queue_stopped(ndev))
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
|
||||
/* Ensure that txbd_dirty is visible to tx() before checking
|
||||
* for queue stopped.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
if (netif_queue_stopped(ndev) && arc_emac_tx_avail(priv))
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,7 +316,7 @@ static int arc_emac_poll(struct napi_struct *napi, int budget)
|
||||
work_done = arc_emac_rx(ndev, budget);
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
arc_reg_or(priv, R_ENABLE, RXINT_MASK);
|
||||
arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK);
|
||||
}
|
||||
|
||||
return work_done;
|
||||
@@ -329,9 +345,9 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
|
||||
/* Reset all flags except "MDIO complete" */
|
||||
arc_reg_set(priv, R_STATUS, status);
|
||||
|
||||
if (status & RXINT_MASK) {
|
||||
if (status & (RXINT_MASK | TXINT_MASK)) {
|
||||
if (likely(napi_schedule_prep(&priv->napi))) {
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK);
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK);
|
||||
__napi_schedule(&priv->napi);
|
||||
}
|
||||
}
|
||||
@@ -442,7 +458,7 @@ static int arc_emac_open(struct net_device *ndev)
|
||||
arc_reg_set(priv, R_TX_RING, (unsigned int)priv->txbd_dma);
|
||||
|
||||
/* Enable interrupts */
|
||||
arc_reg_set(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
|
||||
arc_reg_set(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Set CONTROL */
|
||||
arc_reg_set(priv, R_CTRL,
|
||||
@@ -513,7 +529,7 @@ static int arc_emac_stop(struct net_device *ndev)
|
||||
netif_stop_queue(ndev);
|
||||
|
||||
/* Disable interrupts */
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Disable EMAC */
|
||||
arc_reg_clr(priv, R_CTRL, EN_MASK);
|
||||
@@ -576,11 +592,9 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
|
||||
|
||||
len = max_t(unsigned int, ETH_ZLEN, skb->len);
|
||||
|
||||
/* EMAC still holds this buffer in its possession.
|
||||
* CPU must not modify this buffer descriptor
|
||||
*/
|
||||
if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC)) {
|
||||
if (unlikely(!arc_emac_tx_avail(priv))) {
|
||||
netif_stop_queue(ndev);
|
||||
netdev_err(ndev, "BUG! Tx Ring full when queue awake!\n");
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
@@ -609,12 +623,19 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
|
||||
/* Increment index to point to the next BD */
|
||||
*txbd_curr = (*txbd_curr + 1) % TX_BD_NUM;
|
||||
|
||||
/* Get "info" of the next BD */
|
||||
info = &priv->txbd[*txbd_curr].info;
|
||||
/* Ensure that tx_clean() sees the new txbd_curr before
|
||||
* checking the queue status. This prevents an unneeded wake
|
||||
* of the queue in tx_clean().
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
/* Check if if Tx BD ring is full - next BD is still owned by EMAC */
|
||||
if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC))
|
||||
if (!arc_emac_tx_avail(priv)) {
|
||||
netif_stop_queue(ndev);
|
||||
/* Refresh tx_dirty */
|
||||
smp_mb();
|
||||
if (arc_emac_tx_avail(priv))
|
||||
netif_start_queue(ndev);
|
||||
}
|
||||
|
||||
arc_reg_set(priv, R_STATUS, TXPL_MASK);
|
||||
|
||||
|
Reference in New Issue
Block a user