Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a8d1407 authored by Bob Sharp's avatar Bob Sharp Committed by Roland Dreier
Browse files

RDMA/nes: Free NIC TX buffers when destroying NIC QP

parent e88bd7b6
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
@@ -1797,9 +1797,14 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
 */
void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
{
	u64 u64temp;
	dma_addr_t bus_address;
	struct nes_device *nesdev = nesvnic->nesdev;
	struct nes_hw_cqp_wqe *cqp_wqe;
	struct nes_hw_nic_sq_wqe *nic_sqe;
	struct nes_hw_nic_rq_wqe *nic_rqe;
	__le16 *wqe_fragment_length;
	u16  wqe_fragment_index;
	u64 wqe_frag;
	u32 cqp_head;
	unsigned long flags;
@@ -1808,14 +1813,69 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
	/* Free remaining NIC receive buffers */
	while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
		nic_rqe   = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
		wqe_frag  = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
		wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
		wqe_frag  = (u64)le32_to_cpu(
			nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
		wqe_frag |= ((u64)le32_to_cpu(
			nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX]))<<32;
		pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag,
				nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
		dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]);
		nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1);
	}

	/* Free remaining NIC transmit buffers */
	while (nesvnic->nic.sq_head != nesvnic->nic.sq_tail) {
		nic_sqe = &nesvnic->nic.sq_vbase[nesvnic->nic.sq_tail];
		wqe_fragment_index = 1;
		wqe_fragment_length = (__le16 *)
			&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
		/* bump past the vlan tag */
		wqe_fragment_length++;
		if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
			u64temp = (u64)le32_to_cpu(
				nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
				wqe_fragment_index*2]);
			u64temp += ((u64)le32_to_cpu(
				nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
				+ wqe_fragment_index*2]))<<32;
			bus_address = (dma_addr_t)u64temp;
			if (test_and_clear_bit(nesvnic->nic.sq_tail,
					nesvnic->nic.first_frag_overflow)) {
				pci_unmap_single(nesdev->pcidev,
						bus_address,
						le16_to_cpu(wqe_fragment_length[
							wqe_fragment_index++]),
						PCI_DMA_TODEVICE);
			}
			for (; wqe_fragment_index < 5; wqe_fragment_index++) {
				if (wqe_fragment_length[wqe_fragment_index]) {
					u64temp = le32_to_cpu(
						nic_sqe->wqe_words[
						NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
						wqe_fragment_index*2]);
					u64temp += ((u64)le32_to_cpu(
						nic_sqe->wqe_words[
						NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+
						wqe_fragment_index*2]))<<32;
					bus_address = (dma_addr_t)u64temp;
					pci_unmap_page(nesdev->pcidev,
							bus_address,
							le16_to_cpu(
							wqe_fragment_length[
							wqe_fragment_index]),
							PCI_DMA_TODEVICE);
				} else
					break;
			}
		}
		if (nesvnic->nic.tx_skb[nesvnic->nic.sq_tail])
			dev_kfree_skb(
				nesvnic->nic.tx_skb[nesvnic->nic.sq_tail]);

		nesvnic->nic.sq_tail = (++nesvnic->nic.sq_tail)
					& (nesvnic->nic.sq_size - 1);
	}

	spin_lock_irqsave(&nesdev->cqp.lock, flags);

	/* Destroy NIC QP */