Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6060be4 authored by Jie Yang's avatar Jie Yang Committed by David S. Miller
Browse files

atl1c: change atl1c_buffer struct and restructure clean atl1c_buffer procedure



change atl1c_buffer struct, use "u16 flags" instead of "u16 state"
to store more infomation for atl1c_buffer, and restructure clean
atl1c_buffer procedure, add common api atl1c_clean_buffer.

Signed-off-by: default avatarJie Yang <jie.yang@atheros.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d3bcfefa
Loading
Loading
Loading
Loading
+19 −3
Original line number Original line Diff line number Diff line
@@ -470,12 +470,28 @@ struct atl1c_ring_header {
struct atl1c_buffer {
struct atl1c_buffer {
	struct sk_buff *skb;	/* socket buffer */
	struct sk_buff *skb;	/* socket buffer */
	u16 length;		/* rx buffer length */
	u16 length;		/* rx buffer length */
	u16 state;		/* state of buffer */
	u16 flags;		/* information of buffer */
#define ATL1_BUFFER_FREE	0
#define ATL1C_BUFFER_FREE		0x0001
#define ATL1_BUFFER_BUSY	1
#define ATL1C_BUFFER_BUSY		0x0002
#define ATL1C_BUFFER_STATE_MASK		0x0003

#define ATL1C_PCIMAP_SINGLE		0x0004
#define ATL1C_PCIMAP_PAGE		0x0008
#define ATL1C_PCIMAP_TYPE_MASK		0x000C

	dma_addr_t dma;
	dma_addr_t dma;
};
};


#define ATL1C_SET_BUFFER_STATE(buff, state) do {	\
	((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK;	\
	((buff)->flags) |= (state);			\
	} while (0)

#define ATL1C_SET_PCIMAP_TYPE(buff, type) do {		\
	((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK;	\
	((buff)->flags) |= (type);			\
	} while (0)

/* transimit packet descriptor (tpd) ring */
/* transimit packet descriptor (tpd) ring */
struct atl1c_tpd_ring {
struct atl1c_tpd_ring {
	void *desc;		/* descriptor ring virtual address */
	void *desc;		/* descriptor ring virtual address */
+42 −42
Original line number Original line Diff line number Diff line
@@ -710,6 +710,29 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
	return 0;
	return 0;
}
}


static inline void atl1c_clean_buffer(struct pci_dev *pdev,
				struct atl1c_buffer *buffer_info, int in_irq)
{
	if (buffer_info->flags & ATL1C_BUFFER_FREE)
		return;
	if (buffer_info->dma) {
		if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
			pci_unmap_single(pdev, buffer_info->dma,
					buffer_info->length, PCI_DMA_TODEVICE);
		else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
			pci_unmap_page(pdev, buffer_info->dma,
					buffer_info->length, PCI_DMA_TODEVICE);
	}
	if (buffer_info->skb) {
		if (in_irq)
			dev_kfree_skb_irq(buffer_info->skb);
		else
			dev_kfree_skb(buffer_info->skb);
	}
	buffer_info->dma = 0;
	buffer_info->skb = NULL;
	ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
}
/*
/*
 * atl1c_clean_tx_ring - Free Tx-skb
 * atl1c_clean_tx_ring - Free Tx-skb
 * @adapter: board private structure
 * @adapter: board private structure
@@ -725,17 +748,7 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
	ring_count = tpd_ring->count;
	ring_count = tpd_ring->count;
	for (index = 0; index < ring_count; index++) {
	for (index = 0; index < ring_count; index++) {
		buffer_info = &tpd_ring->buffer_info[index];
		buffer_info = &tpd_ring->buffer_info[index];
		if (buffer_info->state == ATL1_BUFFER_FREE)
		atl1c_clean_buffer(pdev, buffer_info, 0);
			continue;
		if (buffer_info->dma)
			pci_unmap_single(pdev, buffer_info->dma,
					buffer_info->length,
					PCI_DMA_TODEVICE);
		if (buffer_info->skb)
			dev_kfree_skb(buffer_info->skb);
		buffer_info->dma = 0;
		buffer_info->skb = NULL;
		buffer_info->state = ATL1_BUFFER_FREE;
	}
	}


	/* Zero out Tx-buffers */
	/* Zero out Tx-buffers */
@@ -760,16 +773,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
	for (i = 0; i < adapter->num_rx_queues; i++) {
	for (i = 0; i < adapter->num_rx_queues; i++) {
		for (j = 0; j < rfd_ring[i].count; j++) {
		for (j = 0; j < rfd_ring[i].count; j++) {
			buffer_info = &rfd_ring[i].buffer_info[j];
			buffer_info = &rfd_ring[i].buffer_info[j];
			if (buffer_info->state == ATL1_BUFFER_FREE)
			atl1c_clean_buffer(pdev, buffer_info, 0);
				continue;
			if (buffer_info->dma)
				pci_unmap_single(pdev, buffer_info->dma,
						buffer_info->length,
						PCI_DMA_FROMDEVICE);
			if (buffer_info->skb)
				dev_kfree_skb(buffer_info->skb);
			buffer_info->state = ATL1_BUFFER_FREE;
			buffer_info->skb = NULL;
		}
		}
		/* zero out the descriptor ring */
		/* zero out the descriptor ring */
		memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
		memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
@@ -796,7 +800,8 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
		atomic_set(&tpd_ring[i].next_to_clean, 0);
		atomic_set(&tpd_ring[i].next_to_clean, 0);
		buffer_info = tpd_ring[i].buffer_info;
		buffer_info = tpd_ring[i].buffer_info;
		for (j = 0; j < tpd_ring->count; j++)
		for (j = 0; j < tpd_ring->count; j++)
			buffer_info[i].state = ATL1_BUFFER_FREE;
			ATL1C_SET_BUFFER_STATE(&buffer_info[i],
					ATL1C_BUFFER_FREE);
	}
	}
	for (i = 0; i < adapter->num_rx_queues; i++) {
	for (i = 0; i < adapter->num_rx_queues; i++) {
		rfd_ring[i].next_to_use = 0;
		rfd_ring[i].next_to_use = 0;
@@ -805,7 +810,7 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
		rrd_ring[i].next_to_clean = 0;
		rrd_ring[i].next_to_clean = 0;
		for (j = 0; j < rfd_ring[i].count; j++) {
		for (j = 0; j < rfd_ring[i].count; j++) {
			buffer_info = &rfd_ring[i].buffer_info[j];
			buffer_info = &rfd_ring[i].buffer_info[j];
			buffer_info->state = ATL1_BUFFER_FREE;
			ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
		}
		}
	}
	}
}
}
@@ -1447,6 +1452,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
	struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
	struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
				&adapter->tpd_ring[type];
				&adapter->tpd_ring[type];
	struct atl1c_buffer *buffer_info;
	struct atl1c_buffer *buffer_info;
	struct pci_dev *pdev = adapter->pdev;
	u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
	u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
	u16 hw_next_to_clean;
	u16 hw_next_to_clean;
	u16 shift;
	u16 shift;
@@ -1462,16 +1468,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,


	while (next_to_clean != hw_next_to_clean) {
	while (next_to_clean != hw_next_to_clean) {
		buffer_info = &tpd_ring->buffer_info[next_to_clean];
		buffer_info = &tpd_ring->buffer_info[next_to_clean];
		if (buffer_info->state == ATL1_BUFFER_BUSY) {
		atl1c_clean_buffer(pdev, buffer_info, 1);
			pci_unmap_page(adapter->pdev, buffer_info->dma,
					buffer_info->length, PCI_DMA_TODEVICE);
			buffer_info->dma = 0;
			if (buffer_info->skb) {
				dev_kfree_skb_irq(buffer_info->skb);
				buffer_info->skb = NULL;
			}
			buffer_info->state = ATL1_BUFFER_FREE;
		}
		if (++next_to_clean == tpd_ring->count)
		if (++next_to_clean == tpd_ring->count)
			next_to_clean = 0;
			next_to_clean = 0;
		atomic_set(&tpd_ring->next_to_clean, next_to_clean);
		atomic_set(&tpd_ring->next_to_clean, next_to_clean);
@@ -1587,7 +1584,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid
	buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
	buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
	next_info = &rfd_ring->buffer_info[next_next];
	next_info = &rfd_ring->buffer_info[next_next];


	while (next_info->state == ATL1_BUFFER_FREE) {
	while (next_info->flags & ATL1C_BUFFER_FREE) {
		rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
		rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);


		skb = dev_alloc_skb(adapter->rx_buffer_len);
		skb = dev_alloc_skb(adapter->rx_buffer_len);
@@ -1603,12 +1600,13 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid
		 * the 14 byte MAC header is removed
		 * the 14 byte MAC header is removed
		 */
		 */
		vir_addr = skb->data;
		vir_addr = skb->data;
		buffer_info->state = ATL1_BUFFER_BUSY;
		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
		buffer_info->skb = skb;
		buffer_info->skb = skb;
		buffer_info->length = adapter->rx_buffer_len;
		buffer_info->length = adapter->rx_buffer_len;
		buffer_info->dma = pci_map_single(pdev, vir_addr,
		buffer_info->dma = pci_map_single(pdev, vir_addr,
						buffer_info->length,
						buffer_info->length,
						PCI_DMA_FROMDEVICE);
						PCI_DMA_FROMDEVICE);
		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
		rfd_next_to_use = next_next;
		rfd_next_to_use = next_next;
		if (++next_next == rfd_ring->count)
		if (++next_next == rfd_ring->count)
@@ -1653,7 +1651,8 @@ static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
			RRS_RX_RFD_INDEX_MASK;
			RRS_RX_RFD_INDEX_MASK;
	for (i = 0; i < num; i++) {
	for (i = 0; i < num; i++) {
		buffer_info[rfd_index].skb = NULL;
		buffer_info[rfd_index].skb = NULL;
		buffer_info[rfd_index].state = ATL1_BUFFER_FREE;
		ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
					ATL1C_BUFFER_FREE);
		if (++rfd_index == rfd_ring->count)
		if (++rfd_index == rfd_ring->count)
			rfd_index = 0;
			rfd_index = 0;
	}
	}
@@ -1967,7 +1966,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
		buffer_info->length = map_len;
		buffer_info->length = map_len;
		buffer_info->dma = pci_map_single(adapter->pdev,
		buffer_info->dma = pci_map_single(adapter->pdev,
					skb->data, hdr_len, PCI_DMA_TODEVICE);
					skb->data, hdr_len, PCI_DMA_TODEVICE);
		buffer_info->state = ATL1_BUFFER_BUSY;
		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
		mapped_len += map_len;
		mapped_len += map_len;
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
		use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
@@ -1987,8 +1987,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
		buffer_info->dma =
		buffer_info->dma =
			pci_map_single(adapter->pdev, skb->data + mapped_len,
			pci_map_single(adapter->pdev, skb->data + mapped_len,
					buffer_info->length, PCI_DMA_TODEVICE);
					buffer_info->length, PCI_DMA_TODEVICE);
		buffer_info->state = ATL1_BUFFER_BUSY;
		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);

		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
	}
	}
@@ -2008,8 +2008,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
					frag->page_offset,
					frag->page_offset,
					buffer_info->length,
					buffer_info->length,
					PCI_DMA_TODEVICE);
					PCI_DMA_TODEVICE);
		buffer_info->state = ATL1_BUFFER_BUSY;
		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);

		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE);
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
	}
	}