diff options
-rw-r--r-- | drivers/net/atl1c/atl1c.h | 22 | ||||
-rw-r--r-- | drivers/net/atl1c/atl1c_main.c | 84 |
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 { | |||
470 | struct atl1c_buffer { | 470 | struct 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 */ |
480 | struct atl1c_tpd_ring { | 496 | struct 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 | ||
713 | static 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 | } |