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 */ |
