示例#1
0
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
				struct net_device *dev)
{
	unsigned int data;

	current_tx_ptr->skb = skb;

	/*
	 * Is skb->data always 16-bit aligned?
	 * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)?
	 */
	if ((((unsigned int)(skb->data)) & 0x02) == 2) {
		/* move skb->data to current_tx_ptr payload */
		data = (unsigned int)(skb->data) - 2;
		*((unsigned short *)data) = (unsigned short)(skb->len);
		current_tx_ptr->desc_a.start_addr = (unsigned long)data;
		/* this is important! */
		blackfin_dcache_flush_range(data, (data + (skb->len)) + 2);

	} else {
		*((unsigned short *)(current_tx_ptr->packet)) =
		    (unsigned short)(skb->len);
		memcpy((char *)(current_tx_ptr->packet + 2), skb->data,
		       (skb->len));
		current_tx_ptr->desc_a.start_addr =
		    (unsigned long)current_tx_ptr->packet;
		if (current_tx_ptr->status.status_word != 0)
			current_tx_ptr->status.status_word = 0;
		blackfin_dcache_flush_range((unsigned int)current_tx_ptr->
					    packet,
					    (unsigned int)(current_tx_ptr->
							   packet + skb->len) +
					    2);
	}

	/* enable this packet's dma */
	current_tx_ptr->desc_a.config |= DMAEN;

	/* tx dma is running, just return */
	if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
		goto out;

	/* tx dma is not running */
	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
	/* dma enabled, read from memory, size is 6 */
	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
	/* Turn on the EMAC tx */
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

out:
	adjust_tx_list();
	current_tx_ptr = current_tx_ptr->next;
	dev->trans_start = jiffies;
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += (skb->len);
	return 0;
}
示例#2
0
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
				struct net_device *dev)
{
	u16 *data;
	u32 data_align = (unsigned long)(skb->data) & 0x3;
	current_tx_ptr->skb = skb;

	if (data_align == 0x2) {
		/* move skb->data to current_tx_ptr payload */
		data = (u16 *)(skb->data) - 1;
				*data = (u16)(skb->len);
		current_tx_ptr->desc_a.start_addr = (u32)data;
		/* this is important! */
		blackfin_dcache_flush_range((u32)data,
				(u32)((u8 *)data + skb->len + 4));
	} else {
		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
			skb->len);
		current_tx_ptr->desc_a.start_addr =
			(u32)current_tx_ptr->packet;
		if (current_tx_ptr->status.status_word != 0)
			current_tx_ptr->status.status_word = 0;
		blackfin_dcache_flush_range(
			(u32)current_tx_ptr->packet,
			(u32)(current_tx_ptr->packet + skb->len + 2));
	}

	/* make sure the internal data buffers in the core are drained
	 * so that the DMA descriptors are completely written when the
	 * DMA engine goes to fetch them below
	 */
	SSYNC();

	/* enable this packet's dma */
	current_tx_ptr->desc_a.config |= DMAEN;

	/* tx dma is running, just return */
	if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
		goto out;

	/* tx dma is not running */
	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
	/* dma enabled, read from memory, size is 6 */
	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
	/* Turn on the EMAC tx */
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

out:
	adjust_tx_list();
	current_tx_ptr = current_tx_ptr->next;
	dev->trans_start = jiffies;
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += (skb->len);
	return NETDEV_TX_OK;
}
示例#3
0
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
				struct net_device *dev)
{
	u16 *data;
	u32 data_align = (unsigned long)(skb->data) & 0x3;
	current_tx_ptr->skb = skb;

	if (data_align == 0x2) {
		
		data = (u16 *)(skb->data) - 1;
				*data = (u16)(skb->len);
		current_tx_ptr->desc_a.start_addr = (u32)data;
		
		blackfin_dcache_flush_range((u32)data,
				(u32)((u8 *)data + skb->len + 4));
	} else {
		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
			skb->len);
		current_tx_ptr->desc_a.start_addr =
			(u32)current_tx_ptr->packet;
		if (current_tx_ptr->status.status_word != 0)
			current_tx_ptr->status.status_word = 0;
		blackfin_dcache_flush_range(
			(u32)current_tx_ptr->packet,
			(u32)(current_tx_ptr->packet + skb->len + 2));
	}

	
	SSYNC();

	
	current_tx_ptr->desc_a.config |= DMAEN;

	
	if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
		goto out;

	
	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
	
	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
	
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

out:
	adjust_tx_list();
	current_tx_ptr = current_tx_ptr->next;
	dev->trans_start = jiffies;
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += (skb->len);
	return NETDEV_TX_OK;
}
示例#4
0
static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length)
{
	int i;
	int result = 0;
	unsigned int *buf;
	buf = (unsigned int *)packet;

	if (length <= 0) {
		printf("Ethernet: bad packet size: %d\n", length);
		goto out;
	}

	if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) {
		printf("Ethernet: tx DMA error\n");
		goto out;
	}

	for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) {
		if (i > TOUT_LOOP) {
			puts("Ethernet: tx time out\n");
			goto out;
		}
	}
	txbuf[txIdx]->FrmData->NoBytes = length;
	memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
	txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
	bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma);
	bfin_write_DMA2_CONFIG(txdmacfg.data);
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

	for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
		if (i > TOUT_LOOP) {
			puts("Ethernet: tx error\n");
			goto out;
		}
	}
	result = txbuf[txIdx]->StatusWord;
	txbuf[txIdx]->StatusWord = 0;
	if ((txIdx + 1) >= TX_BUF_CNT)
		txIdx = 0;
	else
		txIdx++;
 out:
	debug("BFIN EMAC send: length = %d\n", length);
	return result;
}
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
				struct net_device *dev)
{
	u16 *data;
	u32 data_align = (unsigned long)(skb->data) & 0x3;
	union skb_shared_tx *shtx = skb_tx(skb);

	current_tx_ptr->skb = skb;

	if (data_align == 0x2) {
		/* move skb->data to current_tx_ptr payload */
		data = (u16 *)(skb->data) - 1;
		*data = (u16)(skb->len);
		/*
		 * When transmitting an Ethernet packet, the PTP_TSYNC module requires
		 * a DMA_Length_Word field associated with the packet. The lower 12 bits
		 * of this field are the length of the packet payload in bytes and the higher
		 * 4 bits are the timestamping enable field.
		 */
		if (shtx->hardware)
			*data |= 0x1000;

		current_tx_ptr->desc_a.start_addr = (u32)data;
		/* this is important! */
		blackfin_dcache_flush_range((u32)data,
				(u32)((u8 *)data + skb->len + 4));
	} else {
		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
		/* enable timestamping for the sent packet */
		if (shtx->hardware)
			*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
			skb->len);
		current_tx_ptr->desc_a.start_addr =
			(u32)current_tx_ptr->packet;
		if (current_tx_ptr->status.status_word != 0)
			current_tx_ptr->status.status_word = 0;
		blackfin_dcache_flush_range(
			(u32)current_tx_ptr->packet,
			(u32)(current_tx_ptr->packet + skb->len + 2));
	}

	/* make sure the internal data buffers in the core are drained
	 * so that the DMA descriptors are completely written when the
	 * DMA engine goes to fetch them below
	 */
	SSYNC();

	/* enable this packet's dma */
	current_tx_ptr->desc_a.config |= DMAEN;

	/* tx dma is running, just return */
	if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
		goto out;

	/* tx dma is not running */
	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
	/* dma enabled, read from memory, size is 6 */
	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
	/* Turn on the EMAC tx */
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

out:
	adjust_tx_list();

	bfin_tx_hwtstamp(dev, skb);

	current_tx_ptr = current_tx_ptr->next;
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += (skb->len);
	return NETDEV_TX_OK;
}
示例#6
0
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
				struct net_device *dev)
{
	u16 *data;

	current_tx_ptr->skb = skb;

	if (ANOMALY_05000285) {
		/*
		 * TXDWA feature is not avaible to older revision < 0.3 silicon
		 * of BF537
		 *
		 * Only if data buffer is ODD WORD alignment, we do not
		 * need to memcpy
		 */
		u32 data_align = (u32)(skb->data) & 0x3;
		if (data_align == 0x2) {
			/* move skb->data to current_tx_ptr payload */
			data = (u16 *)(skb->data) - 1;
			*data = (u16)(skb->len);
			current_tx_ptr->desc_a.start_addr = (u32)data;
			/* this is important! */
			blackfin_dcache_flush_range((u32)data,
					(u32)((u8 *)data + skb->len + 4));
		} else {
			*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
			memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
				skb->len);
			current_tx_ptr->desc_a.start_addr =
				(u32)current_tx_ptr->packet;
			if (current_tx_ptr->status.status_word != 0)
				current_tx_ptr->status.status_word = 0;
			blackfin_dcache_flush_range(
				(u32)current_tx_ptr->packet,
				(u32)(current_tx_ptr->packet + skb->len + 2));
		}
	} else {
		/*
		 * TXDWA feature is avaible to revision < 0.3 silicon of
		 * BF537 and always avaible to BF52x
		 */
		u32 data_align = (u32)(skb->data) & 0x3;
		if (data_align == 0x0) {
			u16 sysctl = bfin_read_EMAC_SYSCTL();
			sysctl |= TXDWA;
			bfin_write_EMAC_SYSCTL(sysctl);

			/* move skb->data to current_tx_ptr payload */
			data = (u16 *)(skb->data) - 2;
			*data = (u16)(skb->len);
			current_tx_ptr->desc_a.start_addr = (u32)data;
			/* this is important! */
			blackfin_dcache_flush_range(
					(u32)data,
					(u32)((u8 *)data + skb->len + 4));
		} else if (data_align == 0x2) {
			u16 sysctl = bfin_read_EMAC_SYSCTL();
			sysctl &= ~TXDWA;
			bfin_write_EMAC_SYSCTL(sysctl);

			/* move skb->data to current_tx_ptr payload */
			data = (u16 *)(skb->data) - 1;
			*data = (u16)(skb->len);
			current_tx_ptr->desc_a.start_addr = (u32)data;
			/* this is important! */
			blackfin_dcache_flush_range(
					(u32)data,
					(u32)((u8 *)data + skb->len + 4));
		} else {
			u16 sysctl = bfin_read_EMAC_SYSCTL();
			sysctl &= ~TXDWA;
			bfin_write_EMAC_SYSCTL(sysctl);

			*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
			memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
				skb->len);
			current_tx_ptr->desc_a.start_addr =
				(u32)current_tx_ptr->packet;
			if (current_tx_ptr->status.status_word != 0)
				current_tx_ptr->status.status_word = 0;
			blackfin_dcache_flush_range(
				(u32)current_tx_ptr->packet,
				(u32)(current_tx_ptr->packet + skb->len + 2));
		}
	}

	/* enable this packet's dma */
	current_tx_ptr->desc_a.config |= DMAEN;

	/* tx dma is running, just return */
	if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
		goto out;

	/* tx dma is not running */
	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
	/* dma enabled, read from memory, size is 6 */
	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
	/* Turn on the EMAC tx */
	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);

out:
	adjust_tx_list();
	current_tx_ptr = current_tx_ptr->next;
	dev->trans_start = jiffies;
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += (skb->len);
	return 0;
}