aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJie Yang <jie.yang@atheros.com>2009-11-06 03:32:05 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-07 03:46:35 -0500
commitc6060be46fbda5af651b6ed2b85502ccbb3d9279 (patch)
tree89ef8caaecd190a6ab29e38b78382775589e4050
parentd3bcfefaca27c1bfc8f740f5fff5b25d52ed1211 (diff)
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: Jie Yang <jie.yang@atheros.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/atl1c/atl1c.h22
-rw-r--r--drivers/net/atl1c/atl1c_main.c84
2 files changed, 61 insertions, 45 deletions
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
index 2a1120ad2e74..a348a22551d9 100644
--- a/drivers/net/atl1c/atl1c.h
+++ b/drivers/net/atl1c/atl1c.h
@@ -470,12 +470,28 @@ struct atl1c_ring_header {
470struct atl1c_buffer { 470struct atl1c_buffer {
471 struct sk_buff *skb; /* socket buffer */ 471 struct sk_buff *skb; /* socket buffer */
472 u16 length; /* rx buffer length */ 472 u16 length; /* rx buffer length */
473 u16 state; /* state of buffer */ 473 u16 flags; /* information of buffer */
474#define ATL1_BUFFER_FREE 0 474#define ATL1C_BUFFER_FREE 0x0001
475#define ATL1_BUFFER_BUSY 1 475#define ATL1C_BUFFER_BUSY 0x0002
476#define ATL1C_BUFFER_STATE_MASK 0x0003
477
478#define ATL1C_PCIMAP_SINGLE 0x0004
479#define ATL1C_PCIMAP_PAGE 0x0008
480#define ATL1C_PCIMAP_TYPE_MASK 0x000C
481
476 dma_addr_t dma; 482 dma_addr_t dma;
477}; 483};
478 484
485#define ATL1C_SET_BUFFER_STATE(buff, state) do { \
486 ((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK; \
487 ((buff)->flags) |= (state); \
488 } while (0)
489
490#define ATL1C_SET_PCIMAP_TYPE(buff, type) do { \
491 ((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK; \
492 ((buff)->flags) |= (type); \
493 } while (0)
494
479/* transimit packet descriptor (tpd) ring */ 495/* transimit packet descriptor (tpd) ring */
480struct atl1c_tpd_ring { 496struct atl1c_tpd_ring {
481 void *desc; /* descriptor ring virtual address */ 497 void *desc; /* descriptor ring virtual address */
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 3b8801a39726..5ef9e23435f4 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -710,6 +710,29 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
710 return 0; 710 return 0;
711} 711}
712 712
713static inline void atl1c_clean_buffer(struct pci_dev *pdev,
714 struct atl1c_buffer *buffer_info, int in_irq)
715{
716 if (buffer_info->flags & ATL1C_BUFFER_FREE)
717 return;
718 if (buffer_info->dma) {
719 if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
720 pci_unmap_single(pdev, buffer_info->dma,
721 buffer_info->length, PCI_DMA_TODEVICE);
722 else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
723 pci_unmap_page(pdev, buffer_info->dma,
724 buffer_info->length, PCI_DMA_TODEVICE);
725 }
726 if (buffer_info->skb) {
727 if (in_irq)
728 dev_kfree_skb_irq(buffer_info->skb);
729 else
730 dev_kfree_skb(buffer_info->skb);
731 }
732 buffer_info->dma = 0;
733 buffer_info->skb = NULL;
734 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
735}
713/* 736/*
714 * atl1c_clean_tx_ring - Free Tx-skb 737 * atl1c_clean_tx_ring - Free Tx-skb
715 * @adapter: board private structure 738 * @adapter: board private structure
@@ -725,22 +748,12 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
725 ring_count = tpd_ring->count; 748 ring_count = tpd_ring->count;
726 for (index = 0; index < ring_count; index++) { 749 for (index = 0; index < ring_count; index++) {
727 buffer_info = &tpd_ring->buffer_info[index]; 750 buffer_info = &tpd_ring->buffer_info[index];
728 if (buffer_info->state == ATL1_BUFFER_FREE) 751 atl1c_clean_buffer(pdev, buffer_info, 0);
729 continue;
730 if (buffer_info->dma)
731 pci_unmap_single(pdev, buffer_info->dma,
732 buffer_info->length,
733 PCI_DMA_TODEVICE);
734 if (buffer_info->skb)
735 dev_kfree_skb(buffer_info->skb);
736 buffer_info->dma = 0;
737 buffer_info->skb = NULL;
738 buffer_info->state = ATL1_BUFFER_FREE;
739 } 752 }
740 753
741 /* Zero out Tx-buffers */ 754 /* Zero out Tx-buffers */
742 memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * 755 memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
743 ring_count); 756 ring_count);
744 atomic_set(&tpd_ring->next_to_clean, 0); 757 atomic_set(&tpd_ring->next_to_clean, 0);
745 tpd_ring->next_to_use = 0; 758 tpd_ring->next_to_use = 0;
746} 759}
@@ -760,16 +773,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
760 for (i = 0; i < adapter->num_rx_queues; i++) { 773 for (i = 0; i < adapter->num_rx_queues; i++) {
761 for (j = 0; j < rfd_ring[i].count; j++) { 774 for (j = 0; j < rfd_ring[i].count; j++) {
762 buffer_info = &rfd_ring[i].buffer_info[j]; 775 buffer_info = &rfd_ring[i].buffer_info[j];
763 if (buffer_info->state == ATL1_BUFFER_FREE) 776 atl1c_clean_buffer(pdev, buffer_info, 0);
764 continue;
765 if (buffer_info->dma)
766 pci_unmap_single(pdev, buffer_info->dma,
767 buffer_info->length,
768 PCI_DMA_FROMDEVICE);
769 if (buffer_info->skb)
770 dev_kfree_skb(buffer_info->skb);
771 buffer_info->state = ATL1_BUFFER_FREE;
772 buffer_info->skb = NULL;
773 } 777 }
774 /* zero out the descriptor ring */ 778 /* zero out the descriptor ring */
775 memset(rfd_ring[i].desc, 0, rfd_ring[i].size); 779 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 atomic_set(&tpd_ring[i].next_to_clean, 0); 800 atomic_set(&tpd_ring[i].next_to_clean, 0);
797 buffer_info = tpd_ring[i].buffer_info; 801 buffer_info = tpd_ring[i].buffer_info;
798 for (j = 0; j < tpd_ring->count; j++) 802 for (j = 0; j < tpd_ring->count; j++)
799 buffer_info[i].state = ATL1_BUFFER_FREE; 803 ATL1C_SET_BUFFER_STATE(&buffer_info[i],
804 ATL1C_BUFFER_FREE);
800 } 805 }
801 for (i = 0; i < adapter->num_rx_queues; i++) { 806 for (i = 0; i < adapter->num_rx_queues; i++) {
802 rfd_ring[i].next_to_use = 0; 807 rfd_ring[i].next_to_use = 0;
@@ -805,7 +810,7 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
805 rrd_ring[i].next_to_clean = 0; 810 rrd_ring[i].next_to_clean = 0;
806 for (j = 0; j < rfd_ring[i].count; j++) { 811 for (j = 0; j < rfd_ring[i].count; j++) {
807 buffer_info = &rfd_ring[i].buffer_info[j]; 812 buffer_info = &rfd_ring[i].buffer_info[j];
808 buffer_info->state = ATL1_BUFFER_FREE; 813 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
809 } 814 }
810 } 815 }
811} 816}
@@ -1447,6 +1452,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
1447 struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) 1452 struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
1448 &adapter->tpd_ring[type]; 1453 &adapter->tpd_ring[type];
1449 struct atl1c_buffer *buffer_info; 1454 struct atl1c_buffer *buffer_info;
1455 struct pci_dev *pdev = adapter->pdev;
1450 u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); 1456 u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
1451 u16 hw_next_to_clean; 1457 u16 hw_next_to_clean;
1452 u16 shift; 1458 u16 shift;
@@ -1462,16 +1468,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
1462 1468
1463 while (next_to_clean != hw_next_to_clean) { 1469 while (next_to_clean != hw_next_to_clean) {
1464 buffer_info = &tpd_ring->buffer_info[next_to_clean]; 1470 buffer_info = &tpd_ring->buffer_info[next_to_clean];
1465 if (buffer_info->state == ATL1_BUFFER_BUSY) { 1471 atl1c_clean_buffer(pdev, buffer_info, 1);
1466 pci_unmap_page(adapter->pdev, buffer_info->dma,
1467 buffer_info->length, PCI_DMA_TODEVICE);
1468 buffer_info->dma = 0;
1469 if (buffer_info->skb) {
1470 dev_kfree_skb_irq(buffer_info->skb);
1471 buffer_info->skb = NULL;
1472 }
1473 buffer_info->state = ATL1_BUFFER_FREE;
1474 }
1475 if (++next_to_clean == tpd_ring->count) 1472 if (++next_to_clean == tpd_ring->count)
1476 next_to_clean = 0; 1473 next_to_clean = 0;
1477 atomic_set(&tpd_ring->next_to_clean, next_to_clean); 1474 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 buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; 1584 buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
1588 next_info = &rfd_ring->buffer_info[next_next]; 1585 next_info = &rfd_ring->buffer_info[next_next];
1589 1586
1590 while (next_info->state == ATL1_BUFFER_FREE) { 1587 while (next_info->flags & ATL1C_BUFFER_FREE) {
1591 rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); 1588 rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
1592 1589
1593 skb = dev_alloc_skb(adapter->rx_buffer_len); 1590 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 * the 14 byte MAC header is removed 1600 * the 14 byte MAC header is removed
1604 */ 1601 */
1605 vir_addr = skb->data; 1602 vir_addr = skb->data;
1606 buffer_info->state = ATL1_BUFFER_BUSY; 1603 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
1607 buffer_info->skb = skb; 1604 buffer_info->skb = skb;
1608 buffer_info->length = adapter->rx_buffer_len; 1605 buffer_info->length = adapter->rx_buffer_len;
1609 buffer_info->dma = pci_map_single(pdev, vir_addr, 1606 buffer_info->dma = pci_map_single(pdev, vir_addr,
1610 buffer_info->length, 1607 buffer_info->length,
1611 PCI_DMA_FROMDEVICE); 1608 PCI_DMA_FROMDEVICE);
1609 ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
1612 rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); 1610 rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
1613 rfd_next_to_use = next_next; 1611 rfd_next_to_use = next_next;
1614 if (++next_next == rfd_ring->count) 1612 if (++next_next == rfd_ring->count)
@@ -1653,7 +1651,8 @@ static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
1653 RRS_RX_RFD_INDEX_MASK; 1651 RRS_RX_RFD_INDEX_MASK;
1654 for (i = 0; i < num; i++) { 1652 for (i = 0; i < num; i++) {
1655 buffer_info[rfd_index].skb = NULL; 1653 buffer_info[rfd_index].skb = NULL;
1656 buffer_info[rfd_index].state = ATL1_BUFFER_FREE; 1654 ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
1655 ATL1C_BUFFER_FREE);
1657 if (++rfd_index == rfd_ring->count) 1656 if (++rfd_index == rfd_ring->count)
1658 rfd_index = 0; 1657 rfd_index = 0;
1659 } 1658 }
@@ -1967,7 +1966,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
1967 buffer_info->length = map_len; 1966 buffer_info->length = map_len;
1968 buffer_info->dma = pci_map_single(adapter->pdev, 1967 buffer_info->dma = pci_map_single(adapter->pdev,
1969 skb->data, hdr_len, PCI_DMA_TODEVICE); 1968 skb->data, hdr_len, PCI_DMA_TODEVICE);
1970 buffer_info->state = ATL1_BUFFER_BUSY; 1969 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
1970 ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
1971 mapped_len += map_len; 1971 mapped_len += map_len;
1972 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); 1972 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
1973 use_tpd->buffer_len = cpu_to_le16(buffer_info->length); 1973 use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
@@ -1987,8 +1987,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
1987 buffer_info->dma = 1987 buffer_info->dma =
1988 pci_map_single(adapter->pdev, skb->data + mapped_len, 1988 pci_map_single(adapter->pdev, skb->data + mapped_len,
1989 buffer_info->length, PCI_DMA_TODEVICE); 1989 buffer_info->length, PCI_DMA_TODEVICE);
1990 buffer_info->state = ATL1_BUFFER_BUSY; 1990 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
1991 1991 ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE);
1992 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); 1992 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
1993 use_tpd->buffer_len = cpu_to_le16(buffer_info->length); 1993 use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
1994 } 1994 }
@@ -2008,8 +2008,8 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
2008 frag->page_offset, 2008 frag->page_offset,
2009 buffer_info->length, 2009 buffer_info->length,
2010 PCI_DMA_TODEVICE); 2010 PCI_DMA_TODEVICE);
2011 buffer_info->state = ATL1_BUFFER_BUSY; 2011 ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
2012 2012 ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE);
2013 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); 2013 use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
2014 use_tpd->buffer_len = cpu_to_le16(buffer_info->length); 2014 use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
2015 } 2015 }