diff options
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 1437b6e397bc..bc16fc082d95 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -1797,9 +1797,14 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
1797 | */ | 1797 | */ |
1798 | void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | 1798 | void nes_destroy_nic_qp(struct nes_vnic *nesvnic) |
1799 | { | 1799 | { |
1800 | u64 u64temp; | ||
1801 | dma_addr_t bus_address; | ||
1800 | struct nes_device *nesdev = nesvnic->nesdev; | 1802 | struct nes_device *nesdev = nesvnic->nesdev; |
1801 | struct nes_hw_cqp_wqe *cqp_wqe; | 1803 | struct nes_hw_cqp_wqe *cqp_wqe; |
1804 | struct nes_hw_nic_sq_wqe *nic_sqe; | ||
1802 | struct nes_hw_nic_rq_wqe *nic_rqe; | 1805 | struct nes_hw_nic_rq_wqe *nic_rqe; |
1806 | __le16 *wqe_fragment_length; | ||
1807 | u16 wqe_fragment_index; | ||
1803 | u64 wqe_frag; | 1808 | u64 wqe_frag; |
1804 | u32 cqp_head; | 1809 | u32 cqp_head; |
1805 | unsigned long flags; | 1810 | unsigned long flags; |
@@ -1808,14 +1813,69 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1808 | /* Free remaining NIC receive buffers */ | 1813 | /* Free remaining NIC receive buffers */ |
1809 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1814 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
1810 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1815 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
1811 | wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); | 1816 | wqe_frag = (u64)le32_to_cpu( |
1812 | wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; | 1817 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); |
1818 | wqe_frag |= ((u64)le32_to_cpu( | ||
1819 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX]))<<32; | ||
1813 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, | 1820 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, |
1814 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); | 1821 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); |
1815 | dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]); | 1822 | dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]); |
1816 | nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1); | 1823 | nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1); |
1817 | } | 1824 | } |
1818 | 1825 | ||
1826 | /* Free remaining NIC transmit buffers */ | ||
1827 | while (nesvnic->nic.sq_head != nesvnic->nic.sq_tail) { | ||
1828 | nic_sqe = &nesvnic->nic.sq_vbase[nesvnic->nic.sq_tail]; | ||
1829 | wqe_fragment_index = 1; | ||
1830 | wqe_fragment_length = (__le16 *) | ||
1831 | &nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX]; | ||
1832 | /* bump past the vlan tag */ | ||
1833 | wqe_fragment_length++; | ||
1834 | if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { | ||
1835 | u64temp = (u64)le32_to_cpu( | ||
1836 | nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+ | ||
1837 | wqe_fragment_index*2]); | ||
1838 | u64temp += ((u64)le32_to_cpu( | ||
1839 | nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX | ||
1840 | + wqe_fragment_index*2]))<<32; | ||
1841 | bus_address = (dma_addr_t)u64temp; | ||
1842 | if (test_and_clear_bit(nesvnic->nic.sq_tail, | ||
1843 | nesvnic->nic.first_frag_overflow)) { | ||
1844 | pci_unmap_single(nesdev->pcidev, | ||
1845 | bus_address, | ||
1846 | le16_to_cpu(wqe_fragment_length[ | ||
1847 | wqe_fragment_index++]), | ||
1848 | PCI_DMA_TODEVICE); | ||
1849 | } | ||
1850 | for (; wqe_fragment_index < 5; wqe_fragment_index++) { | ||
1851 | if (wqe_fragment_length[wqe_fragment_index]) { | ||
1852 | u64temp = le32_to_cpu( | ||
1853 | nic_sqe->wqe_words[ | ||
1854 | NES_NIC_SQ_WQE_FRAG0_LOW_IDX+ | ||
1855 | wqe_fragment_index*2]); | ||
1856 | u64temp += ((u64)le32_to_cpu( | ||
1857 | nic_sqe->wqe_words[ | ||
1858 | NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+ | ||
1859 | wqe_fragment_index*2]))<<32; | ||
1860 | bus_address = (dma_addr_t)u64temp; | ||
1861 | pci_unmap_page(nesdev->pcidev, | ||
1862 | bus_address, | ||
1863 | le16_to_cpu( | ||
1864 | wqe_fragment_length[ | ||
1865 | wqe_fragment_index]), | ||
1866 | PCI_DMA_TODEVICE); | ||
1867 | } else | ||
1868 | break; | ||
1869 | } | ||
1870 | } | ||
1871 | if (nesvnic->nic.tx_skb[nesvnic->nic.sq_tail]) | ||
1872 | dev_kfree_skb( | ||
1873 | nesvnic->nic.tx_skb[nesvnic->nic.sq_tail]); | ||
1874 | |||
1875 | nesvnic->nic.sq_tail = (++nesvnic->nic.sq_tail) | ||
1876 | & (nesvnic->nic.sq_size - 1); | ||
1877 | } | ||
1878 | |||
1819 | spin_lock_irqsave(&nesdev->cqp.lock, flags); | 1879 | spin_lock_irqsave(&nesdev->cqp.lock, flags); |
1820 | 1880 | ||
1821 | /* Destroy NIC QP */ | 1881 | /* Destroy NIC QP */ |