提交 c6060be4 编写于 作者: J Jie Yang 提交者: David S. Miller

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: NJie Yang <jie.yang@atheros.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d3bcfefa
...@@ -470,12 +470,28 @@ struct atl1c_ring_header { ...@@ -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 */
......
...@@ -710,6 +710,29 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) ...@@ -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,22 +748,12 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, ...@@ -725,22 +748,12 @@ 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 */
memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
ring_count); ring_count);
atomic_set(&tpd_ring->next_to_clean, 0); atomic_set(&tpd_ring->next_to_clean, 0);
tpd_ring->next_to_use = 0; tpd_ring->next_to_use = 0;
} }
...@@ -760,16 +773,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册