diff options
Diffstat (limited to 'drivers/net/ethernet/ti/davinci_emac.c')
-rw-r--r-- | drivers/net/ethernet/ti/davinci_emac.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 815c7970261..4b2f54565f6 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -115,6 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DEF_TX_CH (0) /* Default 0th channel */ #define EMAC_DEF_RX_CH (0) /* Default 0th channel */ #define EMAC_DEF_RX_NUM_DESC (128) +#define EMAC_DEF_TX_NUM_DESC (128) #define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */ #define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */ #define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */ @@ -336,6 +337,7 @@ struct emac_priv { u32 mac_hash2; u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; u32 rx_addr_type; + atomic_t cur_tx; const char *phy_id; struct phy_device *phydev; spinlock_t lock; @@ -1007,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status) int ret; /* free and bail if we are shutting down */ - if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { + if (unlikely(!netif_running(ndev))) { dev_kfree_skb_any(skb); return; } @@ -1036,7 +1038,9 @@ static void emac_rx_handler(void *token, int len, int status) recycle: ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, skb_tailroom(skb), GFP_KERNEL); - if (WARN_ON(ret < 0)) + + WARN_ON(ret == -ENOMEM); + if (unlikely(ret < 0)) dev_kfree_skb_any(skb); } @@ -1044,6 +1048,9 @@ static void emac_tx_handler(void *token, int len, int status) { struct sk_buff *skb = token; struct net_device *ndev = skb->dev; + struct emac_priv *priv = netdev_priv(ndev); + + atomic_dec(&priv->cur_tx); if (unlikely(netif_queue_stopped(ndev))) netif_start_queue(ndev); @@ -1092,6 +1099,9 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) goto fail_tx; } + if (atomic_inc_return(&priv->cur_tx) >= EMAC_DEF_TX_NUM_DESC) + netif_stop_queue(ndev); + return NETDEV_TX_OK; fail_tx: @@ -1592,8 +1602,9 @@ static int emac_dev_open(struct net_device *ndev) if (IS_ERR(priv->phydev)) { dev_err(emac_dev, "could not connect to phy %s\n", priv->phy_id); + ret = PTR_ERR(priv->phydev); priv->phydev = NULL; - return PTR_ERR(priv->phydev); + return ret; } priv->link = 0; |