[U-Boot] [PATCH 04/14] powerpc/fman: add 10GEC controller and PHY support
Mingkai Hu
Mingkai.hu at freescale.com
Thu Jan 27 05:52:42 CET 2011
From: Kumar Gala <galak at kernel.crashing.org>
Signed-off-by: Kumar Gala <galak at kernel.crashing.org>
Signed-off-by: Mingkai Hu <Mingkai.hu at freescale.com>
---
drivers/net/fm/tgec.c | 104 ++++++++++++++++++++
drivers/net/fm/tgec.h | 230 +++++++++++++++++++++++++++++++++++++++++++++
drivers/net/fm/tgec_phy.c | 155 ++++++++++++++++++++++++++++++
3 files changed, 489 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/fm/tgec.c
create mode 100644 drivers/net/fm/tgec.h
create mode 100644 drivers/net/fm/tgec_phy.c
diff --git a/drivers/net/fm/tgec.c b/drivers/net/fm/tgec.c
new file mode 100644
index 0000000..02a2476
--- /dev/null
+++ b/drivers/net/fm/tgec.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ * Dave Liu <daveliu at freescale.com>
+ *
+ * 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 Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/fsl_enet.h>
+
+#include "tgec.h"
+
+static void tgec_init_mac(struct fsl_enet_mac *mac)
+{
+ struct tgec *regs = mac->base;
+
+ /* mask all interrupt */
+ out_be32(®s->imask, IMASK_MASK_ALL);
+
+ /* clear all events */
+ out_be32(®s->ievent, IEVENT_CLEAR_ALL);
+
+ /* set the max receive length */
+ out_be32(®s->maxfrm, mac->max_rx_len);
+
+ /* 1588 disable, insert second mac disable
+ * payload length check disable, normal operation,
+ * any rx error frame is discarded, clear counters,
+ * pause frame ignore, no promiscuous, LAN mode
+ * Rx CRC no strip, Tx CRC append, Rx disable and Tx disable
+ */
+ out_be32(®s->command_config, TGEC_CMD_CFG_INIT);
+ udelay(1000);
+ out_be32(®s->command_config, TGEC_CMD_CFG_FINAL);
+
+ /* multicast frame reception for the hash entry disable */
+ out_be32(®s->hashtable_ctrl, 0);
+}
+
+static void tgec_enable_mac(struct fsl_enet_mac *mac)
+{
+ struct tgec *regs = mac->base;
+
+ setbits_be32(®s->command_config, TGEC_CMD_CFG_RXTX_EN);
+}
+
+static void tgec_disable_mac(struct fsl_enet_mac *mac)
+{
+ struct tgec *regs = mac->base;
+
+ clrbits_be32(®s->command_config, TGEC_CMD_CFG_RXTX_EN);
+}
+
+static void tgec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
+{
+ struct tgec *regs = mac->base;
+ u32 mac_addr0, mac_addr1;
+
+ /* if a station address of 0x12345678ABCD, perform a write to
+ MAC_ADDR0 of 0x78563412,
+ MAC_ADDR1 of 0x0000CDAB */
+
+ mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]);
+ out_be32(®s->mac_addr_0, mac_addr0);
+
+ mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff;
+ out_be32(®s->mac_addr_1, mac_addr1);
+}
+
+static void tgec_set_interface_mode(struct fsl_enet_mac *mac,
+ enum fsl_phy_enet_if type, int speed)
+{
+ /* nothing right now */
+ return;
+}
+
+void init_tgec(struct fsl_enet_mac *mac, void *base,
+ void *phyregs, int max_rx_len)
+{
+ mac->base = base;
+ mac->phyregs = phyregs;
+ mac->max_rx_len = max_rx_len;
+ mac->init_mac = tgec_init_mac;
+ mac->enable_mac = tgec_enable_mac;
+ mac->disable_mac = tgec_disable_mac;
+ mac->set_mac_addr = tgec_set_mac_addr;
+ mac->set_if_mode = tgec_set_interface_mode;
+}
diff --git a/drivers/net/fm/tgec.h b/drivers/net/fm/tgec.h
new file mode 100644
index 0000000..8d64db2
--- /dev/null
+++ b/drivers/net/fm/tgec.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ * Dave Liu <daveliu at freescale.com>
+ *
+ * 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 Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __TGEC_H__
+#define __TGEC_H__
+
+#include "../fsl_phy.h"
+
+/* EC10G_ID - 10-gigabit ethernet MAC controller ID
+ */
+#define EC10G_ID_VER_MASK 0x0000ff00
+#define EC10G_ID_VER_SHIFT 8
+#define EC10G_ID_REV_MASK 0x000000ff
+
+/* COMMAND_CONFIG - command and configuration register
+ */
+#define TGEC_CMD_CFG_EN_TIMESTAMP 0x00100000 /* enable IEEE1588 */
+#define TGEC_CMD_CFG_TX_ADDR_INS_SEL 0x00080000 /* Tx mac address with second */
+#define TGEC_CMD_CFG_NO_LEN_CHK 0x00020000 /* payload length check disable */
+#define TGEC_CMD_CFG_SEND_IDLE 0x00010000 /* send XGMII idle sequences */
+#define TGEC_CMD_CFG_RX_ER_DISC 0x00004000 /* enable receive error frame discard */
+#define TGEC_CMD_CFG_CMD_FRM_EN 0x00002000 /* all command frames are accepted */
+#define TGEC_CMD_CFG_STAT_CLR 0x00001000 /* all statistics counters are cleared */
+#define TGEC_CMD_CFG_TX_ADDR_INS 0x00000200 /* overwrite the souce MAC address */
+#define TGEC_CMD_CFG_PAUSE_IGNORE 0x00000100 /* ignores received pause frames */
+#define TGEC_CMD_CFG_PAUSE_FWD 0x00000080 /* forwards pause frames to the user app */
+#define TGEC_CMD_CFG_CRC_FWD 0x00000040 /* MAC forward Rx CRC to user */
+#define TGEC_CMD_CFG_PAD_EN 0x00000020 /* MAC remove Rx padding */
+#define TGEC_CMD_CFG_PROM_EN 0x00000010 /* promiscuous mode enable */
+#define TGEC_CMD_CFG_WAN_MODE 0x00000008 /* WAN mode enable */
+#define TGEC_CMD_CFG_RX_EN 0x00000002 /* MAC receive path enable */
+#define TGEC_CMD_CFG_TX_EN 0x00000001 /* MAC transmit path enable */
+
+#define TGEC_CMD_CFG_RXTX_EN (TGEC_CMD_CFG_RX_EN | TGEC_CMD_CFG_TX_EN)
+
+#define TGEC_CMD_CFG_INIT (TGEC_CMD_CFG_NO_LEN_CHK | \
+ TGEC_CMD_CFG_RX_ER_DISC | \
+ TGEC_CMD_CFG_STAT_CLR | \
+ TGEC_CMD_CFG_PAUSE_IGNORE | \
+ TGEC_CMD_CFG_CRC_FWD)
+
+#define TGEC_CMD_CFG_FINAL (TGEC_CMD_CFG_NO_LEN_CHK | \
+ TGEC_CMD_CFG_RX_ER_DISC | \
+ TGEC_CMD_CFG_PAUSE_IGNORE | \
+ TGEC_CMD_CFG_CRC_FWD)
+/* HASHTABLE_CTRL - Hashtable control register
+ */
+#define HASHTABLE_CTRL_MCAST_EN 0x00000200 /* enable mulitcast Rx hash */
+#define HASHTABLE_CTRL_ADDR_MASK 0x000001ff
+
+/* TX_IPG_LENGTH - Transmit inter-packet gap length register
+ */
+#define TX_IPG_LENGTH_IPG_LEN_MASK 0x000003ff
+
+/* IMASK - interrupt mask register
+ */
+#define IMASK_MDIO_SCAN_EVENT 0x00010000 /* MDIO scan event mask */
+#define IMASK_MDIO_CMD_CMPL 0x00008000 /* MDIO cmd completion mask */
+#define IMASK_REM_FAULT 0x00004000 /* remote fault mask */
+#define IMASK_LOC_FAULT 0x00002000 /* local fault mask */
+#define IMASK_TX_ECC_ER 0x00001000 /* Tx frame ECC error mask */
+#define IMASK_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow mask */
+#define IMASK_TX_ER 0x00000200 /* Tx frame error mask */
+#define IMASK_RX_FIFO_OVFL 0x00000100 /* Rx FIFO overflow mask */
+#define IMASK_RX_ECC_ER 0x00000080 /* Rx frame ECC error mask */
+#define IMASK_RX_JAB_FRM 0x00000040 /* Rx jabber frame mask */
+#define IMASK_RX_OVRSZ_FRM 0x00000020 /* Rx oversized frame mask */
+#define IMASK_RX_RUNT_FRM 0x00000010 /* Rx runt frame mask */
+#define IMASK_RX_FRAG_FRM 0x00000008 /* Rx fragment frame mask */
+#define IMASK_RX_LEN_ER 0x00000004 /* Rx payload length error mask */
+#define IMASK_RX_CRC_ER 0x00000002 /* Rx CRC error mask */
+#define IMASK_RX_ALIGN_ER 0x00000001 /* Rx alignment error mask */
+
+#define IMASK_MASK_ALL 0x00000000
+
+/* IEVENT - interrupt event register
+ */
+#define IEVENT_MDIO_SCAN_EVENT 0x00010000 /* MDIO scan event */
+#define IEVENT_MDIO_CMD_CMPL 0x00008000 /* MDIO cmd completion */
+#define IEVENT_REM_FAULT 0x00004000 /* remote fault */
+#define IEVENT_LOC_FAULT 0x00002000 /* local fault */
+#define IEVENT_TX_ECC_ER 0x00001000 /* Tx frame ECC error */
+#define IEVENT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
+#define IEVENT_TX_ER 0x00000200 /* Tx frame error */
+#define IEVENT_RX_FIFO_OVFL 0x00000100 /* Rx FIFO overflow */
+#define IEVENT_RX_ECC_ER 0x00000080 /* Rx frame ECC error */
+#define IEVENT_RX_JAB_FRM 0x00000040 /* Rx jabber frame */
+#define IEVENT_RX_OVRSZ_FRM 0x00000020 /* Rx oversized frame */
+#define IEVENT_RX_RUNT_FRM 0x00000010 /* Rx runt frame */
+#define IEVENT_RX_FRAG_FRM 0x00000008 /* Rx fragment frame */
+#define IEVENT_RX_LEN_ER 0x00000004 /* Rx payload length error */
+#define IEVENT_RX_CRC_ER 0x00000002 /* Rx CRC error */
+#define IEVENT_RX_ALIGN_ER 0x00000001 /* Rx alignment error */
+
+#define IEVENT_CLEAR_ALL 0xffffffff
+
+struct tgec {
+ /* 10GEC general control and status registers */
+ u32 tgec_id; /* Controller ID register */
+ u32 res0;
+ u32 command_config; /* Control and configuration register */
+ u32 mac_addr_0; /* Lower 32 bits of 48-bit MAC address */
+ u32 mac_addr_1; /* Upper 16 bits of 48-bit MAC address */
+ u32 maxfrm; /* Maximum frame length register */
+ u32 pause_quant; /* Pause quanta register */
+ u32 res1[4];
+ u32 hashtable_ctrl; /* Hash table control register */
+ u32 res2[4];
+ u32 status; /* MAC status register */
+ u32 tx_ipg_length; /* Transmitter inter-packet-gap register */
+ u32 mac_addr_2; /* Lower 32 bits of the second 48-bit MAC address */
+ u32 mac_addr_3; /* Upper 16 bits of the second 48-bit MAC address */
+ u32 res3[4];
+ u32 imask; /* Interrupt mask register */
+ u32 ievent; /* Interrupt event register */
+ u32 res4[6];
+ /* 10GEC statistics counter registers */
+ u32 tx_frame_u; /* Transmit frame counter upper */
+ u32 tx_frame_l; /* Transmit frame counter lower */
+ u32 rx_frame_u; /* Receive frame counter upper */
+ u32 rx_frame_l; /* Receive frame counter lower */
+ u32 rx_frame_crc_err_u; /* Receive frame check sequence error upper */
+ u32 rx_frame_crc_err_l; /* Receive frame check sequence error lower */
+ u32 rx_align_err_u; /* Receive alignment error upper */
+ u32 rx_align_err_l; /* Receive alignment error lower */
+ u32 tx_pause_frame_u; /* Transmit valid pause frame upper */
+ u32 tx_pause_frame_l; /* Transmit valid pause frame lower */
+ u32 rx_pause_frame_u; /* Receive valid pause frame upper */
+ u32 rx_pause_frame_l; /* Receive valid pause frame upper */
+ u32 rx_long_err_u; /* Receive too long frame error upper */
+ u32 rx_long_err_l; /* Receive too long frame error lower */
+ u32 rx_frame_err_u; /* Receive frame length error upper */
+ u32 rx_frame_err_l; /* Receive frame length error lower */
+ u32 tx_vlan_u; /* Transmit VLAN frame upper */
+ u32 tx_vlan_l; /* Transmit VLAN frame lower */
+ u32 rx_vlan_u; /* Receive VLAN frame upper */
+ u32 rx_vlan_l; /* Receive VLAN frame lower */
+ u32 tx_oct_u; /* Transmit octets upper */
+ u32 tx_oct_l; /* Transmit octets lower */
+ u32 rx_oct_u; /* Receive octets upper */
+ u32 rx_oct_l; /* Receive octets lower */
+ u32 rx_uni_u; /* Receive unicast frame upper */
+ u32 rx_uni_l; /* Receive unicast frame lower */
+ u32 rx_multi_u; /* Receive multicast frame upper */
+ u32 rx_multi_l; /* Receive multicast frame lower */
+ u32 rx_brd_u; /* Receive broadcast frame upper */
+ u32 rx_brd_l; /* Receive broadcast frame lower */
+ u32 tx_frame_err_u; /* Transmit frame error upper */
+ u32 tx_frame_err_l; /* Transmit frame error lower */
+ u32 tx_uni_u; /* Transmit unicast frame upper */
+ u32 tx_uni_l; /* Transmit unicast frame lower */
+ u32 tx_multi_u; /* Transmit multicast frame upper */
+ u32 tx_multi_l; /* Transmit multicast frame lower */
+ u32 tx_brd_u; /* Transmit broadcast frame upper */
+ u32 tx_brd_l; /* Transmit broadcast frame lower */
+ u32 rx_drop_u; /* Receive dropped packets upper */
+ u32 rx_drop_l; /* Receive dropped packets lower */
+ u32 rx_eoct_u; /* Receive ethernet octets upper */
+ u32 rx_eoct_l; /* Receive ethernet octets lower */
+ u32 rx_pkt_u; /* Receive packets upper */
+ u32 rx_pkt_l; /* Receive packets lower */
+ u32 tx_undsz_u; /* Undersized packet upper */
+ u32 tx_undsz_l; /* Undersized packet lower */
+ u32 rx_64_u; /* Receive 64 oct packet upper */
+ u32 rx_64_l; /* Receive 64 oct packet lower */
+ u32 rx_127_u; /* Receive 65 to 127 oct packet upper */
+ u32 rx_127_l; /* Receive 65 to 127 oct packet lower */
+ u32 rx_255_u; /* Receive 128 to 255 oct packet upper */
+ u32 rx_255_l; /* Receive 128 to 255 oct packet lower */
+ u32 rx_511_u; /* Receive 256 to 511 oct packet upper */
+ u32 rx_511_l; /* Receive 256 to 511 oct packet lower */
+ u32 rx_1023_u; /* Receive 512 to 1023 oct packet upper */
+ u32 rx_1023_l; /* Receive 512 to 1023 oct packet lower */
+ u32 rx_1518_u; /* Receive 1024 to 1518 oct packet upper */
+ u32 rx_1518_l; /* Receive 1024 to 1518 oct packet lower */
+ u32 rx_1519_u; /* Receive 1519 to max oct packet upper */
+ u32 rx_1519_l; /* Receive 1519 to max oct packet lower */
+ u32 tx_oversz_u; /* oversized packet upper */
+ u32 tx_oversz_l; /* oversized packet lower */
+ u32 tx_jabber_u; /* Jabber packet upper */
+ u32 tx_jabber_l; /* Jabber packet lower */
+ u32 tx_frag_u; /* Fragment packet upper */
+ u32 tx_frag_l; /* Fragment packet lower */
+ u32 rx_err_u; /* Receive frame error upper */
+ u32 rx_err_l; /* Receive frame error lower */
+ u32 res5[0x39a];
+} __attribute__ ((packed));
+
+struct tgec_mdio_controller {
+ u32 res0[0xc];
+ u32 mdio_stat; /* MDIO configuration and status */
+ u32 mdio_ctl; /* MDIO control */
+ u32 mdio_data; /* MDIO data */
+ u32 mdio_addr; /* MDIO address */
+} __attribute__ ((packed));
+
+#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8)
+#define MDIO_STAT_BSY (1 << 0)
+#define MDIO_STAT_RD_ER (1 << 1)
+#define MDIO_CTL_DEV_ADDR(x) (x & 0x1f)
+#define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5)
+#define MDIO_CTL_PRE_DIS (1 << 10)
+#define MDIO_CTL_SCAN_EN (1 << 11)
+#define MDIO_CTL_POST_INC (1 << 14)
+#define MDIO_CTL_READ (1 << 15)
+
+#define MDIO_DATA(x) (x & 0xffff)
+#define MDIO_DATA_BSY (1 << 31)
+
+void init_tgec(struct fsl_enet_mac *mac, void *base, void *phyregs, int max_rx_len);
+struct phy_info *tgec_get_phy_info(struct mii_info *mii_info);
+
+#endif
diff --git a/drivers/net/fm/tgec_phy.c b/drivers/net/fm/tgec_phy.c
new file mode 100644
index 0000000..cf95e02
--- /dev/null
+++ b/drivers/net/fm/tgec_phy.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ * Andy Fleming <afleming at freescale.com>
+ *
+ * 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 Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ * Some part is taken from tsec.c
+ */
+#include <common.h>
+#include <asm/io.h>
+
+#include "../fsl_phy.h"
+#include "tgec.h"
+
+/* Write value to the PHY for this device to the register at regnum, */
+/* waiting until the write is done before it returns. All PHY */
+/* configuration has to be done through the TSEC1 MIIM regs */
+int tgec_write_phy_reg(struct tgec_mdio_controller *regs, int port_addr,
+ int dev_addr, int regnum, int value)
+{
+ u32 mdio_ctl;
+ u32 stat_val;
+
+ /* Wait till the bus is free */
+ stat_val = MDIO_STAT_CLKDIV(100);
+ out_be32(®s->mdio_stat, stat_val);
+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY);
+
+ /* Set the port and dev addr */
+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+ out_be32(®s->mdio_ctl, mdio_ctl);
+
+ /* Set the register address */
+ out_be32(®s->mdio_addr, regnum & 0xffff);
+
+ /* Wait till the bus is free */
+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY);
+
+ /* Write the value to the register */
+ out_be32(®s->mdio_data, MDIO_DATA(value));
+
+ /* Wait till the MDIO write is complete */
+ while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY);
+
+ return 0;
+}
+
+/* Reads from register regnum in the PHY for device dev, */
+/* returning the value. Clears miimcom first. All PHY */
+/* configuration has to be done through the TSEC1 MIIM regs */
+int tgec_read_phy_reg(struct tgec_mdio_controller *regs, int port_addr,
+ int dev_addr, int regnum)
+{
+ u32 mdio_ctl;
+ u32 stat_val;
+
+ stat_val = MDIO_STAT_CLKDIV(100);
+ out_be32(®s->mdio_stat, stat_val);
+ /* Wait till the bus is free */
+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY);
+
+ /* Set the Port and Device Addrs */
+ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+ out_be32(®s->mdio_ctl, mdio_ctl);
+
+ /* Set the register address */
+ out_be32(®s->mdio_addr, regnum & 0xffff);
+
+ /* Wait till the bus is free */
+ while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY);
+
+ /* Initiate the read */
+ mdio_ctl |= MDIO_CTL_READ;
+ out_be32(®s->mdio_ctl, mdio_ctl);
+
+ /* Wait till the MDIO write is complete */
+ while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY);
+
+ return in_be32(®s->mdio_data) & 0xffff;
+}
+
+int tgec_phy_write(struct mii_info *mii_info, int dev_addr, int regnum,
+ int value)
+{
+ struct tgec_mdio_controller *regs = mii_info->phyregs;
+
+ return tgec_write_phy_reg(regs, mii_info->mii_id, dev_addr, regnum,
+ value);
+}
+
+int tgec_phy_read(struct mii_info *mii_info, int dev_addr, int regnum)
+{
+ struct tgec_mdio_controller *regs = mii_info->phyregs;
+
+ return tgec_read_phy_reg(regs, mii_info->mii_id, dev_addr, regnum);
+}
+
+/* For now, just assume 10G, and use AN as basis for link state */
+int tgec_shutdown_phy(struct mii_info *mii_info)
+{
+ return 0;
+}
+int tgec_startup_phy(struct mii_info *mii_info)
+{
+ mii_info->link = 1;
+ mii_info->speed = 1000;
+ mii_info->duplex = 1;
+ return 0;
+}
+
+int tgec_config_phy(struct mii_info *mii_info)
+{
+ return 0;
+}
+
+int tn2020_config_phy(struct mii_info *mii_info)
+{
+ if (mii_info->port == PORT_FIBRE) {
+ tgec_phy_write(mii_info, 30, 93, 2);
+ tgec_phy_write(mii_info, 7, 0, 0x3200);
+ }
+
+ return 0;
+}
+
+/* Giant hack. */
+struct phy_info phy_info_tgec = {
+ "Teranetics TN2020",
+ 0xf00,
+ 0xf00,
+ &tn2020_config_phy,
+ &tgec_startup_phy,
+ &tgec_shutdown_phy,
+};
+
+struct phy_info *tgec_phy_info[] = {
+ &phy_info_tgec,
+};
+
+struct phy_info *tgec_get_phy_info(struct mii_info *mii_info)
+{
+ return &phy_info_tgec;
+}
--
1.6.4
More information about the U-Boot
mailing list