* mpc83xx/network/tsec.c, mpc83xx/network/tsec.h: Use configuration
	structure instead of many function parameters.  Moved board specific
	initializations.  Added support for interfaces without PHY access.
This commit is contained in:
Sebastian Huber
2011-01-14 10:48:57 +00:00
parent e7620cbd10
commit f2c8c34887
3 changed files with 57 additions and 99 deletions

View File

@@ -1,3 +1,9 @@
2011-01-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* mpc83xx/network/tsec.c, mpc83xx/network/tsec.h: Use configuration
structure instead of many function parameters. Moved board specific
initializations. Added support for interfaces without PHY access.
2011-01-09 Sebastian Huber <sebastian.huber@embedded-brains.de> 2011-01-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
* new-exceptions/bspsupport/ppc_exc_categories.c: Fixed e200 machine * new-exceptions/bspsupport/ppc_exc_categories.c: Fixed e200 machine

View File

@@ -16,17 +16,11 @@
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| this file contains the MPC83xx TSEC networking driver | | this file contains the MPC83xx TSEC networking driver |
\*===============================================================*/ \*===============================================================*/
/*
* this driver has the following HW assumptions:
* - PHY for TSEC1 uses address 0
* - PHY for TSEC2 uses address 1
* - PHY uses GMII for 1000Base-T and MII for the rest of the modes
*/
#include <stdlib.h> #include <stdlib.h>
#include <bsp.h> #include <bsp.h>
#include <bsp/irq.h> #include <bsp/irq.h>
#include <bsp/tsec.h> #include <bsp/tsec.h>
#include <libcpu/spr.h>
#include <rtems/error.h> #include <rtems/error.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include <rtems/rtems_bsdnet.h> #include <rtems/rtems_bsdnet.h>
@@ -43,17 +37,16 @@
#include <netinet/if_ether.h> #include <netinet/if_ether.h>
#include <stdio.h> #include <stdio.h>
/* System Version Register */
#define SVR 286
SPR_RO( SVR)
/* Processor Version Register */
SPR_RO( PVR)
#define CLREVENT_IN_IRQ #define CLREVENT_IN_IRQ
#define TSEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */ #define TSEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */
#ifdef DEBUG
#define PF(fmt, ...) printk("%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define PF(...)
#endif
/* /*
* Device data * Device data
*/ */
@@ -64,11 +57,11 @@ struct tsec_struct {
/* /*
* HW links: (filled from rtems_bsdnet_ifconfig * HW links: (filled from rtems_bsdnet_ifconfig
*/ */
volatile tsec_registers *reg_ptr; /* pointer to TSEC register block */ volatile tsec_registers *reg_ptr; /* pointer to TSEC register block */
volatile tsec_registers *mdio_ptr; /* pointer to TSEC register block which is responsible for MDIO communication */ volatile tsec_registers *mdio_ptr; /* pointer to TSEC register block which is responsible for MDIO communication */
int irq_num_tx; /* tx irq number */ rtems_irq_number irq_num_tx;
int irq_num_rx; /* rx irq number */ rtems_irq_number irq_num_rx;
int irq_num_err; /* error irq number */ rtems_irq_number irq_num_err;
/* /*
* BD management * BD management
@@ -371,14 +364,12 @@ static int tsec_mdio_read
/* pointer to TSEC registers */ /* pointer to TSEC registers */
volatile tsec_registers *reg_ptr = sc->mdio_ptr; volatile tsec_registers *reg_ptr = sc->mdio_ptr;
PF("%u\n", reg);
/* /*
* make sure we work with a valid phy * make sure we work with a valid phy
*/ */
if (phy == -1) { if (phy == -1) {
/*
* set default phy number: 0 for TSEC1, 1 for TSEC2
*/
phy = sc->phy_default; phy = sc->phy_default;
} }
if ( (phy < 0) || (phy > 31)) { if ( (phy < 0) || (phy > 31)) {
@@ -439,6 +430,7 @@ static int tsec_mdio_write
/* pointer to TSEC registers */ /* pointer to TSEC registers */
volatile tsec_registers *reg_ptr = sc->mdio_ptr; volatile tsec_registers *reg_ptr = sc->mdio_ptr;
PF("%u\n", reg);
/* /*
* make sure we work with a valid phy * make sure we work with a valid phy
@@ -622,6 +614,7 @@ static void tsec_receive_packets
- sizeof(struct ether_header)); - sizeof(struct ether_header));
eh = mtod(m, struct ether_header *); eh = mtod(m, struct ether_header *);
m->m_data += sizeof(struct ether_header); m->m_data += sizeof(struct ether_header);
PF("RX[%08x] (%i)\n", BD_ptr, m->m_len);
ether_input(&sc->arpcom.ac_if,eh,m); ether_input(&sc->arpcom.ac_if,eh,m);
} }
else { else {
@@ -1001,6 +994,7 @@ static void tsec_sendpacket
CurrBD->buffer = mtod(m, void *); CurrBD->buffer = mtod(m, void *);
CurrBD->length = (uint32_t)m->m_len; CurrBD->length = (uint32_t)m->m_len;
l = m; /* remember: we use this mbuf */ l = m; /* remember: we use this mbuf */
PF("TX[%08x] (%i)\n", CurrBD, m->m_len);
bd_idx = CurrBD - sc->Tx_Frst_BD; bd_idx = CurrBD - sc->Tx_Frst_BD;
sc->Tx_mBuf_Ptr[bd_idx] = m; sc->Tx_mBuf_Ptr[bd_idx] = m;
@@ -1147,6 +1141,7 @@ static void tsec_tx_irq_handler
uint32_t irq_events; uint32_t irq_events;
#endif #endif
PF("TXIRQ\n");
sc->txInterrupts++; sc->txInterrupts++;
/* /*
* disable tx interrupts * disable tx interrupts
@@ -1191,6 +1186,7 @@ static void tsec_rx_irq_handler
#endif #endif
sc->rxInterrupts++; sc->rxInterrupts++;
PF("RXIRQ\n");
/* /*
* disable rx interrupts * disable rx interrupts
*/ */
@@ -1229,6 +1225,7 @@ static void tsec_err_irq_handler
{ {
struct tsec_struct *sc = struct tsec_struct *sc =
(struct tsec_struct *)handle; (struct tsec_struct *)handle;
PF("ERIRQ\n");
/* /*
* clear error events in IEVENT * clear error events in IEVENT
*/ */
@@ -1689,8 +1686,6 @@ static int tsec_ioctl
return error; return error;
} }
/* #define DEBUG */
/*=========================================================================*\ /*=========================================================================*\
| Function: | | Function: |
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
@@ -1713,9 +1708,11 @@ static int tsec_mode_adapt
struct tsec_struct *sc = ifp->if_softc; struct tsec_struct *sc = ifp->if_softc;
int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default); int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default);
#ifdef DEBUG /* In case no PHY is available stop now */
printf("c"); if (sc->phy_default < 0) {
#endif return 0;
}
/* /*
* fetch media status * fetch media status
*/ */
@@ -1723,9 +1720,7 @@ static int tsec_mode_adapt
if (result != 0) { if (result != 0) {
return result; return result;
} }
#ifdef DEBUG
printf("C");
#endif
/* /*
* status is unchanged? then do nothing * status is unchanged? then do nothing
*/ */
@@ -1821,18 +1816,13 @@ static void tsec_watchdog
ifp->if_timer = TSEC_WATCHDOG_TIMEOUT; ifp->if_timer = TSEC_WATCHDOG_TIMEOUT;
} }
static int tsec_driver_attach( static int tsec_driver_attach(struct rtems_bsdnet_ifconfig *config)
struct rtems_bsdnet_ifconfig *config,
int unitNumber,
char *unitName,
volatile tsec_registers *reg_ptr,
volatile tsec_registers *mdio_ptr
)
{ {
tsec_config *tsec_cfg = config->drv_ctrl;
int unitNumber = tsec_cfg->unit_number;
char *unitName = tsec_cfg->unit_name;
struct tsec_struct *sc; struct tsec_struct *sc;
struct ifnet *ifp; struct ifnet *ifp;
uint32_t svr = _read_SVR();
uint32_t pvr = _read_PVR();
/* /*
* Is driver free? * Is driver free?
@@ -1846,10 +1836,6 @@ static int tsec_driver_attach(
sc = &tsec_driver[unitNumber - 1]; sc = &tsec_driver[unitNumber - 1];
ifp = &sc->arpcom.ac_if; ifp = &sc->arpcom.ac_if;
/*
* add sc to config
*/
config->drv_ctrl = sc;
if(ifp->if_softc != NULL) { if(ifp->if_softc != NULL) {
printk ("Driver already in use.\n"); printk ("Driver already in use.\n");
@@ -1871,35 +1857,14 @@ static int tsec_driver_attach(
sc->acceptBroadcast = !config->ignore_broadcast; sc->acceptBroadcast = !config->ignore_broadcast;
/* get pointer to TSEC register block */ /* get pointer to TSEC register block */
sc->reg_ptr = reg_ptr; sc->reg_ptr = tsec_cfg->reg_ptr;
sc->mdio_ptr = mdio_ptr; sc->mdio_ptr = tsec_cfg->mdio_ptr;
if (svr == 0x80b00010 && pvr == 0x80850010) { /* IRQ numbers */
/* sc->irq_num_tx = tsec_cfg->irq_num_tx;
* This is a special case for MPC8313ERDB with silicon revision 1. Look in sc->irq_num_rx = tsec_cfg->irq_num_rx;
* "MPC8313ECE Rev. 3, 3/2008" errata for "IPIC 1". sc->irq_num_err = tsec_cfg->irq_num_err;
*/
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");
}
/* /*
* setup info about mdio interface * setup info about mdio interface
*/ */
@@ -1907,20 +1872,8 @@ static int tsec_driver_attach(
sc->mdio_info.mdio_w = tsec_mdio_write; sc->mdio_info.mdio_w = tsec_mdio_write;
sc->mdio_info.has_gmii = 1; /* we support gigabit IF */ sc->mdio_info.has_gmii = 1; /* we support gigabit IF */
/* /* PHY address */
* XXX: Although most hardware builders will assign the PHY addresses sc->phy_default = tsec_cfg->phy_default;
* 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 * Set up network interface values
@@ -1954,21 +1907,11 @@ static int tsec_driver_attach(
int tsec_driver_attach_detach( int tsec_driver_attach_detach(
struct rtems_bsdnet_ifconfig *config, struct rtems_bsdnet_ifconfig *config,
int unitNumber,
char *unitName,
volatile tsec_registers *reg_ptr,
volatile tsec_registers *mdio_ptr,
int attaching int attaching
) )
{ {
if (attaching) { if (attaching) {
return tsec_driver_attach( return tsec_driver_attach(config);
config,
unitNumber,
unitName,
reg_ptr,
mdio_ptr
);
} else { } else {
return 0; return 0;
} }

View File

@@ -21,6 +21,8 @@
#define LIBCPU_POWERPC_TSEC_H #define LIBCPU_POWERPC_TSEC_H
#include <stdint.h> #include <stdint.h>
#include <bsp/irq.h>
#include <bsp/tsec-config.h> #include <bsp/tsec-config.h>
#ifdef __cplusplus #ifdef __cplusplus
@@ -355,12 +357,19 @@ typedef struct {
struct rtems_bsdnet_ifconfig; struct rtems_bsdnet_ifconfig;
typedef struct {
int unit_number;
char *unit_name;
volatile tsec_registers *reg_ptr;
volatile tsec_registers *mdio_ptr;
rtems_irq_number irq_num_tx;
rtems_irq_number irq_num_rx;
rtems_irq_number irq_num_err;
int phy_default;
} tsec_config;
int tsec_driver_attach_detach( int tsec_driver_attach_detach(
struct rtems_bsdnet_ifconfig *config, struct rtems_bsdnet_ifconfig *config,
int unitNumber,
char *unitName,
volatile tsec_registers *reg_ptr,
volatile tsec_registers *mdio_ptr,
int attaching int attaching
); );