/* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
*
* Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com)
*
* This program is dual-licensed; you may select either version 2 of
* the GNU General Public License ("GPL") or BSD license ("BSD").
*
* This Synopsys DWC XLGMAC software driver and associated documentation
* (hereinafter the "Software") is an unsupported proprietary work of
* Synopsys, Inc. unless otherwise expressly agreed to in writing between
* Synopsys and you. The Software IS NOT an item of Licensed Software or a
* Licensed Product under any End User Software License Agreement or
* Agreement for Licensed Products with Synopsys or any supplement thereto.
* Synopsys is a registered trademark of Synopsys, Inc. Other names included
* in the SOFTWARE may be the trademarks of their respective owners.
*/
#include <linux/netdevice.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include "dwc-xlgmac.h"
#include "dwc-xlgmac-reg.h"
static int xlgmac_one_poll(struct napi_struct *, int);
static int xlgmac_all_poll(struct napi_struct *, int);
static inline unsigned int xlgmac_tx_avail_desc(struct xlgmac_ring *ring)
{
return (ring->dma_desc_count - (ring->cur - ring->dirty));
}
static inline unsigned int xlgmac_rx_dirty_desc(struct xlgmac_ring *ring)
{
return (ring->cur - ring->dirty);
}
static int xlgmac_maybe_stop_tx_queue(
struct xlgmac_channel *channel,
struct xlgmac_ring *ring,
unsigned int count)
{
struct xlgmac_pdata *pdata = channel->pdata;
if (count > xlgmac_tx_avail_desc(ring)) {
netif_info(pdata, drv, pdata->netdev,
"Tx queue stopped, not enough descriptors available\n");
netif_stop_subqueue(pdata->netdev, channel->queue_index);
ring->tx.queue_stopped = 1;
/* If we haven't notified the hardware because of xmit_more
* support, tell it now
*/
if (ring->tx.xmit_more)
pdata->hw_ops.tx_start_xmit(channel, ring);
return NETDEV_TX_BUSY;
}
return 0;
}
static void xlgmac_prep_vlan(struct sk_buff *skb,
struct xlgmac_pkt_info *pkt_info)
{
if (skb_vlan_tag_present(skb))
pkt_info->vlan_ctag = skb_vlan_tag_get(skb);
}
static int