aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBob Sharp <bsharp@neteffect.com>2008-09-26 16:08:10 -0400
committerRoland Dreier <rolandd@cisco.com>2008-09-30 18:35:47 -0400
commit7a8d14070b3e2d52d2b531434ed09fa1787ae7ca (patch)
tree2a8849888a7c2e1ee6675428660f4c706368ac1f /drivers/infiniband
parente88bd7b624133e0b07adb21c45c9e6f68f8fdda2 (diff)
RDMA/nes: Free NIC TX buffers when destroying NIC QP
Signed-off-by: Bob Sharp <bsharp@neteffect.com> Signed-off-by: Sweta Bhatt <sweta.bhatt@einfochips.com> Signed-off-by: Chien Tung <ctung@neteffect.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c64
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 1437b6e397b..bc16fc082d9 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 */
1798void nes_destroy_nic_qp(struct nes_vnic *nesvnic) 1798void 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 */