summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c87
1 files changed, 69 insertions, 18 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c b/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
index 501b31e4ec..32812114ab 100644
--- a/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
+++ b/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
@@ -27,6 +27,7 @@
#include <bsp/irq.h>
#include <mpc83xx/mpc83xx.h>
#include <mpc83xx/tsec.h>
+#include <libcpu/spr.h>
#include <rtems/error.h>
#include <rtems/bspIo.h>
#include <rtems/rtems_bsdnet.h>
@@ -43,6 +44,13 @@
#include <netinet/if_ether.h>
#include <stdio.h>
+/* System Version Register */
+#define SVR 286
+SPR_RO( SVR)
+
+/* Processor Version Register */
+SPR_RO( PVR)
+
#define CLREVENT_IN_IRQ
#define TSEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */
@@ -57,7 +65,8 @@ struct mpc83xx_tsec_struct {
/*
* HW links: (filled from rtems_bsdnet_ifconfig
*/
- m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC register block */
+ m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC register block */
+ m83xxTSEC_Registers_t *mdio_ptr; /* pointer to TSEC register block which is responsible for MDIO communication */
int irq_num_tx; /* tx irq number */
int irq_num_rx; /* rx irq number */
int irq_num_err; /* error irq number */
@@ -192,7 +201,7 @@ static void mpc83xx_tsec_hwinit
{
m83xxTSEC_Registers_t *reg_ptr = sc->reg_ptr; /* pointer to TSEC registers*/
uint8_t *mac_addr;
- int i;
+ size_t i;
/*
* init ECNTL register
@@ -272,9 +281,9 @@ static void mpc83xx_tsec_hwinit
/*
* init MACCFG2 register
*/
- reg_ptr->maccfg2 = ((reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
- | M83xx_TSEC_MACCFG2_PRELEN(7)
- | M83xx_TSEC_MACCFG2_FULLDUPLEX);
+ reg_ptr->maccfg2 = (reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
+ | M83xx_TSEC_MACCFG2_PRELEN( 7)
+ | M83xx_TSEC_MACCFG2_FULLDUPLEX;
/*
* init station address register
@@ -324,10 +333,19 @@ static void mpc83xx_tsec_mdio_init
| <none> |
\*=========================================================================*/
{
+
+ /* Set TSEC registers for MDIO communication */
+
+ /*
+ * FIXME: Not clear if this works for all boards.
+ * Tested only on MPC8313ERDB.
+ */
+ sc->mdio_ptr = &mpc83xx.tsec [0];
+
/*
* set clock divider
*/
- sc->reg_ptr->miimcfg = 3;
+ sc->mdio_ptr->miimcfg = 3;
}
/*=========================================================================*\
@@ -351,10 +369,10 @@ int mpc83xx_tsec_mdio_read
| 0, if ok, else error |
\*=========================================================================*/
{
- struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
- m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
+ struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
- reg_ptr = sc->reg_ptr;
+ /* pointer to TSEC registers */
+ m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
/*
* make sure we work with a valid phy
@@ -419,10 +437,10 @@ int mpc83xx_tsec_mdio_write
| 0, if ok, else error |
\*=========================================================================*/
{
- struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
- m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
+ struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
- reg_ptr = sc->reg_ptr;
+ /* pointer to TSEC registers */
+ m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
/*
* make sure we work with a valid phy
@@ -1685,9 +1703,9 @@ int rtems_mpc83xx_tsec_mode_adapt
| 0, if success |
\*=========================================================================*/
{
- int result;
- int media;
+ int result = 0;
struct mpc83xx_tsec_struct *sc = ifp->if_softc;
+ int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default);
#ifdef DEBUG
printf("c");
@@ -1819,6 +1837,8 @@ static int mpc83xx_tsec_driver_attach
struct ifnet *ifp;
int unitNumber;
char *unitName;
+ uint32_t svr = _read_SVR();
+ uint32_t pvr = _read_PVR();
/*
* Parse driver name
@@ -1865,10 +1885,30 @@ static int mpc83xx_tsec_driver_attach
/* get pointer to TSEC register block */
sc->reg_ptr = &mpc83xx.tsec[unitNumber-1];
- /* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */
- sc->irq_num_tx = config->irno + 0; /* tx irq number from BSP */
- sc->irq_num_rx = config->irno + 1; /* rx irq number from BSP */
- sc->irq_num_err = config->irno + 2; /* err irq number from BSP */
+
+ if (svr == 0x80b00010 && pvr == 0x80850010) {
+ /*
+ * This is a special case for MPC8313ERDB with silicon revision 1. Look in
+ * "MPC8313ECE Rev. 3, 3/2008" errata for "IPIC 1".
+ */
+ if (unitNumber == 1) {
+ sc->irq_num_tx = 37;
+ sc->irq_num_rx = 36;
+ sc->irq_num_err = 35;
+ } else if (unitNumber == 2) {
+ sc->irq_num_tx = 34;
+ sc->irq_num_rx = 33;
+ sc->irq_num_err = 32;
+ } else {
+ return 0;
+ }
+ } else {
+ /* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */
+ sc->irq_num_tx = config->irno + 0; /* tx irq number from BSP */
+ sc->irq_num_rx = config->irno + 1; /* rx irq number from BSP */
+ sc->irq_num_err = config->irno + 2; /* err irq number from BSP */
+ }
+
if (config->irno == 0) {
rtems_panic("TSEC: interupt base number irno not defined");
}
@@ -1878,11 +1918,22 @@ static int mpc83xx_tsec_driver_attach
sc->mdio_info.mdio_r = mpc83xx_tsec_mdio_read;
sc->mdio_info.mdio_w = mpc83xx_tsec_mdio_write;
sc->mdio_info.has_gmii = 1; /* we support gigabit IF */
+
/*
* XXX: Although most hardware builders will assign the PHY addresses
* like this, this should be more configurable
*/
+#ifdef MPC8313ERDB
+ if (unitNumber == 2) {
+ sc->phy_default = 4;
+ } else {
+ /* TODO */
+ return 0;
+ }
+#else /* MPC8313ERDB */
sc->phy_default = unitNumber-1;
+#endif /* MPC8313ERDB */
+
/*
* Set up network interface values
*/