static void bfin_mac_shutdown(struct net_device *dev) { bfin_write_EMAC_OPMODE(0x00000000); bfin_write_DMA1_CONFIG(0x0000); bfin_write_DMA2_CONFIG(0x0000); }
/* * this puts the device in an inactive state */ static void bfin_mac_shutdown(struct net_device *dev) { /* Turn off the EMAC */ bfin_write_EMAC_OPMODE(0x00000000); /* Turn off the EMAC RX DMA */ bfin_write_DMA1_CONFIG(0x0000); bfin_write_DMA2_CONFIG(0x0000); }
static void bfin_EMAC_halt(struct eth_device *dev) { debug("Eth_halt: ......\n"); /* Turn off the EMAC */ bfin_write_EMAC_OPMODE(0); /* Turn off the EMAC RX DMA */ bfin_write_DMA1_CONFIG(0); bfin_write_DMA2_CONFIG(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; }
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; }
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; }
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; }
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; }