aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bfin_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r--drivers/net/bfin_mac.c111
1 files changed, 81 insertions, 30 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index a8ec60e1ed7..3db7db1828e 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -605,36 +605,87 @@ adjust_head:
605static int bfin_mac_hard_start_xmit(struct sk_buff *skb, 605static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
606 struct net_device *dev) 606 struct net_device *dev)
607{ 607{
608 unsigned int data; 608 u16 *data;
609 609
610 current_tx_ptr->skb = skb; 610 current_tx_ptr->skb = skb;
611 611
612 /* 612 if (ANOMALY_05000285) {
613 * Is skb->data always 16-bit aligned? 613 /*
614 * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)? 614 * TXDWA feature is not avaible to older revision < 0.3 silicon
615 */ 615 * of BF537
616 if ((((unsigned int)(skb->data)) & 0x02) == 2) { 616 *
617 /* move skb->data to current_tx_ptr payload */ 617 * Only if data buffer is ODD WORD alignment, we do not
618 data = (unsigned int)(skb->data) - 2; 618 * need to memcpy
619 *((unsigned short *)data) = (unsigned short)(skb->len); 619 */
620 current_tx_ptr->desc_a.start_addr = (unsigned long)data; 620 u32 data_align = (u32)(skb->data) & 0x3;
621 /* this is important! */ 621 if (data_align == 0x2) {
622 blackfin_dcache_flush_range(data, (data + (skb->len)) + 2); 622 /* move skb->data to current_tx_ptr payload */
623 623 data = (u16 *)(skb->data) - 1;
624 *data = (u16)(skb->len);
625 current_tx_ptr->desc_a.start_addr = (u32)data;
626 /* this is important! */
627 blackfin_dcache_flush_range((u32)data,
628 (u32)((u8 *)data + skb->len + 4));
629 } else {
630 *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
631 memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
632 skb->len);
633 current_tx_ptr->desc_a.start_addr =
634 (u32)current_tx_ptr->packet;
635 if (current_tx_ptr->status.status_word != 0)
636 current_tx_ptr->status.status_word = 0;
637 blackfin_dcache_flush_range(
638 (u32)current_tx_ptr->packet,
639 (u32)(current_tx_ptr->packet + skb->len + 2));
640 }
624 } else { 641 } else {
625 *((unsigned short *)(current_tx_ptr->packet)) = 642 /*
626 (unsigned short)(skb->len); 643 * TXDWA feature is avaible to revision < 0.3 silicon of
627 memcpy((char *)(current_tx_ptr->packet + 2), skb->data, 644 * BF537 and always avaible to BF52x
628 (skb->len)); 645 */
629 current_tx_ptr->desc_a.start_addr = 646 u32 data_align = (u32)(skb->data) & 0x3;
630 (unsigned long)current_tx_ptr->packet; 647 if (data_align == 0x0) {
631 if (current_tx_ptr->status.status_word != 0) 648 u16 sysctl = bfin_read_EMAC_SYSCTL();
632 current_tx_ptr->status.status_word = 0; 649 sysctl |= TXDWA;
633 blackfin_dcache_flush_range((unsigned int)current_tx_ptr-> 650 bfin_write_EMAC_SYSCTL(sysctl);
634 packet, 651
635 (unsigned int)(current_tx_ptr-> 652 /* move skb->data to current_tx_ptr payload */
636 packet + skb->len) + 653 data = (u16 *)(skb->data) - 2;
637 2); 654 *data = (u16)(skb->len);
655 current_tx_ptr->desc_a.start_addr = (u32)data;
656 /* this is important! */
657 blackfin_dcache_flush_range(
658 (u32)data,
659 (u32)((u8 *)data + skb->len + 4));
660 } else if (data_align == 0x2) {
661 u16 sysctl = bfin_read_EMAC_SYSCTL();
662 sysctl &= ~TXDWA;
663 bfin_write_EMAC_SYSCTL(sysctl);
664
665 /* move skb->data to current_tx_ptr payload */
666 data = (u16 *)(skb->data) - 1;
667 *data = (u16)(skb->len);
668 current_tx_ptr->desc_a.start_addr = (u32)data;
669 /* this is important! */
670 blackfin_dcache_flush_range(
671 (u32)data,
672 (u32)((u8 *)data + skb->len + 4));
673 } else {
674 u16 sysctl = bfin_read_EMAC_SYSCTL();
675 sysctl &= ~TXDWA;
676 bfin_write_EMAC_SYSCTL(sysctl);
677
678 *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
679 memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
680 skb->len);
681 current_tx_ptr->desc_a.start_addr =
682 (u32)current_tx_ptr->packet;
683 if (current_tx_ptr->status.status_word != 0)
684 current_tx_ptr->status.status_word = 0;
685 blackfin_dcache_flush_range(
686 (u32)current_tx_ptr->packet,
687 (u32)(current_tx_ptr->packet + skb->len + 2));
688 }
638 } 689 }
639 690
640 /* enable this packet's dma */ 691 /* enable this packet's dma */
@@ -691,7 +742,6 @@ static void bfin_mac_rx(struct net_device *dev)
691 (unsigned long)skb->tail); 742 (unsigned long)skb->tail);
692 743
693 dev->last_rx = jiffies; 744 dev->last_rx = jiffies;
694 skb->dev = dev;
695 skb->protocol = eth_type_trans(skb, dev); 745 skb->protocol = eth_type_trans(skb, dev);
696#if defined(BFIN_MAC_CSUM_OFFLOAD) 746#if defined(BFIN_MAC_CSUM_OFFLOAD)
697 skb->csum = current_rx_ptr->status.ip_payload_csum; 747 skb->csum = current_rx_ptr->status.ip_payload_csum;
@@ -920,6 +970,7 @@ static int bfin_mac_open(struct net_device *dev)
920 phy_start(lp->phydev); 970 phy_start(lp->phydev);
921 phy_write(lp->phydev, MII_BMCR, BMCR_RESET); 971 phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
922 setup_system_regs(dev); 972 setup_system_regs(dev);
973 setup_mac_addr(dev->dev_addr);
923 bfin_mac_disable(); 974 bfin_mac_disable();
924 bfin_mac_enable(); 975 bfin_mac_enable();
925 pr_debug("hardware init finished\n"); 976 pr_debug("hardware init finished\n");
@@ -955,7 +1006,7 @@ static int bfin_mac_close(struct net_device *dev)
955 return 0; 1006 return 0;
956} 1007}
957 1008
958static int __init bfin_mac_probe(struct platform_device *pdev) 1009static int __devinit bfin_mac_probe(struct platform_device *pdev)
959{ 1010{
960 struct net_device *ndev; 1011 struct net_device *ndev;
961 struct bfin_mac_local *lp; 1012 struct bfin_mac_local *lp;
@@ -1081,7 +1132,7 @@ out_err_probe_mac:
1081 return rc; 1132 return rc;
1082} 1133}
1083 1134
1084static int bfin_mac_remove(struct platform_device *pdev) 1135static int __devexit bfin_mac_remove(struct platform_device *pdev)
1085{ 1136{
1086 struct net_device *ndev = platform_get_drvdata(pdev); 1137 struct net_device *ndev = platform_get_drvdata(pdev);
1087 struct bfin_mac_local *lp = netdev_priv(ndev); 1138 struct bfin_mac_local *lp = netdev_priv(ndev);
@@ -1128,7 +1179,7 @@ static int bfin_mac_resume(struct platform_device *pdev)
1128 1179
1129static struct platform_driver bfin_mac_driver = { 1180static struct platform_driver bfin_mac_driver = {
1130 .probe = bfin_mac_probe, 1181 .probe = bfin_mac_probe,
1131 .remove = bfin_mac_remove, 1182 .remove = __devexit_p(bfin_mac_remove),
1132 .resume = bfin_mac_resume, 1183 .resume = bfin_mac_resume,
1133 .suspend = bfin_mac_suspend, 1184 .suspend = bfin_mac_suspend,
1134 .driver = { 1185 .driver = {