Author: raj
Date: Sun Mar  4 19:22:52 2012
New Revision: 232518
URL: http://svn.freebsd.org/changeset/base/232518

Log:
  Respect phy-handle property in Ethernet nodes of the device tree.
  
  This lets specify whereabouts of the parent PHY for a given MAC node
  (and get rid of ugly kludges in mge(4) and tsec(4)).
  
  Obtained from:        Semihalf
  MFC after:    1 week

Modified:
  head/sys/boot/fdt/dts/db78100.dts
  head/sys/dev/fdt/fdt_common.c
  head/sys/dev/fdt/fdt_common.h
  head/sys/dev/mge/if_mge.c
  head/sys/dev/mge/if_mgevar.h
  head/sys/dev/tsec/if_tsec.c
  head/sys/dev/tsec/if_tsec.h
  head/sys/dev/tsec/if_tsec_fdt.c

Modified: head/sys/boot/fdt/dts/db78100.dts
==============================================================================
--- head/sys/boot/fdt/dts/db78100.dts   Sun Mar  4 18:59:38 2012        
(r232517)
+++ head/sys/boot/fdt/dts/db78100.dts   Sun Mar  4 19:22:52 2012        
(r232518)
@@ -221,6 +221,9 @@
                                phy0: ethernet-phy@0 {
                                        reg = <0x8>;
                                };
+                               phy1: ethernet-phy@1 {
+                                       reg = <0x9>;
+                               };
                        };
                };
 
@@ -234,17 +237,7 @@
                        local-mac-address = [ 00 00 00 00 00 00 ];
                        interrupts = <45 46 47 44 70>;
                        interrupt-parent = <&PIC>;
-                       phy-handle = <&phy0>;
-
-                       mdio@0 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               compatible = "mrvl,mdio";
-
-                               phy0: ethernet-phy@0 {
-                                       reg = <0x9>;
-                               };
-                       };
+                       phy-handle = <&phy1>;
                };
 
                serial0: serial@12000 {

Modified: head/sys/dev/fdt/fdt_common.c
==============================================================================
--- head/sys/dev/fdt/fdt_common.c       Sun Mar  4 18:59:38 2012        
(r232517)
+++ head/sys/dev/fdt/fdt_common.c       Sun Mar  4 19:22:52 2012        
(r232518)
@@ -542,11 +542,13 @@ out:
 }
 
 int
-fdt_get_phyaddr(phandle_t node, int *phy_addr)
+fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc)
 {
        phandle_t phy_node;
        ihandle_t phy_ihandle;
        pcell_t phy_handle, phy_reg;
+       uint32_t i;
+       device_t parent, child;
 
        if (OF_getprop(node, "phy-handle", (void *)&phy_handle,
            sizeof(phy_handle)) <= 0)
@@ -561,6 +563,47 @@ fdt_get_phyaddr(phandle_t node, int *phy
                return (ENXIO);
 
        *phy_addr = fdt32_to_cpu(phy_reg);
+
+       /*
+        * Search for softc used to communicate with phy.
+        */
+
+       /*
+        * Step 1: Search for ancestor of the phy-node with a "phy-handle"
+        * property set.
+        */
+       phy_node = OF_parent(phy_node);
+       while (phy_node != 0) {
+               if (OF_getprop(phy_node, "phy-handle", (void *)&phy_handle,
+                   sizeof(phy_handle)) > 0)
+                       break;
+               phy_node = OF_parent(phy_node);
+       }
+       if (phy_node == 0)
+               return (ENXIO);
+
+       /*
+        * Step 2: For each device with the same parent and name as ours
+        * compare its node with the one found in step 1, ancestor of phy
+        * node (stored in phy_node).
+        */
+       parent = device_get_parent(dev);
+       i = 0;
+       child = device_find_child(parent, device_get_name(dev), i);
+       while (child != NULL) {
+               if (ofw_bus_get_node(child) == phy_node)
+                       break;
+               i++;
+               child = device_find_child(parent, device_get_name(dev), i);
+       }
+       if (child == NULL)
+               return (ENXIO);
+
+       /*
+        * Use softc of the device found.
+        */
+       *phy_sc = (void *)device_get_softc(child);
+
        return (0);
 }
 

Modified: head/sys/dev/fdt/fdt_common.h
==============================================================================
--- head/sys/dev/fdt/fdt_common.h       Sun Mar  4 18:59:38 2012        
(r232517)
+++ head/sys/dev/fdt/fdt_common.h       Sun Mar  4 19:22:52 2012        
(r232518)
@@ -89,7 +89,7 @@ int fdt_data_to_res(pcell_t *, int, int,
 int fdt_data_verify(void *, int);
 phandle_t fdt_find_compatible(phandle_t, const char *, int);
 int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *);
-int fdt_get_phyaddr(phandle_t node, int *);
+int fdt_get_phyaddr(phandle_t, device_t, int *, void **);
 int fdt_immr_addr(vm_offset_t);
 int fdt_regsize(phandle_t, u_long *, u_long *);
 int fdt_intr_decode(phandle_t, pcell_t *, int *, int *, int *);

Modified: head/sys/dev/mge/if_mge.c
==============================================================================
--- head/sys/dev/mge/if_mge.c   Sun Mar  4 18:59:38 2012        (r232517)
+++ head/sys/dev/mge/if_mge.c   Sun Mar  4 19:22:52 2012        (r232518)
@@ -79,9 +79,6 @@ __FBSDID("$FreeBSD$");
 
 #include "miibus_if.h"
 
-/* PHY registers are in the address space of the first mge unit */
-static struct mge_softc *sc_mge0 = NULL;
-
 static int mge_probe(device_t dev);
 static int mge_attach(device_t dev);
 static int mge_detach(device_t dev);
@@ -635,14 +632,11 @@ mge_attach(device_t dev)
        sc->dev = dev;
        sc->node = ofw_bus_get_node(dev);
 
-       if (device_get_unit(dev) == 0)
-               sc_mge0 = sc;
-
        /* Set chip version-dependent parameters */
        mge_ver_params(sc);
 
-       /* Get phy address from fdt */
-       if (fdt_get_phyaddr(sc->node, &phy) != 0)
+       /* Get phy address and used softc from fdt */
+       if (fdt_get_phyaddr(sc->node, sc->dev, &phy, (void **)&sc->phy_sc) != 0)
                return (ENXIO);
 
        /* Initialize mutexes */
@@ -1294,17 +1288,18 @@ mge_miibus_readreg(device_t dev, int phy
 
        sc = device_get_softc(dev);
 
-       MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &
+       MGE_WRITE(sc->phy_sc, MGE_REG_SMI, 0x1fffffff &
            (MGE_SMI_READ | (reg << 21) | (phy << 16)));
 
        retries = MGE_SMI_READ_RETRIES;
-       while (--retries && !(MGE_READ(sc_mge0, MGE_REG_SMI) & 
MGE_SMI_READVALID))
+       while (--retries &&
+           !(MGE_READ(sc->phy_sc, MGE_REG_SMI) & MGE_SMI_READVALID))
                DELAY(MGE_SMI_READ_DELAY);
 
        if (retries == 0)
                device_printf(dev, "Timeout while reading from PHY\n");
 
-       return (MGE_READ(sc_mge0, MGE_REG_SMI) & 0xffff);
+       return (MGE_READ(sc->phy_sc, MGE_REG_SMI) & 0xffff);
 }
 
 static int
@@ -1315,11 +1310,11 @@ mge_miibus_writereg(device_t dev, int ph
 
        sc = device_get_softc(dev);
 
-       MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &
+       MGE_WRITE(sc->phy_sc, MGE_REG_SMI, 0x1fffffff &
            (MGE_SMI_WRITE | (reg << 21) | (phy << 16) | (value & 0xffff)));
 
        retries = MGE_SMI_WRITE_RETRIES;
-       while (--retries && MGE_READ(sc_mge0, MGE_REG_SMI) & MGE_SMI_BUSY)
+       while (--retries && MGE_READ(sc->phy_sc, MGE_REG_SMI) & MGE_SMI_BUSY)
                DELAY(MGE_SMI_WRITE_DELAY);
 
        if (retries == 0)

Modified: head/sys/dev/mge/if_mgevar.h
==============================================================================
--- head/sys/dev/mge/if_mgevar.h        Sun Mar  4 18:59:38 2012        
(r232517)
+++ head/sys/dev/mge/if_mgevar.h        Sun Mar  4 19:22:52 2012        
(r232518)
@@ -103,6 +103,8 @@ struct mge_softc {
        uint32_t        mge_tx_tok_cnt;
        uint16_t        mge_mtu;
        int             mge_ver;
+
+       struct mge_softc *phy_sc;
 };
 
 

Modified: head/sys/dev/tsec/if_tsec.c
==============================================================================
--- head/sys/dev/tsec/if_tsec.c Sun Mar  4 18:59:38 2012        (r232517)
+++ head/sys/dev/tsec/if_tsec.c Sun Mar  4 19:22:52 2012        (r232518)
@@ -106,8 +106,6 @@ static void tsec_offload_process_frame(s
 static void    tsec_setup_multicast(struct tsec_softc *sc);
 static int     tsec_set_mtu(struct tsec_softc *sc, unsigned int mtu);
 
-struct tsec_softc *tsec0_sc = NULL; /* XXX ugly hack! */
-
 devclass_t tsec_devclass;
 DRIVER_MODULE(miibus, tsec, miibus_driver, miibus_devclass, 0, 0);
 MODULE_DEPEND(tsec, ether, 1, 1, 1);
@@ -406,14 +404,14 @@ tsec_init_locked(struct tsec_softc *sc)
        TSEC_WRITE(sc, TSEC_REG_TBIPA, 5);
 
        /* Step 6: Reset the management interface */
-       TSEC_WRITE(tsec0_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT);
 
        /* Step 7: Setup the MII Mgmt clock speed */
-       TSEC_WRITE(tsec0_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28);
 
        /* Step 8: Read MII Mgmt indicator register and check for Busy = 0 */
        timeout = TSEC_READ_RETRY;
-       while (--timeout && (TSEC_READ(tsec0_sc, TSEC_REG_MIIMIND) &
+       while (--timeout && (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) &
            TSEC_MIIMIND_BUSY))
                DELAY(TSEC_READ_DELAY);
        if (timeout == 0) {
@@ -1561,21 +1559,21 @@ tsec_miibus_readreg(device_t dev, int ph
        struct tsec_softc *sc;
        uint32_t timeout;
 
-       sc = tsec0_sc;
+       sc = device_get_softc(dev);
 
-       TSEC_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg);
-       TSEC_WRITE(sc, TSEC_REG_MIIMCOM, 0);
-       TSEC_WRITE(sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, 0);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE);
 
        timeout = TSEC_READ_RETRY;
-       while (--timeout && TSEC_READ(sc, TSEC_REG_MIIMIND) &
+       while (--timeout && TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) &
            (TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY))
                DELAY(TSEC_READ_DELAY);
 
        if (timeout == 0)
                device_printf(dev, "Timeout while reading from PHY!\n");
 
-       return (TSEC_READ(sc, TSEC_REG_MIIMSTAT));
+       return (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMSTAT));
 }
 
 int
@@ -1584,13 +1582,13 @@ tsec_miibus_writereg(device_t dev, int p
        struct tsec_softc *sc;
        uint32_t timeout;
 
-       sc = tsec0_sc;
+       sc = device_get_softc(dev);
 
-       TSEC_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg);
-       TSEC_WRITE(sc, TSEC_REG_MIIMCON, value);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg);
+       TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCON, value);
 
        timeout = TSEC_READ_RETRY;
-       while (--timeout && (TSEC_READ(sc, TSEC_REG_MIIMIND) &
+       while (--timeout && (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) &
            TSEC_MIIMIND_BUSY))
                DELAY(TSEC_READ_DELAY);
 

Modified: head/sys/dev/tsec/if_tsec.h
==============================================================================
--- head/sys/dev/tsec/if_tsec.h Sun Mar  4 18:59:38 2012        (r232517)
+++ head/sys/dev/tsec/if_tsec.h Sun Mar  4 19:22:52 2012        (r232518)
@@ -133,6 +133,7 @@ struct tsec_softc {
        struct mbuf     *frame;
 
        int             phyaddr;
+       struct tsec_softc *phy_sc;
 };
 
 /* interface to get/put generic objects */

Modified: head/sys/dev/tsec/if_tsec_fdt.c
==============================================================================
--- head/sys/dev/tsec/if_tsec_fdt.c     Sun Mar  4 18:59:38 2012        
(r232517)
+++ head/sys/dev/tsec/if_tsec_fdt.c     Sun Mar  4 19:22:52 2012        
(r232518)
@@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$");
 #define        TSEC_RID_RXIRQ  1
 #define        TSEC_RID_ERRIRQ 2
 
-extern struct tsec_softc *tsec0_sc;
-
 static int tsec_fdt_probe(device_t dev);
 static int tsec_fdt_attach(device_t dev);
 static int tsec_fdt_detach(device_t dev);
@@ -156,12 +154,9 @@ tsec_fdt_attach(device_t dev)
        sc->dev = dev;
        sc->node = ofw_bus_get_node(dev);
 
-       /* XXX add comment on weird FSL's MII registers access design */
-       if (device_get_unit(dev) == 0)
-               tsec0_sc = sc;
-
        /* Get phy address from fdt */
-       if (fdt_get_phyaddr(sc->node, &sc->phyaddr) != 0)
+       if (fdt_get_phyaddr(sc->node, sc->dev, &sc->phyaddr,
+           (void **)&sc->phy_sc) != 0)
                return (ENXIO);
 
        /* Init timer */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to