devices/e100-2.6.26-ethercat.c
changeset 1276 c4fafee8043a
parent 1274 d5ddf04c76fc
child 1300 428bf6d7c905
equal deleted inserted replaced
1275:c9de1c0c1f51 1276:c4fafee8043a
  1989 	if (nic->ecdev) {
  1989 	if (nic->ecdev) {
  1990 		// make receive frame descriptior usable again
  1990 		// make receive frame descriptior usable again
  1991 		memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd));
  1991 		memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd));
  1992 		rx->dma_addr = pci_map_single(nic->pdev, skb->data,
  1992 		rx->dma_addr = pci_map_single(nic->pdev, skb->data,
  1993 				RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
  1993 				RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
  1994 		if(pci_dma_mapping_error(rx->dma_addr)) {
  1994 		if (pci_dma_mapping_error(rx->dma_addr)) {
  1995 			rx->dma_addr = 0;
  1995 			rx->dma_addr = 0;
  1996 		}
  1996 		}
  1997 
  1997 
  1998 		/* Link the RFD to end of RFA by linking previous RFD to
  1998 		/* Link the RFD to end of RFA by linking previous RFD to
  1999 		 * this one, and clearing EL bit of previous.  */
  1999 		 * this one.  We are safe to touch the previous RFD because
  2000 		if(rx->prev->skb) {
  2000 		 * it is protected by the before last buffer's el bit being set */
       
  2001 		if (rx->prev->skb) {
  2001 			struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
  2002 			struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
  2002 			put_unaligned(cpu_to_le32(rx->dma_addr),
  2003 			put_unaligned_le32(rx->dma_addr, &prev_rfd->link);
  2003 					(u32 *)&prev_rfd->link);
       
  2004 			wmb();
       
  2005 			prev_rfd->command &= ~cpu_to_le16(cb_el);
       
  2006 			pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
  2004 			pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
  2007 					sizeof(struct rfd), PCI_DMA_TODEVICE);
  2005 					sizeof(struct rfd), PCI_DMA_TODEVICE);
  2008 		}
  2006 		}
  2009 	} else {
  2007 	} else {
  2010 		rx->skb = NULL;
  2008 		rx->skb = NULL;
  2131 		if(e100_rx_alloc_skb(nic, rx)) {
  2129 		if(e100_rx_alloc_skb(nic, rx)) {
  2132 			e100_rx_clean_list(nic);
  2130 			e100_rx_clean_list(nic);
  2133 			return -ENOMEM;
  2131 			return -ENOMEM;
  2134 		}
  2132 		}
  2135 	}
  2133 	}
  2136 	/* Set the el-bit on the buffer that is before the last buffer.
  2134 
  2137 	 * This lets us update the next pointer on the last buffer without
  2135 	if (!nic->ecdev) {
  2138 	 * worrying about hardware touching it.
  2136 		/* Set the el-bit on the buffer that is before the last buffer.
  2139 	 * We set the size to 0 to prevent hardware from touching this buffer.
  2137 		 * This lets us update the next pointer on the last buffer without
  2140 	 * When the hardware hits the before last buffer with el-bit and size
  2138 		 * worrying about hardware touching it.
  2141 	 * of 0, it will RNR interrupt, the RU will go into the No Resources
  2139 		 * We set the size to 0 to prevent hardware from touching this buffer.
  2142 	 * state.  It will not complete nor write to this buffer. */
  2140 		 * When the hardware hits the before last buffer with el-bit and size
  2143 	rx = nic->rxs->prev->prev;
  2141 		 * of 0, it will RNR interrupt, the RU will go into the No Resources
  2144 	before_last = (struct rfd *)rx->skb->data;
  2142 		 * state.  It will not complete nor write to this buffer. */
  2145 	before_last->command |= cpu_to_le16(cb_el);
  2143 		rx = nic->rxs->prev->prev;
  2146 	before_last->size = 0;
  2144 		before_last = (struct rfd *)rx->skb->data;
  2147 	pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
  2145 		before_last->command |= cpu_to_le16(cb_el);
  2148 		sizeof(struct rfd), PCI_DMA_TODEVICE);
  2146 		before_last->size = 0;
       
  2147 		pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
       
  2148 				sizeof(struct rfd), PCI_DMA_TODEVICE);
       
  2149 	}
  2149 
  2150 
  2150 	nic->rx_to_use = nic->rx_to_clean = nic->rxs;
  2151 	nic->rx_to_use = nic->rx_to_clean = nic->rxs;
  2151 	nic->ru_running = RU_SUSPENDED;
  2152 	nic->ru_running = RU_SUSPENDED;
  2152 
  2153 
  2153 	return 0;
  2154 	return 0;