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.c264
1 files changed, 131 insertions, 133 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 9f971ed6b58d..c15fc281f79f 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -194,13 +194,13 @@ static int desc_list_init(void)
194 struct dma_descriptor *b = &(r->desc_b); 194 struct dma_descriptor *b = &(r->desc_b);
195 195
196 /* allocate a new skb for next time receive */ 196 /* allocate a new skb for next time receive */
197 new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); 197 new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
198 if (!new_skb) { 198 if (!new_skb) {
199 printk(KERN_NOTICE DRV_NAME 199 printk(KERN_NOTICE DRV_NAME
200 ": init: low on mem - packet dropped\n"); 200 ": init: low on mem - packet dropped\n");
201 goto init_error; 201 goto init_error;
202 } 202 }
203 skb_reserve(new_skb, 2); 203 skb_reserve(new_skb, NET_IP_ALIGN);
204 r->skb = new_skb; 204 r->skb = new_skb;
205 205
206 /* 206 /*
@@ -566,9 +566,9 @@ static void adjust_tx_list(void)
566 */ 566 */
567 if (current_tx_ptr->next->next == tx_list_head) { 567 if (current_tx_ptr->next->next == tx_list_head) {
568 while (tx_list_head->status.status_word == 0) { 568 while (tx_list_head->status.status_word == 0) {
569 mdelay(1); 569 udelay(10);
570 if (tx_list_head->status.status_word != 0 570 if (tx_list_head->status.status_word != 0
571 || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) { 571 || !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
572 goto adjust_head; 572 goto adjust_head;
573 } 573 }
574 if (timeout_cnt-- < 0) { 574 if (timeout_cnt-- < 0) {
@@ -606,93 +606,41 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
606 struct net_device *dev) 606 struct net_device *dev)
607{ 607{
608 u16 *data; 608 u16 *data;
609 609 u32 data_align = (unsigned long)(skb->data) & 0x3;
610 current_tx_ptr->skb = skb; 610 current_tx_ptr->skb = skb;
611 611
612 if (ANOMALY_05000285) { 612 if (data_align == 0x2) {
613 /* 613 /* move skb->data to current_tx_ptr payload */
614 * TXDWA feature is not avaible to older revision < 0.3 silicon 614 data = (u16 *)(skb->data) - 1;
615 * of BF537 615 *data = (u16)(skb->len);
616 * 616 current_tx_ptr->desc_a.start_addr = (u32)data;
617 * Only if data buffer is ODD WORD alignment, we do not 617 /* this is important! */
618 * need to memcpy 618 blackfin_dcache_flush_range((u32)data,
619 */ 619 (u32)((u8 *)data + skb->len + 4));
620 u32 data_align = (u32)(skb->data) & 0x3;
621 if (data_align == 0x2) {
622 /* move skb->data to current_tx_ptr payload */
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 }
641 } else { 620 } else {
642 /* 621 *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
643 * TXDWA feature is avaible to revision < 0.3 silicon of 622 memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
644 * BF537 and always avaible to BF52x 623 skb->len);
645 */ 624 current_tx_ptr->desc_a.start_addr =
646 u32 data_align = (u32)(skb->data) & 0x3; 625 (u32)current_tx_ptr->packet;
647 if (data_align == 0x0) { 626 if (current_tx_ptr->status.status_word != 0)
648 u16 sysctl = bfin_read_EMAC_SYSCTL(); 627 current_tx_ptr->status.status_word = 0;
649 sysctl |= TXDWA; 628 blackfin_dcache_flush_range(
650 bfin_write_EMAC_SYSCTL(sysctl); 629 (u32)current_tx_ptr->packet,
651 630 (u32)(current_tx_ptr->packet + skb->len + 2));
652 /* move skb->data to current_tx_ptr payload */
653 data = (u16 *)(skb->data) - 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 }
689 } 631 }
690 632
633 /* make sure the internal data buffers in the core are drained
634 * so that the DMA descriptors are completely written when the
635 * DMA engine goes to fetch them below
636 */
637 SSYNC();
638
691 /* enable this packet's dma */ 639 /* enable this packet's dma */
692 current_tx_ptr->desc_a.config |= DMAEN; 640 current_tx_ptr->desc_a.config |= DMAEN;
693 641
694 /* tx dma is running, just return */ 642 /* tx dma is running, just return */
695 if (bfin_read_DMA2_IRQ_STATUS() & 0x08) 643 if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
696 goto out; 644 goto out;
697 645
698 /* tx dma is not running */ 646 /* tx dma is not running */
@@ -718,7 +666,7 @@ static void bfin_mac_rx(struct net_device *dev)
718 666
719 /* allocate a new skb for next time receive */ 667 /* allocate a new skb for next time receive */
720 skb = current_rx_ptr->skb; 668 skb = current_rx_ptr->skb;
721 new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); 669 new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
722 if (!new_skb) { 670 if (!new_skb) {
723 printk(KERN_NOTICE DRV_NAME 671 printk(KERN_NOTICE DRV_NAME
724 ": rx: low on mem - packet dropped\n"); 672 ": rx: low on mem - packet dropped\n");
@@ -726,7 +674,7 @@ static void bfin_mac_rx(struct net_device *dev)
726 goto out; 674 goto out;
727 } 675 }
728 /* reserve 2 bytes for RXDWA padding */ 676 /* reserve 2 bytes for RXDWA padding */
729 skb_reserve(new_skb, 2); 677 skb_reserve(new_skb, NET_IP_ALIGN);
730 current_rx_ptr->skb = new_skb; 678 current_rx_ptr->skb = new_skb;
731 current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; 679 current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
732 680
@@ -979,22 +927,7 @@ static int bfin_mac_open(struct net_device *dev)
979 return 0; 927 return 0;
980} 928}
981 929
982static const struct net_device_ops bfin_mac_netdev_ops = {
983 .ndo_open = bfin_mac_open,
984 .ndo_stop = bfin_mac_close,
985 .ndo_start_xmit = bfin_mac_hard_start_xmit,
986 .ndo_set_mac_address = bfin_mac_set_mac_address,
987 .ndo_tx_timeout = bfin_mac_timeout,
988 .ndo_set_multicast_list = bfin_mac_set_multicast_list,
989 .ndo_validate_addr = eth_validate_addr,
990 .ndo_change_mtu = eth_change_mtu,
991#ifdef CONFIG_NET_POLL_CONTROLLER
992 .ndo_poll_controller = bfin_mac_poll,
993#endif
994};
995
996/* 930/*
997 *
998 * this makes the board clean up everything that it can 931 * this makes the board clean up everything that it can
999 * and not talk to the outside world. Caused by 932 * and not talk to the outside world. Caused by
1000 * an 'ifconfig ethX down' 933 * an 'ifconfig ethX down'
@@ -1019,11 +952,26 @@ static int bfin_mac_close(struct net_device *dev)
1019 return 0; 952 return 0;
1020} 953}
1021 954
955static const struct net_device_ops bfin_mac_netdev_ops = {
956 .ndo_open = bfin_mac_open,
957 .ndo_stop = bfin_mac_close,
958 .ndo_start_xmit = bfin_mac_hard_start_xmit,
959 .ndo_set_mac_address = bfin_mac_set_mac_address,
960 .ndo_tx_timeout = bfin_mac_timeout,
961 .ndo_set_multicast_list = bfin_mac_set_multicast_list,
962 .ndo_validate_addr = eth_validate_addr,
963 .ndo_change_mtu = eth_change_mtu,
964#ifdef CONFIG_NET_POLL_CONTROLLER
965 .ndo_poll_controller = bfin_mac_poll,
966#endif
967};
968
1022static int __devinit bfin_mac_probe(struct platform_device *pdev) 969static int __devinit bfin_mac_probe(struct platform_device *pdev)
1023{ 970{
1024 struct net_device *ndev; 971 struct net_device *ndev;
1025 struct bfin_mac_local *lp; 972 struct bfin_mac_local *lp;
1026 int rc, i; 973 struct platform_device *pd;
974 int rc;
1027 975
1028 ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); 976 ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
1029 if (!ndev) { 977 if (!ndev) {
@@ -1048,13 +996,6 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
1048 goto out_err_probe_mac; 996 goto out_err_probe_mac;
1049 } 997 }
1050 998
1051 /* set the GPIO pins to Ethernet mode */
1052 rc = peripheral_request_list(pin_req, DRV_NAME);
1053 if (rc) {
1054 dev_err(&pdev->dev, "Requesting peripherals failed!\n");
1055 rc = -EFAULT;
1056 goto out_err_setup_pin_mux;
1057 }
1058 999
1059 /* 1000 /*
1060 * Is it valid? (Did bootloader initialize it?) 1001 * Is it valid? (Did bootloader initialize it?)
@@ -1070,26 +1011,14 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
1070 1011
1071 setup_mac_addr(ndev->dev_addr); 1012 setup_mac_addr(ndev->dev_addr);
1072 1013
1073 /* MDIO bus initial */ 1014 if (!pdev->dev.platform_data) {
1074 lp->mii_bus = mdiobus_alloc(); 1015 dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n");
1075 if (lp->mii_bus == NULL) 1016 rc = -ENODEV;
1076 goto out_err_mdiobus_alloc; 1017 goto out_err_probe_mac;
1077
1078 lp->mii_bus->priv = ndev;
1079 lp->mii_bus->read = bfin_mdiobus_read;
1080 lp->mii_bus->write = bfin_mdiobus_write;
1081 lp->mii_bus->reset = bfin_mdiobus_reset;
1082 lp->mii_bus->name = "bfin_mac_mdio";
1083 snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0");
1084 lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
1085 for (i = 0; i < PHY_MAX_ADDR; ++i)
1086 lp->mii_bus->irq[i] = PHY_POLL;
1087
1088 rc = mdiobus_register(lp->mii_bus);
1089 if (rc) {
1090 dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
1091 goto out_err_mdiobus_register;
1092 } 1018 }
1019 pd = pdev->dev.platform_data;
1020 lp->mii_bus = platform_get_drvdata(pd);
1021 lp->mii_bus->priv = ndev;
1093 1022
1094 rc = mii_probe(ndev); 1023 rc = mii_probe(ndev);
1095 if (rc) { 1024 if (rc) {
@@ -1108,7 +1037,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
1108 /* now, enable interrupts */ 1037 /* now, enable interrupts */
1109 /* register irq handler */ 1038 /* register irq handler */
1110 rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt, 1039 rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
1111 IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev); 1040 IRQF_DISABLED, "EMAC_RX", ndev);
1112 if (rc) { 1041 if (rc) {
1113 dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n"); 1042 dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
1114 rc = -EBUSY; 1043 rc = -EBUSY;
@@ -1131,11 +1060,8 @@ out_err_reg_ndev:
1131out_err_request_irq: 1060out_err_request_irq:
1132out_err_mii_probe: 1061out_err_mii_probe:
1133 mdiobus_unregister(lp->mii_bus); 1062 mdiobus_unregister(lp->mii_bus);
1134out_err_mdiobus_register:
1135 mdiobus_free(lp->mii_bus); 1063 mdiobus_free(lp->mii_bus);
1136out_err_mdiobus_alloc:
1137 peripheral_free_list(pin_req); 1064 peripheral_free_list(pin_req);
1138out_err_setup_pin_mux:
1139out_err_probe_mac: 1065out_err_probe_mac:
1140 platform_set_drvdata(pdev, NULL); 1066 platform_set_drvdata(pdev, NULL);
1141 free_netdev(ndev); 1067 free_netdev(ndev);
@@ -1150,8 +1076,7 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
1150 1076
1151 platform_set_drvdata(pdev, NULL); 1077 platform_set_drvdata(pdev, NULL);
1152 1078
1153 mdiobus_unregister(lp->mii_bus); 1079 lp->mii_bus->priv = NULL;
1154 mdiobus_free(lp->mii_bus);
1155 1080
1156 unregister_netdev(ndev); 1081 unregister_netdev(ndev);
1157 1082
@@ -1189,6 +1114,74 @@ static int bfin_mac_resume(struct platform_device *pdev)
1189#define bfin_mac_resume NULL 1114#define bfin_mac_resume NULL
1190#endif /* CONFIG_PM */ 1115#endif /* CONFIG_PM */
1191 1116
1117static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
1118{
1119 struct mii_bus *miibus;
1120 int rc, i;
1121
1122 /*
1123 * We are setting up a network card,
1124 * so set the GPIO pins to Ethernet mode
1125 */
1126 rc = peripheral_request_list(pin_req, DRV_NAME);
1127 if (rc) {
1128 dev_err(&pdev->dev, "Requesting peripherals failed!\n");
1129 return rc;
1130 }
1131
1132 rc = -ENOMEM;
1133 miibus = mdiobus_alloc();
1134 if (miibus == NULL)
1135 goto out_err_alloc;
1136 miibus->read = bfin_mdiobus_read;
1137 miibus->write = bfin_mdiobus_write;
1138 miibus->reset = bfin_mdiobus_reset;
1139
1140 miibus->parent = &pdev->dev;
1141 miibus->name = "bfin_mii_bus";
1142 snprintf(miibus->id, MII_BUS_ID_SIZE, "0");
1143 miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
1144 if (miibus->irq == NULL)
1145 goto out_err_alloc;
1146 for (i = 0; i < PHY_MAX_ADDR; ++i)
1147 miibus->irq[i] = PHY_POLL;
1148
1149 rc = mdiobus_register(miibus);
1150 if (rc) {
1151 dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
1152 goto out_err_mdiobus_register;
1153 }
1154
1155 platform_set_drvdata(pdev, miibus);
1156 return 0;
1157
1158out_err_mdiobus_register:
1159 mdiobus_free(miibus);
1160out_err_alloc:
1161 peripheral_free_list(pin_req);
1162
1163 return rc;
1164}
1165
1166static int __devexit bfin_mii_bus_remove(struct platform_device *pdev)
1167{
1168 struct mii_bus *miibus = platform_get_drvdata(pdev);
1169 platform_set_drvdata(pdev, NULL);
1170 mdiobus_unregister(miibus);
1171 mdiobus_free(miibus);
1172 peripheral_free_list(pin_req);
1173 return 0;
1174}
1175
1176static struct platform_driver bfin_mii_bus_driver = {
1177 .probe = bfin_mii_bus_probe,
1178 .remove = __devexit_p(bfin_mii_bus_remove),
1179 .driver = {
1180 .name = "bfin_mii_bus",
1181 .owner = THIS_MODULE,
1182 },
1183};
1184
1192static struct platform_driver bfin_mac_driver = { 1185static struct platform_driver bfin_mac_driver = {
1193 .probe = bfin_mac_probe, 1186 .probe = bfin_mac_probe,
1194 .remove = __devexit_p(bfin_mac_remove), 1187 .remove = __devexit_p(bfin_mac_remove),
@@ -1202,7 +1195,11 @@ static struct platform_driver bfin_mac_driver = {
1202 1195
1203static int __init bfin_mac_init(void) 1196static int __init bfin_mac_init(void)
1204{ 1197{
1205 return platform_driver_register(&bfin_mac_driver); 1198 int ret;
1199 ret = platform_driver_register(&bfin_mii_bus_driver);
1200 if (!ret)
1201 return platform_driver_register(&bfin_mac_driver);
1202 return -ENODEV;
1206} 1203}
1207 1204
1208module_init(bfin_mac_init); 1205module_init(bfin_mac_init);
@@ -1210,6 +1207,7 @@ module_init(bfin_mac_init);
1210static void __exit bfin_mac_cleanup(void) 1207static void __exit bfin_mac_cleanup(void)
1211{ 1208{
1212 platform_driver_unregister(&bfin_mac_driver); 1209 platform_driver_unregister(&bfin_mac_driver);
1210 platform_driver_unregister(&bfin_mii_bus_driver);
1213} 1211}
1214 1212
1215module_exit(bfin_mac_cleanup); 1213module_exit(bfin_mac_cleanup);