forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user