vserver 1.9.3
[linux-2.6.git] / drivers / net / gianfar_phy.h
index df4c0ec..1e9b3ab 100644 (file)
@@ -8,7 +8,7 @@
  * Author: Andy Fleming
  * Maintainer: Kumar Gala (kumar.gala@freescale.com)
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
 #ifndef __GIANFAR_PHY_H
 #define __GIANFAR_PHY_H
 
-/* simple datum processing commands */
-#define miim_end               (0xffff0000U)
-#define miim_read              (0x00010000U)
-#define miim_clear_bits(reg,x) { reg, (0x00020000U | ~(u32)(x)), NULL }
-#define miim_set_bits(reg,x)   { reg, (0x00030000U | (u32)(x)),  NULL }
-#define miim_flip_bits(reg,x)  { reg, (0x00040000U | (u32)(x)),  NULL }
-#define miim_write(reg, x)     { reg, (0x0000ffffU & (u32)(x)),  NULL }
+#define MII_end ((u32)-2)
+#define MII_read ((u32)-1)
 
 #define MIIMIND_BUSY            0x00000001
 #define MIIMIND_NOTVALID        0x00000004
 
-#define MIIM_CONTROL           0x00
-#define MIIM_CONTROL_RESET     0x00008000
-#define MIIM_CONTROL_INIT      0x00001140
-#define MIIM_ANEN              0x00001000
-
-#define MIIM_CR                 0x00
-#define MIIM_CR_RST            0x00008000
-#define MIIM_CR_INIT           0x00001000
-
-#define MIIM_STATUS            0x1
-#define MIIM_STATUS_AN_DONE    0x00000020
-#define MIIM_STATUS_LINK       0x0004
-
-#define MIIM_PHYIR1            0x2
-#define MIIM_PHYIR2            0x3
-
-#define GFAR_AN_TIMEOUT         0x000fffff
-
-#define MIIM_ANLPBPA   0x5
-#define MIIM_ANLPBPA_HALF      0x00000040
-#define MIIM_ANLPBPA_FULL      0x00000020
-
-#define MIIM_ANEX              0x6
-#define MIIM_ANEX_NP           0x00000004
-#define MIIM_ANEX_PRX          0x00000002
+#define GFAR_AN_TIMEOUT         2000
 
+/* 1000BT control (Marvell & BCM54xx at least) */
+#define MII_1000BASETCONTROL                   0x09
+#define MII_1000BASETCONTROL_FULLDUPLEXCAP     0x0200
+#define MII_1000BASETCONTROL_HALFDUPLEXCAP     0x0100
 
 /* Cicada Extended Control Register 1 */
-#define MIIM_CIS8201_EXT_CON1           0x17
-#define MIIM_CIS8201_EXTCON1_INIT       0x0000
+#define MII_CIS8201_EXT_CON1           0x17
+#define MII_CIS8201_EXTCON1_INIT       0x0000
 
 /* Cicada Interrupt Mask Register */
-#define MIIM_CIS8204_IMASK             0x19
-#define MIIM_CIS8204_IMASK_IEN         0x8000
-#define MIIM_CIS8204_IMASK_SPEED       0x4000
-#define MIIM_CIS8204_IMASK_LINK                0x2000
-#define MIIM_CIS8204_IMASK_DUPLEX      0x1000
-#define MIIM_CIS8204_IMASK_MASK                0xf000
+#define MII_CIS8201_IMASK              0x19
+#define MII_CIS8201_IMASK_IEN          0x8000
+#define MII_CIS8201_IMASK_SPEED        0x4000
+#define MII_CIS8201_IMASK_LINK         0x2000
+#define MII_CIS8201_IMASK_DUPLEX       0x1000
+#define MII_CIS8201_IMASK_MASK         0xf000
 
 /* Cicada Interrupt Status Register */
-#define MIIM_CIS8204_ISTAT             0x1a
-#define MIIM_CIS8204_ISTAT_STATUS      0x8000
-#define MIIM_CIS8204_ISTAT_SPEED       0x4000
-#define MIIM_CIS8204_ISTAT_LINK                0x2000
-#define MIIM_CIS8204_ISTAT_DUPLEX      0x1000
+#define MII_CIS8201_ISTAT              0x1a
+#define MII_CIS8201_ISTAT_STATUS       0x8000
+#define MII_CIS8201_ISTAT_SPEED        0x4000
+#define MII_CIS8201_ISTAT_LINK         0x2000
+#define MII_CIS8201_ISTAT_DUPLEX       0x1000
 
 /* Cicada Auxiliary Control/Status Register */
-#define MIIM_CIS8201_AUX_CONSTAT        0x1c
-#define MIIM_CIS8201_AUXCONSTAT_INIT    0x0004
-#define MIIM_CIS8201_AUXCONSTAT_DUPLEX  0x0020
-#define MIIM_CIS8201_AUXCONSTAT_SPEED   0x0018
-#define MIIM_CIS8201_AUXCONSTAT_GBIT    0x0010
-#define MIIM_CIS8201_AUXCONSTAT_100     0x0008
+#define MII_CIS8201_AUX_CONSTAT        0x1c
+#define MII_CIS8201_AUXCONSTAT_INIT    0x0004
+#define MII_CIS8201_AUXCONSTAT_DUPLEX  0x0020
+#define MII_CIS8201_AUXCONSTAT_SPEED   0x0018
+#define MII_CIS8201_AUXCONSTAT_GBIT    0x0010
+#define MII_CIS8201_AUXCONSTAT_100     0x0008
                                                                                 
 /* 88E1011 PHY Status Register */
-#define MIIM_88E1011_PHY_STATUS         0x11
-#define MIIM_88E1011_PHYSTAT_SPEED      0xc000
-#define MIIM_88E1011_PHYSTAT_GBIT       0x8000
-#define MIIM_88E1011_PHYSTAT_100        0x4000
-#define MIIM_88E1011_PHYSTAT_DUPLEX     0x2000
-#define MIIM_88E1011_PHYSTAT_LINK      0x0400
+#define MII_M1011_PHY_SPEC_STATUS              0x11
+#define MII_M1011_PHY_SPEC_STATUS_1000         0x8000
+#define MII_M1011_PHY_SPEC_STATUS_100          0x4000
+#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK     0xc000
+#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX   0x2000
+#define MII_M1011_PHY_SPEC_STATUS_RESOLVED     0x0800
+#define MII_M1011_PHY_SPEC_STATUS_LINK         0x0400
 
-#define MIIM_88E1011_IEVENT            0x13
-#define MIIM_88E1011_IEVENT_CLEAR      0x0000
+#define MII_M1011_IEVENT               0x13
+#define MII_M1011_IEVENT_CLEAR         0x0000
 
-#define MIIM_88E1011_IMASK             0x12
-#define MIIM_88E1011_IMASK_INIT                0x6400
-#define MIIM_88E1011_IMASK_CLEAR       0x0000
+#define MII_M1011_IMASK                        0x12
+#define MII_M1011_IMASK_INIT           0x6400
+#define MII_M1011_IMASK_CLEAR          0x0000
 
-/* DM9161 Control register values */
-#define MIIM_DM9161_CR_STOP    0x0400
-#define MIIM_DM9161_CR_RSTAN   0x1200
-
-#define MIIM_DM9161_SCR                0x10
-#define MIIM_DM9161_SCR_INIT   0x0610
+#define MII_DM9161_SCR         0x10
+#define MII_DM9161_SCR_INIT    0x0610
 
 /* DM9161 Specified Configuration and Status Register */
-#define MIIM_DM9161_SCSR       0x11
-#define MIIM_DM9161_SCSR_100F  0x8000
-#define MIIM_DM9161_SCSR_100H  0x4000
-#define MIIM_DM9161_SCSR_10F   0x2000
-#define MIIM_DM9161_SCSR_10H   0x1000
+#define MII_DM9161_SCSR        0x11
+#define MII_DM9161_SCSR_100F   0x8000
+#define MII_DM9161_SCSR_100H   0x4000
+#define MII_DM9161_SCSR_10F    0x2000
+#define MII_DM9161_SCSR_10H    0x1000
 
 /* DM9161 Interrupt Register */
-#define MIIM_DM9161_INTR       0x15
-#define MIIM_DM9161_INTR_PEND          0x8000
-#define MIIM_DM9161_INTR_DPLX_MASK     0x0800
-#define MIIM_DM9161_INTR_SPD_MASK      0x0400
-#define MIIM_DM9161_INTR_LINK_MASK     0x0200
-#define MIIM_DM9161_INTR_MASK          0x0100
-#define MIIM_DM9161_INTR_DPLX_CHANGE   0x0010
-#define MIIM_DM9161_INTR_SPD_CHANGE    0x0008
-#define MIIM_DM9161_INTR_LINK_CHANGE   0x0004
-#define MIIM_DM9161_INTR_INIT          0x0000
-#define MIIM_DM9161_INTR_STOP  \
-(MIIM_DM9161_INTR_DPLX_MASK | MIIM_DM9161_INTR_SPD_MASK \
- | MIIM_DM9161_INTR_LINK_MASK | MIIM_DM9161_INTR_MASK)
+#define MII_DM9161_INTR        0x15
+#define MII_DM9161_INTR_PEND           0x8000
+#define MII_DM9161_INTR_DPLX_MASK      0x0800
+#define MII_DM9161_INTR_SPD_MASK       0x0400
+#define MII_DM9161_INTR_LINK_MASK      0x0200
+#define MII_DM9161_INTR_MASK           0x0100
+#define MII_DM9161_INTR_DPLX_CHANGE    0x0010
+#define MII_DM9161_INTR_SPD_CHANGE     0x0008
+#define MII_DM9161_INTR_LINK_CHANGE    0x0004
+#define MII_DM9161_INTR_INIT           0x0000
+#define MII_DM9161_INTR_STOP   \
+(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
+ | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
 
 /* DM9161 10BT Configuration/Status */
-#define MIIM_DM9161_10BTCSR    0x12
-#define MIIM_DM9161_10BTCSR_INIT       0x7800
-
-/* BCM54xx regs */
-#define MIIM_BCM54xx_AUXCONTROL        0x18
-#define MIIM_BCM54xx_AUXSTATUS 0x19
-#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK     0x0700
-#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT    8  
-
-#define MIIM_READ_COMMAND       0x00000001
-
-/*
- * struct phy_cmd:  A command for reading or writing a PHY register
- *
- * mii_reg:  The register to read or write
- *
- * mii_data:  For writes, the value to put in the register.
- *     A value of -1 indicates this is a read.
- *
- * funct: A function pointer which is invoked for each command.
- *     For reads, this function will be passed the value read
- *     from the PHY, and process it.
- *     For writes, the result of this function will be written
- *     to the PHY register
- */
-struct phy_cmd {
-    u32 mii_reg;
-    u32 mii_data;
-    u16 (*funct) (u16 mii_reg, struct net_device * dev);
+#define MII_DM9161_10BTCSR     0x12
+#define MII_DM9161_10BTCSR_INIT        0x7800
+
+#define MII_BASIC_FEATURES     (SUPPORTED_10baseT_Half | \
+                                SUPPORTED_10baseT_Full | \
+                                SUPPORTED_100baseT_Half | \
+                                SUPPORTED_100baseT_Full | \
+                                SUPPORTED_Autoneg | \
+                                SUPPORTED_TP | \
+                                SUPPORTED_MII)
+
+#define MII_GBIT_FEATURES      (MII_BASIC_FEATURES | \
+                                SUPPORTED_1000baseT_Half | \
+                                SUPPORTED_1000baseT_Full)
+
+#define MII_READ_COMMAND       0x00000001
+
+#define MII_INTERRUPT_DISABLED 0x0
+#define MII_INTERRUPT_ENABLED 0x1
+/* Taken from mii_if_info and sungem_phy.h */
+struct gfar_mii_info {
+       /* Information about the PHY type */
+       /* And management functions */
+       struct phy_info *phyinfo;
+
+       /* forced speed & duplex (no autoneg)
+        * partner speed & duplex & pause (autoneg)
+        */
+       int speed;
+       int duplex;
+       int pause;
+
+       /* The most recently read link state */
+       int link;
+
+       /* Enabled Interrupts */
+       u32 interrupts;
+
+       u32 advertising;
+       int autoneg;
+       int mii_id;
+
+       /* private data pointer */
+       /* For use by PHYs to maintain extra state */
+       void *priv;
+
+       /* Provided by host chip */
+       struct net_device *dev;
+
+       /* A lock to ensure that only one thing can read/write
+        * the MDIO bus at a time */
+       spinlock_t mdio_lock;
+
+       /* Provided by ethernet driver */
+       int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
+       void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
 };
 
 /* struct phy_info: a structure which defines attributes for a PHY
@@ -165,38 +164,50 @@ struct phy_cmd {
  * id will contain a number which represents the PHY.  During
  * startup, the driver will poll the PHY to find out what its
  * UID--as defined by registers 2 and 3--is.  The 32-bit result
- * gotten from the PHY will be shifted right by "shift" bits to
+ * gotten from the PHY will be ANDed with phy_id_mask to
  * discard any bits which may change based on revision numbers
  * unimportant to functionality
  *
- * The struct phy_cmd entries represent pointers to an arrays of
- * commands which tell the driver what to do to the PHY.
+ * There are 6 commands which take a gfar_mii_info structure.
+ * Each PHY must declare config_aneg, and read_status.
  */
 struct phy_info {
-    u32 id;
-    char *name;
-    unsigned int shift;
-    /* Called to configure the PHY, and modify the controller
-     * based on the results */
-    const struct phy_cmd *config;
-
-    /* Called when starting up the controller.  Usually sets
-     * up the interrupt for state changes */
-    const struct phy_cmd *startup;
-
-    /* Called inside the interrupt handler to acknowledge
-     * the interrupt */
-    const struct phy_cmd *ack_int;
-
-    /* Called in the bottom half to handle the interrupt */
-    const struct phy_cmd *handle_int;
-
-    /* Called when bringing down the controller.  Usually stops
-     * the interrupts from being generated */
-    const struct phy_cmd *shutdown;
+       u32 phy_id;
+       char *name;
+       unsigned int phy_id_mask;
+       u32 features;
+
+       /* Called to initialize the PHY */
+       int (*init)(struct gfar_mii_info *mii_info);
+
+       /* Called to suspend the PHY for power */
+       int (*suspend)(struct gfar_mii_info *mii_info);
+
+       /* Reconfigures autonegotiation (or disables it) */
+       int (*config_aneg)(struct gfar_mii_info *mii_info);
+
+       /* Determines the negotiated speed and duplex */
+       int (*read_status)(struct gfar_mii_info *mii_info);
+
+       /* Clears any pending interrupts */
+       int (*ack_interrupt)(struct gfar_mii_info *mii_info);
+
+       /* Enables or disables interrupts */
+       int (*config_intr)(struct gfar_mii_info *mii_info);
+
+       /* Clears up any memory if needed */
+       void (*close)(struct gfar_mii_info *mii_info);
 };
 
-struct phy_info *get_phy_info(struct net_device *dev);
-void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd);
+struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
+int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
+void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
+void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
+void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
+
+struct dm9161_private {
+       struct timer_list timer;
+       int resetdone;
+};
 
 #endif /* GIANFAR_PHY_H */