/*
 * Copyright (c) 2012 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
#include <linux/mii.h>
#include <linux/mdio.h>
#include <linux/aer.h>
#include <linux/bitops.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>

#include "alx_reg.h"
#include "alx_hw.h"
#include "alx.h"

#define DRV_MAJ		1
#define DRV_MIN		2
#define DRV_PATCH	2
#define DRV_MODULE_VER	\
	__stringify(DRV_MAJ) "." __stringify(DRV_MIN) "." \
	__stringify(DRV_PATCH)

char alx_drv_name[] = "alx";
char alx_drv_version[] = DRV_MODULE_VER;
static const char alx_drv_desc[] =
"Qualcomm Atheros(R) AR816x/AR817x PCI-E Ethernet Network Driver";

/* alx_pci_tbl - PCI Device ID Table
 *
 * Wildcard entries (PCI_ANY_ID) should come last
 * Last entry must be all 0s
 *
 * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
 *   Class, Class Mask, private data (not used) }
 */
#define ALX_ETHER_DEVICE(device_id) {\
	PCI_DEVICE(ALX_VENDOR_ID, device_id)}
static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = {
	ALX_ETHER_DEVICE(ALX_DEV_ID_AR8161),
	ALX_ETHER_DEVICE(ALX_DEV_ID_AR8162),
	ALX_ETHER_DEVICE(ALX_DEV_ID_AR8171),
	ALX_ETHER_DEVICE(ALX_DEV_ID_AR8172),
	{0,}
};

MODULE_DEVICE_TABLE(pci, alx_pci_tbl);
MODULE_AUTHOR("Qualcomm Corporation, <nic-devel@qualcomm.com>");
MODULE_DESCRIPTION("Qualcomm Atheros Gigabit Ethernet Driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_MODULE_VER);

static int alx_poll(struct napi_struct *napi, int budget);
static irqreturn_t alx_msix_ring(int irq, void *data);
static irqreturn_t alx_intr_msix_misc(int irq, void *data);
static irqreturn_t alx_intr_msi(int irq, void *data);
static irqreturn_t alx_intr_legacy(int irq, void *data);
static void alx_init_ring_ptrs(struct alx_adapter *adpt);
static int alx_reinit_rings(struct alx_adapter *adpt);

static inline void alx_schedule_work(struct alx_adapter *adpt)
{
	if (!ALX_FLAG(adpt, HALT))
		schedule_work(&adpt->task);
}

static inline void alx_cancel_work(struct alx_adapter *adpt)
{
	cancel_work_sync(&adpt->task);
}


static void __alx_set_rx_mode(struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	struct alx_hw *hw = &adpt->hw;
	struct netdev_hw_addr *ha;


	/* comoute mc addresses' hash value ,and put it into hash table */
	netdev_for_each_mc_addr(ha, netdev)
		alx_add_mc_addr(hw, ha->addr);

	ALX_MEM_W32(hw, ALX_HASH_TBL0, hw->mc_hash[0]);
	ALX_MEM_W32(hw, ALX_HASH_TBL1, hw->mc_hash[1]);

	/* check for Promiscuous and All Multicast modes */
	hw->rx_ctrl &= ~(ALX_MAC_CTRL_MULTIALL_EN | ALX_MAC_CTRL_PROMISC_EN);
	if (netdev->flags & IFF_PROMISC)
		hw->rx_ctrl |= ALX_MAC_CTRL_PROMISC_EN;
	if (netdev->flags & IFF_ALLMULTI)
		hw->rx_ctrl |= ALX_MAC_CTRL_MULTIALL_EN;

	ALX_MEM_W32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
}

/* alx_set_rx_mode - Multicast and Promiscuous mode set */
static void alx_set_rx_mode(struct net_device *netdev)
{
	__alx_set_rx_mode(netdev);
}


/* alx_set_mac - Change the Ethernet Address of the NIC */
static int alx_set_mac_address(struct net_device *netdev, void *data)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	struct alx_hw *hw = &adpt->hw;
	struct sockaddr *addr = data;

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	if (netdev->addr_assign_type & NET_ADDR_RANDOM)
		netdev->addr_assign_type ^= NET_ADDR_RANDOM;

	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
	alx_set_macaddr(hw, hw->mac_addr);

	return 0;
}

static void alx_free_napis(struct alx_adapter *adpt)
{
	struct alx_napi *np;
	int i;

	for (i = 0; i < adpt->nr_napi; i++) {
		np = adpt->qnapi[i];
		if (!np)
			continue;

		netif_napi_del(&np->napi);
		kfree(np->txq);
		np->txq = NULL;
		kfree(np->rxq);
		np->rxq = NULL;
		adpt->qnapi[i] = NULL;
	}
}
static u16 tx_pidx_reg[] = {ALX_TPD_PRI0_PIDX, ALX_TPD_PRI1_PIDX,
			    ALX_TPD_PRI2_PIDX, ALX_TPD_PRI3_PIDX};
static u16 tx_cidx_reg[] = {ALX_TPD_PRI0_CIDX, ALX_TPD_PRI1_CIDX,
			    ALX_TPD_PRI2_CIDX, ALX_TPD_PRI3_CIDX};
static u32 tx_vect_mask[] = {ALX_ISR_TX_Q0, ALX_ISR_TX_Q1,
			     ALX_ISR_TX_Q2, ALX_ISR_TX_Q3};
static u32 rx_vect_mask[] = {ALX_ISR_RX_Q0, ALX_ISR_RX_Q1,
			     ALX_ISR_RX_Q2, ALX_ISR_RX_Q3,
			     ALX_ISR_RX_Q4, ALX_ISR_RX_Q5,
			     ALX_ISR_RX_Q6, ALX_ISR_RX_Q7};
static int alx_alloc_napis(struct alx_adapter *adpt)
{
	struct alx_hw		*hw = &adpt->hw;
	struct alx_napi		*np;
	struct alx_rx_queue	*rxq;
	struct alx_tx_queue	*txq;
	int i;

	hw->imask &= ~ALX_ISR_ALL_QUEUES;

	/* alloc alx_napi */
	for (i = 0; i < adpt->nr_napi; i++) {
		np = kzalloc(sizeof(struct alx_napi), GFP_KERNEL);
		if (!np)
			goto err_out;

		np->adpt = adpt;
		netif_napi_add(adpt->netdev, &np->napi, alx_poll, 64);
		adpt->qnapi[i] = np;
	}

	/* alloc tx queue */
	for (i = 0; i < adpt->nr_txq; i++) {
		np = adpt->qnapi[i];
		txq = kzalloc(sizeof(struct alx_tx_queue), GFP_KERNEL);
		if (!txq)
			goto err_out;
		np->txq = txq;
		txq->p_reg = tx_pidx_reg[i];
		txq->c_reg = tx_cidx_reg[i];
		txq->count = adpt->tx_ringsz;
		txq->qidx = (u16)i;
		np->vec_mask |= tx_vect_mask[i];
		hw->imask |= tx_vect_mask[i];
	}

	/* alloc rx queue */
	for (i = 0; i < adpt->nr_rxq; i++) {
		np = adpt->qnapi[i];
		rxq = kzalloc(sizeof(struct alx_rx_queue), GFP_KERNEL);
		if (!rxq)
			goto err_out;
		np->rxq = rxq;
		rxq->p_reg = ALX_RFD_PIDX;
		rxq->c_reg = ALX_RFD_CIDX;
		rxq->count = adpt->rx_ringsz;
		rxq->qidx = (u16)i;
		__skb_queue_head_init(&rxq->list);
		np->vec_mask |= rx_vect_mask[i];
		hw->imask |= rx_vect_mask[i];
	}

	return 0;

err_out:
	alx_free_napis(adpt);
	return -ENOMEM;
}

static int alx_alloc_rings(struct alx_adapter *adpt)
{
	struct alx_buffer *bf;
	u8 *desc;
	dma_addr_t  dma;
	int i, size, offset;

	/* alx_buffer */
	size = sizeof(struct alx_buffer) * adpt->nr_txq * adpt->tx_ringsz +
	       sizeof(struct alx_buffer) * adpt->nr_hwrxq * adpt->rx_ringsz;

	bf = vzalloc(size);
	if (!bf)
		goto err_out;

	/* physical rx rings */
	size = sizeof(struct tpd_desc) * adpt->tx_ringsz * adpt->nr_txq +
	       (sizeof(struct rrd_desc) + sizeof(struct rfd_desc)) *
	       adpt->rx_ringsz * adpt->nr_hwrxq +
	       adpt->nr_txq * 8 +
	       adpt->nr_hwrxq * 8;
	desc = dma_alloc_coherent(&adpt->pdev->dev, size, &dma, GFP_KERNEL);
	if (!desc)
		goto err_out;

	memset(desc, 0, size);
	adpt->ring_header.desc = desc;
	adpt->ring_header.dma = dma;
	adpt->ring_header.size = size;

	size = sizeof(struct tpd_desc) * adpt->tx_ringsz;
	for (i = 0; i < adpt->nr_txq; i++) {
		offset = ALIGN(dma, 8) - dma;
		desc += offset;
		dma += offset;
		adpt->qnapi[i]->txq->netdev = adpt->netdev;
		adpt->qnapi[i]->txq->dev = &adpt->pdev->dev;
		adpt->qnapi[i]->txq->tpd_hdr = (struct tpd_desc *)desc;
		adpt->qnapi[i]->txq->tpd_dma = dma;
		adpt->qnapi[i]->txq->count = adpt->tx_ringsz;
		adpt->qnapi[i]->txq->bf_info = bf;
		desc += size;
		dma += size;
		bf += adpt->tx_ringsz;
	}
	size = sizeof(struct rrd_desc) * adpt->rx_ringsz;
	for (i = 0; i < adpt->nr_hwrxq; i++) {
		offset = ALIGN(dma, 8) - dma;
		desc += offset;
		dma += offset;
		adpt->qnapi[i]->rxq->rrd_hdr = (struct rrd_desc *)desc;
		adpt->qnapi[i]->rxq->rrd_dma = dma;
		adpt->qnapi[i]->rxq->bf_info = bf;
		desc += size;
		dma += size;
		bf += adpt->rx_ringsz;
	}
	size = sizeof(struct rfd_desc) * adpt->rx_ringsz;
	for (i = 0; i < adpt->nr_hwrxq; i++) {
		offset = ALIGN(dma, 8) - dma;
		desc += offset;
		dma += offset;
		adpt->qnapi[i]->rxq->rfd_hdr = (struct rfd_desc *)desc;
		adpt->qnapi[i]->rxq->rfd_dma = dma;
		desc += size;
		dma += size;
	}
	for (i = 0; i < adpt->nr_rxq; i++) {
		adpt->qnapi[i]->rxq->netdev = adpt->netdev;
		adpt->qnapi[i]->rxq->dev = &adpt->pdev->dev;
		adpt->qnapi[i]->rxq->count = adpt->rx_ringsz;
	}

	return 0;

err_out:
	if (bf)
		vfree(bf);

	return -ENOMEM;
}

static void alx_free_rings(struct alx_adapter *adpt)
{
	struct alx_buffer *bf;
	struct alx_napi *np;

	/* alx_buffer header is in the 1st tpdq->bf_info */
	np = adpt->qnapi[0];
	if (np) {
		bf = np->txq->bf_info;
		if (bf) {
			vfree(bf);
			np->txq->bf_info = NULL;
		}
	}
	if (adpt->ring_header.desc) {
		dma_free_coherent(&adpt->pdev->dev,
				  adpt->ring_header.size,
				  adpt->ring_header.desc,
				  adpt->ring_header.dma);
		adpt->ring_header.desc = NULL;
	}
}

/* dequeue skb from RXQ, return true if the RXQ is empty */
static inline bool alx_skb_dequeue_n(struct alx_rx_queue *rxq, int max_pkts,
				     struct sk_buff_head *list)
{
	struct alx_adapter *adpt = netdev_priv(rxq->netdev);
	bool use_lock = !ALX_CAP(&adpt->hw, MRQ);
	bool empty;
	struct sk_buff *skb;
	int count = 0;

	if (use_lock)
		spin_lock(&rxq->list.lock);

	while (count < max_pkts || max_pkts == -1) {
		skb = __skb_dequeue(&rxq->list);
		if (skb) {
			__skb_queue_tail(list, skb);
			count++;
		} else
			break;
	}

	empty = skb_queue_empty(&rxq->list);

	if (use_lock)
		spin_unlock(&rxq->list.lock);

	netif_info(adpt, rx_status, adpt->netdev,
		   "RX %d packets\n",
		   count);

	return empty;
}

static inline void alx_skb_queue_tail(struct alx_rx_queue *rxq,
				      struct sk_buff *skb)
{
	struct alx_adapter *adpt = netdev_priv(rxq->netdev);
	bool use_lock = !ALX_CAP(&adpt->hw, MRQ);

	if (use_lock)
		spin_lock(&rxq->list.lock);

	__skb_queue_tail(&rxq->list, skb);

	if (use_lock)
		spin_unlock(&rxq->list.lock);
}

int alx_alloc_rxring_buf(struct alx_adapter *adpt,
			 struct alx_rx_queue *rxq)
{
	struct sk_buff *skb;
	struct alx_buffer *cur_buf;
	struct rfd_desc *rfd;
	dma_addr_t dma;
	u16 cur, next, count = 0;

	next = cur = rxq->pidx;
	if (++next == rxq->count)
		next = 0;
	cur_buf = rxq->bf_info + cur;
	rfd = rxq->rfd_hdr + cur;

	while (!cur_buf->skb && next != rxq->cidx) {
		skb = dev_alloc_skb(adpt->rxbuf_size);
		if (unlikely(!skb)) {
			netdev_warn(adpt->netdev, "alloc skb failed\n");
			break;
		}
		skb_reserve(skb, NET_IP_ALIGN);
		dma = dma_map_single(rxq->dev,
				     skb->data,
				     adpt->rxbuf_size,
				     DMA_FROM_DEVICE);
		if (dma_mapping_error(rxq->dev, dma)) {
			netdev_warn(adpt->netdev, "mapping rx-buffer failed\n");
			dev_kfree_skb(skb);
			break;
		}
		cur_buf->skb = skb;
		dma_unmap_len_set(cur_buf, size, adpt->rxbuf_size);
		dma_unmap_addr_set(cur_buf, dma, dma);
		rfd->addr = cpu_to_le64(dma);

		cur = next;
		if (++next == rxq->count)
			next = 0;
		cur_buf = rxq->bf_info + cur;
		rfd = rxq->rfd_hdr + cur;
		count++;
	}

	if (count) {
		wmb();
		rxq->pidx = cur;
		ALX_MEM_W16(&adpt->hw, rxq->p_reg, (u16)cur);
	}

	return count;
}

static void alx_free_rxring_buf(struct alx_rx_queue *rxq)
{
	struct alx_buffer *cur_buf;
	struct sk_buff_head list;
	u16 i;

	if (rxq == NULL)
		return;

	for (i = 0; i < rxq->count; i++) {
		cur_buf = rxq->bf_info + i;
		if (cur_buf->skb) {
			dma_unmap_single(rxq->dev,
					 dma_unmap_addr(cur_buf, dma),
					 dma_unmap_len(cur_buf, size),
					 DMA_FROM_DEVICE);
			dev_kfree_skb(cur_buf->skb);
			cur_buf->skb = NULL;
			dma_unmap_len_set(cur_buf, size, 0);
			dma_unmap_addr_set(cur_buf, dma, 0);
		}
	}

	/* some skbs might be pending in the list */
	__skb_queue_head_init(&list);
	alx_skb_dequeue_n(rxq, -1, &list);
	while (!skb_queue_empty(&list)) {
		struct sk_buff *skb;

		skb = __skb_dequeue(&list);
		dev_kfree_skb(skb);
	}

	rxq->pidx = 0;
	rxq->cidx = 0;
	rxq->rrd_cidx = 0;
}

int alx_setup_all_ring_resources(struct alx_adapter *adpt)
{
	int err;

	err = alx_alloc_napis(adpt);
	if (err)
		goto out;

	err = alx_alloc_rings(adpt);
	if (err)
		goto out;

	err = alx_reinit_rings(adpt);

out:
	if (unlikely(err)) {
		netif_err(adpt, ifup, adpt->netdev,
			  "setup_all_ring_resources fail %d\n",
			  err);
	}
	return err;
}

static void alx_txbuf_unmap_and_free(struct alx_tx_queue *txq, int entry)
{
	struct alx_buffer *txb = txq->bf_info + entry;

	if (dma_unmap_len(txb, size) &&
	    txb->flags & ALX_BUF_TX_FIRSTFRAG) {
		dma_unmap_single(txq->dev,
				 dma_unmap_addr(txb, dma),
				 dma_unmap_len(txb, size),
				 DMA_TO_DEVICE);
		txb->flags &= ~ALX_BUF_TX_FIRSTFRAG;
	} else if (dma_unmap_len(txb, size)) {
		dma_unmap_page(txq->dev,
			       dma_unmap_addr(txb, dma),
			       dma_unmap_len(txb, size),
			       DMA_TO_DEVICE);
	}
	if (txb->skb) {
		dev_kfree_skb_any(txb->skb);
		txb->skb = NULL;
	}
	dma_unmap_len_set(txb, size, 0);
}

static void alx_free_txring_buf(struct alx_tx_queue *txq)
{
	int i;

	if (!txq->bf_info)
		return;

	for (i = 0; i < txq->count; i++)
		alx_txbuf_unmap_and_free(txq, i);

	memset(txq->bf_info, 0, txq->count * sizeof(struct alx_buffer));
	memset(txq->tpd_hdr, 0, txq->count * sizeof(struct tpd_desc));
	txq->pidx = 0;
	atomic_set(&txq->cidx, 0);

	netdev_tx_reset_queue(netdev_get_tx_queue(txq->netdev, txq->qidx));
}

/* free up pending skb for tx/rx */
static void alx_free_all_rings_buf(struct alx_adapter *adpt)
{
	int i;

	for (i = 0; i < adpt->nr_txq; i++)
		if (adpt->qnapi[i])
			alx_free_txring_buf(adpt->qnapi[i]->txq);

	for (i = 0; i < adpt->nr_hwrxq; i++)
		if (adpt->qnapi[i])
			alx_free_rxring_buf(adpt->qnapi[i]->rxq);
}

void alx_free_all_ring_resources(struct alx_adapter *adpt)
{
	alx_free_all_rings_buf(adpt);
	alx_free_rings(adpt);
	alx_free_napis(adpt);
}

static inline int alx_tpd_avail(struct alx_tx_queue *txq)
{
	u16 cidx = atomic_read(&txq->cidx);

	return txq->pidx >= cidx ?
		txq->count + cidx - txq->pidx - 1 :
		cidx - txq->pidx - 1;
}



static bool alx_clean_tx_irq(struct alx_tx_queue *txq)
{
	struct alx_adapter *adpt = netdev_priv(txq->netdev);
	struct netdev_queue *netque;
	u16 hw_cidx, sw_cidx;
	unsigned int total_bytes = 0, total_packets = 0;
	int budget = ALX_DEFAULT_TX_WORK;

	if (ALX_FLAG(adpt, HALT))
		return true;

	netque = netdev_get_tx_queue(adpt->netdev, txq->qidx);
	sw_cidx = atomic_read(&txq->cidx);

	ALX_MEM_R16(&adpt->hw, txq->c_reg, &hw_cidx);

	if (sw_cidx != hw_cidx) {

		netif_info(adpt, tx_done, adpt->netdev,
			   "TX[Q:%d, Preg:%x]: cons = 0x%x, hw-cons = 0x%x\n",
			   txq->qidx, txq->p_reg, sw_cidx, hw_cidx);

		while (sw_cidx != hw_cidx && budget > 0) {
			struct sk_buff *skb;

			skb = txq->bf_info[sw_cidx].skb;
			if (skb) {
				total_bytes += skb->len;
				total_packets++;
				budget--;
			}
			alx_txbuf_unmap_and_free(txq, sw_cidx);
			if (++sw_cidx == txq->count)
				sw_cidx = 0;
		}
		atomic_set(&txq->cidx, sw_cidx);

		netdev_tx_completed_queue(netque, total_packets, total_bytes);
	}

	if (unlikely(netif_tx_queue_stopped(netque) &&
		     netif_carrier_ok(adpt->netdev) &&
		     alx_tpd_avail(txq) > ALX_TX_WAKEUP_THRESH(txq) &&
		     !ALX_FLAG(adpt, HALT))) {
		netif_tx_wake_queue(netque);
	}

	return sw_cidx == hw_cidx;
}

static bool alx_dispatch_skb(struct alx_rx_queue *rxq)
{
	struct alx_adapter *adpt = netdev_priv(rxq->netdev);
	struct rrd_desc *rrd;
	struct alx_buffer *rxb;
	struct sk_buff *skb;
	u16 length, rfd_cleaned = 0;
	struct alx_rx_queue *tmp_rxq;
	int qnum;

	if (test_and_set_bit(ALX_RQ_USING, &rxq->flag))
		return false;

	while (1) {
		rrd = rxq->rrd_hdr + rxq->rrd_cidx;
		if (!(rrd->word3 & (1 << RRD_UPDATED_SHIFT)))
			break;
		rrd->word3 &= ~(1 << RRD_UPDATED_SHIFT);

		if (unlikely(FIELD_GETX(rrd->word0, RRD_SI) != rxq->cidx ||
			     FIELD_GETX(rrd->word0, RRD_NOR) != 1)) {
			netif_err(adpt, rx_err, adpt->netdev,
				  "wrong SI/NOR packet! rrd->word0= %08x\n",
				  rrd->word0);
			/* reset chip */
			ALX_FLAG_SET(adpt, TASK_RESET);
			alx_schedule_work(adpt);
			return true;
		}
		rxb = rxq->bf_info + rxq->cidx;
		dma_unmap_single(rxq->dev,
				 dma_unmap_addr(rxb, dma),
				 dma_unmap_len(rxb, size),
				 DMA_FROM_DEVICE);
		dma_unmap_len_set(rxb, size, 0);
		skb = rxb->skb;
		rxb->skb = NULL;

		if (unlikely(rrd->word3 & (1 << RRD_ERR_RES_SHIFT) ||
			     rrd->word3 & (1 << RRD_ERR_LEN_SHIFT))) {
			netdev_warn(adpt->netdev,
				   "wrong packet! rrd->word3 is %08x\n",
				   rrd->word3);
			rrd->word3 = 0;
			dev_kfree_skb_any(skb);
			goto next_pkt;
		}
		length = FIELD_GETX(rrd->word3, RRD_PKTLEN) - ETH_FCS_LEN;
		skb_put(skb, length);
		skb->protocol = eth_type_trans(skb, adpt->netdev);
		/* checksum */
		skb_checksum_none_assert(skb);
		if (adpt->netdev->features & NETIF_F_RXCSUM) {
			switch (FIELD_GETX(rrd->word2, RRD_PID)) {
			case RRD_PID_IPV6UDP:
			case RRD_PID_IPV4UDP:
			case RRD_PID_IPV4TCP:
			case RRD_PID_IPV6TCP:
				if (rrd->word3 & ((1 << RRD_ERR_L4_SHIFT) |
						  (1 << RRD_ERR_IPV4_SHIFT))) {
					netdev_warn(
						adpt->netdev,
						"rx-chksum error, w2=%X\n",
						rrd->word2);
					break;
				}
				skb->ip_summed = CHECKSUM_UNNECESSARY;
				break;
			}
		}
		/* vlan tag */
		if (rrd->word3 & (1 << RRD_VLTAGGED_SHIFT)) {
			u16 tag = ntohs(FIELD_GETX(rrd->word2, RRD_VLTAG));
			__vlan_hwaccel_put_tag(skb, ntohs(tag));
		}
		qnum = FIELD_GETX(rrd->word2, RRD_RSSQ) % adpt->nr_rxq;
		tmp_rxq = ALX_CAP(&adpt->hw, MRQ) ?
				rxq : adpt->qnapi[qnum]->rxq;
		alx_skb_queue_tail(tmp_rxq, skb);

next_pkt:

		if (++rxq->cidx == rxq->count)
			rxq->cidx = 0;
		if (++rxq->rrd_cidx == rxq->count)
			rxq->rrd_cidx = 0;

		if (++rfd_cleaned > ALX_RX_ALLOC_THRESH)
			rfd_cleaned -= alx_alloc_rxring_buf(adpt, rxq);
	}

	if (rfd_cleaned)
		alx_alloc_rxring_buf(adpt, rxq);

	clear_bit(ALX_RQ_USING, &rxq->flag);

	return true;
}

static inline struct napi_struct *alx_rxq_to_napi(
	struct alx_rx_queue *rxq)
{
	struct alx_adapter *adpt = netdev_priv(rxq->netdev);

	return &adpt->qnapi[rxq->qidx]->napi;
}

static bool alx_clean_rx_irq(struct alx_rx_queue *rxq, int budget)
{
	struct sk_buff_head list;
	bool empty;

	__skb_queue_head_init(&list);
	alx_dispatch_skb(alx_hw_rxq(rxq));
	empty = alx_skb_dequeue_n(rxq, budget, &list);
	if (!skb_queue_empty(&list)) {
		struct napi_struct *napi;
		struct sk_buff *skb;

		napi = alx_rxq_to_napi(rxq);
		while (!skb_queue_empty(&list)) {
			skb = __skb_dequeue(&list);
			napi_gro_receive(napi, skb);
		}
	} else {
		struct alx_adapter *adpt = netdev_priv(rxq->netdev);

		netif_info(adpt, rx_status, adpt->netdev,
			   "no packet received for this rxQ\n");
	}


	return empty;
}

static int alx_request_msix(struct alx_adapter *adpt)
{
	struct net_device *netdev = adpt->netdev;
	int i, err;
	int vec;

	err = request_irq(adpt->msix_ent[0].vector,
		alx_intr_msix_misc, 0, netdev->name, adpt);
	if (err)
		goto out;

	vec = 1;
	for (i = 0; i < adpt->nr_napi; i++) {
		struct alx_napi *np = adpt->qnapi[i];

		if (np->txq && np->rxq)
			sprintf(np->irq_lbl, "%s-TR-%u", netdev->name, i);
		else if (np->txq)
			sprintf(np->irq_lbl, "%s-T-%u", netdev->name, i);
		else
			sprintf(np->irq_lbl, "%s-R-%u", netdev->name, i);

		np->vec_idx = vec;
		err = request_irq(adpt->msix_ent[vec].vector,
			alx_msix_ring, 0, np->irq_lbl, np);
		if (err) {
			for (i--, vec--; i >= 0; i--) {
				np = adpt->qnapi[i];
				free_irq(adpt->msix_ent[vec].vector, np);
			}
			free_irq(adpt->msix_ent[0].vector, adpt);
			goto out;
		}
		vec++;
	}

out:
	return err;
}

static void alx_disable_msix(struct alx_adapter *adpt)
{
	if (adpt->msix_ent) {
		pci_disable_msix(adpt->pdev);
		kfree(adpt->msix_ent);
		adpt->msix_ent = NULL;
	}
	ALX_FLAG_CLEAR(adpt, USING_MSIX);
}

static void alx_disable_msi(struct alx_adapter *adpt)
{
	if (ALX_FLAG(adpt, USING_MSI)) {
		pci_disable_msi(adpt->pdev);
		ALX_FLAG_CLEAR(adpt, USING_MSI);
	}
}

static int txq_vec_mapping_shift[] = {
	0, ALX_MSI_MAP_TBL1_TXQ0_SHIFT,
	0, ALX_MSI_MAP_TBL1_TXQ1_SHIFT,
	1, ALX_MSI_MAP_TBL2_TXQ2_SHIFT,
	1, ALX_MSI_MAP_TBL2_TXQ3_SHIFT,
};
static int rxq_vec_mapping_shift[] = {
	0, ALX_MSI_MAP_TBL1_RXQ0_SHIFT,
	0, ALX_MSI_MAP_TBL1_RXQ1_SHIFT,
	0, ALX_MSI_MAP_TBL1_RXQ2_SHIFT,
	0, ALX_MSI_MAP_TBL1_RXQ3_SHIFT,
	1, ALX_MSI_MAP_TBL2_RXQ4_SHIFT,
	1, ALX_MSI_MAP_TBL2_RXQ5_SHIFT,
	1, ALX_MSI_MAP_TBL2_RXQ6_SHIFT,
	1, ALX_MSI_MAP_TBL2_RXQ7_SHIFT,
};
static void alx_config_vector_mapping(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	u32 tbl[2];
	int vect, idx, shft;
	int i;

	tbl[0] = tbl[1] = 0;

	if (ALX_FLAG(adpt, USING_MSIX)) {
		for (vect = 1, i = 0; i < adpt->nr_txq; i++, vect++) {
			idx = txq_vec_mapping_shift[i * 2];
			shft = txq_vec_mapping_shift[i * 2 + 1];
			tbl[idx] |= vect << shft;
		}
		for (vect = 1, i = 0; i < adpt->nr_rxq; i++, vect++) {
			idx = rxq_vec_mapping_shift[i * 2];
			shft = rxq_vec_mapping_shift[i * 2 + 1];
			tbl[idx] |= vect << shft;
		}
	}
	ALX_MEM_W32(hw, ALX_MSI_MAP_TBL1, tbl[0]);
	ALX_MEM_W32(hw, ALX_MSI_MAP_TBL2, tbl[1]);
	ALX_MEM_W32(hw, ALX_MSI_ID_MAP, 0);
}

void alx_disable_advanced_intr(struct alx_adapter *adpt)
{
	alx_disable_msix(adpt);
	alx_disable_msi(adpt);

	/* clear vector/intr-event mapping */
	alx_config_vector_mapping(adpt);
}

static void alx_irq_enable(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	int i;

	if (!atomic_dec_and_test(&adpt->irq_sem))
		return;

	/* level-1 interrupt switch */
	ALX_MEM_W32(hw, ALX_ISR, 0);
	ALX_MEM_W32(hw, ALX_IMR, hw->imask);
	ALX_MEM_FLUSH(hw);

	if (!ALX_FLAG(adpt, USING_MSIX))
		return;

	/* enable all individual MSIX IRQs */
	for (i = 0; i < adpt->nr_vec; i++)
		alx_mask_msix(hw, i, false);
}

static void alx_irq_disable(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	int i;

	atomic_inc(&adpt->irq_sem);

	ALX_MEM_W32(hw, ALX_ISR, ALX_ISR_DIS);
	ALX_MEM_W32(hw, ALX_IMR, 0);
	ALX_MEM_FLUSH(hw);

	if (ALX_FLAG(adpt, USING_MSIX)) {
		for (i = 0; i < adpt->nr_vec; i++) {
			alx_mask_msix(hw, i, true);
			synchronize_irq(adpt->msix_ent[i].vector);
		}
	} else {
		synchronize_irq(adpt->pdev->irq);
	}
}

static int alx_request_irq(struct alx_adapter *adpt)
{
	struct pci_dev *pdev = adpt->pdev;
	struct alx_hw *hw = &adpt->hw;
	int err;
	u32 msi_ctrl;

	msi_ctrl = FIELDX(ALX_MSI_RETRANS_TM, hw->imt >> 1);

	if (ALX_FLAG(adpt, USING_MSIX)) {
		ALX_MEM_W32(hw, ALX_MSI_RETRANS_TIMER, msi_ctrl);
		err = alx_request_msix(adpt);
		if (!err)
			goto out;
		/* fall back to MSI or legacy interrupt mode,
		 * re-alloc all resources
		 */
		alx_free_all_ring_resources(adpt);
		alx_disable_msix(adpt);
		adpt->nr_rxq = 1;
		adpt->nr_txq = 1;
		adpt->nr_napi = 1;
		adpt->nr_vec = 1;
		adpt->nr_hwrxq = 1;
		alx_configure_rss(hw, false);
		if (!pci_enable_msi(pdev))
			ALX_FLAG_SET(adpt, USING_MSI);

		err = alx_setup_all_ring_resources(adpt);
		if (err)
			goto out;
	}

	if (ALX_FLAG(adpt, USING_MSI)) {
		ALX_MEM_W32(hw, ALX_MSI_RETRANS_TIMER,
			    msi_ctrl | ALX_MSI_MASK_SEL_LINE);
		err = request_irq(pdev->irq, alx_intr_msi, 0,
				  adpt->netdev->name, adpt);
		if (!err)
			goto out;
		/* fall back to legacy interrupt */
		alx_disable_msi(adpt);
	}

	ALX_MEM_W32(hw, ALX_MSI_RETRANS_TIMER, 0);
	err = request_irq(pdev->irq, alx_intr_legacy, IRQF_SHARED,
			  adpt->netdev->name, adpt);

	if (err)
		netif_err(adpt, intr, adpt->netdev,
			  "request shared irq failed, err = %d\n",
			  err);

out:
	if (likely(!err)) {
		alx_config_vector_mapping(adpt);

		netif_info(adpt, drv, adpt->netdev,
			   "nr_rxq=%d, nr_txq=%d, nr_napi=%d, nr_vec=%d\n",
			   adpt->nr_rxq, adpt->nr_txq,
			   adpt->nr_napi, adpt->nr_vec);
		netif_info(adpt, drv, adpt->netdev,
			   "flags=%lX, Interrupt Mode: %s\n",
			   adpt->flags,
			   ALX_FLAG(adpt, USING_MSIX) ? "MSIX" :
			   ALX_FLAG(adpt, USING_MSI) ? "MSI" : "INTx");
	} else
		netdev_err(adpt->netdev,
			   "register IRQ fail %d\n",
			   err);

	return err;
}

static void alx_free_irq(struct alx_adapter *adpt)
{
	struct pci_dev *pdev = adpt->pdev;
	int i, vec;

	if (ALX_FLAG(adpt, USING_MSIX)) {
		free_irq(adpt->msix_ent[0].vector, adpt);
		vec = 1;
		for (i = 0; i < adpt->nr_napi; i++, vec++)
			free_irq(adpt->msix_ent[vec].vector, adpt->qnapi[i]);
	} else {
		free_irq(pdev->irq, adpt);
	}
	alx_disable_advanced_intr(adpt);
}


static int alx_identify_hw(struct alx_adapter *adpt)
{
	struct pci_dev *pdev = adpt->pdev;
	struct alx_hw *hw = &adpt->hw;
	int rev;
	int err = -EINVAL;

	hw->device_id = pdev->device;
	hw->subdev_id = pdev->subsystem_device;
	hw->subven_id = pdev->subsystem_vendor;
	hw->revision = pdev->revision;
	rev = ALX_REVID(hw);

	switch (ALX_DID(hw)) {
	case ALX_DEV_ID_AR8161:
	case ALX_DEV_ID_AR8162:
	case ALX_DEV_ID_AR8171:
	case ALX_DEV_ID_AR8172:
		if (rev > ALX_REV_C0)
			break;
		err = 0;
		ALX_CAP_SET(hw, L0S);
		ALX_CAP_SET(hw, L1);
		ALX_CAP_SET(hw, MTQ);
		ALX_CAP_SET(hw, RSS);
		ALX_CAP_SET(hw, MSIX);
		ALX_CAP_SET(hw, SWOI);
		hw->max_dma_chnl = rev >= ALX_REV_B0 ? 4 : 2;
		if (rev < ALX_REV_C0) {
			hw->ptrn_ofs = 0x600;
			hw->max_ptrns = 8;
		} else {
			hw->ptrn_ofs = 0x14000;
			hw->max_ptrns = 16;
		}
		break;
	}

	if (!err && ALX_DID(hw) & 1)
		ALX_CAP_SET(hw, GIGA);

	return err;
}


static const u8 def_rss_key[40] = {
	0xE2, 0x91, 0xD7, 0x3D, 0x18, 0x05, 0xEC, 0x6C,
	0x2A, 0x94, 0xB3, 0x0D, 0xA5, 0x4F, 0x2B, 0xEC,
	0xEA, 0x49, 0xAF, 0x7C, 0xE2, 0x14, 0xAD, 0x3D,
	0xB8, 0x55, 0xAA, 0xBE, 0x6A, 0x3E, 0x67, 0xEA,
	0x14, 0x36, 0x4D, 0x17, 0x3B, 0xED, 0x20, 0x0D,
};

void alx_init_def_rss_idt(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	int i, x, y;
	u32 val;

	for (i = 0; i < hw->rss_idt_size; i++) {
		val = ethtool_rxfh_indir_default(i, adpt->nr_rxq);
		x = i >> 3;
		y = i * 4 & 0x1F;
		hw->rss_idt[x] &= ~(0xF << y);
		hw->rss_idt[x] |= (val & 0xF) << y;
	}
}

/* alx_init_adapter -
 *    initialize general software structure (struct alx_adapter).
 *    fields are inited based on PCI device information.
 */
static int alx_init_sw(struct alx_adapter *adpt)
{
	struct pci_dev	*pdev = adpt->pdev;
	struct alx_hw *hw = &adpt->hw;
	int i, err;

	err = alx_identify_hw(adpt);
	if (err) {
		dev_err(&pdev->dev, "unrecognize the chip, aborting\n");
		return err;
	}

	/* assign patch flag for specific platforms */
	alx_patch_assign(hw);

	memcpy(hw->rss_key, def_rss_key, sizeof(def_rss_key));
	hw->rss_idt_size = 128;
	hw->rss_hash_type = ALX_RSS_HASH_TYPE_ALL;
	hw->smb_timer = 400;
	hw->mtu = adpt->netdev->mtu;
	adpt->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8);
	adpt->tx_ringsz = 256;
	adpt->rx_ringsz = 512;
	hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY;
	hw->imt = 200;
	hw->imask = ALX_ISR_MISC;
	hw->dma_chnl = hw->max_dma_chnl;
	hw->ith_tpd = adpt->tx_ringsz / 3;
	hw->link_up = false;
	hw->link_duplex = 0;
	hw->link_speed = SPEED_0;
	hw->adv_cfg =	ADVERTISED_Autoneg |
			ADVERTISED_10baseT_Half |
			ADVERTISED_10baseT_Full |
			ADVERTISED_100baseT_Full |
			ADVERTISED_100baseT_Half |
			ADVERTISED_1000baseT_Full;
	hw->flowctrl = ALX_FC_ANEG | ALX_FC_RX | ALX_FC_TX;
	hw->wrr_ctrl = ALX_WRR_PRI_RESTRICT_NONE;
	for (i = 0; i < ARRAY_SIZE(hw->wrr); i++)
		hw->wrr[i] = 4;

	hw->rx_ctrl = ALX_MAC_CTRL_WOLSPED_SWEN |
			ALX_MAC_CTRL_MHASH_ALG_HI5B |
			ALX_MAC_CTRL_BRD_EN |
			ALX_MAC_CTRL_PCRCE |
			ALX_MAC_CTRL_CRCE |
			ALX_MAC_CTRL_RXFC_EN |
			ALX_MAC_CTRL_TXFC_EN |
			FIELDX(ALX_MAC_CTRL_PRMBLEN, 7);
	hw->is_fpga = false;

	atomic_set(&adpt->irq_sem, 1);
	ALX_FLAG_SET(adpt, HALT);

	return err;
}


static void alx_set_vlan_mode(struct alx_hw *hw,
			      netdev_features_t features)
{
	if (features & NETIF_F_HW_VLAN_RX)
		hw->rx_ctrl |= ALX_MAC_CTRL_VLANSTRIP;
	else
		hw->rx_ctrl &= ~ALX_MAC_CTRL_VLANSTRIP;

	ALX_MEM_W32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
}


static netdev_features_t alx_fix_features(struct net_device *netdev,
					  netdev_features_t features)
{
	/*
	 * Since there is no support for separate rx/tx vlan accel
	 * enable/disable make sure tx flag is always in same state as rx.
	 */
	if (features & NETIF_F_HW_VLAN_RX)
		features |= NETIF_F_HW_VLAN_TX;
	else
		features &= ~NETIF_F_HW_VLAN_TX;

	if (netdev->mtu > ALX_MAX_TSO_PKT_SIZE)
		features &= ~(NETIF_F_TSO | NETIF_F_TSO6);

	return features;
}


static int alx_set_features(struct net_device *netdev,
			    netdev_features_t features)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	netdev_features_t changed = netdev->features ^ features;

	if (!(changed & NETIF_F_HW_VLAN_RX))
		return 0;

	alx_set_vlan_mode(&adpt->hw, features);

	return 0;
}

/* alx_change_mtu - Change the Maximum Transfer Unit */
static int alx_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	int old_mtu   = netdev->mtu;
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;

	if ((max_frame < ALX_MIN_FRAME_SIZE) ||
	    (max_frame > ALX_MAX_FRAME_SIZE)) {
		netif_err(adpt, hw, netdev,
			  "invalid MTU setting (%x)\n",
			  new_mtu);
		return -EINVAL;
	}
	/* set MTU */
	if (old_mtu != new_mtu) {
		netif_info(adpt, drv, adpt->netdev,
			   "changing MTU from %d to %d\n",
			   netdev->mtu, new_mtu);
		netdev->mtu = new_mtu;
		adpt->hw.mtu = new_mtu;
		adpt->rxbuf_size = new_mtu > ALX_DEF_RXBUF_SIZE ?
				   ALIGN(max_frame, 8) : ALX_DEF_RXBUF_SIZE;
		netdev_update_features(netdev);
		if (netif_running(netdev))
			alx_reinit(adpt);
	}

	return 0;
}

/* configure hardware everything except:
 *  1. interrupt vectors
 *  2. enable control for rx modules
 */
void alx_configure(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;

	alx_configure_basic(hw);
	alx_configure_rss(hw, adpt->nr_rxq > 1);
	__alx_set_rx_mode(adpt->netdev);
	alx_set_vlan_mode(hw, adpt->netdev->features);
}

static void alx_netif_stop(struct alx_adapter *adpt)
{
	int i;

	adpt->netdev->trans_start = jiffies;
	if (netif_carrier_ok(adpt->netdev)) {
		netif_carrier_off(adpt->netdev);
		netif_tx_disable(adpt->netdev);
		for (i = 0; i < adpt->nr_napi; i++)
			napi_disable(&adpt->qnapi[i]->napi);
	}
}

static void alx_netif_start(struct alx_adapter *adpt)
{
	int i;

	netif_tx_wake_all_queues(adpt->netdev);
	for (i = 0; i < adpt->nr_napi; i++)
		napi_enable(&adpt->qnapi[i]->napi);
	netif_carrier_on(adpt->netdev);
}

static bool alx_enable_msix(struct alx_adapter *adpt)
{
	int nr_txq, nr_rxq, vec_req;
	int i, err;

	nr_txq = min_t(int, num_online_cpus(), ALX_MAX_TX_QUEUES);
	nr_rxq = min_t(int, num_online_cpus(), ALX_MAX_RX_QUEUES);
	nr_rxq = rounddown_pow_of_two(nr_rxq);
	/* one more vector for PHY link change & timer & other events */
	vec_req = max_t(int, nr_txq, nr_rxq) + 1;

	if (vec_req  <= 2) {
		netif_info(adpt, intr, adpt->netdev,
			   "cpu core num is less, MSI-X isn't necessary\n");
		return false;
	}

	adpt->msix_ent = kcalloc(vec_req,
				 sizeof(struct msix_entry),
				 GFP_KERNEL);
	if (!adpt->msix_ent) {
		netif_warn(adpt, intr, adpt->netdev,
			   "can't alloc msix entries\n");
		return false;
	}
	for (i = 0; i < vec_req; i++)
		adpt->msix_ent[i].entry = i;

	err = pci_enable_msix(adpt->pdev, adpt->msix_ent, vec_req);
	if (err) {
		kfree(adpt->msix_ent);
		adpt->msix_ent = NULL;
		netif_warn(adpt, intr, adpt->netdev,
			   "can't enable MSI-X interrupt\n");
		return false;
	}

	adpt->nr_txq = nr_txq;
	adpt->nr_rxq = nr_rxq;
	adpt->nr_vec = vec_req;
	adpt->nr_napi = vec_req - 1;
	adpt->nr_hwrxq = ALX_CAP(&adpt->hw, MRQ) ? adpt->nr_rxq : 1;

	return true;
}

void alx_init_intr(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;

	if ((ALX_CAP(hw, MTQ) || ALX_CAP(hw, RSS)) && ALX_CAP(hw, MSIX)) {
		if (alx_enable_msix(adpt))
			ALX_FLAG_SET(adpt, USING_MSIX);
	}
	if (!ALX_FLAG(adpt, USING_MSIX)) {
		adpt->nr_txq = 1;
		adpt->nr_rxq = 1;
		adpt->nr_napi = 1;
		adpt->nr_vec = 1;
		adpt->nr_hwrxq = 1;

		if (!pci_enable_msi(adpt->pdev))
			ALX_FLAG_SET(adpt, USING_MSI);
	}
}

static int __alx_open(struct alx_adapter *adpt, bool resume)
{
	int err;

	/* decide interrupt mode, some resources allocation depend on it */
	alx_init_intr(adpt);

	/* init rss indirection table */
	alx_init_def_rss_idt(adpt);

	if (!resume)
		netif_carrier_off(adpt->netdev);

	/* allocate all memory resources */
	err = alx_setup_all_ring_resources(adpt);
	if (err)
		goto err_out;

	/* make hardware ready before allocate interrupt */
	alx_configure(adpt);

	err = alx_request_irq(adpt);
	if (err)
		goto err_out;

	/* netif_set_real_num_tx/rx_queues need rtnl_lock held */
	if (resume)
		rtnl_lock();
	netif_set_real_num_tx_queues(adpt->netdev, adpt->nr_txq);
	netif_set_real_num_rx_queues(adpt->netdev, adpt->nr_rxq);
	if (resume)
		rtnl_unlock();

	ALX_FLAG_CLEAR(adpt, HALT);

	/* clear old interrupts */
	ALX_MEM_W32(&adpt->hw, ALX_ISR, (u32)~ALX_ISR_DIS);

	alx_irq_enable(adpt);

	if (!resume)
		netif_tx_start_all_queues(adpt->netdev);

	ALX_FLAG_SET(adpt, TASK_CHK_LINK);
	alx_schedule_work(adpt);
	return 0;

err_out:

	alx_free_all_ring_resources(adpt);
	alx_disable_advanced_intr(adpt);
	return err;
}

static void alx_halt(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;

	ALX_FLAG_SET(adpt, HALT);
	alx_cancel_work(adpt);

	alx_netif_stop(adpt);
	hw->link_up = false;
	hw->link_speed = SPEED_0;

	alx_reset_mac(hw);

	/* disable l0s/l1 */
	alx_enable_aspm(hw, false, false);
	alx_irq_disable(adpt);
	alx_free_all_rings_buf(adpt);
}

static void alx_activate(struct alx_adapter *adpt)
{
	/* hardware setting lost, restore it */
	alx_reinit_rings(adpt);
	alx_configure(adpt);

	ALX_FLAG_CLEAR(adpt, HALT);
	/* clear old interrupts */
	ALX_MEM_W32(&adpt->hw, ALX_ISR, (u32)~ALX_ISR_DIS);

	alx_irq_enable(adpt);

	ALX_FLAG_SET(adpt, TASK_CHK_LINK);
	alx_schedule_work(adpt);
}

static void __alx_stop(struct alx_adapter *adpt)
{
	alx_halt(adpt);

	alx_free_irq(adpt);

	alx_free_all_ring_resources(adpt);
}

static void alx_init_ring_ptrs(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	struct alx_napi *np;
	int i, tx_idx, rx_idx;
	u32 addr_hi;
	u16 txring_header_reg[] = {ALX_TPD_PRI0_ADDR_LO, ALX_TPD_PRI1_ADDR_LO,
				   ALX_TPD_PRI2_ADDR_LO, ALX_TPD_PRI3_ADDR_LO};
	u16 rfdring_header_reg[] = {ALX_RFD_ADDR_LO};
	u16 rrdring_header_reg[] = {ALX_RRD_ADDR_LO};

	tx_idx = 0;
	rx_idx = 0;
	for (i = 0; i < adpt->nr_napi; i++) {
		np = adpt->qnapi[i];
		if (np->rxq) {
			np->rxq->pidx = 0;
			np->rxq->cidx = 0;
			np->rxq->rrd_cidx = 0;
			if (!ALX_CAP(hw, MRQ) && rx_idx == 0) {
				ALX_MEM_W32(hw, rfdring_header_reg[0],
					    np->rxq->rfd_dma);
				ALX_MEM_W32(hw, rrdring_header_reg[0],
					    np->rxq->rrd_dma);
			}
			rx_idx++;
		}
		if (np->txq) {
			np->txq->pidx = 0;
			atomic_set(&np->txq->cidx, 0);
			ALX_MEM_W32(hw, txring_header_reg[tx_idx],
				np->txq->tpd_dma);
			tx_idx++;
		}
	}

	addr_hi = ((u64)adpt->ring_header.dma) >> 32;
	ALX_MEM_W32(hw, ALX_TX_BASE_ADDR_HI, addr_hi);
	ALX_MEM_W32(hw, ALX_RX_BASE_ADDR_HI, addr_hi);
	ALX_MEM_W32(hw, ALX_TPD_RING_SZ, adpt->tx_ringsz);
	ALX_MEM_W32(hw, ALX_RRD_RING_SZ, adpt->rx_ringsz);
	ALX_MEM_W32(hw, ALX_RFD_RING_SZ, adpt->rx_ringsz);
	ALX_MEM_W32(hw, ALX_RFD_BUF_SZ, adpt->rxbuf_size);

	/* load these ptrs into chip internal */
	ALX_MEM_W32(hw, ALX_SRAM9, ALX_SRAM_LOAD_PTR);
}

static void alx_show_speed(struct alx_adapter *adpt, u16 speed)
{
	netif_info(adpt, link, adpt->netdev,
		   "NIC Link Up: %s\n",
		   speed_desc(speed));
}

static int alx_reinit_rings(struct alx_adapter *adpt)
{
	int i, err = 0;

	alx_free_all_rings_buf(adpt);

	/* set rings' header to HW register */
	alx_init_ring_ptrs(adpt);

	/* alloc hw-rxing buf */
	for (i = 0; i < adpt->nr_hwrxq; i++) {
		int count;

		count = alx_alloc_rxring_buf(adpt, adpt->qnapi[i]->rxq);
		if (unlikely(!count)) {
			err = -ENOMEM;
			break;
		}
	}

	return err;
}



static void alx_check_link(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	u16 speed, old_speed;
	bool link_up, old_link_up;
	int err;

	if (ALX_FLAG(adpt, HALT))
		return;

	/* clear PHY internal interrupt status,
	 * otherwise the Main interrupt status will be asserted
	 * for ever.
	 */
	alx_clear_phy_intr(hw);

	err = alx_get_phy_link(hw, &link_up, &speed);
	if (err)
		goto out;

	/* open interrutp mask */
	hw->imask |= ALX_ISR_PHY;
	ALX_MEM_W32(hw, ALX_IMR, hw->imask);

	if (!link_up && !hw->link_up)
		goto out;

	old_speed = hw->link_speed + hw->link_duplex;
	old_link_up = hw->link_up;

	if (link_up) {
		/* same speed ? */
		if (old_link_up && old_speed == speed)
			goto out;

		alx_show_speed(adpt, speed);
		hw->link_duplex = speed % 10;
		hw->link_speed = speed - hw->link_duplex;
		hw->link_up = true;
		alx_post_phy_link(hw, hw->link_speed, ALX_CAP(hw, AZ));
		alx_enable_aspm(hw, ALX_CAP(hw, L0S), ALX_CAP(hw, L1));
		alx_start_mac(hw);

		/* link kept, just speed changed */
		if (old_link_up)
			goto out;
		/* link changed from 'down' to 'up' */
		alx_netif_start(adpt);
		goto out;
	}

	/* link changed from 'up' to 'down' */
	alx_netif_stop(adpt);
	hw->link_up = false;
	hw->link_speed = SPEED_0;
	netif_info(adpt, link, adpt->netdev, "NIC Link Down\n");
	err = alx_reset_mac(hw);
	if (err) {
		netif_err(adpt, hw, adpt->netdev,
			  "linkdown:reset_mac fail %d\n", err);
		err = -EIO;
		goto out;
	}
	alx_irq_disable(adpt);

	/* reset-mac cause all settings on HW lost,
	 * following steps restore all of them and
	 * refresh whole RX/TX rings
	 */
	err = alx_reinit_rings(adpt);
	if (err)
		goto out;
	alx_configure(adpt);
	alx_enable_aspm(hw, false, ALX_CAP(hw, L1));
	alx_post_phy_link(hw, SPEED_0, ALX_CAP(hw, AZ));
	alx_irq_enable(adpt);

out:

	if (err) {
		ALX_FLAG_SET(adpt, TASK_RESET);
		alx_schedule_work(adpt);
	}
}

/* alx_open - Called when a network interface is made active */
static int alx_open(struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	int err;

	/* during diag running, disallow open */
	if (ALX_FLAG(adpt, TESTING))
		return -EBUSY;

	err = __alx_open(adpt, false);

	return err;
}

/* alx_stop - Disables a network interface */
static int alx_stop(struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);

	WARN_ON(ALX_FLAG(adpt, RESETING));

	__alx_stop(adpt);

	return 0;
}

static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
{
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct net_device *netdev = adpt->netdev;
	struct alx_hw *hw = &adpt->hw;
	int err;
	u16 speed;

	netif_device_detach(netdev);
	if (netif_running(netdev))
		__alx_stop(adpt);

#ifdef CONFIG_PM_SLEEP
	err = pci_save_state(pdev);
	if (err)
		goto out;
#endif

	err = alx_select_powersaving_speed(hw, &speed);
	if (!err)
		err = alx_clear_phy_intr(hw);
	if (!err)
		err = alx_pre_suspend(hw, speed);
	if (!err)
		err = alx_config_wol(hw);
	if (err)
		goto out;

	*wol_en = false;
	if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) {
		netif_info(adpt, wol, netdev,
			   "wol: ctrl=%X, speed=%X\n",
			   hw->sleep_ctrl, speed);

		device_set_wakeup_enable(&pdev->dev, true);
		*wol_en = true;
	}

	pci_disable_device(pdev);

out:
	if (unlikely(err)) {
		netif_info(adpt, hw, netdev,
			   "shutown err(%x)\n",
			   err);
		err = -EIO;
	}

	return err;
}

static void alx_shutdown(struct pci_dev *pdev)
{
	int err;
	bool wol_en;

	err = __alx_shutdown(pdev, &wol_en);
	if (likely(!err)) {
		pci_wake_from_d3(pdev, wol_en);
		pci_set_power_state(pdev, PCI_D3hot);
	} else {
		dev_err(&pdev->dev, "shutdown fail %d\n", err);
	}
}

#ifdef CONFIG_PM_SLEEP
static int alx_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	int err;
	bool wol_en;

	err = __alx_shutdown(pdev, &wol_en);
	if (unlikely(err)) {
		dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err);
		err = -EIO;
		goto out;
	}
	if (wol_en) {
		pci_prepare_to_sleep(pdev);
	} else {
		pci_wake_from_d3(pdev, false);
		pci_set_power_state(pdev, PCI_D3hot);
	}

out:
	return err;
}

static int alx_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct net_device *netdev = adpt->netdev;
	struct alx_hw *hw = &adpt->hw;
	int err;

	if (!netif_running(netdev))
		return 0;

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);
	pci_save_state(pdev);

	pci_enable_wake(pdev, PCI_D3hot, 0);
	pci_enable_wake(pdev, PCI_D3cold, 0);

	hw->link_up = false;
	hw->link_speed = SPEED_0;
	hw->imask = ALX_ISR_MISC;

	alx_reset_pcie(hw);
	alx_reset_phy(hw, !hw->hib_patch);
	err = alx_reset_mac(hw);
	if (err) {
		netif_err(adpt, hw, adpt->netdev,
			  "resume:reset_mac fail %d\n",
			  err);
		return -EIO;
	}
	err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl);
	if (err) {
		netif_err(adpt, hw, adpt->netdev,
			  "resume:setup_speed_duplex fail %d\n",
			  err);
		return -EIO;
	}

	if (netif_running(netdev)) {
		err = __alx_open(adpt, true);
		if (err)
			return err;
	}

	netif_device_attach(netdev);

	return err;
}
#endif



/* alx_update_hw_stats - Update the board statistics counters. */
static void alx_update_hw_stats(struct alx_adapter *adpt)
{
	if (ALX_FLAG(adpt, HALT) || ALX_FLAG(adpt, RESETING))
		return;

	__alx_update_hw_stats(&adpt->hw);
}

/* alx_get_stats - Get System Network Statistics
 *
 * Returns the address of the device statistics structure.
 * The statistics are actually updated from the timer callback.
 */
static struct net_device_stats *alx_get_stats(struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	struct net_device_stats *net_stats = &netdev->stats;
	struct alx_hw_stats *hw_stats = &adpt->hw.stats;

	spin_lock(&adpt->smb_lock);

	alx_update_hw_stats(adpt);

	net_stats->tx_packets = hw_stats->tx_ok;
	net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
	net_stats->rx_packets = hw_stats->rx_ok;
	net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
	net_stats->multicast  = hw_stats->rx_mcast;
	net_stats->collisions = hw_stats->tx_single_col +
				hw_stats->tx_multi_col * 2 +
				hw_stats->tx_late_col + hw_stats->tx_abort_col;

	net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
				hw_stats->rx_len_err + hw_stats->rx_ov_sz +
				hw_stats->rx_ov_rrd + hw_stats->rx_align_err;

	net_stats->rx_fifo_errors   = hw_stats->rx_ov_rxf;
	net_stats->rx_length_errors = hw_stats->rx_len_err;
	net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
	net_stats->rx_frame_errors  = hw_stats->rx_align_err;
	net_stats->rx_over_errors   = hw_stats->rx_ov_rrd + hw_stats->rx_ov_rxf;

	net_stats->rx_missed_errors = hw_stats->rx_ov_rrd + hw_stats->rx_ov_rxf;

	net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
			       hw_stats->tx_underrun + hw_stats->tx_trunc;

	net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
	net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
	net_stats->tx_window_errors  = hw_stats->tx_late_col;

	spin_unlock(&adpt->smb_lock);

	return net_stats;
}

static void alx_update_stats(struct alx_adapter *adpt)
{
	spin_lock(&adpt->smb_lock);
	alx_update_hw_stats(adpt);
	spin_unlock(&adpt->smb_lock);
}

void alx_reinit(struct alx_adapter *adpt)
{
	WARN_ON(in_interrupt());

	while (test_and_set_bit(ALX_FLAG_RESETING, &adpt->flags))
		msleep(20);

	if (ALX_FLAG(adpt, HALT))
		return;

	alx_halt(adpt);
	alx_activate(adpt);

	ALX_FLAG_CLEAR(adpt, RESETING);
}

/* alx_task - manages and runs subtasks */
static void alx_task(struct work_struct *work)
{
	struct alx_adapter *adpt = container_of(work, struct alx_adapter, task);

	/* don't support reentrance */
	while (test_and_set_bit(ALX_FLAG_TASK_PENDING, &adpt->flags))
		msleep(20);

	if (ALX_FLAG(adpt, HALT))
		goto out;

	if (test_and_clear_bit(ALX_FLAG_TASK_RESET, &adpt->flags)) {
		netif_info(adpt, hw, adpt->netdev,
			   "task:alx_reinit\n");
		alx_reinit(adpt);
	}

	if (test_and_clear_bit(ALX_FLAG_TASK_UPDATE_SMB, &adpt->flags))
		alx_update_stats(adpt);

	if (test_and_clear_bit(ALX_FLAG_TASK_CHK_LINK, &adpt->flags))
		alx_check_link(adpt);

out:
	ALX_FLAG_CLEAR(adpt, TASK_PENDING);
}


static irqreturn_t alx_msix_ring(int irq, void *data)
{
	struct alx_napi *np = data;
	struct alx_adapter *adpt = np->adpt;
	struct alx_hw *hw = &adpt->hw;

	/* mask interrupt to ACK chip */
	alx_mask_msix(hw, np->vec_idx, true);
	/* clear interrutp status */
	ALX_MEM_W32(hw, ALX_ISR, np->vec_mask);

	if (!ALX_FLAG(adpt, HALT))
		napi_schedule(&np->napi);

	return IRQ_HANDLED;
}

static inline bool alx_handle_intr_misc(struct alx_adapter *adpt, u32 intr)
{
	struct alx_hw *hw = &adpt->hw;

	if (unlikely(intr & ALX_ISR_FATAL)) {
		netif_info(adpt, hw, adpt->netdev,
			   "intr-fatal:%08X\n", intr);
		ALX_FLAG_SET(adpt, TASK_RESET);
		alx_schedule_work(adpt);
		return true;
	}

	if (intr & ALX_ISR_ALERT)
		netdev_warn(adpt->netdev, "interrutp alert :%x\n", intr);

	if (intr & ALX_ISR_SMB) {
		ALX_FLAG_SET(adpt, TASK_UPDATE_SMB);
		alx_schedule_work(adpt);
	}

	if (intr & ALX_ISR_PHY) {
		/* suppress PHY interrupt, because the source
		 * is from PHY internal. only the internal status
		 * is cleared, the interrupt status could be cleared.
		 */
		hw->imask &= ~ALX_ISR_PHY;
		ALX_MEM_W32(hw, ALX_IMR, hw->imask);
		ALX_FLAG_SET(adpt, TASK_CHK_LINK);
		alx_schedule_work(adpt);
	}

	return false;
}

static irqreturn_t alx_intr_msix_misc(int irq, void *data)
{
	struct alx_adapter *adpt = data;
	struct alx_hw *hw = &adpt->hw;
	u32 intr;

	/* mask interrupt to ACK chip */
	alx_mask_msix(hw, 0, true);

	/* read interrupt status */
	ALX_MEM_R32(hw, ALX_ISR, &intr);
	intr &= (hw->imask & ~ALX_ISR_ALL_QUEUES);

	if (alx_handle_intr_misc(adpt, intr))
		return IRQ_HANDLED;

	/* clear interrupt status */
	ALX_MEM_W32(hw, ALX_ISR, intr);

	/* enable interrupt again */
	if (!ALX_FLAG(adpt, HALT))
		alx_mask_msix(hw, 0, false);

	return IRQ_HANDLED;
}

static inline irqreturn_t alx_intr_1(struct alx_adapter *adpt, u32 intr)
{
	struct alx_hw *hw = &adpt->hw;

	/* ACK interrupt */
	netif_info(adpt, intr, adpt->netdev,
		   "ACK interrupt: 0x%lx\n",
		   intr | ALX_ISR_DIS);
	ALX_MEM_W32(hw, ALX_ISR, intr | ALX_ISR_DIS);
	intr &= hw->imask;

	if (alx_handle_intr_misc(adpt, intr))
		return IRQ_HANDLED;

	if (intr & (ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0)) {
		napi_schedule(&adpt->qnapi[0]->napi);
		/* mask rx/tx interrupt, enable them when napi complete */
		hw->imask &= ~ALX_ISR_ALL_QUEUES;
		ALX_MEM_W32(hw, ALX_IMR, hw->imask);
	}

	ALX_MEM_W32(hw, ALX_ISR, 0);

	return IRQ_HANDLED;
}


static irqreturn_t alx_intr_msi(int irq, void *data)
{
	struct alx_adapter *adpt = data;
	u32 intr;

	/* read interrupt status */
	ALX_MEM_R32(&adpt->hw, ALX_ISR, &intr);

	return alx_intr_1(adpt, intr);
}

static irqreturn_t alx_intr_legacy(int irq, void *data)
{
	struct alx_adapter *adpt = data;
	struct alx_hw *hw = &adpt->hw;
	u32 intr;

	/* read interrupt status */
	ALX_MEM_R32(hw, ALX_ISR, &intr);
	if (intr & ALX_ISR_DIS || 0 == (intr & hw->imask)) {
		u32 mask;

		ALX_MEM_R32(hw, ALX_IMR, &mask);
		netif_info(adpt, intr, adpt->netdev,
			   "seems a wild interrupt, intr=%X, imask=%X, %X\n",
			   intr, hw->imask, mask);

		return IRQ_NONE;
	}

	return alx_intr_1(adpt, intr);
}


static int alx_poll(struct napi_struct *napi, int budget)
{
	struct alx_napi *np = container_of(napi, struct alx_napi, napi);
	struct alx_adapter *adpt = np->adpt;
	bool complete = true;

	netif_info(adpt, intr, adpt->netdev,
		   "alx_poll, budget(%d)\n",
		   budget);

	if (np->txq)
		complete = alx_clean_tx_irq(np->txq);
	if (np->rxq)
		complete &= alx_clean_rx_irq(np->rxq, budget);

	if (!complete)
		return budget;

	/* rx-packet finished, exit the polling mode */
	napi_complete(&np->napi);

	/* enable interrupt */
	if (!ALX_FLAG(adpt, HALT)) {
		struct alx_hw *hw = &adpt->hw;

		if (ALX_FLAG(adpt, USING_MSIX))
			alx_mask_msix(hw, np->vec_idx, false);
		else {
			/* TODO: need irq spinlock for imask ?? */
			hw->imask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0;
			ALX_MEM_W32(hw, ALX_IMR, hw->imask);
		}
		ALX_MEM_FLUSH(hw);
	}

	return 0;
}

static inline struct alx_tx_queue *alx_tx_queue_mapping(
			struct alx_adapter *adpt,
			struct sk_buff *skb)
{
	int index = skb_get_queue_mapping(skb);

	if (index >= adpt->nr_txq)
		index = index % adpt->nr_txq;

	return adpt->qnapi[index]->txq;
}

static inline int alx_tpd_req(struct sk_buff *skb)
{
	int num;

	num = skb_shinfo(skb)->nr_frags + 1;
	if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
		num++;

	return num;
}

/* get custom checksum offload params
 * return val:
 *     neg-val: drop this skb
 *     0: no custom checksum offload
 *     pos-val: have custom cksum offload
 */
static int alx_tx_csum(struct sk_buff *skb, struct tpd_desc *first)
{
	u8 cso, css;

	if (skb->ip_summed != CHECKSUM_PARTIAL)
		return 0;

	cso = skb_checksum_start_offset(skb);
	if (cso & 0x1)
		return -1;

	css = cso + skb->csum_offset;
	first->word1 |= FIELDX(TPD_CXSUMSTART, cso >> 1);
	first->word1 |= FIELDX(TPD_CXSUMOFFSET, css >> 1);
	first->word1 |= 1 << TPD_CXSUM_EN_SHIFT;

	return 1;
}

static int alx_tso(struct sk_buff *skb, struct tpd_desc *first)
{
	int hdr_len;
	int err;

	if (skb->ip_summed != CHECKSUM_PARTIAL ||
	    !skb_is_gso(skb))
		return 0;

	if (skb_header_cloned(skb)) {
		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
		if (unlikely(err))
			return err;
	}

	if (skb->protocol == htons(ETH_P_IP)) {
		struct iphdr *iph;

		iph = ip_hdr(skb);
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
		iph->check = 0;
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(
						iph->saddr,
						iph->daddr,
						0, IPPROTO_TCP, 0);
		first->word1 |= 1 << TPD_IPV4_SHIFT;
		first->word1 |= FIELDX(TPD_L4HDROFFSET,
				       skb_transport_offset(skb));
		if (unlikely(skb->len == hdr_len)) {
			/* no tcp payload */
			first->word1 |= 1 << TPD_IP_XSUM_SHIFT;
			first->word1 |= 1 << TPD_TCP_XSUM_SHIFT;
			return 0;
		}
		first->word1 |= 1 << TPD_LSO_EN_SHIFT;
		first->word1 |= FIELDX(TPD_MSS, skb_shinfo(skb)->gso_size);
	} else if (skb_is_gso_v6(skb)) {
		struct ipv6hdr *ip6h;

		ip6h = ipv6_hdr(skb);
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
		ip6h->payload_len = 0;
		tcp_hdr(skb)->check = ~csum_ipv6_magic(
						&ip6h->saddr,
						&ip6h->daddr,
						0, IPPROTO_TCP, 0);
		first->word1 |= FIELDX(TPD_L4HDROFFSET,
				       skb_transport_offset(skb));
		if (unlikely(skb->len == hdr_len)) {
			/* no tcp payload */
			ip6h->payload_len = skb->len -
				((unsigned char *)ip6h - skb->data) -
				sizeof(struct ipv6hdr);
			first->word1 |= 1 << TPD_IP_XSUM_SHIFT;
			first->word1 |= 1 << TPD_TCP_XSUM_SHIFT;
			return 0;
		}
		/* for LSOv2, the 1st TPD just provides packet length */
		first->adrl.l.pkt_len = skb->len;
		first->word1 |= 1 << TPD_LSO_EN_SHIFT;
		first->word1 |= 1 << TPD_LSO_V2_SHIFT;
		first->word1 |= FIELDX(TPD_MSS, skb_shinfo(skb)->gso_size);
	}

	return 1;
}

static int alx_tx_map(struct alx_tx_queue *txq, struct sk_buff *skb)
{
	struct tpd_desc *tpd, *first_tpd;
	struct alx_buffer *buf, *first_buf;
	dma_addr_t dma;
	u16 producer, maplen, f;

	producer = txq->pidx;

	first_tpd = txq->tpd_hdr + producer;
	first_buf = txq->bf_info + producer;
	tpd = first_tpd;
	buf = first_buf;
	if (tpd->word1 & (1 << TPD_LSO_V2_SHIFT)) {
		if (++producer == txq->count)
			producer = 0;
		tpd = txq->tpd_hdr + producer;
		buf = txq->bf_info + producer;
		tpd->word0 = first_tpd->word0;
		tpd->word1 = first_tpd->word1;
	}
	maplen = skb_headlen(skb);
	dma = dma_map_single(txq->dev, skb->data, maplen, DMA_TO_DEVICE);
	if (dma_mapping_error(txq->dev, dma))
		goto err_dma;

	dma_unmap_len_set(buf, size, maplen);
	dma_unmap_addr_set(buf, dma, dma);

	tpd->adrl.addr = cpu_to_le64(dma);
	FIELD_SET32(tpd->word0, TPD_BUFLEN, maplen);

	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
		struct skb_frag_struct *frag;

		frag = &skb_shinfo(skb)->frags[f];
		if (++producer == txq->count)
			producer = 0;
		tpd = txq->tpd_hdr + producer;
		buf = txq->bf_info + producer;
		tpd->word0 = first_tpd->word0;
		tpd->word1 = first_tpd->word1;
		maplen = skb_frag_size(frag);
		dma = skb_frag_dma_map(txq->dev, frag, 0,
				       maplen, DMA_TO_DEVICE);
		if (dma_mapping_error(txq->dev, dma))
			goto err_dma;
		dma_unmap_len_set(buf, size, maplen);
		dma_unmap_addr_set(buf, dma, dma);

		tpd->adrl.addr = cpu_to_le64(dma);
		FIELD_SET32(tpd->word0, TPD_BUFLEN, maplen);
	}
	/* last TPD */
	tpd->word1 |= 1 << TPD_EOP_SHIFT;

	if (++producer == txq->count)
		producer = 0;

	first_buf->flags |= ALX_BUF_TX_FIRSTFRAG;
	buf->skb = skb;
	txq->pidx = producer;

	return 0;

err_dma:

	for (f = txq->pidx; f != producer;) {
		alx_txbuf_unmap_and_free(txq, f);
		if (++f == txq->count)
			f = 0;
	}
	return -1;
}

static netdev_tx_t alx_start_xmit_ring(struct alx_tx_queue *txq,
				       struct sk_buff *skb)
{
	struct alx_adapter *adpt;
	struct netdev_queue *netque;
	struct tpd_desc *first;
	int budget, tpdreq;
	int do_tso;

	adpt = netdev_priv(txq->netdev);
	netque = netdev_get_tx_queue(txq->netdev, skb_get_queue_mapping(skb));

	tpdreq = alx_tpd_req(skb);
	budget = alx_tpd_avail(txq);

	if (unlikely(budget < tpdreq)) {
		if (!netif_tx_queue_stopped(netque)) {
			netif_tx_stop_queue(netque);

			/* TX reclaim might have plenty of free TPD
			 * but see tx_queue is active (because its
			 * judement doesn't acquire tx-spin-lock,
			 * this situation cause the TX-queue stop and
			 * never be wakeup.
			 * try one more time
			 */
			budget = alx_tpd_avail(txq);
			if (budget >= tpdreq) {
				netif_tx_wake_queue(netque);
				goto tx_conti;
			}
			netif_err(adpt, tx_err, adpt->netdev,
				  "TPD Ring is full when queue awake!\n");
		}
		return NETDEV_TX_BUSY;
	}

tx_conti:

	first = txq->tpd_hdr + txq->pidx;
	memset(first, 0, sizeof(struct tpd_desc));

	/* NOTE, chip only supports single-VLAN insertion (81-00-TAG) */
	if (vlan_tx_tag_present(skb)) {
		first->word1 |= 1 << TPD_INS_VLTAG_SHIFT;
		first->word0 |= FIELDX(TPD_VLTAG, htons(vlan_tx_tag_get(skb)));
	}
	if (skb->protocol == htons(ETH_P_8021Q))
		first->word1 |= 1 << TPD_VLTAGGED_SHIFT;
	if (skb_network_offset(skb) != ETH_HLEN)
		first->word1 |= 1 << TPD_ETHTYPE_SHIFT;

	do_tso = alx_tso(skb, first);
	if (do_tso < 0)
		goto drop;
	else if (!do_tso && alx_tx_csum(skb, first) < 0)
		goto drop;

	if (alx_tx_map(txq, skb) < 0)
		goto drop;

	netdev_tx_sent_queue(netque, skb->len);

	/* refresh produce idx on HW */
	wmb();
	ALX_MEM_W16(&adpt->hw, txq->p_reg, txq->pidx);

	netif_info(adpt, tx_done, adpt->netdev,
		   "TX[Preg:%X]: producer = 0x%x, consumer = 0x%x\n",
		   txq->p_reg, txq->pidx, atomic_read(&txq->cidx));

	return NETDEV_TX_OK;

drop:
	netif_info(adpt, tx_done, adpt->netdev,
		   "tx-skb(%d) dropped\n",
		   skb->len);
	memset(first, 0, sizeof(struct tpd_desc));
	dev_kfree_skb(skb);

	return NETDEV_TX_OK;
}

static netdev_tx_t alx_start_xmit(struct sk_buff *skb,
				  struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);

	if (ALX_FLAG(adpt, HALT)) {
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}

	if (skb->len <= 0) {
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}

	return alx_start_xmit_ring(alx_tx_queue_mapping(adpt, skb), skb);
}


static void alx_dump_state(struct alx_adapter *adpt)
{
	struct alx_hw *hw = &adpt->hw;
	struct alx_tx_queue *txq;
	struct tpd_desc *tpd;
	u16 begin, end;
	int i;

	for (i = 0; i < adpt->nr_txq; i++) {

		txq = adpt->qnapi[i]->txq;
		begin = txq->pidx >=  8 ? (txq->pidx - 8) :
				(txq->count + txq->pidx - 8);
		end = txq->pidx + 4;
		if (end >= txq->count)
			end -= txq->count;

		netif_err(adpt, tx_err, adpt->netdev,
			  "-----------------TPD-ring(%d)------------------\n",
			  i);

		while (begin != end) {
			tpd = txq->tpd_hdr + begin;
			netif_err(adpt, tx_err, adpt->netdev,
				  "%X: W0=%08X, W1=%08X, W2=%X\n",
				  begin, tpd->word0, tpd->word1,
				  tpd->adrl.l.pkt_len);
			if (++begin >= txq->count)
				begin = 0;
		}
	}

	netif_err(adpt, tx_err, adpt->netdev,
		  "---------------dump registers-----------------\n");
	end = 0x1800;
	for (begin = 0x1400; begin < end; begin += 16) {
		u32 v1, v2, v3, v4;

		ALX_MEM_R32(hw, begin, &v1);
		ALX_MEM_R32(hw, begin+4, &v2);
		ALX_MEM_R32(hw, begin+8, &v3);
		ALX_MEM_R32(hw, begin+12, &v4);
		netif_err(adpt, tx_err, adpt->netdev,
			  "%04X: %08X,%08X,%08X,%08X\n",
			  begin, v1, v2, v3, v4);
	}
}

static void alx_tx_timeout(struct net_device *dev)
{
	struct alx_adapter *adpt = netdev_priv(dev);

	alx_dump_state(adpt);

	ALX_FLAG_SET(adpt, TASK_RESET);
	alx_schedule_work(adpt);
}

static int alx_mdio_read(struct net_device *netdev,
			 int prtad, int devad, u16 addr)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	struct alx_hw *hw = &adpt->hw;
	u16 val;
	int err;

	netif_dbg(adpt, hw, netdev,
		  "alx_mdio_read, prtad=%d, devad=%d, addr=%X\n",
		  prtad, devad, addr);

	if (prtad != hw->mdio.prtad)
		return -EINVAL;

	if (devad != MDIO_DEVAD_NONE)
		err = alx_read_phy_ext(hw, devad, addr, &val);
	else
		err = alx_read_phy_reg(hw, addr, &val);

	return err ? -EIO : val;
}

static int alx_mdio_write(struct net_device *netdev,
			  int prtad, int devad, u16 addr, u16 val)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	struct alx_hw *hw = &adpt->hw;
	int err;

	netif_dbg(adpt, hw, netdev,
		  "alx_mdio_write: prtad=%d, devad=%d, addr=%X, val=%X\n",
		  prtad, devad, addr, val);

	if (prtad != hw->mdio.prtad)
		return -EINVAL;

	if (devad != MDIO_DEVAD_NONE)
		err = alx_write_phy_ext(hw, devad, addr, val);
	else
		err = alx_write_phy_reg(hw, addr, val);

	return err ? -EIO : 0;
}

static int alx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
	struct alx_adapter *adpt = netdev_priv(netdev);

	if (!netif_running(netdev))
		return -EAGAIN;

	return mdio_mii_ioctl(&adpt->hw.mdio, if_mii(ifr), cmd);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void alx_poll_controller(struct net_device *netdev)
{
	struct alx_adapter *adpt = netdev_priv(netdev);
	int i;

	if (ALX_FLAG(adpt, HALT))
		return;

	if (ALX_FLAG(adpt, USING_MSIX)) {
		alx_intr_msix_misc(0, adpt);
		for (i = 0; i < adpt->nr_napi; i++)
			alx_msix_ring(0, adpt->qnapi[i]);
	} else if (ALX_FLAG(adpt, USING_MSI))
		alx_intr_msi(0, adpt);
	else
		alx_intr_legacy(0, adpt);

}
#endif

static const struct net_device_ops alx_netdev_ops = {
	.ndo_open               = alx_open,
	.ndo_stop               = alx_stop,
	.ndo_start_xmit         = alx_start_xmit,
	.ndo_get_stats          = alx_get_stats,
	.ndo_set_rx_mode        = alx_set_rx_mode,
	.ndo_validate_addr      = eth_validate_addr,
	.ndo_set_mac_address    = alx_set_mac_address,
	.ndo_change_mtu         = alx_change_mtu,
	.ndo_do_ioctl           = alx_ioctl,
	.ndo_tx_timeout         = alx_tx_timeout,
	.ndo_fix_features	= alx_fix_features,
	.ndo_set_features	= alx_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller    = alx_poll_controller,
#endif
};

/* alx_probe - Device Initialization Routine */
static int
alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *netdev;
	struct alx_adapter *adpt = NULL;
	struct alx_hw *hw;
	bool phy_cfged;
	int bars, pm_cap, err;
	static int cards_found;

	/* enable device (incl. PCI PM wakeup and hotplug setup) */
	err = pci_enable_device_mem(pdev);
	if (err) {
		dev_err(&pdev->dev, "cannot enable PCI device memory\n");
		return err;
	}

	/* The alx chip can DMA to 64-bit addresses, but it uses a single
	 * shared register for the high 32 bits, so only a single, aligned,
	 * 4 GB physical address range can be used at a time.
	 */
	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
	    !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
		dev_dbg(&pdev->dev, "DMA to 64-BIT addresses\n");
	} else {
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
		if (err) {
			err = dma_set_coherent_mask(&pdev->dev,
						    DMA_BIT_MASK(32));
			if (err) {
				dev_err(&pdev->dev,
					"No usable DMA config, aborting\n");
				goto err_dma_mask;
			}
		}
	}

	/* obtain PCI resources */
	bars = pci_select_bars(pdev, IORESOURCE_MEM);
	err = pci_request_selected_regions(pdev, bars, alx_drv_name);
	if (err) {
		dev_err(&pdev->dev,
			"pci_request_selected_regions failed(bars:%d)\n", bars);
		goto err_pci_region;
	}

	pci_enable_pcie_error_reporting(pdev);
	pci_set_master(pdev);

	/* find PM capability */
	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
	if (pm_cap == 0) {
		dev_err(&pdev->dev,
			"Can't find power management capability, aborting\n");
		err = -EIO;
		goto err_pm;
	}
	err = pci_set_power_state(pdev, PCI_D0);
	if (err) {
		dev_err(&pdev->dev, "switch to D0 status failed, aborting\n");
		goto err_pm;
	}

	/* netdev zeroed in init_etherdev */
	netdev = alloc_etherdev_mqs(sizeof(struct alx_adapter),
				    ALX_MAX_TX_QUEUES,
				    ALX_MAX_RX_QUEUES);
	if (!netdev) {
		dev_err(&pdev->dev, "etherdev_mq alloc failed\n");
		err = -ENOMEM;
		goto err_alloc_ethdev;
	}

	SET_NETDEV_DEV(netdev, &pdev->dev);
	adpt = netdev_priv(netdev);
	adpt->netdev = netdev;
	adpt->pdev = pdev;
	adpt->msg_enable = NETIF_MSG_LINK |
			   NETIF_MSG_HW |
			   NETIF_MSG_IFUP |
			   NETIF_MSG_TX_ERR |
			   NETIF_MSG_RX_ERR |
			   NETIF_MSG_WOL;
	adpt->bd_number = cards_found;
	hw = &adpt->hw;
	hw->pdev = pdev;
	pci_set_drvdata(pdev, adpt);

	hw->hw_addr = pci_ioremap_bar(pdev, 0);
	if (!hw->hw_addr) {
		dev_err(&pdev->dev, "cannot map device registers\n");
		err = -EIO;
		goto err_iomap;
	}

	netdev->netdev_ops = &alx_netdev_ops;
	alx_set_ethtool_ops(netdev);
	netdev->irq  = pdev->irq;
	netdev->watchdog_timeo = ALX_WATCHDOG_TIME;

	/* init alx_adapte structure */
	err = alx_init_sw(adpt);
	if (err) {
		dev_err(&pdev->dev, "net device private data init failed\n");
		goto err_init_sw;
	}

	/* reset pcie */
	alx_reset_pcie(hw);

	/* check if phy already configed by ohter driver */
	phy_cfged = alx_phy_configed(hw);

	/* reset PHY to a known stable status */
	if (!phy_cfged)
		alx_reset_phy(hw, !hw->hib_patch);
	else
		dev_info(&pdev->dev, "PHY has been configured.\n");

	/* reset mac/dma controller */
	err = alx_reset_mac(hw);
	if (err) {
		dev_err(&pdev->dev, "MAC Reset failed, error = %d\n", err);
		err = -EIO;
		goto err_rst_mac;
	}

	/* setup link to put it in a known good starting state */
	if (!phy_cfged) {
		err = alx_setup_speed_duplex(hw,
			hw->adv_cfg, hw->flowctrl);
		if (err) {
			dev_err(&pdev->dev,
				"config PHY speed/duplex failed,err=%d\n",
				err);
			err = -EIO;
			goto err_setup_link;
		}
	}

	netdev->hw_features = NETIF_F_SG	 |
			      NETIF_F_HW_CSUM	 |
			      NETIF_F_HW_VLAN_RX |
			      NETIF_F_TSO        |
			      NETIF_F_TSO6;
	netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX;

	/* read permanent mac addr from register or eFuse */
	if (alx_get_perm_macaddr(hw, hw->perm_addr)) {
		dev_warn(&pdev->dev, "invalid perm-address, use random one\n");
		eth_hw_addr_random(netdev);
		memcpy(hw->perm_addr, netdev->dev_addr, netdev->addr_len);
	}
	/* using permanent address as current address */
	memcpy(hw->mac_addr, hw->perm_addr, ETH_ALEN);
	memcpy(netdev->dev_addr, hw->mac_addr, ETH_ALEN);
	memcpy(netdev->perm_addr, hw->perm_addr, ETH_ALEN);

	/* PHY mdio */
	hw->mdio.prtad = 0;
	hw->mdio.mmds = 0;
	hw->mdio.dev = netdev;
	hw->mdio.mode_support =
		MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22 | MDIO_EMULATE_C22;
	hw->mdio.mdio_read = alx_mdio_read;
	hw->mdio.mdio_write = alx_mdio_write;
	if (!alx_get_phy_info(hw)) {
		dev_err(&pdev->dev, "identify PHY failed\n");
		err = -EIO;
		goto err_id_phy;
	}

	INIT_WORK(&adpt->task, alx_task);

	err = register_netdev(netdev);
	if (err) {
		dev_err(&pdev->dev, "register netdevice failed\n");
		goto err_register_netdev;
	}

	/* carrier off reporting is important to ethtool even BEFORE open */
	netif_carrier_off(netdev);

	device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl);
	cards_found++;

	dev_info(&pdev->dev,
		 "alx(%pM): Qualcomm Atheros Ethernet Network Connection\n",
		 netdev->dev_addr);

	return 0;

err_id_phy:
err_register_netdev:
err_setup_link:
err_rst_mac:
err_init_sw:
	iounmap(hw->hw_addr);
err_iomap:
	free_netdev(netdev);
err_alloc_ethdev:
err_pm:
	pci_release_selected_regions(pdev, bars);
err_pci_region:
err_dma_mask:
	pci_disable_device(pdev);
	dev_err(&pdev->dev, "error when probe device, error = %d\n", err);
	return err;
}

/* alx_remove - Device Removal Routine */
static void alx_remove(struct pci_dev *pdev)
{
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct alx_hw *hw = &adpt->hw;
	struct net_device *netdev;

	if (!adpt)
		return;

	netdev = adpt->netdev;

	ALX_FLAG_SET(adpt, HALT);
	alx_cancel_work(adpt);

	/* restore permanent mac address */
	alx_set_macaddr(hw, hw->perm_addr);

	unregister_netdev(netdev);
	iounmap(hw->hw_addr);
	pci_release_selected_regions(pdev,
				     pci_select_bars(pdev, IORESOURCE_MEM));
	free_netdev(netdev);
	pci_disable_pcie_error_reporting(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
}

/* alx_pci_error_detected */
static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev,
					       pci_channel_state_t state)
{
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct net_device *netdev = adpt->netdev;
	pci_ers_result_t rc = PCI_ERS_RESULT_NEED_RESET;

	dev_info(&pdev->dev, "pci error detected\n");

	rtnl_lock();

	if (netif_running(netdev)) {
		netif_device_detach(netdev);
		alx_halt(adpt);
	}
	if (state == pci_channel_io_perm_failure)
		rc = PCI_ERS_RESULT_DISCONNECT;
	else
		pci_disable_device(pdev);

	rtnl_unlock();

	return rc;
}

/* alx_pci_error_slot_reset */
static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
{
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct alx_hw *hw = &adpt->hw;
	pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;

	dev_info(&pdev->dev, "pci error slot reset\n");

	rtnl_lock();

	if (pci_enable_device(pdev)) {
		dev_err(&pdev->dev, "Re-enable PCI device after reset fail\n");
		goto out;
	}

	pci_set_master(pdev);
	pci_enable_wake(pdev, PCI_D3hot, 0);
	pci_enable_wake(pdev, PCI_D3cold, 0);

	alx_reset_pcie(hw);
	if (!alx_reset_mac(hw))
		rc = PCI_ERS_RESULT_RECOVERED;
out:
	pci_cleanup_aer_uncorrect_error_status(pdev);

	rtnl_unlock();

	return rc;
}

/* alx_pci_error_resume */
static void alx_pci_error_resume(struct pci_dev *pdev)
{
	struct alx_adapter *adpt = pci_get_drvdata(pdev);
	struct net_device *netdev = adpt->netdev;

	dev_info(&pdev->dev, "pci error resume\n");

	rtnl_lock();

	if (netif_running(netdev)) {
		alx_activate(adpt);
		netif_device_attach(netdev);
	}

	rtnl_unlock();
}


static struct pci_error_handlers alx_err_handler = {
	.error_detected = alx_pci_error_detected,
	.slot_reset     = alx_pci_error_slot_reset,
	.resume         = alx_pci_error_resume,
};

#ifdef CONFIG_PM_SLEEP
static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
#define ALX_PM_OPS      (&alx_pm_ops)
#else
#define ALX_PM_OPS      NULL
#endif

static struct pci_driver alx_driver = {
	.name        = alx_drv_name,
	.id_table    = alx_pci_tbl,
	.probe       = alx_probe,
	.remove      = alx_remove,
	.shutdown    = alx_shutdown,
	.err_handler = &alx_err_handler,
	.driver.pm   = ALX_PM_OPS,
};


static int __init alx_init_module(void)
{
	pr_info("%s\n", alx_drv_desc);
	return pci_register_driver(&alx_driver);
}
module_init(alx_init_module);

static void __exit alx_exit_module(void)
{
	pci_unregister_driver(&alx_driver);
}
module_exit(alx_exit_module);
