]> git.sur5r.net Git - u-boot/blobdiff - drivers/qe/uec.c
Merge branch 'master' of ssh://gemini/home/wd/git/u-boot/master
[u-boot] / drivers / qe / uec.c
index d34430c659161d032182d3a89ad80585a1a517ad..bba3ef2c66a06daca976bbf6b7520adde39bcf68 100644 (file)
 #include "uccf.h"
 #include "uec.h"
 #include "uec_phy.h"
-
-#if defined(CONFIG_QE)
+#include "miiphy.h"
 
 #ifdef CONFIG_UEC_ETH1
 static uec_info_t eth1_uec_info = {
        .uf_info                = {
-               .ucc_num        = CFG_UEC1_UCC_NUM,
-               .rx_clock       = CFG_UEC1_RX_CLK,
-               .tx_clock       = CFG_UEC1_TX_CLK,
-               .eth_type       = CFG_UEC1_ETH_TYPE,
+               .ucc_num        = CONFIG_SYS_UEC1_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC1_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC1_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC1_ETH_TYPE,
        },
-#if (CFG_UEC1_ETH_TYPE == FAST_ETH)
+#if (CONFIG_SYS_UEC1_ETH_TYPE == FAST_ETH)
        .num_threads_tx         = UEC_NUM_OF_THREADS_1,
        .num_threads_rx         = UEC_NUM_OF_THREADS_1,
 #else
@@ -51,19 +50,19 @@ static uec_info_t eth1_uec_info = {
        .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
        .tx_bd_ring_len         = 16,
        .rx_bd_ring_len         = 16,
-       .phy_address            = CFG_UEC1_PHY_ADDR,
-       .enet_interface         = CFG_UEC1_INTERFACE_MODE,
+       .phy_address            = CONFIG_SYS_UEC1_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC1_INTERFACE_MODE,
 };
 #endif
 #ifdef CONFIG_UEC_ETH2
 static uec_info_t eth2_uec_info = {
        .uf_info                = {
-               .ucc_num        = CFG_UEC2_UCC_NUM,
-               .rx_clock       = CFG_UEC2_RX_CLK,
-               .tx_clock       = CFG_UEC2_TX_CLK,
-               .eth_type       = CFG_UEC2_ETH_TYPE,
+               .ucc_num        = CONFIG_SYS_UEC2_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC2_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC2_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC2_ETH_TYPE,
        },
-#if (CFG_UEC2_ETH_TYPE == FAST_ETH)
+#if (CONFIG_SYS_UEC2_ETH_TYPE == FAST_ETH)
        .num_threads_tx         = UEC_NUM_OF_THREADS_1,
        .num_threads_rx         = UEC_NUM_OF_THREADS_1,
 #else
@@ -74,19 +73,19 @@ static uec_info_t eth2_uec_info = {
        .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
        .tx_bd_ring_len         = 16,
        .rx_bd_ring_len         = 16,
-       .phy_address            = CFG_UEC2_PHY_ADDR,
-       .enet_interface         = CFG_UEC2_INTERFACE_MODE,
+       .phy_address            = CONFIG_SYS_UEC2_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC2_INTERFACE_MODE,
 };
 #endif
 #ifdef CONFIG_UEC_ETH3
 static uec_info_t eth3_uec_info = {
        .uf_info                = {
-               .ucc_num        = CFG_UEC3_UCC_NUM,
-               .rx_clock       = CFG_UEC3_RX_CLK,
-               .tx_clock       = CFG_UEC3_TX_CLK,
-               .eth_type       = CFG_UEC3_ETH_TYPE,
+               .ucc_num        = CONFIG_SYS_UEC3_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC3_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC3_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC3_ETH_TYPE,
        },
-#if (CFG_UEC3_ETH_TYPE == FAST_ETH)
+#if (CONFIG_SYS_UEC3_ETH_TYPE == FAST_ETH)
        .num_threads_tx         = UEC_NUM_OF_THREADS_1,
        .num_threads_rx         = UEC_NUM_OF_THREADS_1,
 #else
@@ -97,19 +96,65 @@ static uec_info_t eth3_uec_info = {
        .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
        .tx_bd_ring_len         = 16,
        .rx_bd_ring_len         = 16,
-       .phy_address            = CFG_UEC3_PHY_ADDR,
-       .enet_interface         = CFG_UEC3_INTERFACE_MODE,
+       .phy_address            = CONFIG_SYS_UEC3_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC3_INTERFACE_MODE,
 };
 #endif
 #ifdef CONFIG_UEC_ETH4
 static uec_info_t eth4_uec_info = {
        .uf_info                = {
-               .ucc_num        = CFG_UEC4_UCC_NUM,
-               .rx_clock       = CFG_UEC4_RX_CLK,
-               .tx_clock       = CFG_UEC4_TX_CLK,
-               .eth_type       = CFG_UEC4_ETH_TYPE,
+               .ucc_num        = CONFIG_SYS_UEC4_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC4_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC4_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC4_ETH_TYPE,
+       },
+#if (CONFIG_SYS_UEC4_ETH_TYPE == FAST_ETH)
+       .num_threads_tx         = UEC_NUM_OF_THREADS_1,
+       .num_threads_rx         = UEC_NUM_OF_THREADS_1,
+#else
+       .num_threads_tx         = UEC_NUM_OF_THREADS_4,
+       .num_threads_rx         = UEC_NUM_OF_THREADS_4,
+#endif
+       .riscTx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+       .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+       .tx_bd_ring_len         = 16,
+       .rx_bd_ring_len         = 16,
+       .phy_address            = CONFIG_SYS_UEC4_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC4_INTERFACE_MODE,
+};
+#endif
+#ifdef CONFIG_UEC_ETH5
+static uec_info_t eth5_uec_info = {
+       .uf_info                = {
+               .ucc_num        = CONFIG_SYS_UEC5_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC5_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC5_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC5_ETH_TYPE,
+       },
+#if (CONFIG_SYS_UEC5_ETH_TYPE == FAST_ETH)
+       .num_threads_tx         = UEC_NUM_OF_THREADS_1,
+       .num_threads_rx         = UEC_NUM_OF_THREADS_1,
+#else
+       .num_threads_tx         = UEC_NUM_OF_THREADS_4,
+       .num_threads_rx         = UEC_NUM_OF_THREADS_4,
+#endif
+       .riscTx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+       .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+       .tx_bd_ring_len         = 16,
+       .rx_bd_ring_len         = 16,
+       .phy_address            = CONFIG_SYS_UEC5_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC5_INTERFACE_MODE,
+};
+#endif
+#ifdef CONFIG_UEC_ETH6
+static uec_info_t eth6_uec_info = {
+       .uf_info                = {
+               .ucc_num        = CONFIG_SYS_UEC6_UCC_NUM,
+               .rx_clock       = CONFIG_SYS_UEC6_RX_CLK,
+               .tx_clock       = CONFIG_SYS_UEC6_TX_CLK,
+               .eth_type       = CONFIG_SYS_UEC6_ETH_TYPE,
        },
-#if (CFG_UEC4_ETH_TYPE == FAST_ETH)
+#if (CONFIG_SYS_UEC6_ETH_TYPE == FAST_ETH)
        .num_threads_tx         = UEC_NUM_OF_THREADS_1,
        .num_threads_rx         = UEC_NUM_OF_THREADS_1,
 #else
@@ -120,11 +165,18 @@ static uec_info_t eth4_uec_info = {
        .riscRx                 = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
        .tx_bd_ring_len         = 16,
        .rx_bd_ring_len         = 16,
-       .phy_address            = CFG_UEC4_PHY_ADDR,
-       .enet_interface         = CFG_UEC4_INTERFACE_MODE,
+       .phy_address            = CONFIG_SYS_UEC6_PHY_ADDR,
+       .enet_interface         = CONFIG_SYS_UEC6_INTERFACE_MODE,
 };
 #endif
 
+#define MAXCONTROLLERS (6)
+
+static struct eth_device *devlist[MAXCONTROLLERS];
+
+u16 phy_read (struct uec_mii_info *mii_info, u16 regnum);
+void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val);
+
 static int uec_mac_enable(uec_private_t *uec, comm_dir_e mode)
 {
        uec_t           *uec_regs;
@@ -381,7 +433,7 @@ static int uec_set_mac_duplex(uec_private_t *uec, int duplex)
 static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode)
 {
        enet_interface_e        enet_if_mode;
-       uec_info_t              *uec_info;
+       uec_info_t              *uec_info;
        uec_t                   *uec_regs;
        u32                     upsmr;
        u32                     maccfg2;
@@ -418,6 +470,7 @@ static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode)
                        upsmr |= (UPSMR_RPM | UPSMR_TBIM);
                        break;
                case ENET_1000_RGMII_RXID:
+               case ENET_1000_RGMII_ID:
                case ENET_1000_RGMII:
                        maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
                        upsmr |= UPSMR_RPM;
@@ -629,6 +682,79 @@ static void phy_change(struct eth_device *dev)
        adjust_link(dev);
 }
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+       && !defined(BITBANGMII)
+
+/*
+ * Find a device index from the devlist by name
+ *
+ * Returns:
+ *  The index where the device is located, -1 on error
+ */
+static int uec_miiphy_find_dev_by_name(char *devname)
+{
+       int i;
+
+       for (i = 0; i < MAXCONTROLLERS; i++) {
+               if (strncmp(devname, devlist[i]->name, strlen(devname)) == 0) {
+                       break;
+               }
+       }
+
+       /* If device cannot be found, returns -1 */
+       if (i == MAXCONTROLLERS) {
+               debug ("%s: device %s not found in devlist\n", __FUNCTION__, devname);
+               i = -1;
+       }
+
+       return i;
+}
+
+/*
+ * Read a MII PHY register.
+ *
+ * Returns:
+ *  0 on success
+ */
+static int uec_miiphy_read(char *devname, unsigned char addr,
+                           unsigned char reg, unsigned short *value)
+{
+       int devindex = 0;
+
+       if (devname == NULL || value == NULL) {
+               debug("%s: NULL pointer given\n", __FUNCTION__);
+       } else {
+               devindex = uec_miiphy_find_dev_by_name(devname);
+               if (devindex >= 0) {
+                       *value = uec_read_phy_reg(devlist[devindex], addr, reg);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Write a MII PHY register.
+ *
+ * Returns:
+ *  0 on success
+ */
+static int uec_miiphy_write(char *devname, unsigned char addr,
+                            unsigned char reg, unsigned short value)
+{
+       int devindex = 0;
+
+       if (devname == NULL) {
+               debug("%s: NULL pointer given\n", __FUNCTION__);
+       } else {
+               devindex = uec_miiphy_find_dev_by_name(devname);
+               if (devindex >= 0) {
+                       uec_write_phy_reg(devlist[devindex], addr, reg, value);
+               }
+       }
+       return 0;
+}
+#endif
+
 static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr)
 {
        uec_t           *uec_regs;
@@ -1328,12 +1454,22 @@ int uec_initialize(int index)
        } else if (index == 3) {
 #ifdef CONFIG_UEC_ETH4
                uec_info = &eth4_uec_info;
+#endif
+       } else if (index == 4) {
+#ifdef CONFIG_UEC_ETH5
+               uec_info = &eth5_uec_info;
+#endif
+       } else if (index == 5) {
+#ifdef CONFIG_UEC_ETH6
+               uec_info = &eth6_uec_info;
 #endif
        } else {
                printf("%s: index is illegal.\n", __FUNCTION__);
                return -EINVAL;
        }
 
+       devlist[index] = dev;
+
        uec->uec_info = uec_info;
 
        sprintf(dev->name, "FSL UEC%d", index);
@@ -1356,6 +1492,10 @@ int uec_initialize(int index)
                return err;
        }
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+       && !defined(BITBANGMII)
+       miiphy_register(dev->name, uec_miiphy_read, uec_miiphy_write);
+#endif
+
        return 1;
 }
-#endif /* CONFIG_QE */