aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fs_enet/fs_enet-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fs_enet/fs_enet-main.c')
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c212
1 files changed, 131 insertions, 81 deletions
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 196298f33db..34412bc7c4b 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -15,7 +15,6 @@
15 * kind, whether express or implied. 15 * kind, whether express or implied.
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/types.h> 20#include <linux/types.h>
@@ -38,6 +37,7 @@
38#include <linux/bitops.h> 37#include <linux/bitops.h>
39#include <linux/fs.h> 38#include <linux/fs.h>
40#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <linux/phy.h>
41 41
42#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
43#include <asm/pgtable.h> 43#include <asm/pgtable.h>
@@ -672,7 +672,7 @@ static int fs_request_irq(struct net_device *dev, int irq, const char *name,
672 struct fs_enet_private *fep = netdev_priv(dev); 672 struct fs_enet_private *fep = netdev_priv(dev);
673 673
674 (*fep->ops->pre_request_irq)(dev, irq); 674 (*fep->ops->pre_request_irq)(dev, irq);
675 return request_irq(irq, irqf, SA_SHIRQ, name, dev); 675 return request_irq(irq, irqf, IRQF_SHARED, name, dev);
676} 676}
677 677
678static void fs_free_irq(struct net_device *dev, int irq) 678static void fs_free_irq(struct net_device *dev, int irq)
@@ -683,35 +683,6 @@ static void fs_free_irq(struct net_device *dev, int irq)
683 (*fep->ops->post_free_irq)(dev, irq); 683 (*fep->ops->post_free_irq)(dev, irq);
684} 684}
685 685
686/**********************************************************************************/
687
688/* This interrupt occurs when the PHY detects a link change. */
689static irqreturn_t
690fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
691{
692 struct net_device *dev = dev_id;
693 struct fs_enet_private *fep;
694 const struct fs_platform_info *fpi;
695
696 fep = netdev_priv(dev);
697 fpi = fep->fpi;
698
699 /*
700 * Acknowledge the interrupt if possible. If we have not
701 * found the PHY yet we can't process or acknowledge the
702 * interrupt now. Instead we ignore this interrupt for now,
703 * which we can do since it is edge triggered. It will be
704 * acknowledged later by fs_enet_open().
705 */
706 if (!fep->phy)
707 return IRQ_NONE;
708
709 fs_mii_ack_int(dev);
710 fs_mii_link_status_change_check(dev, 0);
711
712 return IRQ_HANDLED;
713}
714
715static void fs_timeout(struct net_device *dev) 686static void fs_timeout(struct net_device *dev)
716{ 687{
717 struct fs_enet_private *fep = netdev_priv(dev); 688 struct fs_enet_private *fep = netdev_priv(dev);
@@ -723,10 +694,13 @@ static void fs_timeout(struct net_device *dev)
723 spin_lock_irqsave(&fep->lock, flags); 694 spin_lock_irqsave(&fep->lock, flags);
724 695
725 if (dev->flags & IFF_UP) { 696 if (dev->flags & IFF_UP) {
697 phy_stop(fep->phydev);
726 (*fep->ops->stop)(dev); 698 (*fep->ops->stop)(dev);
727 (*fep->ops->restart)(dev); 699 (*fep->ops->restart)(dev);
700 phy_start(fep->phydev);
728 } 701 }
729 702
703 phy_start(fep->phydev);
730 wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY); 704 wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
731 spin_unlock_irqrestore(&fep->lock, flags); 705 spin_unlock_irqrestore(&fep->lock, flags);
732 706
@@ -734,35 +708,112 @@ static void fs_timeout(struct net_device *dev)
734 netif_wake_queue(dev); 708 netif_wake_queue(dev);
735} 709}
736 710
711/*-----------------------------------------------------------------------------
712 * generic link-change handler - should be sufficient for most cases
713 *-----------------------------------------------------------------------------*/
714static void generic_adjust_link(struct net_device *dev)
715{
716 struct fs_enet_private *fep = netdev_priv(dev);
717 struct phy_device *phydev = fep->phydev;
718 int new_state = 0;
719
720 if (phydev->link) {
721
722 /* adjust to duplex mode */
723 if (phydev->duplex != fep->oldduplex){
724 new_state = 1;
725 fep->oldduplex = phydev->duplex;
726 }
727
728 if (phydev->speed != fep->oldspeed) {
729 new_state = 1;
730 fep->oldspeed = phydev->speed;
731 }
732
733 if (!fep->oldlink) {
734 new_state = 1;
735 fep->oldlink = 1;
736 netif_schedule(dev);
737 netif_carrier_on(dev);
738 netif_start_queue(dev);
739 }
740
741 if (new_state)
742 fep->ops->restart(dev);
743
744 } else if (fep->oldlink) {
745 new_state = 1;
746 fep->oldlink = 0;
747 fep->oldspeed = 0;
748 fep->oldduplex = -1;
749 netif_carrier_off(dev);
750 netif_stop_queue(dev);
751 }
752
753 if (new_state && netif_msg_link(fep))
754 phy_print_status(phydev);
755}
756
757
758static void fs_adjust_link(struct net_device *dev)
759{
760 struct fs_enet_private *fep = netdev_priv(dev);
761 unsigned long flags;
762
763 spin_lock_irqsave(&fep->lock, flags);
764
765 if(fep->ops->adjust_link)
766 fep->ops->adjust_link(dev);
767 else
768 generic_adjust_link(dev);
769
770 spin_unlock_irqrestore(&fep->lock, flags);
771}
772
773static int fs_init_phy(struct net_device *dev)
774{
775 struct fs_enet_private *fep = netdev_priv(dev);
776 struct phy_device *phydev;
777
778 fep->oldlink = 0;
779 fep->oldspeed = 0;
780 fep->oldduplex = -1;
781 if(fep->fpi->bus_id)
782 phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0);
783 else {
784 printk("No phy bus ID specified in BSP code\n");
785 return -EINVAL;
786 }
787 if (IS_ERR(phydev)) {
788 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
789 return PTR_ERR(phydev);
790 }
791
792 fep->phydev = phydev;
793
794 return 0;
795}
796
797
737static int fs_enet_open(struct net_device *dev) 798static int fs_enet_open(struct net_device *dev)
738{ 799{
739 struct fs_enet_private *fep = netdev_priv(dev); 800 struct fs_enet_private *fep = netdev_priv(dev);
740 const struct fs_platform_info *fpi = fep->fpi;
741 int r; 801 int r;
802 int err;
742 803
743 /* Install our interrupt handler. */ 804 /* Install our interrupt handler. */
744 r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); 805 r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
745 if (r != 0) { 806 if (r != 0) {
746 printk(KERN_ERR DRV_MODULE_NAME 807 printk(KERN_ERR DRV_MODULE_NAME
747 ": %s Could not allocate FEC IRQ!", dev->name); 808 ": %s Could not allocate FS_ENET IRQ!", dev->name);
748 return -EINVAL; 809 return -EINVAL;
749 } 810 }
750 811
751 /* Install our phy interrupt handler */ 812 err = fs_init_phy(dev);
752 if (fpi->phy_irq != -1) { 813 if(err)
753 814 return err;
754 r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt);
755 if (r != 0) {
756 printk(KERN_ERR DRV_MODULE_NAME
757 ": %s Could not allocate PHY IRQ!", dev->name);
758 fs_free_irq(dev, fep->interrupt);
759 return -EINVAL;
760 }
761 }
762 815
763 fs_mii_startup(dev); 816 phy_start(fep->phydev);
764 netif_carrier_off(dev);
765 fs_mii_link_status_change_check(dev, 1);
766 817
767 return 0; 818 return 0;
768} 819}
@@ -770,20 +821,19 @@ static int fs_enet_open(struct net_device *dev)
770static int fs_enet_close(struct net_device *dev) 821static int fs_enet_close(struct net_device *dev)
771{ 822{
772 struct fs_enet_private *fep = netdev_priv(dev); 823 struct fs_enet_private *fep = netdev_priv(dev);
773 const struct fs_platform_info *fpi = fep->fpi;
774 unsigned long flags; 824 unsigned long flags;
775 825
776 netif_stop_queue(dev); 826 netif_stop_queue(dev);
777 netif_carrier_off(dev); 827 netif_carrier_off(dev);
778 fs_mii_shutdown(dev); 828 phy_stop(fep->phydev);
779 829
780 spin_lock_irqsave(&fep->lock, flags); 830 spin_lock_irqsave(&fep->lock, flags);
781 (*fep->ops->stop)(dev); 831 (*fep->ops->stop)(dev);
782 spin_unlock_irqrestore(&fep->lock, flags); 832 spin_unlock_irqrestore(&fep->lock, flags);
783 833
784 /* release any irqs */ 834 /* release any irqs */
785 if (fpi->phy_irq != -1) 835 phy_disconnect(fep->phydev);
786 fs_free_irq(dev, fpi->phy_irq); 836 fep->phydev = NULL;
787 fs_free_irq(dev, fep->interrupt); 837 fs_free_irq(dev, fep->interrupt);
788 838
789 return 0; 839 return 0;
@@ -831,33 +881,19 @@ static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
831static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 881static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
832{ 882{
833 struct fs_enet_private *fep = netdev_priv(dev); 883 struct fs_enet_private *fep = netdev_priv(dev);
834 unsigned long flags; 884 return phy_ethtool_gset(fep->phydev, cmd);
835 int rc;
836
837 spin_lock_irqsave(&fep->lock, flags);
838 rc = mii_ethtool_gset(&fep->mii_if, cmd);
839 spin_unlock_irqrestore(&fep->lock, flags);
840
841 return rc;
842} 885}
843 886
844static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 887static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
845{ 888{
846 struct fs_enet_private *fep = netdev_priv(dev); 889 struct fs_enet_private *fep = netdev_priv(dev);
847 unsigned long flags; 890 phy_ethtool_sset(fep->phydev, cmd);
848 int rc; 891 return 0;
849
850 spin_lock_irqsave(&fep->lock, flags);
851 rc = mii_ethtool_sset(&fep->mii_if, cmd);
852 spin_unlock_irqrestore(&fep->lock, flags);
853
854 return rc;
855} 892}
856 893
857static int fs_nway_reset(struct net_device *dev) 894static int fs_nway_reset(struct net_device *dev)
858{ 895{
859 struct fs_enet_private *fep = netdev_priv(dev); 896 return 0;
860 return mii_nway_restart(&fep->mii_if);
861} 897}
862 898
863static u32 fs_get_msglevel(struct net_device *dev) 899static u32 fs_get_msglevel(struct net_device *dev)
@@ -872,7 +908,7 @@ static void fs_set_msglevel(struct net_device *dev, u32 value)
872 fep->msg_enable = value; 908 fep->msg_enable = value;
873} 909}
874 910
875static struct ethtool_ops fs_ethtool_ops = { 911static const struct ethtool_ops fs_ethtool_ops = {
876 .get_drvinfo = fs_get_drvinfo, 912 .get_drvinfo = fs_get_drvinfo,
877 .get_regs_len = fs_get_regs_len, 913 .get_regs_len = fs_get_regs_len,
878 .get_settings = fs_get_settings, 914 .get_settings = fs_get_settings,
@@ -899,7 +935,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
899 return -EINVAL; 935 return -EINVAL;
900 936
901 spin_lock_irqsave(&fep->lock, flags); 937 spin_lock_irqsave(&fep->lock, flags);
902 rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); 938 rc = phy_mii_ioctl(fep->phydev, mii, cmd);
903 spin_unlock_irqrestore(&fep->lock, flags); 939 spin_unlock_irqrestore(&fep->lock, flags);
904 return rc; 940 return rc;
905} 941}
@@ -1031,12 +1067,6 @@ static struct net_device *fs_init_instance(struct device *dev,
1031 } 1067 }
1032 registered = 1; 1068 registered = 1;
1033 1069
1034 err = fs_mii_connect(ndev);
1035 if (err != 0) {
1036 printk(KERN_ERR DRV_MODULE_NAME
1037 ": %s fs_mii_connect failed.\n", ndev->name);
1038 goto err;
1039 }
1040 1070
1041 return ndev; 1071 return ndev;
1042 1072
@@ -1074,8 +1104,6 @@ static int fs_cleanup_instance(struct net_device *ndev)
1074 1104
1075 fpi = fep->fpi; 1105 fpi = fep->fpi;
1076 1106
1077 fs_mii_disconnect(ndev);
1078
1079 unregister_netdev(ndev); 1107 unregister_netdev(ndev);
1080 1108
1081 dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), 1109 dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
@@ -1197,17 +1225,39 @@ static int __init fs_init(void)
1197 r = setup_immap(); 1225 r = setup_immap();
1198 if (r != 0) 1226 if (r != 0)
1199 return r; 1227 return r;
1200 r = driver_register(&fs_enet_fec_driver); 1228
1229#ifdef CONFIG_FS_ENET_HAS_FCC
1230 /* let's insert mii stuff */
1231 r = fs_enet_mdio_bb_init();
1232
1233 if (r != 0) {
1234 printk(KERN_ERR DRV_MODULE_NAME
1235 "BB PHY init failed.\n");
1236 return r;
1237 }
1238 r = driver_register(&fs_enet_fcc_driver);
1201 if (r != 0) 1239 if (r != 0)
1202 goto err; 1240 goto err;
1241#endif
1203 1242
1204 r = driver_register(&fs_enet_fcc_driver); 1243#ifdef CONFIG_FS_ENET_HAS_FEC
1244 r = fs_enet_mdio_fec_init();
1245 if (r != 0) {
1246 printk(KERN_ERR DRV_MODULE_NAME
1247 "FEC PHY init failed.\n");
1248 return r;
1249 }
1250
1251 r = driver_register(&fs_enet_fec_driver);
1205 if (r != 0) 1252 if (r != 0)
1206 goto err; 1253 goto err;
1254#endif
1207 1255
1256#ifdef CONFIG_FS_ENET_HAS_SCC
1208 r = driver_register(&fs_enet_scc_driver); 1257 r = driver_register(&fs_enet_scc_driver);
1209 if (r != 0) 1258 if (r != 0)
1210 goto err; 1259 goto err;
1260#endif
1211 1261
1212 return 0; 1262 return 0;
1213err: 1263err: