forked from Imagelibrary/rtems
2007-09-07 Daniel Hellstrom <daniel@gaisler.com>
* libchip/network/greth.c, libchip/network/greth.h: GRETH_GBIT support and GBIT PHY support for 10/100 MAC, also auto negotiation updated.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2007-09-07 Daniel Hellstrom <daniel@gaisler.com>
|
||||||
|
|
||||||
|
* libchip/network/greth.c, libchip/network/greth.h: GRETH_GBIT support
|
||||||
|
and GBIT PHY support for 10/100 MAC, also auto negotiation updated.
|
||||||
|
|
||||||
2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com>
|
2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||||
|
|
||||||
* configure.ac, wrapup/Makefile.am: Remove RDBG.
|
* configure.ac, wrapup/Makefile.am: Remove RDBG.
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* RTEMS driver for Opencores Ethernet Controller
|
* Gaisler Research ethernet MAC driver
|
||||||
*
|
* adapted from Opencores driver by Marko Isomaki
|
||||||
* Weakly based on dec21140 rtems driver and open_eth linux driver
|
|
||||||
* Written by Jiri Gaisler, Gaisler Research
|
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in found in the file LICENSE in this distribution or at
|
* found in found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.com/license/LICENSE.
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
*
|
||||||
|
* 2007-09-07, Ported GBIT support from 4.6.5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -47,9 +48,8 @@ extern m68k_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
|
|||||||
extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
|
extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
#define GRETH_DEBUG
|
/* #define GRETH_DEBUG */
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CPU_U32_FIX
|
#ifdef CPU_U32_FIX
|
||||||
extern void ipalign(struct mbuf *m);
|
extern void ipalign(struct mbuf *m);
|
||||||
@@ -91,6 +91,14 @@ extern void ipalign(struct mbuf *m);
|
|||||||
# error "Driver must have MCLBYTES > RBUF_SIZE"
|
# error "Driver must have MCLBYTES > RBUF_SIZE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 4s Autonegotiation Timeout */
|
||||||
|
#ifndef GRETH_AUTONEGO_TIMEOUT_MS
|
||||||
|
#define GRETH_AUTONEGO_TIMEOUT_MS 4000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For optimizing the autonegotiation time */
|
||||||
|
#define GRETH_AUTONEGO_PRINT_TIME
|
||||||
|
|
||||||
/* Ethernet buffer descriptor */
|
/* Ethernet buffer descriptor */
|
||||||
|
|
||||||
typedef struct _greth_rxtxdesc {
|
typedef struct _greth_rxtxdesc {
|
||||||
@@ -98,6 +106,7 @@ typedef struct _greth_rxtxdesc {
|
|||||||
uint32_t *addr; /* Buffer pointer */
|
uint32_t *addr; /* Buffer pointer */
|
||||||
} greth_rxtxdesc;
|
} greth_rxtxdesc;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-device data
|
* Per-device data
|
||||||
*/
|
*/
|
||||||
@@ -113,14 +122,26 @@ struct greth_softc
|
|||||||
rtems_id txDaemonTid;
|
rtems_id txDaemonTid;
|
||||||
|
|
||||||
unsigned int tx_ptr;
|
unsigned int tx_ptr;
|
||||||
|
unsigned int tx_dptr;
|
||||||
|
unsigned int tx_cnt;
|
||||||
unsigned int rx_ptr;
|
unsigned int rx_ptr;
|
||||||
unsigned int txbufs;
|
unsigned int txbufs;
|
||||||
unsigned int rxbufs;
|
unsigned int rxbufs;
|
||||||
greth_rxtxdesc *txdesc;
|
greth_rxtxdesc *txdesc;
|
||||||
greth_rxtxdesc *rxdesc;
|
greth_rxtxdesc *rxdesc;
|
||||||
struct mbuf **rxmbuf;
|
struct mbuf **rxmbuf;
|
||||||
|
struct mbuf **txmbuf;
|
||||||
rtems_vector_number vector;
|
rtems_vector_number vector;
|
||||||
|
|
||||||
|
/*Status*/
|
||||||
|
struct phy_device_info phydev;
|
||||||
|
int fd;
|
||||||
|
int sp;
|
||||||
|
int gb;
|
||||||
|
int gbit_mac;
|
||||||
|
int auto_neg;
|
||||||
|
unsigned int auto_neg_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
*/
|
*/
|
||||||
@@ -139,6 +160,7 @@ struct greth_softc
|
|||||||
unsigned long txLateCollision;
|
unsigned long txLateCollision;
|
||||||
unsigned long txRetryLimit;
|
unsigned long txRetryLimit;
|
||||||
unsigned long txUnderrun;
|
unsigned long txUnderrun;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct greth_softc greth;
|
static struct greth_softc greth;
|
||||||
@@ -156,36 +178,36 @@ static char *almalloc(int sz)
|
|||||||
static rtems_isr
|
static rtems_isr
|
||||||
greth_interrupt_handler (rtems_vector_number v)
|
greth_interrupt_handler (rtems_vector_number v)
|
||||||
{
|
{
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
/* read and clear interrupt cause */
|
/* read and clear interrupt cause */
|
||||||
|
|
||||||
status = greth.regs->status;
|
status = greth.regs->status;
|
||||||
greth.regs->status = status;
|
greth.regs->status = status;
|
||||||
|
|
||||||
/* Frame received? */
|
/* Frame received? */
|
||||||
if (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))
|
if (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))
|
||||||
{
|
{
|
||||||
greth.rxInterrupts++;
|
greth.rxInterrupts++;
|
||||||
rtems_event_send (greth.rxDaemonTid, INTERRUPT_EVENT);
|
rtems_event_send (greth.rxDaemonTid, INTERRUPT_EVENT);
|
||||||
}
|
}
|
||||||
#ifdef GRETH_SUSPEND_NOTXBUF
|
#ifdef GRETH_SUSPEND_NOTXBUF
|
||||||
if (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ))
|
if (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ))
|
||||||
{
|
{
|
||||||
greth.txInterrupts++;
|
greth.txInterrupts++;
|
||||||
rtems_event_send (greth.txDaemonTid, GRETH_TX_WAIT_EVENT);
|
rtems_event_send (greth.txDaemonTid, GRETH_TX_WAIT_EVENT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
#ifdef __leon__
|
#ifdef __leon__
|
||||||
LEON_Clear_interrupt(v-0x10);
|
LEON_Clear_interrupt(v-0x10);
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t read_mii(uint32_t addr)
|
static uint32_t read_mii(uint32_t phy_addr, uint32_t reg_addr)
|
||||||
{
|
{
|
||||||
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
||||||
greth.regs->mdio_ctrl = addr << 6 | GRETH_MDIO_READ;
|
greth.regs->mdio_ctrl = (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_READ;
|
||||||
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
||||||
if (!(greth.regs->mdio_ctrl & GRETH_MDIO_LINKFAIL))
|
if (!(greth.regs->mdio_ctrl & GRETH_MDIO_LINKFAIL))
|
||||||
return((greth.regs->mdio_ctrl >> 16) & 0xFFFF);
|
return((greth.regs->mdio_ctrl >> 16) & 0xFFFF);
|
||||||
@@ -195,13 +217,40 @@ static uint32_t read_mii(uint32_t addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_mii(uint32_t addr, uint32_t data)
|
static void write_mii(uint32_t phy_addr, uint32_t reg_addr, uint32_t data)
|
||||||
{
|
{
|
||||||
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
||||||
greth.regs->mdio_ctrl =
|
greth.regs->mdio_ctrl =
|
||||||
((data & 0xFFFF) << 16) | (addr << 8) | GRETH_MDIO_WRITE;
|
((data & 0xFFFF) << 16) | (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_WRITE;
|
||||||
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_init_info(struct greth_softc *sc)
|
||||||
|
{
|
||||||
|
printf("greth: driver attached\n");
|
||||||
|
printf("**** PHY ****\n");
|
||||||
|
printf("Vendor: %x Device: %x Revision: %d\n",sc->phydev.vendor, sc->phydev.device, sc->phydev.rev);
|
||||||
|
printf("Current Operating Mode: ");
|
||||||
|
if (sc->gb) {
|
||||||
|
printf("1000 Mbit ");
|
||||||
|
} else if (sc->sp) {
|
||||||
|
printf("100 Mbit ");
|
||||||
|
} else {
|
||||||
|
printf("10 Mbit ");
|
||||||
|
}
|
||||||
|
if (sc->fd) {
|
||||||
|
printf("Full Duplex\n");
|
||||||
|
} else {
|
||||||
|
printf("Half Duplex\n");
|
||||||
|
}
|
||||||
|
#ifdef GRETH_AUTONEGO_PRINT_TIME
|
||||||
|
if ( sc->auto_neg ){
|
||||||
|
printf("Autonegotiation Time: %dms\n",sc->auto_neg_time);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the ethernet hardware
|
* Initialize the ethernet hardware
|
||||||
*/
|
*/
|
||||||
@@ -210,12 +259,18 @@ greth_initialize_hardware (struct greth_softc *sc)
|
|||||||
{
|
{
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
int i;
|
int i;
|
||||||
int fd;
|
int phyaddr;
|
||||||
|
int phyctrl;
|
||||||
|
int phystatus;
|
||||||
|
int tmp1;
|
||||||
|
int tmp2;
|
||||||
|
unsigned int msecs;
|
||||||
|
rtems_clock_time_value tstart, tnow;
|
||||||
|
|
||||||
greth_regs *regs;
|
greth_regs *regs;
|
||||||
|
|
||||||
regs = sc->regs;
|
regs = sc->regs;
|
||||||
|
|
||||||
/* Reset the controller. */
|
/* Reset the controller. */
|
||||||
greth.rxInterrupts = 0;
|
greth.rxInterrupts = 0;
|
||||||
greth.rxPackets = 0;
|
greth.rxPackets = 0;
|
||||||
@@ -224,44 +279,172 @@ greth_initialize_hardware (struct greth_softc *sc)
|
|||||||
regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
|
regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
|
||||||
regs->ctrl = 0; /* Reset OFF */
|
regs->ctrl = 0; /* Reset OFF */
|
||||||
|
|
||||||
/* reset PHY and wait for complettion */
|
/* Check if mac is gbit capable*/
|
||||||
/*
|
sc->gbit_mac = (regs->ctrl >> 27) & 1;
|
||||||
*/
|
|
||||||
write_mii(0, 0x8000);
|
/* Get the phy address which assumed to have been set
|
||||||
while (read_mii(0) & 0x8000) {}
|
correctly with the reset value in hardware*/
|
||||||
fd = regs->mdio_ctrl >> 24; /*duplex mode*/
|
phyaddr = (regs->mdio_ctrl >> 11) & 0x1F;
|
||||||
printf(
|
|
||||||
"greth: driver attached, PHY config: 0x%04" PRIx32 "\n", read_mii(0));
|
/* get phy control register default values */
|
||||||
|
while ((phyctrl = read_mii(phyaddr, 0)) & 0x8000) {}
|
||||||
|
|
||||||
|
/* reset PHY and wait for completion */
|
||||||
|
write_mii(phyaddr, 0, 0x8000 | phyctrl);
|
||||||
|
|
||||||
|
while ((read_mii(phyaddr, 0)) & 0x8000) {}
|
||||||
|
|
||||||
|
/* Check if PHY is autoneg capable and then determine operating mode,
|
||||||
|
otherwise force it to 10 Mbit halfduplex */
|
||||||
|
sc->gb = 0;
|
||||||
|
sc->fd = 0;
|
||||||
|
sc->sp = 0;
|
||||||
|
sc->auto_neg = 0;
|
||||||
|
sc->auto_neg_time = 0;
|
||||||
|
if ((phyctrl >> 12) & 1) {
|
||||||
|
/*wait for auto negotiation to complete*/
|
||||||
|
msecs = 0;
|
||||||
|
sc->auto_neg = 1;
|
||||||
|
if ( rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tstart) == RTEMS_NOT_DEFINED){
|
||||||
|
/* Not inited, set to epoch */
|
||||||
|
rtems_time_of_day time;
|
||||||
|
time.year = 1988;
|
||||||
|
time.month = 1;
|
||||||
|
time.day = 1;
|
||||||
|
time.hour = 0;
|
||||||
|
time.minute = 0;
|
||||||
|
time.second = 0;
|
||||||
|
time.ticks = 0;
|
||||||
|
rtems_clock_set(&time);
|
||||||
|
|
||||||
|
tstart.seconds = 0;
|
||||||
|
tstart.microseconds = 0;
|
||||||
|
rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tstart);
|
||||||
|
}
|
||||||
|
while (!(((phystatus = read_mii(phyaddr, 1)) >> 5) & 1)) {
|
||||||
|
if ( rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tnow) != RTEMS_SUCCESSFUL )
|
||||||
|
printk("rtems_clock_get failed\n\r");
|
||||||
|
msecs = (tnow.seconds-tstart.seconds)*1000+(tnow.microseconds-tstart.microseconds)/1000;
|
||||||
|
if ( msecs > GRETH_AUTONEGO_TIMEOUT_MS ){
|
||||||
|
sc->auto_neg_time = msecs;
|
||||||
|
printk("Auto negotiation timed out. Selecting default config\n\r");
|
||||||
|
tmp1 = read_mii(phyaddr, 0);
|
||||||
|
sc->gb = ((phyctrl >> 6) & 1) && !((phyctrl >> 13) & 1);
|
||||||
|
sc->sp = !((phyctrl >> 6) & 1) && ((phyctrl >> 13) & 1);
|
||||||
|
sc->fd = (phyctrl >> 8) & 1;
|
||||||
|
goto auto_neg_done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sc->auto_neg_time = msecs;
|
||||||
|
sc->phydev.adv = read_mii(phyaddr, 4);
|
||||||
|
sc->phydev.part = read_mii(phyaddr, 5);
|
||||||
|
if ((phystatus >> 8) & 1) {
|
||||||
|
sc->phydev.extadv = read_mii(phyaddr, 9);
|
||||||
|
sc->phydev.extpart = read_mii(phyaddr, 10);
|
||||||
|
if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000FD) &&
|
||||||
|
(sc->phydev.extpart & GRETH_MII_EXTPRT_1000FD)) {
|
||||||
|
sc->gb = 1;
|
||||||
|
sc->fd = 1;
|
||||||
|
}
|
||||||
|
if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000HD) &&
|
||||||
|
(sc->phydev.extpart & GRETH_MII_EXTPRT_1000HD)) {
|
||||||
|
sc->gb = 1;
|
||||||
|
sc->fd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((sc->gb == 0) || ((sc->gb == 1) && (sc->gbit_mac == 0))) {
|
||||||
|
if ( (sc->phydev.adv & GRETH_MII_100TXFD) &&
|
||||||
|
(sc->phydev.part & GRETH_MII_100TXFD)) {
|
||||||
|
sc->sp = 1;
|
||||||
|
sc->fd = 1;
|
||||||
|
}
|
||||||
|
if ( (sc->phydev.adv & GRETH_MII_100TXHD) &&
|
||||||
|
(sc->phydev.part & GRETH_MII_100TXHD)) {
|
||||||
|
sc->sp = 1;
|
||||||
|
sc->fd = 0;
|
||||||
|
}
|
||||||
|
if ( (sc->phydev.adv & GRETH_MII_10FD) &&
|
||||||
|
(sc->phydev.part & GRETH_MII_10FD)) {
|
||||||
|
sc->fd = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto_neg_done:
|
||||||
|
sc->phydev.vendor = 0;
|
||||||
|
sc->phydev.device = 0;
|
||||||
|
sc->phydev.rev = 0;
|
||||||
|
phystatus = read_mii(phyaddr, 1);
|
||||||
|
|
||||||
|
/*Read out PHY info if extended registers are available */
|
||||||
|
if (phystatus & 1) {
|
||||||
|
tmp1 = read_mii(phyaddr, 2);
|
||||||
|
tmp2 = read_mii(phyaddr, 3);
|
||||||
|
|
||||||
|
sc->phydev.vendor = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
|
||||||
|
sc->phydev.rev = tmp2 & 0xF;
|
||||||
|
sc->phydev.device = (tmp2 >> 4) & 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force to 10 mbit half duplex if the 10/100 MAC is used with a 1000 PHY*/
|
||||||
|
/*check if marvell 88EE1111 PHY. Needs special reset handling */
|
||||||
|
if ((phystatus & 1) && (sc->phydev.vendor == 0x005043) && (sc->phydev.device == 0x0C)) {
|
||||||
|
if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
|
||||||
|
write_mii(phyaddr, 0, sc->sp << 13);
|
||||||
|
write_mii(phyaddr, 0, 0x8000);
|
||||||
|
sc->gb = 0;
|
||||||
|
sc->sp = 0;
|
||||||
|
sc->fd = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
|
||||||
|
write_mii(phyaddr, 0, sc->sp << 13);
|
||||||
|
sc->gb = 0;
|
||||||
|
sc->sp = 0;
|
||||||
|
sc->fd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((read_mii(phyaddr, 0)) & 0x8000) {}
|
||||||
|
|
||||||
|
regs->ctrl = 0;
|
||||||
|
regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
|
||||||
|
regs->ctrl = 0;
|
||||||
|
|
||||||
/* Initialize rx/tx descriptor pointers */
|
/* Initialize rx/tx descriptor pointers */
|
||||||
sc->txdesc = (greth_rxtxdesc *) almalloc(1024);
|
sc->txdesc = (greth_rxtxdesc *) almalloc(1024);
|
||||||
sc->rxdesc = (greth_rxtxdesc *) almalloc(1024);
|
sc->rxdesc = (greth_rxtxdesc *) almalloc(1024);
|
||||||
sc->tx_ptr = 0;
|
sc->tx_ptr = 0;
|
||||||
|
sc->tx_dptr = 0;
|
||||||
|
sc->tx_cnt = 0;
|
||||||
sc->rx_ptr = 0;
|
sc->rx_ptr = 0;
|
||||||
regs->txdesc = (int) sc->txdesc;
|
regs->txdesc = (int) sc->txdesc;
|
||||||
regs->rxdesc = (int) sc->rxdesc;
|
regs->rxdesc = (int) sc->rxdesc;
|
||||||
|
|
||||||
sc->rxmbuf = calloc(sc->rxbufs, sizeof(*sc->rxmbuf));
|
sc->rxmbuf = calloc(sc->rxbufs, sizeof(*sc->rxmbuf));
|
||||||
|
sc->txmbuf = calloc(sc->txbufs, sizeof(*sc->txmbuf));
|
||||||
|
|
||||||
for (i = 0; i < sc->txbufs; i++)
|
for (i = 0; i < sc->txbufs; i++)
|
||||||
{
|
{
|
||||||
sc->txdesc[i].addr = (uint32_t *) calloc(1, GRETH_MAXBUF_LEN);
|
sc->txdesc[i].ctrl = 0;
|
||||||
|
if (!(sc->gbit_mac)) {
|
||||||
|
sc->txdesc[i].addr = malloc(GRETH_MAXBUF_LEN);
|
||||||
|
}
|
||||||
#ifdef GRETH_DEBUG
|
#ifdef GRETH_DEBUG
|
||||||
printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr);
|
/* printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr); */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*printf("RXbufs: %i\n", sc->rxbufs);*/
|
|
||||||
for (i = 0; i < sc->rxbufs; i++)
|
for (i = 0; i < sc->rxbufs; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
MGETHDR (m, M_WAIT, MT_DATA);
|
MGETHDR (m, M_WAIT, MT_DATA);
|
||||||
MCLGET (m, M_WAIT);
|
MCLGET (m, M_WAIT);
|
||||||
|
if (sc->gbit_mac)
|
||||||
|
m->m_data += 2;
|
||||||
m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
|
m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
|
||||||
sc->rxmbuf[i] = m;
|
sc->rxmbuf[i] = m;
|
||||||
sc->rxdesc[i].addr = (uint32_t *) mtod(m, uint32_t *);
|
sc->rxdesc[i].addr = (uint32_t *) mtod(m, uint32_t *);
|
||||||
sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
|
sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
|
||||||
#ifdef GRETH_DEBUG
|
#ifdef GRETH_DEBUG
|
||||||
printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr);
|
/* printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr); */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sc->rxdesc[sc->rxbufs - 1].ctrl |= GRETH_RXD_WRAP;
|
sc->rxdesc[sc->rxbufs - 1].ctrl |= GRETH_RXD_WRAP;
|
||||||
@@ -284,7 +467,9 @@ greth_initialize_hardware (struct greth_softc *sc)
|
|||||||
regs->ctrl |= GRETH_CTRL_TXIRQ;
|
regs->ctrl |= GRETH_CTRL_TXIRQ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
regs->ctrl |= GRETH_CTRL_RXEN | (fd << 4) | GRETH_CTRL_RXIRQ;
|
regs->ctrl |= GRETH_CTRL_RXEN | (sc->fd << 4) | GRETH_CTRL_RXIRQ | (sc->sp << 7) | (sc->gb << 8);
|
||||||
|
|
||||||
|
print_init_info(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -297,7 +482,6 @@ greth_rxDaemon (void *arg)
|
|||||||
unsigned int len, len_status, bad;
|
unsigned int len, len_status, bad;
|
||||||
rtems_event_set events;
|
rtems_event_set events;
|
||||||
|
|
||||||
/*printf("Started RxDaemon\n");*/
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
|
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
|
||||||
@@ -307,73 +491,75 @@ greth_rxDaemon (void *arg)
|
|||||||
#ifdef GRETH_ETH_DEBUG
|
#ifdef GRETH_ETH_DEBUG
|
||||||
printf ("r\n");
|
printf ("r\n");
|
||||||
#endif
|
#endif
|
||||||
/*printf("Packet received\n");*/
|
while (!((len_status =
|
||||||
while (!((len_status =
|
dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
|
||||||
dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
|
|
||||||
{
|
{
|
||||||
/*printf("Status: %x\n", dp->rxdesc[dp->rx_ptr].ctrl);*/
|
bad = 0;
|
||||||
bad = 0;
|
if (len_status & GRETH_RXD_TOOLONG)
|
||||||
|
{
|
||||||
if (len_status & GRETH_RXD_TOOLONG)
|
dp->rxLengthError++;
|
||||||
{
|
bad = 1;
|
||||||
dp->rxLengthError++;
|
}
|
||||||
bad = 1;
|
if (len_status & GRETH_RXD_DRIBBLE)
|
||||||
}
|
{
|
||||||
if (len_status & GRETH_RXD_DRIBBLE)
|
dp->rxNonOctet++;
|
||||||
{
|
bad = 1;
|
||||||
dp->rxNonOctet++;
|
}
|
||||||
bad = 1;
|
if (len_status & GRETH_RXD_CRCERR)
|
||||||
}
|
{
|
||||||
if (len_status & GRETH_RXD_CRCERR)
|
dp->rxBadCRC++;
|
||||||
{
|
bad = 1;
|
||||||
dp->rxBadCRC++;
|
}
|
||||||
bad = 1;
|
if (len_status & GRETH_RXD_OVERRUN)
|
||||||
}
|
{
|
||||||
if (len_status & GRETH_RXD_OVERRUN)
|
dp->rxOverrun++;
|
||||||
{
|
bad = 1;
|
||||||
dp->rxOverrun++;
|
}
|
||||||
bad = 1;
|
if (len_status & GRETH_RXD_LENERR)
|
||||||
}
|
{
|
||||||
if (!bad)
|
dp->rxLengthError++;
|
||||||
{
|
bad = 1;
|
||||||
/*printf("Received Ok packet\n");*/
|
}
|
||||||
/* pass on the packet in the receive buffer */
|
if (!bad)
|
||||||
len = len_status & 0x7FF;
|
{
|
||||||
m = dp->rxmbuf[dp->rx_ptr];
|
/* pass on the packet in the receive buffer */
|
||||||
m->m_len = m->m_pkthdr.len =
|
len = len_status & 0x7FF;
|
||||||
len - sizeof (struct ether_header);
|
m = dp->rxmbuf[dp->rx_ptr];
|
||||||
/*printf("Packet of length: %i\n", len);*/
|
#ifdef GRETH_DEBUG
|
||||||
eh = mtod (m, struct ether_header *);
|
int i;
|
||||||
m->m_data += sizeof (struct ether_header);
|
printf("RX: 0x%08x, Len: %d : ", (int) m->m_data, len);
|
||||||
/*printf("Mbuf handling done\n");*/
|
for (i=0; i<len; i++)
|
||||||
#ifdef CPU_U32_FIX
|
printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
|
||||||
/*printf("Ip aligning\n");*/
|
printf("\n");
|
||||||
ipalign(m); /* Align packet on 32-bit boundary */
|
|
||||||
#endif
|
#endif
|
||||||
/*printf("Calling stack\n");*/
|
m->m_len = m->m_pkthdr.len =
|
||||||
/*printf("Ifp: %x, Eh: %x, M: %x\n", (int)ifp, (int)eh, (int)m);*/
|
len - sizeof (struct ether_header);
|
||||||
ether_input (ifp, eh, m);
|
|
||||||
/*printf("Returned from stack\n");*/
|
eh = mtod (m, struct ether_header *);
|
||||||
/* get a new mbuf */
|
m->m_data += sizeof (struct ether_header);
|
||||||
/*printf("Getting new mbuf\n");*/
|
#ifdef CPU_U32_FIX
|
||||||
MGETHDR (m, M_WAIT, MT_DATA);
|
if(!(dp->gbit_mac))
|
||||||
MCLGET (m, M_WAIT);
|
ipalign(m); /* Align packet on 32-bit boundary */
|
||||||
/*printf("Got new mbuf\n");*/
|
#endif
|
||||||
dp->rxmbuf[dp->rx_ptr] = m;
|
|
||||||
m->m_pkthdr.rcvif = ifp;
|
ether_input (ifp, eh, m);
|
||||||
dp->rxdesc[dp->rx_ptr].addr =
|
MGETHDR (m, M_WAIT, MT_DATA);
|
||||||
(uint32_t *) mtod (m, uint32_t *);
|
MCLGET (m, M_WAIT);
|
||||||
dp->rxPackets++;
|
if (dp->gbit_mac)
|
||||||
}
|
m->m_data += 2;
|
||||||
/*printf("Reenabling desc\n");*/
|
dp->rxmbuf[dp->rx_ptr] = m;
|
||||||
dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
if (dp->rx_ptr == dp->rxbufs - 1) {
|
dp->rxdesc[dp->rx_ptr].addr =
|
||||||
dp->rxdesc[dp->rx_ptr].ctrl |= GRETH_RXD_WRAP;
|
(uint32_t *) mtod (m, uint32_t *);
|
||||||
}
|
dp->rxPackets++;
|
||||||
dp->regs->ctrl |= GRETH_CTRL_RXEN;
|
}
|
||||||
/*printf("rxptr: %i\n", dp->rx_ptr);*/
|
if (dp->rx_ptr == dp->rxbufs - 1) {
|
||||||
dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
|
dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ | GRETH_RXD_WRAP;
|
||||||
/*printf("RxDesc reenabled\n");*/
|
} else {
|
||||||
|
dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
|
||||||
|
}
|
||||||
|
dp->regs->ctrl |= GRETH_CTRL_RXEN;
|
||||||
|
dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,42 +596,111 @@ sendpacket (struct ifnet *ifp, struct mbuf *m)
|
|||||||
len = 0;
|
len = 0;
|
||||||
temp = (unsigned char *) dp->txdesc[dp->tx_ptr].addr;
|
temp = (unsigned char *) dp->txdesc[dp->tx_ptr].addr;
|
||||||
#ifdef GRETH_DEBUG
|
#ifdef GRETH_DEBUG
|
||||||
printf("TXD: 0x%08x\n", (int) m->m_data);
|
printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int) temp);
|
||||||
#endif
|
#endif
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
#ifdef GRETH_DEBUG
|
#ifdef GRETH_DEBUG
|
||||||
int i;
|
int i;
|
||||||
printf("MBUF: 0x%08x : ", (int) m->m_data);
|
printf("MBUF: 0x%08x : ", (int) m->m_data);
|
||||||
for (i=0;i<m->m_len;i++)
|
for (i=0;i<m->m_len;i++)
|
||||||
printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
|
printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
len += m->m_len;
|
len += m->m_len;
|
||||||
if (len <= RBUF_SIZE)
|
if (len <= RBUF_SIZE)
|
||||||
memcpy ((void *) temp, (char *) m->m_data, m->m_len);
|
memcpy ((void *) temp, (char *) m->m_data, m->m_len);
|
||||||
temp += m->m_len;
|
temp += m->m_len;
|
||||||
if ((m = m->m_next) == NULL)
|
if ((m = m->m_next) == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem (n);
|
m_freem (n);
|
||||||
|
|
||||||
/* don't send long packets */
|
/* don't send long packets */
|
||||||
|
|
||||||
if (len <= GRETH_MAXBUF_LEN) {
|
if (len <= GRETH_MAXBUF_LEN) {
|
||||||
if (dp->tx_ptr < dp->txbufs-1) {
|
if (dp->tx_ptr < dp->txbufs-1) {
|
||||||
dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;
|
dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;
|
||||||
} else {
|
} else {
|
||||||
dp->txdesc[dp->tx_ptr].ctrl =
|
dp->txdesc[dp->tx_ptr].ctrl =
|
||||||
GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
|
GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
|
||||||
}
|
}
|
||||||
dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
|
dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
|
||||||
dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
|
dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
|
||||||
}
|
}
|
||||||
inside = 0;
|
inside = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)
|
||||||
|
{
|
||||||
|
struct greth_softc *dp = ifp->if_softc;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
/*printf("Send packet entered\n");*/
|
||||||
|
if (inside) printf ("error: sendpacket re-entered!!\n");
|
||||||
|
inside = 1;
|
||||||
|
/*
|
||||||
|
* Waiting for Transmitter ready
|
||||||
|
*/
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
#ifdef GRETH_DEBUG
|
||||||
|
printf("TXD: 0x%08x\n", (int) m->m_data);
|
||||||
|
#endif
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE)
|
||||||
|
{
|
||||||
|
#ifdef GRETH_SUSPEND_NOTXBUF
|
||||||
|
dp->txdesc[dp->tx_ptr].ctrl |= GRETH_TXD_IRQ;
|
||||||
|
rtems_event_set events;
|
||||||
|
rtems_bsdnet_event_receive (GRETH_TX_WAIT_EVENT,
|
||||||
|
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
||||||
|
TOD_MILLISECONDS_TO_TICKS(500), &events);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef GRETH_DEBUG
|
||||||
|
int i;
|
||||||
|
printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);
|
||||||
|
for (i=0; i<m->m_len; i++)
|
||||||
|
printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
len += m->m_len;
|
||||||
|
dp->txdesc[dp->tx_ptr].addr = (uint32_t *)m->m_data;
|
||||||
|
if (dp->tx_ptr < dp->txbufs-1) {
|
||||||
|
if ((m->m_next) == NULL) {
|
||||||
|
dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((m->m_next) == NULL) {
|
||||||
|
dp->txdesc[dp->tx_ptr].ctrl =
|
||||||
|
GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
dp->txdesc[dp->tx_ptr].ctrl =
|
||||||
|
GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dp->txmbuf[dp->tx_ptr] = m;
|
||||||
|
dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
|
||||||
|
dp->tx_cnt++;
|
||||||
|
m = m->m_next;
|
||||||
|
|
||||||
|
}
|
||||||
|
dp->txmbuf[dp->tx_ptr] = m;
|
||||||
|
dp->tx_cnt++;
|
||||||
|
dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
|
||||||
|
dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
|
||||||
|
inside = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver transmit daemon
|
* Driver transmit daemon
|
||||||
*/
|
*/
|
||||||
@@ -458,34 +713,81 @@ greth_txDaemon (void *arg)
|
|||||||
rtems_event_set events;
|
rtems_event_set events;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Wait for packet
|
* Wait for packet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
|
rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
|
||||||
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
||||||
RTEMS_NO_TIMEOUT, &events);
|
RTEMS_NO_TIMEOUT, &events);
|
||||||
#ifdef GRETH_DEBUG
|
#ifdef GRETH_DEBUG
|
||||||
printf ("t\n");
|
printf ("t\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send packets till queue is empty
|
* Send packets till queue is empty
|
||||||
*/
|
*/
|
||||||
for (;;)
|
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Get the next mbuf chain to transmit.
|
* Get the next mbuf chain to transmit.
|
||||||
*/
|
*/
|
||||||
IF_DEQUEUE (&ifp->if_snd, m);
|
IF_DEQUEUE (&ifp->if_snd, m);
|
||||||
if (!m)
|
if (!m)
|
||||||
break;
|
break;
|
||||||
|
sendpacket(ifp, m);
|
||||||
sendpacket (ifp, m);
|
}
|
||||||
}
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
ifp->if_flags &= ~IFF_OACTIVE;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver transmit daemon
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
greth_txDaemon_gbit (void *arg)
|
||||||
|
{
|
||||||
|
struct greth_softc *sc = (struct greth_softc *) arg;
|
||||||
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
|
struct mbuf *m;
|
||||||
|
rtems_event_set events;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Wait for packet
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
|
||||||
|
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
||||||
|
RTEMS_NO_TIMEOUT, &events);
|
||||||
|
#ifdef GRETH_DEBUG
|
||||||
|
printf ("t\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send packets till queue is empty
|
||||||
|
*/
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while((sc->tx_cnt > 0) && !(sc->txdesc[sc->tx_dptr].ctrl & GRETH_TXD_ENABLE)) {
|
||||||
|
m_free(sc->txmbuf[sc->tx_dptr]);
|
||||||
|
sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
|
||||||
|
sc->tx_cnt--;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Get the next mbuf chain to transmit.
|
||||||
|
*/
|
||||||
|
IF_DEQUEUE (&ifp->if_snd, m);
|
||||||
|
if (!m)
|
||||||
|
break;
|
||||||
|
sendpacket_gbit(ifp, m);
|
||||||
|
}
|
||||||
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -521,8 +823,14 @@ greth_init (void *arg)
|
|||||||
*/
|
*/
|
||||||
sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
|
sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
|
||||||
greth_rxDaemon, sc);
|
greth_rxDaemon, sc);
|
||||||
sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
|
if (sc->gbit_mac) {
|
||||||
greth_txDaemon, sc);
|
sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
|
||||||
|
greth_txDaemon_gbit, sc);
|
||||||
|
} else {
|
||||||
|
sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
|
||||||
|
greth_txDaemon, sc);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GR_ETH_
|
#ifndef _GR_ETH_
|
||||||
#define _GR_ETH_
|
#define _GR_ETH_
|
||||||
|
|
||||||
@@ -36,16 +37,27 @@ typedef struct _greth_regs {
|
|||||||
|
|
||||||
#define GRETH_TOTAL_BD 128
|
#define GRETH_TOTAL_BD 128
|
||||||
#define GRETH_MAXBUF_LEN 1520
|
#define GRETH_MAXBUF_LEN 1520
|
||||||
|
|
||||||
/* Tx BD */
|
/* Tx BD */
|
||||||
#define GRETH_TXD_ENABLE 0x0800 /* Tx BD Enable */
|
#define GRETH_TXD_ENABLE 0x0800 /* Tx BD Enable */
|
||||||
#define GRETH_TXD_WRAP 0x1000 /* Tx BD Wrap (last BD) */
|
#define GRETH_TXD_WRAP 0x1000 /* Tx BD Wrap (last BD) */
|
||||||
#define GRETH_TXD_IRQ 0x2000 /* Tx BD IRQ Enable */
|
#define GRETH_TXD_IRQ 0x2000 /* Tx BD IRQ Enable */
|
||||||
|
#define GRETH_TXD_MORE 0x20000 /* Tx BD More (more descs for packet) */
|
||||||
|
#define GRETH_TXD_IPCS 0x40000 /* Tx BD insert ip chksum */
|
||||||
|
#define GRETH_TXD_TCPCS 0x80000 /* Tx BD insert tcp chksum */
|
||||||
|
#define GRETH_TXD_UDPCS 0x100000 /* Tx BD insert udp chksum */
|
||||||
|
|
||||||
#define GRETH_TXD_UNDERRUN 0x4000 /* Tx BD Underrun Status */
|
#define GRETH_TXD_UNDERRUN 0x4000 /* Tx BD Underrun Status */
|
||||||
#define GRETH_TXD_RETLIM 0x8000 /* Tx BD Retransmission Limit Status */
|
#define GRETH_TXD_RETLIM 0x8000 /* Tx BD Retransmission Limit Status */
|
||||||
|
#define GRETH_TXD_LATECOL 0x10000 /* Tx BD Late Collision */
|
||||||
|
|
||||||
#define GRETH_TXD_STATS (GRETH_TXD_UNDERRUN | \
|
#define GRETH_TXD_STATS (GRETH_TXD_UNDERRUN | \
|
||||||
GRETH_TXD_RETLIM)
|
GRETH_TXD_RETLIM | \
|
||||||
|
GRETH_TXD_LATECOL)
|
||||||
|
|
||||||
|
#define GRETH_TXD_CS (GRETH_TXD_IPCS | \
|
||||||
|
GRETH_TXD_TCPCS | \
|
||||||
|
GRETH_TXD_UDPCS)
|
||||||
|
|
||||||
/* Rx BD */
|
/* Rx BD */
|
||||||
#define GRETH_RXD_ENABLE 0x0800 /* Rx BD Enable */
|
#define GRETH_RXD_ENABLE 0x0800 /* Rx BD Enable */
|
||||||
@@ -56,6 +68,15 @@ typedef struct _greth_regs {
|
|||||||
#define GRETH_RXD_TOOLONG 0x8000 /* Rx BD Too Long Status */
|
#define GRETH_RXD_TOOLONG 0x8000 /* Rx BD Too Long Status */
|
||||||
#define GRETH_RXD_CRCERR 0x10000 /* Rx BD CRC Error Status */
|
#define GRETH_RXD_CRCERR 0x10000 /* Rx BD CRC Error Status */
|
||||||
#define GRETH_RXD_OVERRUN 0x20000 /* Rx BD Overrun Status */
|
#define GRETH_RXD_OVERRUN 0x20000 /* Rx BD Overrun Status */
|
||||||
|
#define GRETH_RXD_LENERR 0x40000 /* Rx BD Length Error */
|
||||||
|
#define GRETH_RXD_ID 0x40000 /* Rx BD IP Detected */
|
||||||
|
#define GRETH_RXD_IR 0x40000 /* Rx BD IP Chksum Error */
|
||||||
|
#define GRETH_RXD_UD 0x40000 /* Rx BD UDP Detected*/
|
||||||
|
#define GRETH_RXD_UR 0x40000 /* Rx BD UDP Chksum Error */
|
||||||
|
#define GRETH_RXD_TD 0x40000 /* Rx BD TCP Detected */
|
||||||
|
#define GRETH_RXD_TR 0x40000 /* Rx BD TCP Chksum Error */
|
||||||
|
|
||||||
|
|
||||||
#define GRETH_RXD_STATS (GRETH_RXD_OVERRUN | \
|
#define GRETH_RXD_STATS (GRETH_RXD_OVERRUN | \
|
||||||
GRETH_RXD_DRIBBLE | \
|
GRETH_RXD_DRIBBLE | \
|
||||||
GRETH_RXD_TOOLONG | \
|
GRETH_RXD_TOOLONG | \
|
||||||
@@ -86,7 +107,22 @@ typedef struct _greth_regs {
|
|||||||
#define GRETH_MDIO_REGADR 0x000007C0 /* Register Address */
|
#define GRETH_MDIO_REGADR 0x000007C0 /* Register Address */
|
||||||
#define GRETH_MDIO_PHYADR 0x0000F800 /* PHY address */
|
#define GRETH_MDIO_PHYADR 0x0000F800 /* PHY address */
|
||||||
#define GRETH_MDIO_DATA 0xFFFF0000 /* MDIO DATA */
|
#define GRETH_MDIO_DATA 0xFFFF0000 /* MDIO DATA */
|
||||||
|
|
||||||
|
|
||||||
|
/* MII registers */
|
||||||
|
#define GRETH_MII_EXTADV_1000FD 0x00000200
|
||||||
|
#define GRETH_MII_EXTADV_1000HD 0x00000100
|
||||||
|
#define GRETH_MII_EXTPRT_1000FD 0x00000800
|
||||||
|
#define GRETH_MII_EXTPRT_1000HD 0x00000400
|
||||||
|
|
||||||
|
#define GRETH_MII_100T4 0x00000200
|
||||||
|
#define GRETH_MII_100TXFD 0x00000100
|
||||||
|
#define GRETH_MII_100TXHD 0x00000080
|
||||||
|
#define GRETH_MII_10FD 0x00000040
|
||||||
|
#define GRETH_MII_10HD 0x00000020
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Attach routine */
|
/* Attach routine */
|
||||||
|
|
||||||
int rtems_greth_driver_attach (
|
int rtems_greth_driver_attach (
|
||||||
@@ -94,11 +130,25 @@ int rtems_greth_driver_attach (
|
|||||||
greth_configuration_t *chip
|
greth_configuration_t *chip
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* PHY data */
|
||||||
|
struct phy_device_info
|
||||||
|
{
|
||||||
|
int vendor;
|
||||||
|
int device;
|
||||||
|
int rev;
|
||||||
|
|
||||||
|
int adv;
|
||||||
|
int part;
|
||||||
|
|
||||||
|
int extadv;
|
||||||
|
int extpart;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#ifdef CPU_U32_FIX
|
#ifdef CPU_U32_FIX
|
||||||
void ipalign(struct mbuf *m);
|
void ipalign(struct mbuf *m);
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user