aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fs_enet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fs_enet')
-rw-r--r--drivers/net/fs_enet/Makefile6
-rw-r--r--drivers/net/fs_enet/fec.h42
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c212
-rw-r--r--drivers/net/fs_enet/fs_enet-mii.c507
-rw-r--r--drivers/net/fs_enet/fs_enet.h43
-rw-r--r--drivers/net/fs_enet/mac-fcc.c33
-rw-r--r--drivers/net/fs_enet/mac-fec.c143
-rw-r--r--drivers/net/fs_enet/mac-scc.c5
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c449
-rw-r--r--drivers/net/fs_enet/mii-fec.c243
-rw-r--r--drivers/net/fs_enet/mii-fixed.c92
11 files changed, 714 insertions, 1061 deletions
diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile
index d6dd3f2fb43e..02d4dc18ba69 100644
--- a/drivers/net/fs_enet/Makefile
+++ b/drivers/net/fs_enet/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_FS_ENET) += fs_enet.o 5obj-$(CONFIG_FS_ENET) += fs_enet.o
6 6
7obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o 7obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o mii-fec.o
8obj-$(CONFIG_8260) += mac-fcc.o 8obj-$(CONFIG_CPM2) += mac-fcc.o mii-bitbang.o
9 9
10fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o 10fs_enet-objs := fs_enet-main.o
diff --git a/drivers/net/fs_enet/fec.h b/drivers/net/fs_enet/fec.h
new file mode 100644
index 000000000000..e980527e2b99
--- /dev/null
+++ b/drivers/net/fs_enet/fec.h
@@ -0,0 +1,42 @@
1#ifndef FS_ENET_FEC_H
2#define FS_ENET_FEC_H
3
4/* CRC polynomium used by the FEC for the multicast group filtering */
5#define FEC_CRC_POLY 0x04C11DB7
6
7#define FEC_MAX_MULTICAST_ADDRS 64
8
9/* Interrupt events/masks.
10*/
11#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */
12#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */
13#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */
14#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */
15#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */
16#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */
17#define FEC_ENET_RXF 0x02000000U /* Full frame received */
18#define FEC_ENET_RXB 0x01000000U /* A buffer was received */
19#define FEC_ENET_MII 0x00800000U /* MII interrupt */
20#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */
21
22#define FEC_ECNTRL_PINMUX 0x00000004
23#define FEC_ECNTRL_ETHER_EN 0x00000002
24#define FEC_ECNTRL_RESET 0x00000001
25
26#define FEC_RCNTRL_BC_REJ 0x00000010
27#define FEC_RCNTRL_PROM 0x00000008
28#define FEC_RCNTRL_MII_MODE 0x00000004
29#define FEC_RCNTRL_DRT 0x00000002
30#define FEC_RCNTRL_LOOP 0x00000001
31
32#define FEC_TCNTRL_FDEN 0x00000004
33#define FEC_TCNTRL_HBC 0x00000002
34#define FEC_TCNTRL_GTS 0x00000001
35
36
37
38/*
39 * Delay to wait for FEC reset command to complete (in us)
40 */
41#define FEC_RESET_DELAY 50
42#endif
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 196298f33db8..34412bc7c4b6 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:
diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c
deleted file mode 100644
index c6770377ef87..000000000000
--- a/drivers/net/fs_enet/fs_enet-mii.c
+++ /dev/null
@@ -1,507 +0,0 @@
1/*
2 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
3 *
4 * Copyright (c) 2003 Intracom S.A.
5 * by Pantelis Antoniou <panto@intracom.gr>
6 *
7 * 2005 (c) MontaVista Software, Inc.
8 * Vitaly Bordug <vbordug@ru.mvista.com>
9 *
10 * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
11 * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
12 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 */
17
18
19#include <linux/config.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/string.h>
25#include <linux/ptrace.h>
26#include <linux/errno.h>
27#include <linux/ioport.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/pci.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/skbuff.h>
36#include <linux/spinlock.h>
37#include <linux/mii.h>
38#include <linux/ethtool.h>
39#include <linux/bitops.h>
40
41#include <asm/pgtable.h>
42#include <asm/irq.h>
43#include <asm/uaccess.h>
44
45#include "fs_enet.h"
46
47/*************************************************/
48
49/*
50 * Generic PHY support.
51 * Should work for all PHYs, but link change is detected by polling
52 */
53
54static void generic_timer_callback(unsigned long data)
55{
56 struct net_device *dev = (struct net_device *)data;
57 struct fs_enet_private *fep = netdev_priv(dev);
58
59 fep->phy_timer_list.expires = jiffies + HZ / 2;
60
61 add_timer(&fep->phy_timer_list);
62
63 fs_mii_link_status_change_check(dev, 0);
64}
65
66static void generic_startup(struct net_device *dev)
67{
68 struct fs_enet_private *fep = netdev_priv(dev);
69
70 fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */
71 fep->phy_timer_list.data = (unsigned long)dev;
72 fep->phy_timer_list.function = generic_timer_callback;
73 add_timer(&fep->phy_timer_list);
74}
75
76static void generic_shutdown(struct net_device *dev)
77{
78 struct fs_enet_private *fep = netdev_priv(dev);
79
80 del_timer_sync(&fep->phy_timer_list);
81}
82
83/* ------------------------------------------------------------------------- */
84/* The Davicom DM9161 is used on the NETTA board */
85
86/* register definitions */
87
88#define MII_DM9161_ANAR 4 /* Aux. Config Register */
89#define MII_DM9161_ACR 16 /* Aux. Config Register */
90#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */
91#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */
92#define MII_DM9161_INTR 21 /* Interrupt Register */
93#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */
94#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */
95
96static void dm9161_startup(struct net_device *dev)
97{
98 struct fs_enet_private *fep = netdev_priv(dev);
99
100 fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
101 /* Start autonegotiation */
102 fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
103
104 set_current_state(TASK_UNINTERRUPTIBLE);
105 schedule_timeout(HZ*8);
106}
107
108static void dm9161_ack_int(struct net_device *dev)
109{
110 struct fs_enet_private *fep = netdev_priv(dev);
111
112 fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
113}
114
115static void dm9161_shutdown(struct net_device *dev)
116{
117 struct fs_enet_private *fep = netdev_priv(dev);
118
119 fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
120}
121
122/**********************************************************************************/
123
124static const struct phy_info phy_info[] = {
125 {
126 .id = 0x00181b88,
127 .name = "DM9161",
128 .startup = dm9161_startup,
129 .ack_int = dm9161_ack_int,
130 .shutdown = dm9161_shutdown,
131 }, {
132 .id = 0,
133 .name = "GENERIC",
134 .startup = generic_startup,
135 .shutdown = generic_shutdown,
136 },
137};
138
139/**********************************************************************************/
140
141static int phy_id_detect(struct net_device *dev)
142{
143 struct fs_enet_private *fep = netdev_priv(dev);
144 const struct fs_platform_info *fpi = fep->fpi;
145 struct fs_enet_mii_bus *bus = fep->mii_bus;
146 int i, r, start, end, phytype, physubtype;
147 const struct phy_info *phy;
148 int phy_hwid, phy_id;
149
150 phy_hwid = -1;
151 fep->phy = NULL;
152
153 /* auto-detect? */
154 if (fpi->phy_addr == -1) {
155 start = 1;
156 end = 32;
157 } else { /* direct */
158 start = fpi->phy_addr;
159 end = start + 1;
160 }
161
162 for (phy_id = start; phy_id < end; phy_id++) {
163 /* skip already used phy addresses on this bus */
164 if (bus->usage_map & (1 << phy_id))
165 continue;
166 r = fs_mii_read(dev, phy_id, MII_PHYSID1);
167 if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
168 continue;
169 r = fs_mii_read(dev, phy_id, MII_PHYSID2);
170 if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
171 continue;
172 phy_hwid = (phytype << 16) | physubtype;
173 if (phy_hwid != -1)
174 break;
175 }
176
177 if (phy_hwid == -1) {
178 printk(KERN_ERR DRV_MODULE_NAME
179 ": %s No PHY detected! range=0x%02x-0x%02x\n",
180 dev->name, start, end);
181 return -1;
182 }
183
184 for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
185 if (phy->id == (phy_hwid >> 4) || phy->id == 0)
186 break;
187
188 if (i >= ARRAY_SIZE(phy_info)) {
189 printk(KERN_ERR DRV_MODULE_NAME
190 ": %s PHY id 0x%08x is not supported!\n",
191 dev->name, phy_hwid);
192 return -1;
193 }
194
195 fep->phy = phy;
196
197 /* mark this address as used */
198 bus->usage_map |= (1 << phy_id);
199
200 printk(KERN_INFO DRV_MODULE_NAME
201 ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
202 dev->name, phy_id, fep->phy->name, phy_hwid,
203 fpi->phy_addr == -1 ? " (auto-detected)" : "");
204
205 return phy_id;
206}
207
208void fs_mii_startup(struct net_device *dev)
209{
210 struct fs_enet_private *fep = netdev_priv(dev);
211
212 if (fep->phy->startup)
213 (*fep->phy->startup) (dev);
214}
215
216void fs_mii_shutdown(struct net_device *dev)
217{
218 struct fs_enet_private *fep = netdev_priv(dev);
219
220 if (fep->phy->shutdown)
221 (*fep->phy->shutdown) (dev);
222}
223
224void fs_mii_ack_int(struct net_device *dev)
225{
226 struct fs_enet_private *fep = netdev_priv(dev);
227
228 if (fep->phy->ack_int)
229 (*fep->phy->ack_int) (dev);
230}
231
232#define MII_LINK 0x0001
233#define MII_HALF 0x0002
234#define MII_FULL 0x0004
235#define MII_BASE4 0x0008
236#define MII_10M 0x0010
237#define MII_100M 0x0020
238#define MII_1G 0x0040
239#define MII_10G 0x0080
240
241/* return full mii info at one gulp, with a usable form */
242static unsigned int mii_full_status(struct mii_if_info *mii)
243{
244 unsigned int status;
245 int bmsr, adv, lpa, neg;
246 struct fs_enet_private* fep = netdev_priv(mii->dev);
247
248 /* first, a dummy read, needed to latch some MII phys */
249 (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
250 bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
251
252 /* no link */
253 if ((bmsr & BMSR_LSTATUS) == 0)
254 return 0;
255
256 status = MII_LINK;
257
258 /* Lets look what ANEG says if it's supported - otherwize we shall
259 take the right values from the platform info*/
260 if(!mii->force_media) {
261 /* autoneg not completed; don't bother */
262 if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
263 return 0;
264
265 adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
266 lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
267
268 neg = lpa & adv;
269 } else {
270 neg = fep->fpi->bus_info->lpa;
271 }
272
273 if (neg & LPA_100FULL)
274 status |= MII_FULL | MII_100M;
275 else if (neg & LPA_100BASE4)
276 status |= MII_FULL | MII_BASE4 | MII_100M;
277 else if (neg & LPA_100HALF)
278 status |= MII_HALF | MII_100M;
279 else if (neg & LPA_10FULL)
280 status |= MII_FULL | MII_10M;
281 else
282 status |= MII_HALF | MII_10M;
283
284 return status;
285}
286
287void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
288{
289 struct fs_enet_private *fep = netdev_priv(dev);
290 struct mii_if_info *mii = &fep->mii_if;
291 unsigned int mii_status;
292 int ok_to_print, link, duplex, speed;
293 unsigned long flags;
294
295 ok_to_print = netif_msg_link(fep);
296
297 mii_status = mii_full_status(mii);
298
299 if (!init_media && mii_status == fep->last_mii_status)
300 return;
301
302 fep->last_mii_status = mii_status;
303
304 link = !!(mii_status & MII_LINK);
305 duplex = !!(mii_status & MII_FULL);
306 speed = (mii_status & MII_100M) ? 100 : 10;
307
308 if (link == 0) {
309 netif_carrier_off(mii->dev);
310 netif_stop_queue(dev);
311 if (!init_media) {
312 spin_lock_irqsave(&fep->lock, flags);
313 (*fep->ops->stop)(dev);
314 spin_unlock_irqrestore(&fep->lock, flags);
315 }
316
317 if (ok_to_print)
318 printk(KERN_INFO "%s: link down\n", mii->dev->name);
319
320 } else {
321
322 mii->full_duplex = duplex;
323
324 netif_carrier_on(mii->dev);
325
326 spin_lock_irqsave(&fep->lock, flags);
327 fep->duplex = duplex;
328 fep->speed = speed;
329 (*fep->ops->restart)(dev);
330 spin_unlock_irqrestore(&fep->lock, flags);
331
332 netif_start_queue(dev);
333
334 if (ok_to_print)
335 printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
336 dev->name, speed, duplex ? "full" : "half");
337 }
338}
339
340/**********************************************************************************/
341
342int fs_mii_read(struct net_device *dev, int phy_id, int location)
343{
344 struct fs_enet_private *fep = netdev_priv(dev);
345 struct fs_enet_mii_bus *bus = fep->mii_bus;
346
347 unsigned long flags;
348 int ret;
349
350 spin_lock_irqsave(&bus->mii_lock, flags);
351 ret = (*bus->mii_read)(bus, phy_id, location);
352 spin_unlock_irqrestore(&bus->mii_lock, flags);
353
354 return ret;
355}
356
357void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
358{
359 struct fs_enet_private *fep = netdev_priv(dev);
360 struct fs_enet_mii_bus *bus = fep->mii_bus;
361 unsigned long flags;
362
363 spin_lock_irqsave(&bus->mii_lock, flags);
364 (*bus->mii_write)(bus, phy_id, location, value);
365 spin_unlock_irqrestore(&bus->mii_lock, flags);
366}
367
368/*****************************************************************************/
369
370/* list of all registered mii buses */
371static LIST_HEAD(fs_mii_bus_list);
372
373static struct fs_enet_mii_bus *lookup_bus(int method, int id)
374{
375 struct list_head *ptr;
376 struct fs_enet_mii_bus *bus;
377
378 list_for_each(ptr, &fs_mii_bus_list) {
379 bus = list_entry(ptr, struct fs_enet_mii_bus, list);
380 if (bus->bus_info->method == method &&
381 bus->bus_info->id == id)
382 return bus;
383 }
384 return NULL;
385}
386
387static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
388{
389 struct fs_enet_mii_bus *bus;
390 int ret = 0;
391
392 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
393 if (bus == NULL) {
394 ret = -ENOMEM;
395 goto err;
396 }
397 memset(bus, 0, sizeof(*bus));
398 spin_lock_init(&bus->mii_lock);
399 bus->bus_info = bi;
400 bus->refs = 0;
401 bus->usage_map = 0;
402
403 /* perform initialization */
404 switch (bi->method) {
405
406 case fsmii_fixed:
407 ret = fs_mii_fixed_init(bus);
408 if (ret != 0)
409 goto err;
410 break;
411
412 case fsmii_bitbang:
413 ret = fs_mii_bitbang_init(bus);
414 if (ret != 0)
415 goto err;
416 break;
417#ifdef CONFIG_FS_ENET_HAS_FEC
418 case fsmii_fec:
419 ret = fs_mii_fec_init(bus);
420 if (ret != 0)
421 goto err;
422 break;
423#endif
424 default:
425 ret = -EINVAL;
426 goto err;
427 }
428
429 list_add(&bus->list, &fs_mii_bus_list);
430
431 return bus;
432
433err:
434 if (bus)
435 kfree(bus);
436 return ERR_PTR(ret);
437}
438
439static void destroy_bus(struct fs_enet_mii_bus *bus)
440{
441 /* remove from bus list */
442 list_del(&bus->list);
443
444 /* nothing more needed */
445 kfree(bus);
446}
447
448int fs_mii_connect(struct net_device *dev)
449{
450 struct fs_enet_private *fep = netdev_priv(dev);
451 const struct fs_platform_info *fpi = fep->fpi;
452 struct fs_enet_mii_bus *bus = NULL;
453
454 /* check method validity */
455 switch (fpi->bus_info->method) {
456 case fsmii_fixed:
457 case fsmii_bitbang:
458 break;
459#ifdef CONFIG_FS_ENET_HAS_FEC
460 case fsmii_fec:
461 break;
462#endif
463 default:
464 printk(KERN_ERR DRV_MODULE_NAME
465 ": %s Unknown MII bus method (%d)!\n",
466 dev->name, fpi->bus_info->method);
467 return -EINVAL;
468 }
469
470 bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
471
472 /* if not found create new bus */
473 if (bus == NULL) {
474 bus = create_bus(fpi->bus_info);
475 if (IS_ERR(bus)) {
476 printk(KERN_ERR DRV_MODULE_NAME
477 ": %s MII bus creation failure!\n", dev->name);
478 return PTR_ERR(bus);
479 }
480 }
481
482 bus->refs++;
483
484 fep->mii_bus = bus;
485
486 fep->mii_if.dev = dev;
487 fep->mii_if.phy_id_mask = 0x1f;
488 fep->mii_if.reg_num_mask = 0x1f;
489 fep->mii_if.mdio_read = fs_mii_read;
490 fep->mii_if.mdio_write = fs_mii_write;
491 fep->mii_if.force_media = fpi->bus_info->disable_aneg;
492 fep->mii_if.phy_id = phy_id_detect(dev);
493
494 return 0;
495}
496
497void fs_mii_disconnect(struct net_device *dev)
498{
499 struct fs_enet_private *fep = netdev_priv(dev);
500 struct fs_enet_mii_bus *bus = NULL;
501
502 bus = fep->mii_bus;
503 fep->mii_bus = NULL;
504
505 if (--bus->refs <= 0)
506 destroy_bus(bus);
507}
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index e7ec96c964a9..92590d8fc24b 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -5,19 +5,37 @@
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/list.h> 7#include <linux/list.h>
8#include <linux/phy.h>
9#include <linux/dma-mapping.h>
8 10
9#include <linux/fs_enet_pd.h> 11#include <linux/fs_enet_pd.h>
10 12
11#include <asm/dma-mapping.h>
12
13#ifdef CONFIG_CPM1 13#ifdef CONFIG_CPM1
14#include <asm/commproc.h> 14#include <asm/commproc.h>
15
16struct fec_info {
17 fec_t* fecp;
18 u32 mii_speed;
19};
15#endif 20#endif
16 21
17#ifdef CONFIG_CPM2 22#ifdef CONFIG_CPM2
18#include <asm/cpm2.h> 23#include <asm/cpm2.h>
19#endif 24#endif
20 25
26/* This is used to operate with pins.
27 Note that the actual port size may
28 be different; cpm(s) handle it OK */
29struct bb_info {
30 u8 mdio_dat_msk;
31 u8 mdio_dir_msk;
32 u8 *mdio_dir;
33 u8 *mdio_dat;
34 u8 mdc_msk;
35 u8 *mdc_dat;
36 int delay;
37};
38
21/* hw driver ops */ 39/* hw driver ops */
22struct fs_ops { 40struct fs_ops {
23 int (*setup_data)(struct net_device *dev); 41 int (*setup_data)(struct net_device *dev);
@@ -25,6 +43,7 @@ struct fs_ops {
25 void (*free_bd)(struct net_device *dev); 43 void (*free_bd)(struct net_device *dev);
26 void (*cleanup_data)(struct net_device *dev); 44 void (*cleanup_data)(struct net_device *dev);
27 void (*set_multicast_list)(struct net_device *dev); 45 void (*set_multicast_list)(struct net_device *dev);
46 void (*adjust_link)(struct net_device *dev);
28 void (*restart)(struct net_device *dev); 47 void (*restart)(struct net_device *dev);
29 void (*stop)(struct net_device *dev); 48 void (*stop)(struct net_device *dev);
30 void (*pre_request_irq)(struct net_device *dev, int irq); 49 void (*pre_request_irq)(struct net_device *dev, int irq);
@@ -100,10 +119,6 @@ struct fs_enet_mii_bus {
100 }; 119 };
101}; 120};
102 121
103int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus);
104int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
105int fs_mii_fec_init(struct fs_enet_mii_bus *bus);
106
107struct fs_enet_private { 122struct fs_enet_private {
108 struct device *dev; /* pointer back to the device (must be initialized first) */ 123 struct device *dev; /* pointer back to the device (must be initialized first) */
109 spinlock_t lock; /* during all ops except TX pckt processing */ 124 spinlock_t lock; /* during all ops except TX pckt processing */
@@ -130,7 +145,8 @@ struct fs_enet_private {
130 struct fs_enet_mii_bus *mii_bus; 145 struct fs_enet_mii_bus *mii_bus;
131 int interrupt; 146 int interrupt;
132 147
133 int duplex, speed; /* current settings */ 148 struct phy_device *phydev;
149 int oldduplex, oldspeed, oldlink; /* current settings */
134 150
135 /* event masks */ 151 /* event masks */
136 u32 ev_napi_rx; /* mask of NAPI rx events */ 152 u32 ev_napi_rx; /* mask of NAPI rx events */
@@ -168,15 +184,9 @@ struct fs_enet_private {
168}; 184};
169 185
170/***************************************************************************/ 186/***************************************************************************/
171 187int fs_enet_mdio_bb_init(void);
172int fs_mii_read(struct net_device *dev, int phy_id, int location); 188int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
173void fs_mii_write(struct net_device *dev, int phy_id, int location, int value); 189int fs_enet_mdio_fec_init(void);
174
175void fs_mii_startup(struct net_device *dev);
176void fs_mii_shutdown(struct net_device *dev);
177void fs_mii_ack_int(struct net_device *dev);
178
179void fs_mii_link_status_change_check(struct net_device *dev, int init_media);
180 190
181void fs_init_bds(struct net_device *dev); 191void fs_init_bds(struct net_device *dev);
182void fs_cleanup_bds(struct net_device *dev); 192void fs_cleanup_bds(struct net_device *dev);
@@ -194,7 +204,6 @@ int fs_enet_platform_init(void);
194void fs_enet_platform_cleanup(void); 204void fs_enet_platform_cleanup(void);
195 205
196/***************************************************************************/ 206/***************************************************************************/
197
198/* buffer descriptor access macros */ 207/* buffer descriptor access macros */
199 208
200/* access macros */ 209/* access macros */
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 95e2bb8dd7b4..1ff2597b8495 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -12,7 +12,6 @@
12 * kind, whether express or implied. 12 * kind, whether express or implied.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/types.h> 17#include <linux/types.h>
@@ -35,6 +34,7 @@
35#include <linux/bitops.h> 34#include <linux/bitops.h>
36#include <linux/fs.h> 35#include <linux/fs.h>
37#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/phy.h>
38 38
39#include <asm/immap_cpm2.h> 39#include <asm/immap_cpm2.h>
40#include <asm/mpc8260.h> 40#include <asm/mpc8260.h>
@@ -123,22 +123,32 @@ static int do_pd_setup(struct fs_enet_private *fep)
123 123
124 /* Attach the memory for the FCC Parameter RAM */ 124 /* Attach the memory for the FCC Parameter RAM */
125 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); 125 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
126 fep->fcc.ep = (void *)r->start; 126 fep->fcc.ep = (void *)ioremap(r->start, r->end - r->start + 1);
127
128 if (fep->fcc.ep == NULL) 127 if (fep->fcc.ep == NULL)
129 return -EINVAL; 128 return -EINVAL;
130 129
131 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); 130 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
132 fep->fcc.fccp = (void *)r->start; 131 fep->fcc.fccp = (void *)ioremap(r->start, r->end - r->start + 1);
133
134 if (fep->fcc.fccp == NULL) 132 if (fep->fcc.fccp == NULL)
135 return -EINVAL; 133 return -EINVAL;
136 134
137 fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; 135 if (fep->fpi->fcc_regs_c) {
136
137 fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c;
138 } else {
139 r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
140 "fcc_regs_c");
141 fep->fcc.fcccp = (void *)ioremap(r->start,
142 r->end - r->start + 1);
143 }
138 144
139 if (fep->fcc.fcccp == NULL) 145 if (fep->fcc.fcccp == NULL)
140 return -EINVAL; 146 return -EINVAL;
141 147
148 fep->fcc.mem = (void *)fep->fpi->mem_offset;
149 if (fep->fcc.mem == NULL)
150 return -EINVAL;
151
142 return 0; 152 return 0;
143} 153}
144 154
@@ -156,8 +166,6 @@ static int setup_data(struct net_device *dev)
156 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ 166 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
157 return -EINVAL; 167 return -EINVAL;
158 168
159 fep->fcc.mem = (void *)fpi->mem_offset;
160
161 if (do_pd_setup(fep) != 0) 169 if (do_pd_setup(fep) != 0)
162 return -EINVAL; 170 return -EINVAL;
163 171
@@ -395,7 +403,7 @@ static void restart(struct net_device *dev)
395 403
396 /* adjust to speed (for RMII mode) */ 404 /* adjust to speed (for RMII mode) */
397 if (fpi->use_rmii) { 405 if (fpi->use_rmii) {
398 if (fep->speed == 100) 406 if (fep->phydev->speed == 100)
399 C8(fcccp, fcc_gfemr, 0x20); 407 C8(fcccp, fcc_gfemr, 0x20);
400 else 408 else
401 S8(fcccp, fcc_gfemr, 0x20); 409 S8(fcccp, fcc_gfemr, 0x20);
@@ -421,7 +429,7 @@ static void restart(struct net_device *dev)
421 S32(fccp, fcc_fpsmr, FCC_PSMR_RMII); 429 S32(fccp, fcc_fpsmr, FCC_PSMR_RMII);
422 430
423 /* adjust to duplex mode */ 431 /* adjust to duplex mode */
424 if (fep->duplex) 432 if (fep->phydev->duplex)
425 S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); 433 S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
426 else 434 else
427 C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); 435 C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
@@ -487,7 +495,10 @@ static void rx_bd_done(struct net_device *dev)
487 495
488static void tx_kickstart(struct net_device *dev) 496static void tx_kickstart(struct net_device *dev)
489{ 497{
490 /* nothing */ 498 struct fs_enet_private *fep = netdev_priv(dev);
499 fcc_t *fccp = fep->fcc.fccp;
500
501 S32(fccp, fcc_ftodr, 0x80);
491} 502}
492 503
493static u32 get_int_events(struct net_device *dev) 504static u32 get_int_events(struct net_device *dev)
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 3dad69dfdb2c..c2c5fd419bd0 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -12,7 +12,6 @@
12 * kind, whether express or implied. 12 * kind, whether express or implied.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/types.h> 17#include <linux/types.h>
@@ -47,6 +46,7 @@
47#endif 46#endif
48 47
49#include "fs_enet.h" 48#include "fs_enet.h"
49#include "fec.h"
50 50
51/*************************************************/ 51/*************************************************/
52 52
@@ -76,50 +76,8 @@
76/* clear bits */ 76/* clear bits */
77#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) 77#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v))
78 78
79
80/* CRC polynomium used by the FEC for the multicast group filtering */
81#define FEC_CRC_POLY 0x04C11DB7
82
83#define FEC_MAX_MULTICAST_ADDRS 64
84
85/* Interrupt events/masks.
86*/
87#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */
88#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */
89#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */
90#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */
91#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */
92#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */
93#define FEC_ENET_RXF 0x02000000U /* Full frame received */
94#define FEC_ENET_RXB 0x01000000U /* A buffer was received */
95#define FEC_ENET_MII 0x00800000U /* MII interrupt */
96#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */
97
98#define FEC_ECNTRL_PINMUX 0x00000004
99#define FEC_ECNTRL_ETHER_EN 0x00000002
100#define FEC_ECNTRL_RESET 0x00000001
101
102#define FEC_RCNTRL_BC_REJ 0x00000010
103#define FEC_RCNTRL_PROM 0x00000008
104#define FEC_RCNTRL_MII_MODE 0x00000004
105#define FEC_RCNTRL_DRT 0x00000002
106#define FEC_RCNTRL_LOOP 0x00000001
107
108#define FEC_TCNTRL_FDEN 0x00000004
109#define FEC_TCNTRL_HBC 0x00000002
110#define FEC_TCNTRL_GTS 0x00000001
111
112
113/* Make MII read/write commands for the FEC.
114*/
115#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
116#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
117#define mk_mii_end 0
118
119#define FEC_MII_LOOPS 10000
120
121/* 79/*
122 * Delay to wait for FEC reset command to complete (in us) 80 * Delay to wait for FEC reset command to complete (in us)
123 */ 81 */
124#define FEC_RESET_DELAY 50 82#define FEC_RESET_DELAY 50
125 83
@@ -304,13 +262,15 @@ static void restart(struct net_device *dev)
304 int r; 262 int r;
305 u32 addrhi, addrlo; 263 u32 addrhi, addrlo;
306 264
265 struct mii_bus* mii = fep->phydev->bus;
266 struct fec_info* fec_inf = mii->priv;
267
307 r = whack_reset(fep->fec.fecp); 268 r = whack_reset(fep->fec.fecp);
308 if (r != 0) 269 if (r != 0)
309 printk(KERN_ERR DRV_MODULE_NAME 270 printk(KERN_ERR DRV_MODULE_NAME
310 ": %s FEC Reset FAILED!\n", dev->name); 271 ": %s FEC Reset FAILED!\n", dev->name);
311
312 /* 272 /*
313 * Set station address. 273 * Set station address.
314 */ 274 */
315 addrhi = ((u32) dev->dev_addr[0] << 24) | 275 addrhi = ((u32) dev->dev_addr[0] << 24) |
316 ((u32) dev->dev_addr[1] << 16) | 276 ((u32) dev->dev_addr[1] << 16) |
@@ -351,12 +311,12 @@ static void restart(struct net_device *dev)
351 FW(fecp, fun_code, 0x78000000); 311 FW(fecp, fun_code, 0x78000000);
352 312
353 /* 313 /*
354 * Set MII speed. 314 * Set MII speed.
355 */ 315 */
356 FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed); 316 FW(fecp, mii_speed, fec_inf->mii_speed);
357 317
358 /* 318 /*
359 * Clear any outstanding interrupt. 319 * Clear any outstanding interrupt.
360 */ 320 */
361 FW(fecp, ievent, 0xffc0); 321 FW(fecp, ievent, 0xffc0);
362 FW(fecp, ivec, (fep->interrupt / 2) << 29); 322 FW(fecp, ivec, (fep->interrupt / 2) << 29);
@@ -391,11 +351,12 @@ static void restart(struct net_device *dev)
391 } 351 }
392#endif 352#endif
393 353
354
394 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 355 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
395 /* 356 /*
396 * adjust to duplex mode 357 * adjust to duplex mode
397 */ 358 */
398 if (fep->duplex) { 359 if (fep->phydev->duplex) {
399 FC(fecp, r_cntrl, FEC_RCNTRL_DRT); 360 FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
400 FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ 361 FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */
401 } else { 362 } else {
@@ -419,9 +380,11 @@ static void restart(struct net_device *dev)
419static void stop(struct net_device *dev) 380static void stop(struct net_device *dev)
420{ 381{
421 struct fs_enet_private *fep = netdev_priv(dev); 382 struct fs_enet_private *fep = netdev_priv(dev);
383 const struct fs_platform_info *fpi = fep->fpi;
422 fec_t *fecp = fep->fec.fecp; 384 fec_t *fecp = fep->fec.fecp;
423 struct fs_enet_mii_bus *bus = fep->mii_bus; 385
424 const struct fs_mii_bus_info *bi = bus->bus_info; 386 struct fec_info* feci= fep->phydev->bus->priv;
387
425 int i; 388 int i;
426 389
427 if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) 390 if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
@@ -445,11 +408,11 @@ static void stop(struct net_device *dev)
445 fs_cleanup_bds(dev); 408 fs_cleanup_bds(dev);
446 409
447 /* shut down FEC1? that's where the mii bus is */ 410 /* shut down FEC1? that's where the mii bus is */
448 if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) { 411 if (fpi->has_phy) {
449 FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 412 FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
450 FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 413 FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
451 FW(fecp, ievent, FEC_ENET_MII); 414 FW(fecp, ievent, FEC_ENET_MII);
452 FW(fecp, mii_speed, bus->fec.mii_speed); 415 FW(fecp, mii_speed, feci->mii_speed);
453 } 416 }
454} 417}
455 418
@@ -584,73 +547,3 @@ const struct fs_ops fs_fec_ops = {
584 .free_bd = free_bd, 547 .free_bd = free_bd,
585}; 548};
586 549
587/***********************************************************************/
588
589static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
590{
591 fec_t *fecp = bus->fec.fecp;
592 int i, ret = -1;
593
594 if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
595 BUG();
596
597 /* Add PHY address to register command. */
598 FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location));
599
600 for (i = 0; i < FEC_MII_LOOPS; i++)
601 if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
602 break;
603
604 if (i < FEC_MII_LOOPS) {
605 FW(fecp, ievent, FEC_ENET_MII);
606 ret = FR(fecp, mii_data) & 0xffff;
607 }
608
609 return ret;
610}
611
612static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value)
613{
614 fec_t *fecp = bus->fec.fecp;
615 int i;
616
617 /* this must never happen */
618 if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
619 BUG();
620
621 /* Add PHY address to register command. */
622 FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value));
623
624 for (i = 0; i < FEC_MII_LOOPS; i++)
625 if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
626 break;
627
628 if (i < FEC_MII_LOOPS)
629 FW(fecp, ievent, FEC_ENET_MII);
630}
631
632int fs_mii_fec_init(struct fs_enet_mii_bus *bus)
633{
634 bd_t *bd = (bd_t *)__res;
635 const struct fs_mii_bus_info *bi = bus->bus_info;
636 fec_t *fecp;
637
638 if (bi->id != 0)
639 return -1;
640
641 bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec;
642 bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2)
643 & 0x3F) << 1;
644
645 fecp = bus->fec.fecp;
646
647 FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
648 FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
649 FW(fecp, ievent, FEC_ENET_MII);
650 FW(fecp, mii_speed, bus->fec.mii_speed);
651
652 bus->mii_read = mii_read;
653 bus->mii_write = mii_write;
654
655 return 0;
656}
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index a772b286f96d..95ec5872c507 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -12,7 +12,6 @@
12 * kind, whether express or implied. 12 * kind, whether express or implied.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/types.h> 17#include <linux/types.h>
@@ -370,7 +369,7 @@ static void restart(struct net_device *dev)
370 W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22); 369 W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
371 370
372 /* Set full duplex mode if needed */ 371 /* Set full duplex mode if needed */
373 if (fep->duplex) 372 if (fep->phydev->duplex)
374 S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); 373 S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
375 374
376 S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); 375 S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
@@ -501,6 +500,8 @@ static void tx_restart(struct net_device *dev)
501 scc_cr_cmd(fep, CPM_CR_RESTART_TX); 500 scc_cr_cmd(fep, CPM_CR_RESTART_TX);
502} 501}
503 502
503
504
504/*************************************************************************/ 505/*************************************************************************/
505 506
506const struct fs_ops fs_scc_ops = { 507const struct fs_ops fs_scc_ops = {
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 24a5e2e23d18..0b9b8b5c847c 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
@@ -34,6 +33,7 @@
34#include <linux/mii.h> 33#include <linux/mii.h>
35#include <linux/ethtool.h> 34#include <linux/ethtool.h>
36#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/platform_device.h>
37 37
38#include <asm/pgtable.h> 38#include <asm/pgtable.h>
39#include <asm/irq.h> 39#include <asm/irq.h>
@@ -41,129 +41,25 @@
41 41
42#include "fs_enet.h" 42#include "fs_enet.h"
43 43
44#ifdef CONFIG_8xx 44static int bitbang_prep_bit(u8 **datp, u8 *mskp,
45static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) 45 struct fs_mii_bit *mii_bit)
46{ 46{
47 immap_t *im = (immap_t *)fs_enet_immap; 47 void *dat;
48 void *dir, *dat, *ppar;
49 int adv; 48 int adv;
50 u8 msk; 49 u8 msk;
51 50
52 switch (port) { 51 dat = (void*) mii_bit->offset;
53 case fsiop_porta:
54 dir = &im->im_ioport.iop_padir;
55 dat = &im->im_ioport.iop_padat;
56 ppar = &im->im_ioport.iop_papar;
57 break;
58
59 case fsiop_portb:
60 dir = &im->im_cpm.cp_pbdir;
61 dat = &im->im_cpm.cp_pbdat;
62 ppar = &im->im_cpm.cp_pbpar;
63 break;
64
65 case fsiop_portc:
66 dir = &im->im_ioport.iop_pcdir;
67 dat = &im->im_ioport.iop_pcdat;
68 ppar = &im->im_ioport.iop_pcpar;
69 break;
70
71 case fsiop_portd:
72 dir = &im->im_ioport.iop_pddir;
73 dat = &im->im_ioport.iop_pddat;
74 ppar = &im->im_ioport.iop_pdpar;
75 break;
76
77 case fsiop_porte:
78 dir = &im->im_cpm.cp_pedir;
79 dat = &im->im_cpm.cp_pedat;
80 ppar = &im->im_cpm.cp_pepar;
81 break;
82
83 default:
84 printk(KERN_ERR DRV_MODULE_NAME
85 "Illegal port value %d!\n", port);
86 return -EINVAL;
87 }
88
89 adv = bit >> 3;
90 dir = (char *)dir + adv;
91 dat = (char *)dat + adv;
92 ppar = (char *)ppar + adv;
93
94 msk = 1 << (7 - (bit & 7));
95 if ((in_8(ppar) & msk) != 0) {
96 printk(KERN_ERR DRV_MODULE_NAME
97 "pin %d on port %d is not general purpose!\n", bit, port);
98 return -EINVAL;
99 }
100
101 *dirp = dir;
102 *datp = dat;
103 *mskp = msk;
104
105 return 0;
106}
107#endif
108
109#ifdef CONFIG_8260
110static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
111{
112 iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport;
113 void *dir, *dat, *ppar;
114 int adv;
115 u8 msk;
116
117 switch (port) {
118 case fsiop_porta:
119 dir = &io->iop_pdira;
120 dat = &io->iop_pdata;
121 ppar = &io->iop_ppara;
122 break;
123
124 case fsiop_portb:
125 dir = &io->iop_pdirb;
126 dat = &io->iop_pdatb;
127 ppar = &io->iop_pparb;
128 break;
129
130 case fsiop_portc:
131 dir = &io->iop_pdirc;
132 dat = &io->iop_pdatc;
133 ppar = &io->iop_pparc;
134 break;
135
136 case fsiop_portd:
137 dir = &io->iop_pdird;
138 dat = &io->iop_pdatd;
139 ppar = &io->iop_ppard;
140 break;
141
142 default:
143 printk(KERN_ERR DRV_MODULE_NAME
144 "Illegal port value %d!\n", port);
145 return -EINVAL;
146 }
147 52
148 adv = bit >> 3; 53 adv = mii_bit->bit >> 3;
149 dir = (char *)dir + adv;
150 dat = (char *)dat + adv; 54 dat = (char *)dat + adv;
151 ppar = (char *)ppar + adv;
152 55
153 msk = 1 << (7 - (bit & 7)); 56 msk = 1 << (7 - (mii_bit->bit & 7));
154 if ((in_8(ppar) & msk) != 0) {
155 printk(KERN_ERR DRV_MODULE_NAME
156 "pin %d on port %d is not general purpose!\n", bit, port);
157 return -EINVAL;
158 }
159 57
160 *dirp = dir;
161 *datp = dat; 58 *datp = dat;
162 *mskp = msk; 59 *mskp = msk;
163 60
164 return 0; 61 return 0;
165} 62}
166#endif
167 63
168static inline void bb_set(u8 *p, u8 m) 64static inline void bb_set(u8 *p, u8 m)
169{ 65{
@@ -180,44 +76,44 @@ static inline int bb_read(u8 *p, u8 m)
180 return (in_8(p) & m) != 0; 76 return (in_8(p) & m) != 0;
181} 77}
182 78
183static inline void mdio_active(struct fs_enet_mii_bus *bus) 79static inline void mdio_active(struct bb_info *bitbang)
184{ 80{
185 bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); 81 bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk);
186} 82}
187 83
188static inline void mdio_tristate(struct fs_enet_mii_bus *bus) 84static inline void mdio_tristate(struct bb_info *bitbang )
189{ 85{
190 bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); 86 bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk);
191} 87}
192 88
193static inline int mdio_read(struct fs_enet_mii_bus *bus) 89static inline int mdio_read(struct bb_info *bitbang )
194{ 90{
195 return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 91 return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk);
196} 92}
197 93
198static inline void mdio(struct fs_enet_mii_bus *bus, int what) 94static inline void mdio(struct bb_info *bitbang , int what)
199{ 95{
200 if (what) 96 if (what)
201 bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 97 bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk);
202 else 98 else
203 bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 99 bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk);
204} 100}
205 101
206static inline void mdc(struct fs_enet_mii_bus *bus, int what) 102static inline void mdc(struct bb_info *bitbang , int what)
207{ 103{
208 if (what) 104 if (what)
209 bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); 105 bb_set(bitbang->mdc_dat, bitbang->mdc_msk);
210 else 106 else
211 bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); 107 bb_clr(bitbang->mdc_dat, bitbang->mdc_msk);
212} 108}
213 109
214static inline void mii_delay(struct fs_enet_mii_bus *bus) 110static inline void mii_delay(struct bb_info *bitbang )
215{ 111{
216 udelay(bus->bus_info->i.bitbang.delay); 112 udelay(bitbang->delay);
217} 113}
218 114
219/* Utility to send the preamble, address, and register (common to read and write). */ 115/* Utility to send the preamble, address, and register (common to read and write). */
220static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg) 116static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg)
221{ 117{
222 int j; 118 int j;
223 119
@@ -229,177 +125,284 @@ static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg)
229 * but it is safer and will be much more robust. 125 * but it is safer and will be much more robust.
230 */ 126 */
231 127
232 mdio_active(bus); 128 mdio_active(bitbang);
233 mdio(bus, 1); 129 mdio(bitbang, 1);
234 for (j = 0; j < 32; j++) { 130 for (j = 0; j < 32; j++) {
235 mdc(bus, 0); 131 mdc(bitbang, 0);
236 mii_delay(bus); 132 mii_delay(bitbang);
237 mdc(bus, 1); 133 mdc(bitbang, 1);
238 mii_delay(bus); 134 mii_delay(bitbang);
239 } 135 }
240 136
241 /* send the start bit (01) and the read opcode (10) or write (10) */ 137 /* send the start bit (01) and the read opcode (10) or write (10) */
242 mdc(bus, 0); 138 mdc(bitbang, 0);
243 mdio(bus, 0); 139 mdio(bitbang, 0);
244 mii_delay(bus); 140 mii_delay(bitbang);
245 mdc(bus, 1); 141 mdc(bitbang, 1);
246 mii_delay(bus); 142 mii_delay(bitbang);
247 mdc(bus, 0); 143 mdc(bitbang, 0);
248 mdio(bus, 1); 144 mdio(bitbang, 1);
249 mii_delay(bus); 145 mii_delay(bitbang);
250 mdc(bus, 1); 146 mdc(bitbang, 1);
251 mii_delay(bus); 147 mii_delay(bitbang);
252 mdc(bus, 0); 148 mdc(bitbang, 0);
253 mdio(bus, read); 149 mdio(bitbang, read);
254 mii_delay(bus); 150 mii_delay(bitbang);
255 mdc(bus, 1); 151 mdc(bitbang, 1);
256 mii_delay(bus); 152 mii_delay(bitbang);
257 mdc(bus, 0); 153 mdc(bitbang, 0);
258 mdio(bus, !read); 154 mdio(bitbang, !read);
259 mii_delay(bus); 155 mii_delay(bitbang);
260 mdc(bus, 1); 156 mdc(bitbang, 1);
261 mii_delay(bus); 157 mii_delay(bitbang);
262 158
263 /* send the PHY address */ 159 /* send the PHY address */
264 for (j = 0; j < 5; j++) { 160 for (j = 0; j < 5; j++) {
265 mdc(bus, 0); 161 mdc(bitbang, 0);
266 mdio(bus, (addr & 0x10) != 0); 162 mdio(bitbang, (addr & 0x10) != 0);
267 mii_delay(bus); 163 mii_delay(bitbang);
268 mdc(bus, 1); 164 mdc(bitbang, 1);
269 mii_delay(bus); 165 mii_delay(bitbang);
270 addr <<= 1; 166 addr <<= 1;
271 } 167 }
272 168
273 /* send the register address */ 169 /* send the register address */
274 for (j = 0; j < 5; j++) { 170 for (j = 0; j < 5; j++) {
275 mdc(bus, 0); 171 mdc(bitbang, 0);
276 mdio(bus, (reg & 0x10) != 0); 172 mdio(bitbang, (reg & 0x10) != 0);
277 mii_delay(bus); 173 mii_delay(bitbang);
278 mdc(bus, 1); 174 mdc(bitbang, 1);
279 mii_delay(bus); 175 mii_delay(bitbang);
280 reg <<= 1; 176 reg <<= 1;
281 } 177 }
282} 178}
283 179
284static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) 180static int fs_enet_mii_bb_read(struct mii_bus *bus , int phy_id, int location)
285{ 181{
286 u16 rdreg; 182 u16 rdreg;
287 int ret, j; 183 int ret, j;
288 u8 addr = phy_id & 0xff; 184 u8 addr = phy_id & 0xff;
289 u8 reg = location & 0xff; 185 u8 reg = location & 0xff;
186 struct bb_info* bitbang = bus->priv;
290 187
291 bitbang_pre(bus, 1, addr, reg); 188 bitbang_pre(bitbang, 1, addr, reg);
292 189
293 /* tri-state our MDIO I/O pin so we can read */ 190 /* tri-state our MDIO I/O pin so we can read */
294 mdc(bus, 0); 191 mdc(bitbang, 0);
295 mdio_tristate(bus); 192 mdio_tristate(bitbang);
296 mii_delay(bus); 193 mii_delay(bitbang);
297 mdc(bus, 1); 194 mdc(bitbang, 1);
298 mii_delay(bus); 195 mii_delay(bitbang);
299 196
300 /* check the turnaround bit: the PHY should be driving it to zero */ 197 /* check the turnaround bit: the PHY should be driving it to zero */
301 if (mdio_read(bus) != 0) { 198 if (mdio_read(bitbang) != 0) {
302 /* PHY didn't drive TA low */ 199 /* PHY didn't drive TA low */
303 for (j = 0; j < 32; j++) { 200 for (j = 0; j < 32; j++) {
304 mdc(bus, 0); 201 mdc(bitbang, 0);
305 mii_delay(bus); 202 mii_delay(bitbang);
306 mdc(bus, 1); 203 mdc(bitbang, 1);
307 mii_delay(bus); 204 mii_delay(bitbang);
308 } 205 }
309 ret = -1; 206 ret = -1;
310 goto out; 207 goto out;
311 } 208 }
312 209
313 mdc(bus, 0); 210 mdc(bitbang, 0);
314 mii_delay(bus); 211 mii_delay(bitbang);
315 212
316 /* read 16 bits of register data, MSB first */ 213 /* read 16 bits of register data, MSB first */
317 rdreg = 0; 214 rdreg = 0;
318 for (j = 0; j < 16; j++) { 215 for (j = 0; j < 16; j++) {
319 mdc(bus, 1); 216 mdc(bitbang, 1);
320 mii_delay(bus); 217 mii_delay(bitbang);
321 rdreg <<= 1; 218 rdreg <<= 1;
322 rdreg |= mdio_read(bus); 219 rdreg |= mdio_read(bitbang);
323 mdc(bus, 0); 220 mdc(bitbang, 0);
324 mii_delay(bus); 221 mii_delay(bitbang);
325 } 222 }
326 223
327 mdc(bus, 1); 224 mdc(bitbang, 1);
328 mii_delay(bus); 225 mii_delay(bitbang);
329 mdc(bus, 0); 226 mdc(bitbang, 0);
330 mii_delay(bus); 227 mii_delay(bitbang);
331 mdc(bus, 1); 228 mdc(bitbang, 1);
332 mii_delay(bus); 229 mii_delay(bitbang);
333 230
334 ret = rdreg; 231 ret = rdreg;
335out: 232out:
336 return ret; 233 return ret;
337} 234}
338 235
339static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) 236static int fs_enet_mii_bb_write(struct mii_bus *bus, int phy_id, int location, u16 val)
340{ 237{
341 int j; 238 int j;
239 struct bb_info* bitbang = bus->priv;
240
342 u8 addr = phy_id & 0xff; 241 u8 addr = phy_id & 0xff;
343 u8 reg = location & 0xff; 242 u8 reg = location & 0xff;
344 u16 value = val & 0xffff; 243 u16 value = val & 0xffff;
345 244
346 bitbang_pre(bus, 0, addr, reg); 245 bitbang_pre(bitbang, 0, addr, reg);
347 246
348 /* send the turnaround (10) */ 247 /* send the turnaround (10) */
349 mdc(bus, 0); 248 mdc(bitbang, 0);
350 mdio(bus, 1); 249 mdio(bitbang, 1);
351 mii_delay(bus); 250 mii_delay(bitbang);
352 mdc(bus, 1); 251 mdc(bitbang, 1);
353 mii_delay(bus); 252 mii_delay(bitbang);
354 mdc(bus, 0); 253 mdc(bitbang, 0);
355 mdio(bus, 0); 254 mdio(bitbang, 0);
356 mii_delay(bus); 255 mii_delay(bitbang);
357 mdc(bus, 1); 256 mdc(bitbang, 1);
358 mii_delay(bus); 257 mii_delay(bitbang);
359 258
360 /* write 16 bits of register data, MSB first */ 259 /* write 16 bits of register data, MSB first */
361 for (j = 0; j < 16; j++) { 260 for (j = 0; j < 16; j++) {
362 mdc(bus, 0); 261 mdc(bitbang, 0);
363 mdio(bus, (value & 0x8000) != 0); 262 mdio(bitbang, (value & 0x8000) != 0);
364 mii_delay(bus); 263 mii_delay(bitbang);
365 mdc(bus, 1); 264 mdc(bitbang, 1);
366 mii_delay(bus); 265 mii_delay(bitbang);
367 value <<= 1; 266 value <<= 1;
368 } 267 }
369 268
370 /* 269 /*
371 * Tri-state the MDIO line. 270 * Tri-state the MDIO line.
372 */ 271 */
373 mdio_tristate(bus); 272 mdio_tristate(bitbang);
374 mdc(bus, 0); 273 mdc(bitbang, 0);
375 mii_delay(bus); 274 mii_delay(bitbang);
376 mdc(bus, 1); 275 mdc(bitbang, 1);
377 mii_delay(bus); 276 mii_delay(bitbang);
277 return 0;
378} 278}
379 279
380int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus) 280static int fs_enet_mii_bb_reset(struct mii_bus *bus)
281{
282 /*nothing here - dunno how to reset it*/
283 return 0;
284}
285
286static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi)
381{ 287{
382 const struct fs_mii_bus_info *bi = bus->bus_info;
383 int r; 288 int r;
384 289
385 r = bitbang_prep_bit(&bus->bitbang.mdio_dir, 290 bitbang->delay = fmpi->delay;
386 &bus->bitbang.mdio_dat, 291
387 &bus->bitbang.mdio_msk, 292 r = bitbang_prep_bit(&bitbang->mdio_dir,
388 bi->i.bitbang.mdio_port, 293 &bitbang->mdio_dir_msk,
389 bi->i.bitbang.mdio_bit); 294 &fmpi->mdio_dir);
390 if (r != 0) 295 if (r != 0)
391 return r; 296 return r;
392 297
393 r = bitbang_prep_bit(&bus->bitbang.mdc_dir, 298 r = bitbang_prep_bit(&bitbang->mdio_dat,
394 &bus->bitbang.mdc_dat, 299 &bitbang->mdio_dat_msk,
395 &bus->bitbang.mdc_msk, 300 &fmpi->mdio_dat);
396 bi->i.bitbang.mdc_port,
397 bi->i.bitbang.mdc_bit);
398 if (r != 0) 301 if (r != 0)
399 return r; 302 return r;
400 303
401 bus->mii_read = mii_read; 304 r = bitbang_prep_bit(&bitbang->mdc_dat,
402 bus->mii_write = mii_write; 305 &bitbang->mdc_msk,
306 &fmpi->mdc_dat);
307 if (r != 0)
308 return r;
403 309
404 return 0; 310 return 0;
405} 311}
312
313
314static int __devinit fs_enet_mdio_probe(struct device *dev)
315{
316 struct platform_device *pdev = to_platform_device(dev);
317 struct fs_mii_bb_platform_info *pdata;
318 struct mii_bus *new_bus;
319 struct bb_info *bitbang;
320 int err = 0;
321
322 if (NULL == dev)
323 return -EINVAL;
324
325 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
326
327 if (NULL == new_bus)
328 return -ENOMEM;
329
330 bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
331
332 if (NULL == bitbang)
333 return -ENOMEM;
334
335 new_bus->name = "BB MII Bus",
336 new_bus->read = &fs_enet_mii_bb_read,
337 new_bus->write = &fs_enet_mii_bb_write,
338 new_bus->reset = &fs_enet_mii_bb_reset,
339 new_bus->id = pdev->id;
340
341 new_bus->phy_mask = ~0x9;
342 pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data;
343
344 if (NULL == pdata) {
345 printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
346 return -ENODEV;
347 }
348
349 /*set up workspace*/
350 fs_mii_bitbang_init(bitbang, pdata);
351
352 new_bus->priv = bitbang;
353
354 new_bus->irq = pdata->irq;
355
356 new_bus->dev = dev;
357 dev_set_drvdata(dev, new_bus);
358
359 err = mdiobus_register(new_bus);
360
361 if (0 != err) {
362 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
363 new_bus->name);
364 goto bus_register_fail;
365 }
366
367 return 0;
368
369bus_register_fail:
370 kfree(bitbang);
371 kfree(new_bus);
372
373 return err;
374}
375
376
377static int fs_enet_mdio_remove(struct device *dev)
378{
379 struct mii_bus *bus = dev_get_drvdata(dev);
380
381 mdiobus_unregister(bus);
382
383 dev_set_drvdata(dev, NULL);
384
385 iounmap((void *) (&bus->priv));
386 bus->priv = NULL;
387 kfree(bus);
388
389 return 0;
390}
391
392static struct device_driver fs_enet_bb_mdio_driver = {
393 .name = "fsl-bb-mdio",
394 .bus = &platform_bus_type,
395 .probe = fs_enet_mdio_probe,
396 .remove = fs_enet_mdio_remove,
397};
398
399int fs_enet_mdio_bb_init(void)
400{
401 return driver_register(&fs_enet_bb_mdio_driver);
402}
403
404void fs_enet_mdio_bb_exit(void)
405{
406 driver_unregister(&fs_enet_bb_mdio_driver);
407}
408
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
new file mode 100644
index 000000000000..1328e10caa35
--- /dev/null
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -0,0 +1,243 @@
1/*
2 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
3 *
4 * Copyright (c) 2003 Intracom S.A.
5 * by Pantelis Antoniou <panto@intracom.gr>
6 *
7 * 2005 (c) MontaVista Software, Inc.
8 * Vitaly Bordug <vbordug@ru.mvista.com>
9 *
10 * This file is licensed under the terms of the GNU General Public License
11 * version 2. This program is licensed "as is" without any warranty of any
12 * kind, whether express or implied.
13 */
14
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/string.h>
22#include <linux/ptrace.h>
23#include <linux/errno.h>
24#include <linux/ioport.h>
25#include <linux/slab.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/skbuff.h>
33#include <linux/spinlock.h>
34#include <linux/mii.h>
35#include <linux/ethtool.h>
36#include <linux/bitops.h>
37#include <linux/platform_device.h>
38
39#include <asm/pgtable.h>
40#include <asm/irq.h>
41#include <asm/uaccess.h>
42
43#include "fs_enet.h"
44#include "fec.h"
45
46/* Make MII read/write commands for the FEC.
47*/
48#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
49#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
50#define mk_mii_end 0
51
52#define FEC_MII_LOOPS 10000
53
54static int match_has_phy (struct device *dev, void* data)
55{
56 struct platform_device* pdev = container_of(dev, struct platform_device, dev);
57 struct fs_platform_info* fpi;
58 if(strcmp(pdev->name, (char*)data))
59 {
60 return 0;
61 }
62
63 fpi = pdev->dev.platform_data;
64 if((fpi)&&(fpi->has_phy))
65 return 1;
66 return 0;
67}
68
69static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
70{
71 struct resource *r;
72 fec_t *fecp;
73 char* name = "fsl-cpm-fec";
74
75 /* we need fec in order to be useful */
76 struct platform_device *fec_pdev =
77 container_of(bus_find_device(&platform_bus_type, NULL, name, match_has_phy),
78 struct platform_device, dev);
79
80 if(fec_pdev == NULL) {
81 printk(KERN_ERR"Unable to find PHY for %s", name);
82 return -ENODEV;
83 }
84
85 r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs");
86
87 fec->fecp = fecp = (fec_t*)ioremap(r->start,sizeof(fec_t));
88 fec->mii_speed = fmpi->mii_speed;
89
90 setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
91 setbits32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
92 out_be32(&fecp->fec_ievent, FEC_ENET_MII);
93 out_be32(&fecp->fec_mii_speed, fec->mii_speed);
94
95 return 0;
96}
97
98static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
99{
100 struct fec_info* fec = bus->priv;
101 fec_t *fecp = fec->fecp;
102 int i, ret = -1;
103
104 if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
105 BUG();
106
107 /* Add PHY address to register command. */
108 out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
109
110 for (i = 0; i < FEC_MII_LOOPS; i++)
111 if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
112 break;
113
114 if (i < FEC_MII_LOOPS) {
115 out_be32(&fecp->fec_ievent, FEC_ENET_MII);
116 ret = in_be32(&fecp->fec_mii_data) & 0xffff;
117 }
118
119 return ret;
120
121}
122
123static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
124{
125 struct fec_info* fec = bus->priv;
126 fec_t *fecp = fec->fecp;
127 int i;
128
129 /* this must never happen */
130 if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
131 BUG();
132
133 /* Add PHY address to register command. */
134 out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
135
136 for (i = 0; i < FEC_MII_LOOPS; i++)
137 if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
138 break;
139
140 if (i < FEC_MII_LOOPS)
141 out_be32(&fecp->fec_ievent, FEC_ENET_MII);
142
143 return 0;
144
145}
146
147static int fs_enet_fec_mii_reset(struct mii_bus *bus)
148{
149 /* nothing here - for now */
150 return 0;
151}
152
153static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
154{
155 struct platform_device *pdev = to_platform_device(dev);
156 struct fs_mii_fec_platform_info *pdata;
157 struct mii_bus *new_bus;
158 struct fec_info *fec;
159 int err = 0;
160 if (NULL == dev)
161 return -EINVAL;
162 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
163
164 if (NULL == new_bus)
165 return -ENOMEM;
166
167 fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
168
169 if (NULL == fec)
170 return -ENOMEM;
171
172 new_bus->name = "FEC MII Bus",
173 new_bus->read = &fs_enet_fec_mii_read,
174 new_bus->write = &fs_enet_fec_mii_write,
175 new_bus->reset = &fs_enet_fec_mii_reset,
176 new_bus->id = pdev->id;
177
178 pdata = (struct fs_mii_fec_platform_info *)pdev->dev.platform_data;
179
180 if (NULL == pdata) {
181 printk(KERN_ERR "fs_enet FEC mdio %d: Missing platform data!\n", pdev->id);
182 return -ENODEV;
183 }
184
185 /*set up workspace*/
186
187 fs_mii_fec_init(fec, pdata);
188 new_bus->priv = fec;
189
190 new_bus->irq = pdata->irq;
191
192 new_bus->dev = dev;
193 dev_set_drvdata(dev, new_bus);
194
195 err = mdiobus_register(new_bus);
196
197 if (0 != err) {
198 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
199 new_bus->name);
200 goto bus_register_fail;
201 }
202
203 return 0;
204
205bus_register_fail:
206 kfree(new_bus);
207
208 return err;
209}
210
211
212static int fs_enet_fec_mdio_remove(struct device *dev)
213{
214 struct mii_bus *bus = dev_get_drvdata(dev);
215
216 mdiobus_unregister(bus);
217
218 dev_set_drvdata(dev, NULL);
219 kfree(bus->priv);
220
221 bus->priv = NULL;
222 kfree(bus);
223
224 return 0;
225}
226
227static struct device_driver fs_enet_fec_mdio_driver = {
228 .name = "fsl-cpm-fec-mdio",
229 .bus = &platform_bus_type,
230 .probe = fs_enet_fec_mdio_probe,
231 .remove = fs_enet_fec_mdio_remove,
232};
233
234int fs_enet_mdio_fec_init(void)
235{
236 return driver_register(&fs_enet_fec_mdio_driver);
237}
238
239void fs_enet_mdio_fec_exit(void)
240{
241 driver_unregister(&fs_enet_fec_mdio_driver);
242}
243
diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c
deleted file mode 100644
index b3e192d612e5..000000000000
--- a/drivers/net/fs_enet/mii-fixed.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
3 *
4 * Copyright (c) 2003 Intracom S.A.
5 * by Pantelis Antoniou <panto@intracom.gr>
6 *
7 * 2005 (c) MontaVista Software, Inc.
8 * Vitaly Bordug <vbordug@ru.mvista.com>
9 *
10 * This file is licensed under the terms of the GNU General Public License
11 * version 2. This program is licensed "as is" without any warranty of any
12 * kind, whether express or implied.
13 */
14
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/string.h>
22#include <linux/ptrace.h>
23#include <linux/errno.h>
24#include <linux/ioport.h>
25#include <linux/slab.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/skbuff.h>
33#include <linux/spinlock.h>
34#include <linux/mii.h>
35#include <linux/ethtool.h>
36#include <linux/bitops.h>
37
38#include <asm/pgtable.h>
39#include <asm/irq.h>
40#include <asm/uaccess.h>
41
42#include "fs_enet.h"
43
44static const u16 mii_regs[7] = {
45 0x3100,
46 0x786d,
47 0x0fff,
48 0x0fff,
49 0x01e1,
50 0x45e1,
51 0x0003,
52};
53
54static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
55{
56 int ret = 0;
57
58 if ((unsigned int)location >= ARRAY_SIZE(mii_regs))
59 return -1;
60
61 if (location != 5)
62 ret = mii_regs[location];
63 else
64 ret = bus->fixed.lpa;
65
66 return ret;
67}
68
69static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
70{
71 /* do nothing */
72}
73
74int fs_mii_fixed_init(struct fs_enet_mii_bus *bus)
75{
76 const struct fs_mii_bus_info *bi = bus->bus_info;
77
78 bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */
79
80 /* if speed is fixed at 10Mb, remove 100Mb modes */
81 if (bi->i.fixed.speed == 10)
82 bus->fixed.lpa &= ~LPA_100;
83
84 /* if duplex is half, remove full duplex modes */
85 if (bi->i.fixed.duplex == 0)
86 bus->fixed.lpa &= ~LPA_DUPLEX;
87
88 bus->mii_read = mii_read;
89 bus->mii_write = mii_write;
90
91 return 0;
92}