Fixed re-using RFDs.
authorFlorian Pose <fp@igh-essen.com>
Tue, 30 Sep 2008 11:51:23 +0000
changeset 1229 51d447754109
parent 1228 6d9c686f922e
child 1230 0f3878668790
Fixed re-using RFDs.
devices/e100-2.6.20-ethercat.c
--- a/devices/e100-2.6.20-ethercat.c	Tue Sep 30 10:03:10 2008 +0000
+++ b/devices/e100-2.6.20-ethercat.c	Tue Sep 30 11:51:23 2008 +0000
@@ -1945,10 +1945,24 @@
 
 	if (nic->ecdev) {
 		// make receive frame descriptior usable again
-		rfd->status = 0x0000;
-		rfd->command = cpu_to_le16(cb_el);
-		rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
+		memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd));
+		rx->dma_addr = pci_map_single(nic->pdev, skb->data,
 				RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
+		if(pci_dma_mapping_error(rx->dma_addr)) {
+			rx->dma_addr = 0;
+		}
+
+		/* Link the RFD to end of RFA by linking previous RFD to
+		 * this one, and clearing EL bit of previous.  */
+		if(rx->prev->skb) {
+			struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
+			put_unaligned(cpu_to_le32(rx->dma_addr),
+					(u32 *)&prev_rfd->link);
+			wmb();
+			prev_rfd->command &= ~cpu_to_le16(cb_el);
+			pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
+					sizeof(struct rfd), PCI_DMA_TODEVICE);
+		}
 	} else {
 		rx->skb = NULL;
 	}