[PATCH 1/3] Remove duplicate GRETH driver
Jiri Gaisler
jiri at gaisler.se
Sun Oct 25 22:56:50 UTC 2020
On 10/25/20 6:35 PM, Joel Sherrill wrote:
> Is the code deleted referenced in the new build system?
Good question! I don't really know how the new systems works to answer
that. I could only remove the references from the .am files...
>
> On Sun, Oct 25, 2020, 5:26 PM Jiri Gaisler <jiri at gaisler.se
> <mailto:jiri at gaisler.se>> wrote:
>
> * bsps/shared/net/greth2.c is being used instead
> ---
> bsps/shared/grlib-sources.am <http://grlib-sources.am>
> | 4 -
> bsps/shared/grlib/net/README | 7 -
> bsps/shared/grlib/net/greth.c | 1655
> -----------------
> bsps/shared/grlib/net/network_interface_add.c | 62 -
> 4 files changed, 1728 deletions(-)
> delete mode 100644 bsps/shared/grlib/net/README
> delete mode 100644 bsps/shared/grlib/net/greth.c
> delete mode 100644 bsps/shared/grlib/net/network_interface_add.c
>
> diff --git a/bsps/shared/grlib-sources.am
> <http://grlib-sources.am> b/bsps/shared/grlib-sources.am
> <http://grlib-sources.am>
> index 512a48c7f7..2261eb957f 100644
> --- a/bsps/shared/grlib-sources.am <http://grlib-sources.am>
> +++ b/bsps/shared/grlib-sources.am <http://grlib-sources.am>
> @@ -34,10 +34,6 @@ librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/iommu/griommu.c
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/irq/genirq.c
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/l2c/l2c.c
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/mem/mctrl.c
> -if HAS_NETWORKING
> -librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/net/greth.c
> -librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/net/network_interface_add.c
> -endif
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/pci/gr_701.c
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/pci/grpci2.c
> librtemsbsp_a_SOURCES +=
> ../../../../../../bsps/shared/grlib/pci/grpci2dma.c
> diff --git a/bsps/shared/grlib/net/README
> b/bsps/shared/grlib/net/README
> deleted file mode 100644
> index 3ef086f223..0000000000
> --- a/bsps/shared/grlib/net/README
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -A non Driver Manager GRETH driver is located in
> libchip/network/greth.c. This
> -version requires the driver manager.
> -
> -network_interface_add is used to assign IP/NETMASK and MAC address to
> -GRETH interfaces dynamically according to in which order devices are
> -registered. The function takes the settings from the user defined
> -interface_configs[] array, defined in the project configuration.
> diff --git a/bsps/shared/grlib/net/greth.c
> b/bsps/shared/grlib/net/greth.c
> deleted file mode 100644
> index bc4d3cc40f..0000000000
> --- a/bsps/shared/grlib/net/greth.c
> +++ /dev/null
> @@ -1,1655 +0,0 @@
> -/*
> - * Gaisler Research ethernet MAC driver
> - * adapted from Opencores driver by Marko Isomaki
> - *
> - * The license and distribution terms for this file may be
> - * found in found in the file LICENSE in this distribution or at
> - * http://www.rtems.org/license/LICENSE.
> - *
> - *
> - * 2008-12-10, Converted to driver manager and added support for
> - * multiple GRETH cores. <daniel at gaisler.com
> <mailto:daniel at gaisler.com>>
> - * 2007-09-07, Ported GBIT support from 4.6.5
> - */
> -
> -#include <machine/rtems-bsd-kernel-space.h>
> -
> -#include <rtems.h>
> -#define CPU_U32_FIX
> -#include <bsp.h>
> -
> -#ifdef GRETH_SUPPORTED
> -
> -#include <inttypes.h>
> -#include <errno.h>
> -#include <rtems/bspIo.h>
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <stdarg.h>
> -#include <rtems/error.h>
> -#include <rtems/rtems_bsdnet.h>
> -
> -#include <grlib/greth.h>
> -#include <drvmgr/drvmgr.h>
> -#include <grlib/ambapp_bus.h>
> -#include <grlib/ambapp.h>
> -
> -#include <sys/param.h>
> -#include <sys/mbuf.h>
> -
> -#include <sys/socket.h>
> -#include <sys/sockio.h>
> -#include <net/if.h>
> -#include <netinet/in.h>
> -#include <netinet/if_ether.h>
> -
> -#ifdef malloc
> -#undef malloc
> -#endif
> -#ifdef free
> -#undef free
> -#endif
> -
> -#include <grlib/grlib_impl.h>
> -
> -#if defined(__m68k__)
> -extern m68k_isr_entry set_vector( rtems_isr_entry,
> rtems_vector_number, int );
> -#else
> -extern rtems_isr_entry set_vector( rtems_isr_entry,
> rtems_vector_number, int );
> -#endif
> -
> -
> -/* #define GRETH_DEBUG */
> -
> -#ifdef GRETH_DEBUG
> -#define DBG(args...) printk(args)
> -#else
> -#define DBG(args...)
> -#endif
> -
> -/* #define GRETH_DEBUG_MII */
> -
> -#ifdef GRETH_DEBUG_MII
> -#define MIIDBG(args...) printk(args)
> -#else
> -#define MIIDBG(args...)
> -#endif
> -
> -#ifdef CPU_U32_FIX
> -extern void ipalign(struct mbuf *m);
> -#endif
> -
> -/* Used when reading from memory written by GRETH DMA unit */
> -#ifndef GRETH_MEM_LOAD
> -#define GRETH_MEM_LOAD(addr) (*(volatile unsigned int *)(addr))
> -#endif
> -
> -/*
> - * Number of OCs supported by this driver
> - */
> -#define NOCDRIVER 1
> -
> -/*
> - * Receive buffer size -- Allow for a full ethernet packet
> including CRC
> - */
> -#define RBUF_SIZE 1518
> -
> -#define ET_MINLEN 64 /* minimum message length */
> -
> -/*
> - * RTEMS event used by interrupt handler to signal driver tasks.
> - * This must not be any of the events used by the network task
> synchronization.
> - */
> -#define INTERRUPT_EVENT RTEMS_EVENT_1
> -
> -/*
> - * RTEMS event used to start transmit daemon.
> - * This must not be the same as INTERRUPT_EVENT.
> - */
> -#define START_TRANSMIT_EVENT RTEMS_EVENT_2
> -
> - /* event to send when tx buffers become available */
> -#define GRETH_TX_WAIT_EVENT RTEMS_EVENT_3
> -
> -#if (MCLBYTES < RBUF_SIZE)
> -# error "Driver must have MCLBYTES > RBUF_SIZE"
> -#endif
> -
> -/* 4s Autonegotiation Timeout */
> -#ifndef GRETH_AUTONEGO_TIMEOUT_MS
> -#define GRETH_AUTONEGO_TIMEOUT_MS 4000
> -#endif
> -const struct timespec greth_tan = {
> - GRETH_AUTONEGO_TIMEOUT_MS/1000,
> - (GRETH_AUTONEGO_TIMEOUT_MS % 1000) * 1000000
> -};
> -
> -/* For optimizing the autonegotiation time */
> -#define GRETH_AUTONEGO_PRINT_TIME
> -
> -/* Ethernet buffer descriptor */
> -
> -typedef struct _greth_rxtxdesc {
> - volatile uint32_t ctrl; /* Length and status */
> - uint32_t *addr; /* Buffer pointer */
> -} greth_rxtxdesc;
> -
> -
> -/*
> - * Per-device data
> - */
> -struct greth_softc
> -{
> -
> - struct arpcom arpcom;
> - struct drvmgr_dev *dev; /* Driver manager device */
> - char devName[32];
> -
> - greth_regs *regs;
> - int minor;
> - int phyaddr; /* PHY Address configured by user (or -1 to
> autodetect) */
> - unsigned int edcl_dis;
> - int greth_rst;
> -
> - int acceptBroadcast;
> - rtems_id daemonTid;
> -
> - unsigned int tx_ptr;
> - unsigned int tx_dptr;
> - unsigned int tx_cnt;
> - unsigned int rx_ptr;
> - unsigned int txbufs;
> - unsigned int rxbufs;
> - greth_rxtxdesc *txdesc;
> - greth_rxtxdesc *rxdesc;
> - unsigned int txdesc_remote;
> - unsigned int rxdesc_remote;
> - struct mbuf **rxmbuf;
> - struct mbuf **txmbuf;
> - rtems_vector_number vector;
> -
> - /* TX descriptor interrupt generation */
> - int tx_int_gen;
> - int tx_int_gen_cur;
> - struct mbuf *next_tx_mbuf;
> - int max_fragsize;
> -
> - /*Status*/
> - struct phy_device_info phydev;
> - int phy_read_access;
> - int phy_write_access;
> - int fd;
> - int sp;
> - int gb;
> - int gbit_mac;
> - int auto_neg;
> - unsigned int advmodes; /* advertise ethernet speed modes. 0 =
> all modes. */
> - struct timespec auto_neg_time;
> - int mc_available;
> -
> - /*
> - * Statistics
> - */
> - unsigned long rxInterrupts;
> -
> - unsigned long rxPackets;
> - unsigned long rxLengthError;
> - unsigned long rxNonOctet;
> - unsigned long rxBadCRC;
> - unsigned long rxOverrun;
> -
> - unsigned long txInterrupts;
> -
> - unsigned long txDeferred;
> - unsigned long txHeartbeat;
> - unsigned long txLateCollision;
> - unsigned long txRetryLimit;
> - unsigned long txUnderrun;
> -
> - /* Spin-lock ISR protection */
> - SPIN_DECLARE(devlock);
> -};
> -
> -int greth_process_tx_gbit(struct greth_softc *sc);
> -int greth_process_tx(struct greth_softc *sc);
> -
> -static char *almalloc(int sz, int alignment)
> -{
> - char *tmp;
> - tmp = grlib_calloc(1, sz + (alignment-1));
> - tmp = (char *) (((int)tmp+alignment) & ~(alignment -1));
> - return(tmp);
> -}
> -
> -/* GRETH interrupt handler */
> -
> -static void greth_interrupt (void *arg)
> -{
> - uint32_t status;
> - uint32_t ctrl;
> - rtems_event_set events = 0;
> - struct greth_softc *greth = arg;
> - SPIN_ISR_IRQFLAGS(flags);
> -
> - /* read and clear interrupt cause */
> - status = greth->regs->status;
> - greth->regs->status = status;
> -
> - SPIN_LOCK(&greth->devlock, flags);
> - ctrl = greth->regs->ctrl;
> -
> - /* Frame received? */
> - if ((ctrl & GRETH_CTRL_RXIRQ) && (status &
> (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ)))
> - {
> - greth->rxInterrupts++;
> - /* Stop RX-Error and RX-Packet interrupts */
> - ctrl &= ~GRETH_CTRL_RXIRQ;
> - events |= INTERRUPT_EVENT;
> - }
> -
> - if ( (ctrl & GRETH_CTRL_TXIRQ) && (status &
> (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) )
> - {
> - greth->txInterrupts++;
> - ctrl &= ~GRETH_CTRL_TXIRQ;
> - events |= GRETH_TX_WAIT_EVENT;
> - }
> -
> - /* Clear interrupt sources */
> - greth->regs->ctrl = ctrl;
> - SPIN_UNLOCK(&greth->devlock, flags);
> -
> - /* Send the event(s) */
> - if ( events )
> - rtems_bsdnet_event_send(greth->daemonTid, events);
> -}
> -
> -static uint32_t read_mii(struct greth_softc *sc, uint32_t
> phy_addr, uint32_t reg_addr)
> -{
> - sc->phy_read_access++;
> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
> - sc->regs->mdio_ctrl = (phy_addr << 11) | (reg_addr << 6) |
> GRETH_MDIO_READ;
> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
> - if (!(sc->regs->mdio_ctrl & GRETH_MDIO_LINKFAIL)) {
> - MIIDBG("greth%d: mii read[%d] OK to %" PRIx32 ".%" PRIx32
> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",
> - sc->minor, sc->phy_read_access, phy_addr, reg_addr,
> - sc->regs->ctrl, sc->regs->mdio_ctrl);
> - return((sc->regs->mdio_ctrl >> 16) & 0xFFFF);
> - } else {
> - printf("greth%d: mii read[%d] failed to %" PRIx32 ".%" PRIx32
> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",
> - sc->minor, sc->phy_read_access, phy_addr, reg_addr,
> - sc->regs->ctrl, sc->regs->mdio_ctrl);
> - return (0xffff);
> - }
> -}
> -
> -static void write_mii(struct greth_softc *sc, uint32_t phy_addr,
> uint32_t reg_addr, uint32_t data)
> -{
> - sc->phy_write_access++;
> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
> - sc->regs->mdio_ctrl =
> - ((data & 0xFFFF) << 16) | (phy_addr << 11) | (reg_addr << 6)
> | GRETH_MDIO_WRITE;
> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
> - if (!(sc->regs->mdio_ctrl & GRETH_MDIO_LINKFAIL)) {
> - MIIDBG("greth%d: mii write[%d] OK to to %" PRIx32 ".%"
> PRIx32
> - "(0x%08" PRIx32 ",0x%08" PRIx32 ")\n",
> - sc->minor, sc->phy_write_access, phy_addr, reg_addr,
> - sc->regs->ctrl, sc->regs->mdio_ctrl);
> - } else {
> - printf("greth%d: mii write[%d] failed to to %" PRIx32
> ".%" PRIx32
> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",
> - sc->minor, sc->phy_write_access, phy_addr, reg_addr,
> - sc->regs->ctrl, sc->regs->mdio_ctrl);
> - }
> -}
> -
> -static void print_init_info(struct greth_softc *sc)
> -{
> - printf("greth: driver attached\n");
> - if ( sc->auto_neg == -1 ){
> - printf("Auto negotiation timed out. Selecting default
> config\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: %" PRIdMAX "ms\n",
> - (intmax_t)sc->auto_neg_time.tv_sec * 1000 +
> - sc->auto_neg_time.tv_nsec / 1000000);
> - }
> -#endif
> -}
> -
> -/*
> - * Generates the hash words based on CRCs of the enabled MAC
> addresses that are
> - * allowed to be received. The allowed MAC addresses are
> maintained in a linked
> - * "multi-cast" list available in the arpcom structure.
> - *
> - * Returns the number of MAC addresses that were processed (in
> the list)
> - */
> -static int
> -greth_mac_filter_calc(struct arpcom *ac, uint32_t *msb, uint32_t
> *lsb)
> -{
> - struct ether_multistep step;
> - struct ether_multi *enm;
> - int cnt = 0;
> - uint32_t crc, htindex, ht[2] = {0, 0};
> -
> - /* Go through the Ethernet Multicast addresses one by one and
> add their
> - * CRC contribution to the MAC filter.
> - */
> - ETHER_FIRST_MULTI(step, ac, enm);
> - while (enm) {
> - crc = ether_crc32_be((uint8_t *)enm->enm_addrlo, 6);
> - htindex = crc & 0x3f;
> - ht[htindex >> 5] |= (1 << (htindex & 0x1F));
> - cnt++;
> - ETHER_NEXT_MULTI(step, enm);
> - }
> -
> - if (cnt > 0) {
> - *msb = ht[1];
> - *lsb = ht[0];
> - }
> -
> - return cnt;
> -}
> -
> -/*
> - * Initialize the ethernet hardware
> - */
> -static int greth_mac_filter_set(struct greth_softc *sc)
> -{
> - struct ifnet *ifp = &sc->arpcom.ac_if;
> - uint32_t hash_msb, hash_lsb, ctrl;
> - SPIN_IRQFLAGS(flags);
> -
> - hash_msb = 0;
> - hash_lsb = 0;
> - ctrl = 0;
> - if (ifp->if_flags & IFF_PROMISC) {
> - /* No need to enable multi-cast when promiscous mode
> accepts all */
> - ctrl |= GRETH_CTRL_PRO;
> - } else if(!sc->mc_available) {
> - return EINVAL; /* no hardware support for multicast
> filtering. */
> - } else if (ifp->if_flags & IFF_ALLMULTI) {
> - /* We should accept all multicast addresses */
> - ctrl |= GRETH_CTRL_MCE;
> - hash_msb = 0xFFFFFFFF;
> - hash_lsb = 0xFFFFFFFF;
> - } else if (greth_mac_filter_calc(&sc->arpcom, &hash_msb,
> &hash_lsb) > 0) {
> - /* Generate hash for MAC filtering out multicast addresses */
> - ctrl |= GRETH_CTRL_MCE;
> - } else {
> - /* Multicast list is empty .. disable multicast */
> - }
> - SPIN_LOCK_IRQ(&sc->devlock, flags);
> - sc->regs->ht_msb = hash_msb;
> - sc->regs->ht_lsb = hash_lsb;
> - sc->regs->ctrl = (sc->regs->ctrl & ~(GRETH_CTRL_PRO |
> GRETH_CTRL_MCE)) |
> - ctrl;
> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);
> -
> - return 0;
> -}
> -
> -/*
> - * Initialize the ethernet hardware
> - */
> -static void
> -greth_initialize_hardware (struct greth_softc *sc)
> -{
> - struct mbuf *m;
> - int i;
> - int phyaddr;
> - int phyctrl;
> - int phystatus;
> - int tmp1;
> - int tmp2;
> - struct timespec tstart, tnow;
> - greth_regs *regs;
> - unsigned int advmodes, speed;
> -
> - regs = sc->regs;
> -
> - /* Reset the controller. */
> - sc->rxInterrupts = 0;
> - sc->rxPackets = 0;
> -
> - if (sc->greth_rst) {
> - /* Reset ON */
> - regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED;
> - for (i = 0; i<100 && (regs->ctrl & GRETH_CTRL_RST); i++)
> - ;
> - speed = 0; /* probe mode below */
> - } else {
> - /* inherit EDCL mode for now */
> - speed = sc->regs->ctrl &
> (GRETH_CTRL_GB|GRETH_CTRL_SP|GRETH_CTRL_FULLD);
> - }
> - /* Reset OFF and RX/TX DMA OFF. SW do PHY Init */
> - regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED | speed;
> -
> - /* Check if mac is gbit capable*/
> - sc->gbit_mac = (regs->ctrl >> 27) & 1;
> -
> - /* Get the phy address which assumed to have been set
> - correctly with the reset value in hardware*/
> - if ( sc->phyaddr == -1 ) {
> - phyaddr = (regs->mdio_ctrl >> 11) & 0x1F;
> - } else {
> - phyaddr = sc->phyaddr;
> - }
> - sc->phy_read_access = 0;
> - sc->phy_write_access = 0;
> -
> - /* As I understand the PHY comes back to a good default state
> after
> - * Power-down or Reset, so we do both just in case.
> Power-down bit should
> - * be cleared.
> - * Wait for old reset (if asserted by boot loader) to
> complete, otherwise
> - * power-down instruction might not have any effect.
> - */
> - while (read_mii(sc, phyaddr, 0) & 0x8000) {}
> - write_mii(sc, phyaddr, 0, 0x0800); /* Power-down */
> - write_mii(sc, phyaddr, 0, 0x0000); /* Power-Up */
> - write_mii(sc, phyaddr, 0, 0x8000); /* Reset */
> -
> - /* We wait about 30ms */
> - rtems_task_wake_after(rtems_clock_get_ticks_per_second()/32);
> -
> - /* Wait for reset to complete and get default values */
> - while ((phyctrl = read_mii(sc, phyaddr, 0)) & 0x8000) {}
> -
> - /* Set up PHY advertising modes for auto-negotiation */
> - advmodes = sc->advmodes;
> - if (advmodes == 0)
> - advmodes = GRETH_ADV_ALL;
> - if (!sc->gbit_mac)
> - advmodes &= ~(GRETH_ADV_1000_FD | GRETH_ADV_1000_HD);
> -
> - /* Enable/Disable GBit auto-neg advetisement so that the link
> partner
> - * know that we have/haven't GBit capability. The MAC may not
> support
> - * Gbit even though PHY does...
> - */
> - phystatus = read_mii(sc, phyaddr, 1);
> - if (phystatus & 0x0100) {
> - tmp1 = read_mii(sc, phyaddr, 9);
> - tmp1 &= ~0x300;
> - if (advmodes & GRETH_ADV_1000_FD)
> - tmp1 |= 0x200;
> - if (advmodes & GRETH_ADV_1000_HD)
> - tmp1 |= 0x100;
> - write_mii(sc, phyaddr, 9, tmp1);
> - }
> -
> - /* Optionally limit the 10/100 modes as configured by user */
> - tmp1 = read_mii(sc, phyaddr, 4);
> - tmp1 &= ~0x1e0;
> - if (advmodes & GRETH_ADV_100_FD)
> - tmp1 |= 0x100;
> - if (advmodes & GRETH_ADV_100_HD)
> - tmp1 |= 0x080;
> - if (advmodes & GRETH_ADV_10_FD)
> - tmp1 |= 0x040;
> - if (advmodes & GRETH_ADV_10_HD)
> - tmp1 |= 0x020;
> - write_mii(sc, phyaddr, 4, tmp1);
> -
> - /* If autonegotiation implemented we start it */
> - if (phystatus & 0x0008) {
> - write_mii(sc, phyaddr, 0, phyctrl | 0x1200);
> - phyctrl = read_mii(sc, phyaddr, 0);
> - }
> -
> - /* 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;
> - timespecclear(&sc->auto_neg_time);
> - if ((phyctrl >> 12) & 1) {
> - /*wait for auto negotiation to complete*/
> - sc->auto_neg = 1;
> - if (rtems_clock_get_uptime(&tstart) != RTEMS_SUCCESSFUL)
> - printk("rtems_clock_get_uptime failed\n");
> - while (!(((phystatus = read_mii(sc, phyaddr, 1)) >>
> 5) & 1)) {
> - if (rtems_clock_get_uptime(&tnow) !=
> RTEMS_SUCCESSFUL)
> - printk("rtems_clock_get_uptime
> failed\n");
> - timespecsub(&tnow, &tstart, &sc->auto_neg_time);
> - if (timespeccmp(&sc->auto_neg_time,
> &greth_tan, >)) {
> - sc->auto_neg = -1; /* Failed */
> - tmp1 = read_mii(sc, 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;
> - }
> - /* Wait about 30ms, time is PHY dependent */
> -
> rtems_task_wake_after(rtems_clock_get_ticks_per_second()/32);
> - }
> - sc->phydev.adv = read_mii(sc, phyaddr, 4);
> - sc->phydev.part = read_mii(sc, phyaddr, 5);
> - if ((phystatus >> 8) & 1) {
> - sc->phydev.extadv = read_mii(sc, phyaddr, 9);
> - sc->phydev.extpart = read_mii(sc, phyaddr, 10);
> - if ( (sc->phydev.extadv &
> GRETH_MII_EXTADV_1000HD) &&
> - (sc->phydev.extpart &
> GRETH_MII_EXTPRT_1000HD)) {
> - sc->gb = 1;
> - sc->fd = 0;
> - }
> - if ( (sc->phydev.extadv &
> GRETH_MII_EXTADV_1000FD) &&
> - (sc->phydev.extpart &
> GRETH_MII_EXTPRT_1000FD)) {
> - sc->gb = 1;
> - sc->fd = 1;
> - }
> - }
> - 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;
> - } else if ( (sc->phydev.adv &
> GRETH_MII_100TXHD) &&
> - (sc->phydev.part &
> GRETH_MII_100TXHD)) {
> - sc->sp = 1;
> - sc->fd = 0;
> - } else 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(sc, phyaddr, 1);
> -
> - /* Read out PHY info if extended registers are available */
> - if (phystatus & 1) {
> - tmp1 = read_mii(sc, phyaddr, 2);
> - tmp2 = read_mii(sc, 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 */
> - if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
> - write_mii(sc, phyaddr, 0, sc->sp << 13);
> -
> - /* check if marvell 88EE1111 PHY. Needs special reset
> handling */
> - if ((phystatus & 1) && (sc->phydev.vendor == 0x005043) &&
> - (sc->phydev.device == 0x0C))
> - write_mii(sc, phyaddr, 0, 0x8000);
> -
> - sc->gb = 0;
> - sc->sp = 0;
> - sc->fd = 0;
> - }
> - while ((read_mii(sc, phyaddr, 0)) & 0x8000) {}
> -
> - if (sc->greth_rst) {
> - /* Reset ON */
> - regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED;
> - for (i = 0; i < 100 && (regs->ctrl & GRETH_CTRL_RST); i++)
> - ;
> - }
> - /* Reset OFF. Set mode matching PHY settings. */
> - speed = (sc->gb << 8) | (sc->sp << 7) | (sc->fd << 4);
> - regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | speed;
> -
> - /* Initialize rx/tx descriptor table pointers. Due to
> alignment we
> - * always allocate maximum table size.
> - */
> - sc->txdesc = (greth_rxtxdesc *) almalloc(0x800, 0x400);
> - sc->rxdesc = (greth_rxtxdesc *) &sc->txdesc[128];
> - sc->tx_ptr = 0;
> - sc->tx_dptr = 0;
> - sc->tx_cnt = 0;
> - sc->rx_ptr = 0;
> -
> - /* Translate the Descriptor DMA table base address into an
> address that
> - * the GRETH core can understand
> - */
> - drvmgr_translate_check(
> - sc->dev,
> - CPUMEM_TO_DMA,
> - (void *)sc->txdesc,
> - (void **)&sc->txdesc_remote,
> - 0x800);
> - sc->rxdesc_remote = sc->txdesc_remote + 0x400;
> - regs->txdesc = (int) sc->txdesc_remote;
> - regs->rxdesc = (int) sc->rxdesc_remote;
> -
> - sc->rxmbuf = grlib_calloc(sc->rxbufs, sizeof(*sc->rxmbuf));
> - sc->txmbuf = grlib_calloc(sc->txbufs, sizeof(*sc->txmbuf));
> -
> - for (i = 0; i < sc->txbufs; i++)
> - {
> - sc->txdesc[i].ctrl = 0;
> - if (!(sc->gbit_mac)) {
> - drvmgr_translate_check(
> - sc->dev,
> - CPUMEM_TO_DMA,
> - (void *)grlib_malloc(GRETH_MAXBUF_LEN),
> - (void **)&sc->txdesc[i].addr,
> - GRETH_MAXBUF_LEN);
> - }
> -#ifdef GRETH_DEBUG
> - /* printf("TXBUF: %08x\n", (int)
> sc->txdesc[i].addr); */
> -#endif
> - }
> - for (i = 0; i < sc->rxbufs; i++)
> - {
> - MGETHDR (m, M_WAIT, MT_DATA);
> - MCLGET (m, M_WAIT);
> - if (sc->gbit_mac)
> - m->m_data += 2;
> - m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
> - sc->rxmbuf[i] = m;
> - drvmgr_translate_check(
> - sc->dev,
> - CPUMEM_TO_DMA,
> - (void *)mtod(m, uint32_t *),
> - (void **)&sc->rxdesc[i].addr,
> - GRETH_MAXBUF_LEN);
> - sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
> -#ifdef GRETH_DEBUG
> -/* printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr); */
> -#endif
> - }
> - sc->rxdesc[sc->rxbufs - 1].ctrl |= GRETH_RXD_WRAP;
> -
> - /* set ethernet address. */
> - regs->mac_addr_msb =
> - sc->arpcom.ac_enaddr[0] << 8 | sc->arpcom.ac_enaddr[1];
> - regs->mac_addr_lsb =
> - sc->arpcom.ac_enaddr[2] << 24 | sc->arpcom.ac_enaddr[3] << 16 |
> - sc->arpcom.ac_enaddr[4] << 8 | sc->arpcom.ac_enaddr[5];
> -
> - if ( sc->rxbufs < 10 ) {
> - sc->tx_int_gen = sc->tx_int_gen_cur = 1;
> - }else{
> - sc->tx_int_gen = sc->tx_int_gen_cur = sc->txbufs/2;
> - }
> - sc->next_tx_mbuf = NULL;
> -
> - if ( !sc->gbit_mac )
> - sc->max_fragsize = 1;
> -
> - /* clear all pending interrupts */
> - regs->status = 0xffffffff;
> -
> - /* install interrupt handler */
> - drvmgr_interrupt_register(sc->dev, 0, "greth",
> greth_interrupt, sc);
> -
> - regs->ctrl |= GRETH_CTRL_RXEN | GRETH_CTRL_RXIRQ;
> -
> - print_init_info(sc);
> -}
> -
> -#ifdef CPU_U32_FIX
> -
> -/*
> - * Routine to align the received packet so that the ip header
> - * is on a 32-bit boundary. Necessary for cpu's that do not
> - * allow unaligned loads and stores and when the 32-bit DMA
> - * mode is used.
> - *
> - * Transfers are done on word basis to avoid possibly slow byte
> - * and half-word writes.
> - */
> -
> -void ipalign(struct mbuf *m)
> -{
> - unsigned int *first, *last, data;
> - unsigned int tmp = 0;
> -
> - if ((((int) m->m_data) & 2) && (m->m_len)) {
> - last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) &
> ~3);
> - first = (unsigned int *) (((int) m->m_data) & ~3);
> - /* tmp = *first << 16; */
> - asm volatile (" lda [%1] 1, %0\n" : "=r"(tmp) :
> "r"(first) );
> - tmp = tmp << 16;
> - first++;
> - do {
> - /* When snooping is not available the LDA
> instruction must be used
> - * to avoid the cache to return an illegal
> value.
> - ** Load with forced cache miss
> - * data = *first;
> - */
> - asm volatile (" lda [%1] 1, %0\n" : "=r"(data) : "r"(first) );
> - *first = tmp | (data >> 16);
> - tmp = data << 16;
> - first++;
> - } while (first <= last);
> -
> - m->m_data = (caddr_t)(((int) m->m_data) + 2);
> - }
> -}
> -#endif
> -
> -static void
> -greth_Daemon (void *arg)
> -{
> - struct ether_header *eh;
> - struct greth_softc *dp = (struct greth_softc *) arg;
> - struct ifnet *ifp = &dp->arpcom.ac_if;
> - struct mbuf *m;
> - unsigned int len, len_status, bad;
> - rtems_event_set events;
> - SPIN_IRQFLAGS(flags);
> - int first;
> - int tmp;
> - unsigned int addr;
> -
> - for (;;)
> - {
> - rtems_bsdnet_event_receive (INTERRUPT_EVENT |
> GRETH_TX_WAIT_EVENT,
> - RTEMS_WAIT | RTEMS_EVENT_ANY,
> - RTEMS_NO_TIMEOUT, &events);
> -
> - if ( events & GRETH_TX_WAIT_EVENT ){
> - /* TX interrupt.
> - * We only end up here when all TX descriptors has
> been used,
> - * and
> - */
> - if ( dp->gbit_mac )
> - greth_process_tx_gbit(dp);
> - else
> - greth_process_tx(dp);
> -
> - /* If we didn't get a RX interrupt we don't process it */
> - if ( (events & INTERRUPT_EVENT) == 0 )
> - continue;
> - }
> -
> -
> -#ifdef GRETH_ETH_DEBUG
> - printf ("r\n");
> -#endif
> - first=1;
> - /* Scan for Received packets */
> -again:
> - while (!((len_status =
> - GRETH_MEM_LOAD(&dp->rxdesc[dp->rx_ptr].ctrl))
> & GRETH_RXD_ENABLE))
> - {
> - bad = 0;
> - if (len_status & GRETH_RXD_TOOLONG)
> - {
> - dp->rxLengthError++;
> - bad = 1;
> - }
> - if (len_status & GRETH_RXD_DRIBBLE)
> - {
> - dp->rxNonOctet++;
> - bad = 1;
> - }
> - if (len_status & GRETH_RXD_CRCERR)
> - {
> - dp->rxBadCRC++;
> - bad = 1;
> - }
> - if (len_status & GRETH_RXD_OVERRUN)
> - {
> - dp->rxOverrun++;
> - bad = 1;
> - }
> - if (len_status & GRETH_RXD_LENERR)
> - {
> - dp->rxLengthError++;
> - bad = 1;
> - }
> - if (!bad)
> - {
> - /* pass on the packet in the receive
> buffer */
> - len = len_status & 0x7FF;
> - m = dp->rxmbuf[dp->rx_ptr];
> -#ifdef GRETH_DEBUG
> - int i;
> - printf("RX: 0x%08x, Len: %d : ",
> (int) m->m_data, len);
> - for (i=0; i<len; i++)
> - printf("%x%x", (m->m_data[i]
> >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
> - printf("\n");
> -#endif
> - m->m_len = m->m_pkthdr.len =
> - len - sizeof (struct
> ether_header);
> -
> - eh = mtod (m, struct ether_header *);
> -
> - m->m_data += sizeof (struct
> ether_header);
> -#ifdef CPU_U32_FIX
> - if(!dp->gbit_mac) {
> - /* OVERRIDE CACHED ETHERNET
> HEADER FOR NON-SNOOPING SYSTEMS */
> - addr = (unsigned int)eh;
> - asm volatile (" lda [%1] 1,
> %0\n" : "=r"(tmp) : "r"(addr) );
> - addr+=4;
> - asm volatile (" lda [%1] 1,
> %0\n" : "=r"(tmp) : "r"(addr) );
> - addr+=4;
> - asm volatile (" lda [%1] 1,
> %0\n" : "=r"(tmp) : "r"(addr) );
> - addr+=4;
> - asm volatile (" lda [%1] 1,
> %0\n" : "=r"(tmp) : "r"(addr) );
> -
> - ipalign(m); /* Align
> packet on 32-bit boundary */
> - }
> -#endif
> -/*
> - if(!(dp->gbit_mac) &&
> !CPU_SPARC_HAS_SNOOPING) {
> -
> rtems_cache_invalidate_entire_data();
> - }
> -*/
> - ether_input (ifp, eh, m);
> - MGETHDR (m, M_WAIT, MT_DATA);
> - MCLGET (m, M_WAIT);
> - if (dp->gbit_mac)
> - m->m_data += 2;
> - dp->rxmbuf[dp->rx_ptr] = m;
> - m->m_pkthdr.rcvif = ifp;
> - drvmgr_translate_check(
> - dp->dev,
> - CPUMEM_TO_DMA,
> - (void *)mtod (m, uint32_t *),
> - (void
> **)&dp->rxdesc[dp->rx_ptr].addr,
> - GRETH_MAXBUF_LEN);
> - dp->rxPackets++;
> - }
> - if (dp->rx_ptr == dp->rxbufs - 1) {
> - dp->rxdesc[dp->rx_ptr].ctrl =
> GRETH_RXD_ENABLE | GRETH_RXD_IRQ | GRETH_RXD_WRAP;
> - } else {
> - dp->rxdesc[dp->rx_ptr].ctrl =
> GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
> - }
> - SPIN_LOCK_IRQ(&dp->devlock, flags);
> - dp->regs->ctrl |= GRETH_CTRL_RXEN;
> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);
> - dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
> - }
> -
> - /* Always scan twice to avoid deadlock */
> - if ( first ){
> - first=0;
> - SPIN_LOCK_IRQ(&dp->devlock, flags);
> - dp->regs->ctrl |= GRETH_CTRL_RXIRQ;
> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);
> - goto again;
> - }
> -
> - }
> -}
> -
> -static int
> -sendpacket (struct ifnet *ifp, struct mbuf *m)
> -{
> - struct greth_softc *dp = ifp->if_softc;
> - unsigned char *temp;
> - struct mbuf *n;
> - unsigned int len;
> - SPIN_IRQFLAGS(flags);
> -
> - /*
> - * Is there a free descriptor available?
> - */
> - if (GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].ctrl) &
> GRETH_TXD_ENABLE){
> - /* No. */
> - return 1;
> - }
> -
> - /* Remember head of chain */
> - n = m;
> -
> - len = 0;
> - temp = (unsigned char *)
> GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].addr);
> - drvmgr_translate(dp->dev, CPUMEM_FROM_DMA, (void *)temp,
> (void **)&temp);
> -#ifdef GRETH_DEBUG
> - printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int)
> temp);
> -#endif
> - for (;;)
> - {
> -#ifdef GRETH_DEBUG
> - int i;
> - printf("MBUF: 0x%08x : ", (int) m->m_data);
> - 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;
> - if (len <= RBUF_SIZE)
> - memcpy ((void *) temp, (char *) m->m_data,
> m->m_len);
> - temp += m->m_len;
> - if ((m = m->m_next) == NULL)
> - break;
> - }
> -
> - m_freem (n);
> -
> - /* don't send long packets */
> -
> - if (len <= GRETH_MAXBUF_LEN) {
> - if (dp->tx_ptr < dp->txbufs-1) {
> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_IRQ |
> -
> GRETH_TXD_ENABLE | len;
> - } else {
> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_IRQ |
> - GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
> - }
> - dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
> - SPIN_LOCK_IRQ(&dp->devlock, flags);
> - dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);
> - }
> -
> - return 0;
> -}
> -
> -
> -static int
> -sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)
> -{
> - struct greth_softc *dp = ifp->if_softc;
> - unsigned int len;
> -
> - unsigned int ctrl;
> - int frags;
> - struct mbuf *mtmp;
> - int int_en;
> - SPIN_IRQFLAGS(flags);
> -
> - len = 0;
> -#ifdef GRETH_DEBUG
> - printf("TXD: 0x%08x\n", (int) m->m_data);
> -#endif
> - /* Get number of fragments too see if we have enough
> - * resources.
> - */
> - frags=1;
> - mtmp=m;
> - while(mtmp->m_next){
> - frags++;
> - mtmp = mtmp->m_next;
> - }
> -
> - if ( frags > dp->max_fragsize )
> - dp->max_fragsize = frags;
> -
> - if ( frags > dp->txbufs ){
> - printf("GRETH: MBUF-chain cannot be sent. Increase
> descriptor count.\n");
> - return -1;
> - }
> -
> - if ( frags > (dp->txbufs-dp->tx_cnt) ){
> - /* Return number of fragments */
> - return frags;
> - }
> -
> -
> - /* Enable interrupt from descriptor every tx_int_gen
> - * descriptor. Typically every 16 descriptor. This
> - * is only to reduce the number of interrupts during
> - * heavy load.
> - */
> - dp->tx_int_gen_cur-=frags;
> - if ( dp->tx_int_gen_cur <= 0 ){
> - dp->tx_int_gen_cur = dp->tx_int_gen;
> - int_en = GRETH_TXD_IRQ;
> - }else{
> - int_en = 0;
> - }
> -
> - /* At this stage we know that enough descriptors are
> available */
> - for (;;)
> - {
> -
> -#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;
> - drvmgr_translate_check(
> - dp->dev,
> - CPUMEM_TO_DMA,
> - (void *)(uint32_t *)m->m_data,
> - (void **)&dp->txdesc[dp->tx_ptr].addr,
> - m->m_len);
> -
> - /* Wrap around? */
> - if (dp->tx_ptr < dp->txbufs-1) {
> - ctrl = GRETH_TXD_ENABLE;
> - }else{
> - ctrl = GRETH_TXD_ENABLE | GRETH_TXD_WRAP;
> - }
> -
> - /* Enable Descriptor */
> - if ((m->m_next) == NULL) {
> - dp->txdesc[dp->tx_ptr].ctrl = ctrl | int_en |
> m->m_len;
> - break;
> - }else{
> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_MORE |
> ctrl | int_en | m->m_len;
> - }
> -
> - /* Next */
> - 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_ptr = (dp->tx_ptr + 1) % dp->txbufs;
> - dp->tx_cnt++;
> -
> - /* Tell Hardware about newly enabled descriptor */
> - SPIN_LOCK_IRQ(&dp->devlock, flags);
> - dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);
> -
> - return 0;
> -}
> -
> -int greth_process_tx_gbit(struct greth_softc *sc)
> -{
> - struct ifnet *ifp = &sc->arpcom.ac_if;
> - struct mbuf *m;
> - SPIN_IRQFLAGS(flags);
> - int first=1;
> -
> - /*
> - * Send packets till queue is empty
> - */
> - for (;;){
> - /* Reap Sent packets */
> - while((sc->tx_cnt > 0) &&
> !(GRETH_MEM_LOAD(&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--;
> - }
> -
> - if ( sc->next_tx_mbuf ){
> - /* Get packet we tried but faild to transmit last time */
> - m = sc->next_tx_mbuf;
> - sc->next_tx_mbuf = NULL; /* Mark packet taken */
> - }else{
> - /*
> - * Get the next mbuf chain to transmit from Stack.
> - */
> - IF_DEQUEUE (&ifp->if_snd, m);
> - if (!m){
> - /* Hardware has sent all schedule packets, this
> - * makes the stack enter at greth_start next time
> - * a packet is to be sent.
> - */
> - ifp->if_flags &= ~IFF_OACTIVE;
> - break;
> - }
> - }
> -
> - /* Are there free descriptors available? */
> - /* Try to send packet, if it a negative number is
> returned. */
> - if ( (sc->tx_cnt >= sc->txbufs) || sendpacket_gbit(ifp, m) ){
> - /* Not enough resources */
> -
> - /* Since we have taken the mbuf out of the "send chain"
> - * we must remember to use that next time we come back.
> - * or else we have dropped a packet.
> - */
> - sc->next_tx_mbuf = m;
> -
> - /* Not enough resources, enable interrupt for
> transmissions
> - * this way we will be informed when more
> TX-descriptors are
> - * available.
> - */
> - if ( first ){
> - first = 0;
> - SPIN_LOCK_IRQ(&sc->devlock, flags);
> - ifp->if_flags |= IFF_OACTIVE;
> - sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);
> -
> - /* We must check again to be sure that we didn't
> - * miss an interrupt (if a packet was sent just
> before
> - * enabling interrupts)
> - */
> - continue;
> - }
> -
> - return -1;
> - }else{
> - /* Sent Ok, proceed to process more packets if
> available */
> - }
> - }
> - return 0;
> -}
> -
> -int greth_process_tx(struct greth_softc *sc)
> -{
> - struct ifnet *ifp = &sc->arpcom.ac_if;
> - struct mbuf *m;
> - SPIN_IRQFLAGS(flags);
> - int first=1;
> -
> - /*
> - * Send packets till queue is empty
> - */
> - for (;;){
> - if ( sc->next_tx_mbuf ){
> - /* Get packet we tried but failed to transmit last
> time */
> - m = sc->next_tx_mbuf;
> - sc->next_tx_mbuf = NULL; /* Mark packet taken */
> - }else{
> - /*
> - * Get the next mbuf chain to transmit from Stack.
> - */
> - IF_DEQUEUE (&ifp->if_snd, m);
> - if (!m){
> - /* Hardware has sent all schedule packets, this
> - * makes the stack enter at greth_start next time
> - * a packet is to be sent.
> - */
> - ifp->if_flags &= ~IFF_OACTIVE;
> - break;
> - }
> - }
> -
> - /* Try to send packet, failed if it a non-zero number is
> returned. */
> - if ( sendpacket(ifp, m) ){
> - /* Not enough resources */
> -
> - /* Since we have taken the mbuf out of the "send chain"
> - * we must remember to use that next time we come back.
> - * or else we have dropped a packet.
> - */
> - sc->next_tx_mbuf = m;
> -
> - /* Not enough resources, enable interrupt for
> transmissions
> - * this way we will be informed when more
> TX-descriptors are
> - * available.
> - */
> - if ( first ){
> - first = 0;
> - SPIN_LOCK_IRQ(&sc->devlock, flags);
> - ifp->if_flags |= IFF_OACTIVE;
> - sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);
> -
> - /* We must check again to be sure that we didn't
> - * miss an interrupt (if a packet was sent just
> before
> - * enabling interrupts)
> - */
> - continue;
> - }
> -
> - return -1;
> - }else{
> - /* Sent Ok, proceed to process more packets if
> available */
> - }
> - }
> - return 0;
> -}
> -
> -static void
> -greth_start (struct ifnet *ifp)
> -{
> - struct greth_softc *sc = ifp->if_softc;
> -
> - if ( ifp->if_flags & IFF_OACTIVE )
> - return;
> -
> - if ( sc->gbit_mac ){
> - /* No use trying to handle this if we are waiting on GRETH
> - * to send the previously scheduled packets.
> - */
> -
> - greth_process_tx_gbit(sc);
> - }else{
> - greth_process_tx(sc);
> - }
> -
> -}
> -
> -/*
> - * Initialize and start the device
> - */
> -static void
> -greth_init (void *arg)
> -{
> - struct greth_softc *sc = arg;
> - struct ifnet *ifp = &sc->arpcom.ac_if;
> - char name[4] = {'E', 'T', 'H', '0'};
> -
> - if (sc->daemonTid == 0)
> - {
> - /*
> - * Start driver tasks
> - */
> - name[3] += sc->minor;
> - sc->daemonTid = rtems_bsdnet_newproc (name, 4096,
> - greth_Daemon, sc);
> -
> - /*
> - * Set up GRETH hardware
> - */
> - greth_initialize_hardware (sc);
> - }
> -
> - /*
> - * Setup promiscous/multi-cast MAC address filters if user
> enabled it
> - */
> - greth_mac_filter_set(sc);
> -
> - /*
> - * Tell the world that we're running.
> - */
> - ifp->if_flags |= IFF_RUNNING;
> -}
> -
> -/*
> - * Stop the device
> - */
> -static void
> -greth_stop (struct greth_softc *sc)
> -{
> - struct ifnet *ifp = &sc->arpcom.ac_if;
> - SPIN_IRQFLAGS(flags);
> - unsigned int speed;
> -
> - SPIN_LOCK_IRQ(&sc->devlock, flags);
> - ifp->if_flags &= ~IFF_RUNNING;
> -
> - speed = sc->regs->ctrl & (GRETH_CTRL_GB | GRETH_CTRL_SP |
> GRETH_CTRL_FULLD);
> -
> - /* RX/TX OFF */
> - sc->regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED | speed;
> - /* Reset ON */
> - if (sc->greth_rst)
> - sc->regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD |
> GRETH_CTRL_ED | speed;
> - /* Reset OFF and restore link settings previously detected if
> any */
> - sc->regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | speed;
> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);
> -
> - sc->next_tx_mbuf = NULL;
> -}
> -
> -
> -/*
> - * Show interface statistics
> - */
> -static void
> -greth_stats (struct greth_softc *sc)
> -{
> - printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
> - printf (" Rx Packets:%-8lu", sc->rxPackets);
> - printf (" Length:%-8lu", sc->rxLengthError);
> - printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
> - printf (" Bad CRC:%-8lu", sc->rxBadCRC);
> - printf (" Overrun:%-8lu", sc->rxOverrun);
> - printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
> - printf (" Maximal Frags:%-8d", sc->max_fragsize);
> - printf (" GBIT MAC:%-8d", sc->gbit_mac);
> -}
> -
> -/*
> - * Driver ioctl handler
> - */
> -static int
> -greth_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t
> data)
> -{
> - struct greth_softc *sc = ifp->if_softc;
> - int error = 0;
> - struct ifreq *ifr;
> -
> - switch (command)
> - {
> - case SIOCGIFADDR:
> - case SIOCSIFADDR:
> - ether_ioctl (ifp, command, data);
> - break;
> -
> - case SIOCSIFFLAGS:
> - switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))
> - {
> - case IFF_RUNNING:
> - greth_stop (sc);
> - break;
> -
> - case IFF_UP:
> - greth_init (sc);
> - break;
> -
> - case IFF_UP | IFF_RUNNING:
> - greth_stop (sc);
> - greth_init (sc);
> - break;
> - default:
> - break;
> - }
> - break;
> -
> - case SIO_RTEMS_SHOW_STATS:
> - greth_stats (sc);
> - break;
> -
> - /*
> - * Multicast commands: Enabling/disabling filtering of
> MAC addresses
> - */
> - case SIOCADDMULTI:
> - case SIOCDELMULTI:
> - ifr = (struct ifreq *)data;
> - if (command == SIOCADDMULTI) {
> - error = ether_addmulti(ifr, &sc->arpcom);
> - } else {
> - error = ether_delmulti(ifr, &sc->arpcom);
> - }
> - if (error == ENETRESET) {
> - error = greth_mac_filter_set(sc);
> - }
> - break;
> -
> - default:
> - error = EINVAL;
> - break;
> - }
> -
> - return error;
> -}
> -
> -/*
> - * Attach an GRETH driver to the system
> - */
> -static int
> -greth_interface_driver_attach (
> - struct rtems_bsdnet_ifconfig *config,
> - int attach
> - )
> -{
> - struct greth_softc *sc;
> - struct ifnet *ifp;
> - int mtu;
> - int unitNumber;
> - char *unitName;
> -
> - /* parse driver name */
> - if ((unitNumber = rtems_bsdnet_parse_driver_name (config,
> &unitName)) < 0)
> - return 0;
> -
> - sc = config->drv_ctrl;
> - ifp = &sc->arpcom.ac_if;
> -#ifdef GRETH_DEBUG
> - printf("GRETH[%d]: %s, sc %p, dev %p on %s\n", unitNumber,
> config->ip_address, sc, sc->dev, sc->dev->parent->dev->name);
> -#endif
> - if (config->hardware_address)
> - {
> - memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
> - ETHER_ADDR_LEN);
> - }
> - else
> - {
> - memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
> - }
> -
> - if (config->mtu)
> - mtu = config->mtu;
> - else
> - mtu = ETHERMTU;
> -
> - sc->acceptBroadcast = !config->ignore_broadcast;
> -
> - /*
> - * Set up network interface values
> - */
> - ifp->if_softc = sc;
> - ifp->if_unit = unitNumber;
> - ifp->if_name = unitName;
> - ifp->if_mtu = mtu;
> - ifp->if_init = greth_init;
> - ifp->if_ioctl = greth_ioctl;
> - ifp->if_start = greth_start;
> - ifp->if_output = ether_output;
> - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
> - if (sc->mc_available)
> - ifp->if_flags |= IFF_MULTICAST;
> - if (ifp->if_snd.ifq_maxlen == 0)
> - ifp->if_snd.ifq_maxlen = ifqmaxlen;
> -
> - /*
> - * Attach the interface
> - */
> - if_attach (ifp);
> - ether_ifattach (ifp);
> -
> -#ifdef GRETH_DEBUG
> - printf ("GRETH : driver has been attached\n");
> -#endif
> - return 1;
> -}
> -
> -/******************* Driver manager interface
> ***********************/
> -
> -/* Driver prototypes */
> -int greth_register_io(rtems_device_major_number *m);
> -int greth_device_init(struct greth_softc *sc);
> -int network_interface_add(struct rtems_bsdnet_ifconfig *interface);
> -
> -#ifdef GRETH_INFO_AVAIL
> -static int greth_info(
> - struct drvmgr_dev *dev,
> - void (*print_line)(void *p, char *str),
> - void *p, int argc, char *argv[]);
> -#define GRETH_INFO_FUNC greth_info
> -#else
> -#define GRETH_INFO_FUNC NULL
> -#endif
> -
> -int greth_init2(struct drvmgr_dev *dev);
> -int greth_init3(struct drvmgr_dev *dev);
> -
> -struct drvmgr_drv_ops greth_ops =
> -{
> - .init =
> - {
> - NULL,
> - greth_init2,
> - greth_init3,
> - NULL
> - },
> - .remove = NULL,
> - .info = GRETH_INFO_FUNC,
> -};
> -
> -struct amba_dev_id greth_ids[] =
> -{
> - {VENDOR_GAISLER, GAISLER_ETHMAC},
> - {0, 0} /* Mark end of table */
> -};
> -
> -struct amba_drv_info greth_drv_info =
> -{
> - {
> - DRVMGR_OBJ_DRV, /* Driver */
> - NULL, /* Next driver */
> - NULL, /* Device list */
> - DRIVER_AMBAPP_GAISLER_GRETH_ID, /* Driver ID */
> - "GRETH_DRV", /* Driver Name */
> - DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */
> - &greth_ops,
> - NULL, /* Funcs */
> - 0, /* No devices yet */
> - 0,
> - },
> - &greth_ids[0]
> -};
> -
> -void greth_register_drv (void)
> -{
> - DBG("Registering GRETH driver\n");
> - drvmgr_drv_register(&greth_drv_info.general);
> -}
> -
> -int greth_init2(struct drvmgr_dev *dev)
> -{
> - struct greth_softc *priv;
> -
> - DBG("GRETH[%d] on bus %s\n", dev->minor_drv,
> dev->parent->dev->name);
> - priv = dev->priv = grlib_calloc(1, sizeof(*priv));
> - if ( !priv )
> - return DRVMGR_NOMEM;
> - priv->dev = dev;
> -
> - /* This core will not find other cores, so we wait for
> init3() */
> -
> - return DRVMGR_OK;
> -}
> -
> -int greth_init3(struct drvmgr_dev *dev)
> -{
> - struct greth_softc *sc;
> - struct rtems_bsdnet_ifconfig *ifp;
> - rtems_status_code status;
> -
> - sc = dev->priv;
> - sprintf(sc->devName, "gr_eth%d", (dev->minor_drv+1));
> -
> - /* Init GRETH device */
> - if ( greth_device_init(sc) ) {
> - printk("GRETH: Failed to init device\n");
> - return DRVMGR_FAIL;
> - }
> -
> - /* Initialize Spin-lock for GRSPW Device. This is to protect
> - * CTRL and DMACTRL registers from ISR.
> - */
> - SPIN_INIT(&sc->devlock, sc->devName);
> -
> - /* Register GRETH device as an Network interface */
> - ifp = grlib_calloc(1, sizeof(*ifp));
> -
> - ifp->name = sc->devName;
> - ifp->drv_ctrl = sc;
> - ifp->attach = greth_interface_driver_attach;
> -
> - status = network_interface_add(ifp);
> - if (status != 0) {
> - return DRVMGR_FAIL;
> - }
> -
> - return DRVMGR_OK;
> -}
> -
> -int greth_device_init(struct greth_softc *sc)
> -{
> - struct amba_dev_info *ambadev;
> - struct ambapp_core *pnpinfo;
> - union drvmgr_key_value *value;
> - unsigned int speed;
> -
> - /* Get device information from AMBA PnP information */
> - ambadev = (struct amba_dev_info *)sc->dev->businfo;
> - if ( ambadev == NULL ) {
> - return -1;
> - }
> - pnpinfo = &ambadev->info;
> - sc->regs = (greth_regs *)pnpinfo->apb_slv->start;
> - sc->minor = sc->dev->minor_drv;
> - sc->greth_rst = 1;
> -
> - /* Remember EDCL enabled/disable state before reset */
> - sc->edcl_dis = sc->regs->ctrl & GRETH_CTRL_ED;
> -
> - /* Default is to inherit EDCL Disable bit from HW. User can
> force En/Dis */
> - value = drvmgr_dev_key_get(sc->dev, "edclDis", DRVMGR_KT_INT);
> - if ( value ) {
> - /* Force EDCL mode. Has an effect later when GRETH+PHY is
> initialized */
> - if (value->i > 0) {
> - sc->edcl_dis = GRETH_CTRL_ED;
> - } else {
> - /* Default to avoid soft-reset the GRETH when EDCL is
> forced */
> - sc->edcl_dis = 0;
> - sc->greth_rst = 0;
> - }
> - }
> -
> - /* let user control soft-reset of GRETH (for debug) */
> - value = drvmgr_dev_key_get(sc->dev, "soft-reset", DRVMGR_KT_INT);
> - if ( value) {
> - sc->greth_rst = value->i ? 1 : 0;
> - }
> -
> - /* clear control register and reset NIC and keep current
> speed modes.
> - * This should be done as quick as possible during startup,
> this is to
> - * stop DMA transfers after a reboot.
> - *
> - * When EDCL is forced enabled reset is skipped, disabling
> RX/TX DMA is
> - * is enough during debug.
> - */
> - speed = sc->regs->ctrl & (GRETH_CTRL_GB | GRETH_CTRL_SP |
> GRETH_CTRL_FULLD);
> - sc->regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED | speed;
> - if (sc->greth_rst)
> - sc->regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD |
> GRETH_CTRL_ED | speed;
> - sc->regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | speed;
> -
> - /* Configure driver by overriding default config with the bus
> resources
> - * configured by the user
> - */
> - sc->txbufs = 32;
> - sc->rxbufs = 32;
> - sc->phyaddr = -1;
> -
> - value = drvmgr_dev_key_get(sc->dev, "txDescs", DRVMGR_KT_INT);
> - if ( value && (value->i <= 128) )
> - sc->txbufs = value->i;
> -
> - value = drvmgr_dev_key_get(sc->dev, "rxDescs", DRVMGR_KT_INT);
> - if ( value && (value->i <= 128) )
> - sc->rxbufs = value->i;
> -
> - value = drvmgr_dev_key_get(sc->dev, "phyAdr", DRVMGR_KT_INT);
> - if ( value && (value->i < 32) )
> - sc->phyaddr = value->i;
> -
> - value = drvmgr_dev_key_get(sc->dev, "advModes", DRVMGR_KT_INT);
> - if ( value )
> - sc->advmodes = value->i;
> -
> - /* Check if multicast support is available */
> - sc->mc_available = sc->regs->ctrl & GRETH_CTRL_MC;
> -
> - return 0;
> -}
> -
> -#ifdef GRETH_INFO_AVAIL
> -static int greth_info(
> - struct drvmgr_dev *dev,
> - void (*print_line)(void *p, char *str),
> - void *p, int argc, char *argv[])
> -{
> - struct greth_softc *sc;
> - char buf[64];
> -
> - if (dev->priv == NULL)
> - return -DRVMGR_EINVAL;
> - sc = dev->priv;
> -
> - sprintf(buf, "IFACE NAME: %s", sc->devName);
> - print_line(p, buf);
> - sprintf(buf, "GBIT MAC: %s", sc->gbit_mac ? "YES" : "NO");
> - print_line(p, buf);
> -
> - return DRVMGR_OK;
> -}
> -#endif
> -
> -#endif
> diff --git a/bsps/shared/grlib/net/network_interface_add.c
> b/bsps/shared/grlib/net/network_interface_add.c
> deleted file mode 100644
> index 011137404f..0000000000
> --- a/bsps/shared/grlib/net/network_interface_add.c
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -/* Network interface register help function
> - *
> - * COPYRIGHT (c) 2008.
> - * Cobham Gaisler AB.
> - *
> - * This function adds a network interface to the
> - * rtems_bsdnet_config.ifconfig linked list of interfaces.
> - * The interface configuration is taken from the user defined
> - * array interface_configs. This function is useful for PnP
> - * systems when an unknown number of interfaces are available.
> - *
> - * The license and distribution terms for this file may be
> - * found in found in the file LICENSE in this distribution or at
> - * http://www.rtems.org/license/LICENSE.
> - */
> -
> -#include <rtems/rtems_bsdnet.h>
> -#include <stdio.h>
> -
> -#include <grlib/network_interface_add.h>
> -
> -extern struct rtems_bsdnet_config rtems_bsdnet_config;
> -
> -/* Number of interfaces taken */
> -int network_interface_cnt = 0;
> -
> -int network_interface_add(struct rtems_bsdnet_ifconfig *interface)
> -{
> - struct ethernet_config *cfg = NULL;
> - int i, last_entry = 1;
> -
> - /* Init interface description */
> - interface->next = NULL;
> -
> - cfg = &interface_configs[network_interface_cnt];
> - for(i=0; i<6; i++) {
> - if ( cfg->eth_adr[i] != 0 ) {
> - last_entry = 0;
> - break;
> - }
> - }
> - /* Do we have a valid configuration? */
> - if ( last_entry == 0 ) {
> - cfg = &interface_configs[network_interface_cnt];
> -
> - interface->ip_address = cfg->ip_addr;
> - interface->ip_netmask = cfg->ip_netmask;
> - interface->hardware_address = cfg->eth_adr;
> -
> - network_interface_cnt++;
> - } else {
> - interface->ip_address = NULL;
> - interface->ip_netmask = NULL;
> - interface->hardware_address = NULL;
> - }
> -
> - /* Insert interface first into list */
> - interface->next = rtems_bsdnet_config.ifconfig;
> - rtems_bsdnet_config.ifconfig = interface;
> -
> - return 0;
> -}
> --
> 2.17.1
>
> _______________________________________________
> devel mailing list
> devel at rtems.org <mailto:devel at rtems.org>
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20201025/4c9e6c5e/attachment-0001.html>
More information about the devel
mailing list