#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 (CONFIG_SYS_UEC1_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 = 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 (CONFIG_SYS_UEC2_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 = 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 (CONFIG_SYS_UEC3_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_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 = 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 (CONFIG_SYS_UEC6_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 = CFG_UEC3_PHY_ADDR,
- .enet_interface = CFG_UEC3_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;
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;
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
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;
uec->mii_info = mii_info;
+ qe_set_mii_clk_src(uec->uec_info->uf_info.ucc_num);
+
if (init_mii_management_configuration(umii_regs)) {
printf("%s: The MII Bus is stuck!", dev->name);
err = -1;
static void phy_change(struct eth_device *dev)
{
uec_private_t *uec = (uec_private_t *)dev->priv;
- uec_t *uec_regs;
- int result = 0;
-
- uec_regs = uec->uec_regs;
-
- /* Delay 5s to give the PHY a chance to change the register state */
- udelay(5000000);
/* Update the link, speed, duplex */
- result = uec->mii_info->phyinfo->read_status(uec->mii_info);
+ uec->mii_info->phyinfo->read_status(uec->mii_info);
/* Adjust the interface according to speed */
- if ((0 == result) || (uec->mii_info->link == 0)) {
- adjust_link(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;
static int uec_init(struct eth_device* dev, bd_t *bd)
{
uec_private_t *uec;
- int err;
+ int err, i;
+ struct phy_info *curphy;
uec = (uec_private_t *)dev->priv;
if (uec->the_first_run == 0) {
- /* Set up the MAC address */
- if (dev->enetaddr[0] & 0x01) {
- printf("%s: MacAddress is multcast address\n",
- __FUNCTION__);
- return -1;
+ err = init_phy(dev);
+ if (err) {
+ printf("%s: Cannot initialize PHY, aborting.\n",
+ dev->name);
+ return err;
+ }
+
+ curphy = uec->mii_info->phyinfo;
+
+ if (curphy->config_aneg) {
+ err = curphy->config_aneg(uec->mii_info);
+ if (err) {
+ printf("%s: Can't negotiate PHY\n", dev->name);
+ return err;
+ }
}
- uec_set_mac_address(uec, dev->enetaddr);
+
+ /* Give PHYs up to 5 sec to report a link */
+ i = 50;
+ do {
+ err = curphy->read_status(uec->mii_info);
+ udelay(100000);
+ } while (((i-- > 0) && !uec->mii_info->link) || err);
+
+ if (err || i <= 0)
+ printf("warning: %s: timeout on PHY link\n", dev->name);
+
uec->the_first_run = 1;
}
+ /* Set up the MAC address */
+ if (dev->enetaddr[0] & 0x01) {
+ printf("%s: MacAddress is multcast address\n",
+ __FUNCTION__);
+ return -1;
+ }
+ uec_set_mac_address(uec, dev->enetaddr);
+
+
err = uec_open(uec, COMM_DIR_RX_AND_TX);
if (err) {
printf("%s: cannot enable UEC device\n", dev->name);
return -1;
}
+ phy_change(dev);
+
return (uec->mii_info->link ? 0 : -1);
}
memset(uec, 0, sizeof(uec_private_t));
/* Init UEC private struct, they come from board.h */
+ uec_info = NULL;
if (index == 0) {
#ifdef CONFIG_UEC_ETH1
uec_info = ð1_uec_info;
} else if (index == 2) {
#ifdef CONFIG_UEC_ETH3
uec_info = ð3_uec_info;
+#endif
+ } else if (index == 3) {
+#ifdef CONFIG_UEC_ETH4
+ uec_info = ð4_uec_info;
+#endif
+ } else if (index == 4) {
+#ifdef CONFIG_UEC_ETH5
+ uec_info = ð5_uec_info;
+#endif
+ } else if (index == 5) {
+#ifdef CONFIG_UEC_ETH6
+ uec_info = ð6_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);
return err;
}
- err = init_phy(dev);
- if (err) {
- printf("%s: Cannot initialize PHY, aborting.\n", dev->name);
- return err;
- }
-
- phy_change(dev);
+#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 */