From 8416e7c3223f35cf4cda75f7f8ef4677d872a7e6 Mon Sep 17 00:00:00 2001 From: Vijay Kumar Banerjee Date: Wed, 23 Jun 2021 13:20:19 -0600 Subject: bsps/powerpc, bsps/shared: Move remaining legacy networking header files --- bsps/headers.am | 3 - bsps/include/grlib/greth.h | 165 --- bsps/include/grlib/network_interface_add.h | 47 - bsps/powerpc/beatnik/headers.am | 3 - bsps/powerpc/beatnik/include/bsp/if_em_pub.h | 22 - bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h | 30 - bsps/powerpc/beatnik/include/bsp/if_mve_pub.h | 426 ------- bsps/shared/grlib/net/greth.c | 1663 ------------------------- 8 files changed, 2359 deletions(-) delete mode 100644 bsps/include/grlib/greth.h delete mode 100644 bsps/include/grlib/network_interface_add.h delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_em_pub.h delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_mve_pub.h delete mode 100644 bsps/shared/grlib/net/greth.c (limited to 'bsps') diff --git a/bsps/headers.am b/bsps/headers.am index b89e5c2b28..b5821564b1 100644 --- a/bsps/headers.am +++ b/bsps/headers.am @@ -82,7 +82,6 @@ include_grlib_HEADERS += ../../bsps/include/grlib/gradcdac.h include_grlib_HEADERS += ../../bsps/include/grlib/grascs.h include_grlib_HEADERS += ../../bsps/include/grlib/grcan.h include_grlib_HEADERS += ../../bsps/include/grlib/grctm.h -include_grlib_HEADERS += ../../bsps/include/grlib/greth.h include_grlib_HEADERS += ../../bsps/include/grlib/grgpio.h include_grlib_HEADERS += ../../bsps/include/grlib/griommu.h include_grlib_HEADERS += ../../bsps/include/grlib/grlib.h @@ -102,7 +101,6 @@ include_grlib_HEADERS += ../../bsps/include/grlib/l2c.h include_grlib_HEADERS += ../../bsps/include/grlib/l4stat.h include_grlib_HEADERS += ../../bsps/include/grlib/mctrl.h include_grlib_HEADERS += ../../bsps/include/grlib/memscrub.h -include_grlib_HEADERS += ../../bsps/include/grlib/network_interface_add.h include_grlib_HEADERS += ../../bsps/include/grlib/occan.h include_grlib_HEADERS += ../../bsps/include/grlib/pcif.h include_grlib_HEADERS += ../../bsps/include/grlib/satcan.h @@ -118,7 +116,6 @@ include_libchip_HEADERS += ../../bsps/include/libchip/ata.h include_libchip_HEADERS += ../../bsps/include/libchip/ata_internal.h include_libchip_HEADERS += ../../bsps/include/libchip/disp_hcms29xx.h include_libchip_HEADERS += ../../bsps/include/libchip/ds1375-rtc.h -include_libchip_HEADERS += ../../bsps/include/libchip/greth.h include_libchip_HEADERS += ../../bsps/include/libchip/i2c-2b-eeprom.h include_libchip_HEADERS += ../../bsps/include/libchip/i2c-ds1621.h include_libchip_HEADERS += ../../bsps/include/libchip/i2c-sc620.h diff --git a/bsps/include/grlib/greth.h b/bsps/include/grlib/greth.h deleted file mode 100644 index e7970a79f7..0000000000 --- a/bsps/include/grlib/greth.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Cobham Gaisler 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. - */ - -#ifndef __GRETH_H__ -#define __GRETH_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Ethernet configuration registers */ - -typedef struct _greth_regs { - volatile uint32_t ctrl; /* Ctrl Register */ - volatile uint32_t status; /* Status Register */ - volatile uint32_t mac_addr_msb; /* Bit 47-32 of MAC address */ - volatile uint32_t mac_addr_lsb; /* Bit 31-0 of MAC address */ - volatile uint32_t mdio_ctrl; /* MDIO control and status */ - volatile uint32_t txdesc; /* Transmit descriptor pointer */ - volatile uint32_t rxdesc; /* Receive descriptor pointer */ - volatile uint32_t edcl; /* EDCL IP register */ - volatile uint32_t ht_msb; /* Multicast MSB hash */ - volatile uint32_t ht_lsb; /* Multicast LSB hash */ -} greth_regs; - -#define GRETH_TOTAL_BD 128 -#define GRETH_MAXBUF_LEN 1520 - -/* Tx BD */ -#define GRETH_TXD_ENABLE 0x0800 /* Tx BD Enable */ -#define GRETH_TXD_WRAP 0x1000 /* Tx BD Wrap (last BD) */ -#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_RETLIM 0x8000 /* Tx BD Retransmission Limit Status */ -#define GRETH_TXD_LATECOL 0x10000 /* Tx BD Late Collision */ - -#define GRETH_TXD_STATS (GRETH_TXD_UNDERRUN | \ - GRETH_TXD_RETLIM | \ - GRETH_TXD_LATECOL) - -#define GRETH_TXD_CS (GRETH_TXD_IPCS | \ - GRETH_TXD_TCPCS | \ - GRETH_TXD_UDPCS) - -/* Rx BD */ -#define GRETH_RXD_ENABLE 0x0800 /* Rx BD Enable */ -#define GRETH_RXD_WRAP 0x1000 /* Rx BD Wrap (last BD) */ -#define GRETH_RXD_IRQ 0x2000 /* Rx BD IRQ Enable */ - -#define GRETH_RXD_DRIBBLE 0x4000 /* Rx BD Dribble Nibble Status */ -#define GRETH_RXD_TOOLONG 0x8000 /* Rx BD Too Long Status */ -#define GRETH_RXD_CRCERR 0x10000 /* Rx BD CRC Error 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 | \ - GRETH_RXD_DRIBBLE | \ - GRETH_RXD_TOOLONG | \ - GRETH_RXD_CRCERR) - -/* CTRL Register */ -#define GRETH_CTRL_TXEN 0x00000001 /* Transmit Enable */ -#define GRETH_CTRL_RXEN 0x00000002 /* Receive Enable */ -#define GRETH_CTRL_TXIRQ 0x00000004 /* Transmit Enable */ -#define GRETH_CTRL_RXIRQ 0x00000008 /* Receive Enable */ -#define GRETH_CTRL_FULLD 0x00000010 /* Full Duplex */ -#define GRETH_CTRL_PRO 0x00000020 /* Promiscuous (receive all) */ -#define GRETH_CTRL_RST 0x00000040 /* Reset MAC */ -#define GRETH_CTRL_SP 0x00000080 /* 100MBit speed mode */ -#define GRETH_CTRL_GB 0x00000100 /* 1GBit speed mode */ -#define GRETH_CTRL_MCE 0x00000800 /* Multicast Enable */ -#define GRETH_CTRL_DD 0x00001000 /* Disable EDCL Duplex Detection */ -#define GRETH_CTRL_ED 0x00004000 /* EDCL Disable */ -#define GRETH_CTRL_MC 0x02000000 /* Multicast available */ -#define GRETH_CTRL_ME 0x04000000 /* MDIO interrupts enabled */ -#define GRETH_CTRL_GA 0x08000000 /* Gigabit MAC available */ - -/* Status Register */ -#define GRETH_STATUS_RXERR 0x00000001 /* Receive Error */ -#define GRETH_STATUS_TXERR 0x00000002 /* Transmit Error IRQ */ -#define GRETH_STATUS_RXIRQ 0x00000004 /* Receive Frame IRQ */ -#define GRETH_STATUS_TXIRQ 0x00000008 /* Transmit Error IRQ */ -#define GRETH_STATUS_RXAHBERR 0x00000010 /* Receiver AHB Error */ -#define GRETH_STATUS_TXAHBERR 0x00000020 /* Transmitter AHB Error */ -#define GRETH_STATUS_NRD 0x0f000000 /* Number of descriptors */ - -/* MDIO Control */ -#define GRETH_MDIO_WRITE 0x00000001 /* MDIO Write */ -#define GRETH_MDIO_READ 0x00000002 /* MDIO Read */ -#define GRETH_MDIO_LINKFAIL 0x00000004 /* MDIO Link failed */ -#define GRETH_MDIO_BUSY 0x00000008 /* MDIO Link Busy */ -#define GRETH_MDIO_REGADR 0x000007C0 /* Register Address */ -#define GRETH_MDIO_PHYADR 0x0000F800 /* PHY address */ -#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 */ - -void greth_register_drv(void); - -/* PHY data */ -struct phy_device_info -{ - int vendor; - int device; - int rev; - - int adv; - int part; - - int extadv; - int extpart; -}; - -/* Limit speed modes advertised during auto-negotiation */ -#define GRETH_ADV_10_HD 0x0001 -#define GRETH_ADV_10_FD 0x0002 -#define GRETH_ADV_100_HD 0x0004 -#define GRETH_ADV_100_FD 0x0008 -#define GRETH_ADV_1000_HD 0x0010 -#define GRETH_ADV_1000_FD 0x0020 -#define GRETH_ADV_ALL 0x003f -/* -#ifdef CPU_U32_FIX -void ipalign(struct mbuf *m); -#endif - -*/ -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/bsps/include/grlib/network_interface_add.h b/bsps/include/grlib/network_interface_add.h deleted file mode 100644 index b04a96f003..0000000000 --- a/bsps/include/grlib/network_interface_add.h +++ /dev/null @@ -1,47 +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. - */ - -#ifndef __NETWORK_INTERFACE_ADD_H__ -#define __NETWORK_INTERFACE_ADD_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Interface configuration description */ -struct ethernet_config { - char *ip_addr; /* IP address */ - char *ip_netmask; /* IP Netmask */ - char eth_adr[6]; /* Ethernet hardware MAC address */ -}; - -/* Array with configurations for all interfaces in the system - * Must be defined by the user. - */ -extern struct ethernet_config interface_configs[]; - -/* Routine adding interface to rtems_bsdnet_config.ifconfig linked - * list of interfaces. - */ -int network_interface_add(struct rtems_bsdnet_ifconfig *interface); - -#ifdef __cplusplus -} -#endif - -#endif /* _RTEMS_NETWORKCONFIG_H_ */ diff --git a/bsps/powerpc/beatnik/headers.am b/bsps/powerpc/beatnik/headers.am index 36df3cd759..364ea222a8 100644 --- a/bsps/powerpc/beatnik/headers.am +++ b/bsps/powerpc/beatnik/headers.am @@ -16,7 +16,4 @@ include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gti2cr include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtintrreg.h include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtpcireg.h include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtreg.h -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_em_pub.h -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_mve_pub.h include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/irq.h diff --git a/bsps/powerpc/beatnik/include/bsp/if_em_pub.h b/bsps/powerpc/beatnik/include/bsp/if_em_pub.h deleted file mode 100644 index eb970e465b..0000000000 --- a/bsps/powerpc/beatnik/include/bsp/if_em_pub.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H -#define RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H - -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -extern int rtems_em_attach(struct rtems_bsdnet_ifconfig *, int); -extern int rtems_em_pci_setup(int); -extern rtems_bsdnet_early_link_check_ops rtems_em_early_link_check_ops; - -#ifdef __cplusplus - } -#endif - -#endif - - diff --git a/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h b/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h deleted file mode 100644 index 8ea849efb1..0000000000 --- a/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H -#define RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H - -#include -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -extern int -rtems_gfe_attach(struct rtems_bsdnet_ifconfig *, int); - - -/* enet_addr must be 6 bytes long */ -int -rtems_gfe_setup(int unit, char *enet_addr, uint32_t base_addr); - -extern rtems_bsdnet_early_link_check_ops -rtems_gfe_early_link_check_ops; - -#ifdef __cplusplus - } -#endif - -#endif - - diff --git a/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h b/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h deleted file mode 100644 index 46cc4ccd23..0000000000 --- a/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h +++ /dev/null @@ -1,426 +0,0 @@ -#ifndef RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H -#define RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H - -/* - * Authorship - * ---------- - * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was - * created by Till Straumann , 2005-2007, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * The 'beatnik' BSP was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ -#include -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -extern int rtems_mve_attach(struct rtems_bsdnet_ifconfig *, int); -extern rtems_bsdnet_early_link_check_ops rtems_mve_early_link_check_ops; - -/* Low-level Driver API. - * This provides driver access to applications that want to use e.g., the second - * ethernet interface w/o running the BSD TCP/IP stack. - */ - -/* Opaque handle */ -struct mveth_private; - -/* Direct assignment of MVE flags to user API relies on irqs and x-irqs not overlapping */ -#define BSP_MVE_IRQ_RX (1<<2) -#define BSP_MVE_IRQ_TX (1<<0) -#define BSP_MVE_IRQ_LINK (1<<16) - -/* Setup an interface. - * Allocates resources for descriptor rings and sets up the driver software structure. - * - * Arguments: - * unit: - * interface # (1..2). The interface must not be attached to BSD. - * - * driver_tid: - * ISR posts RTEMS event # ('unit' - 1) to task with ID 'driver_tid' and disables interrupts - * from this interface. - * - * void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred): - * Pointer to user-supplied callback to release a buffer that had been sent - * by BSP_mve_send_buf() earlier. The callback is passed 'cleanup_txbuf_arg' - * and a flag indicating whether the send had been successful. - * The driver no longer accesses 'user_buf' after invoking this callback. - * CONTEXT: This callback is executed either by BSP_mve_swipe_tx() or - * BSP_mve_send_buf(), BSP_mve_init_hw(), BSP_mve_stop_hw() (the latter - * ones calling BSP_mve_swipe_tx()). - * void *cleanup_txbuf_arg: - * Closure argument that is passed on to 'cleanup_txbuf()' callback; - * - * void *(*alloc_rxbuf)(int *p_size, unsigned long *p_data_addr), - * Pointer to user-supplied callback to allocate a buffer for subsequent - * insertion into the RX ring by the driver. - * RETURNS: opaque handle to the buffer (which may be a more complex object - * such as an 'mbuf'). The handle is not used by the driver directly - * but passed back to the 'consume_rxbuf()' callback. - * Size of the available data area and pointer to buffer's data area - * in '*psize' and '*p_data_area', respectively. - * If no buffer is available, this routine should return NULL in which - * case the driver drops the last packet and re-uses the last buffer - * instead of handing it out to 'consume_rxbuf()'. - * CONTEXT: Called when initializing the RX ring (BSP_mve_init_hw()) or when - * swiping it (BSP_mve_swipe_rx()). - * - * - * void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len); - * Pointer to user-supplied callback to pass a received buffer back to - * the user. The driver no longer accesses the buffer after invoking this - * callback (with 'len'>0, see below). 'user_buf' is the buffer handle - * previously generated by 'alloc_rxbuf()'. - * The callback is passed 'cleanup_rxbuf_arg' and a 'len' - * argument giving the number of bytes that were received. - * 'len' may be <=0 in which case the 'user_buf' argument is NULL. - * 'len' == 0 means that the last 'alloc_rxbuf()' had failed, - * 'len' < 0 indicates a receiver error. In both cases, the last packet - * was dropped/missed and the last buffer will be re-used by the driver. - * NOTE: the data are 'prefixed' with two bytes, i.e., the ethernet packet header - * is stored at offset 2 in the buffer's data area. Also, the FCS (4 bytes) - * is appended. 'len' accounts for both. - * CONTEXT: Called from BSP_mve_swipe_rx(). - * void *cleanup_rxbuf_arg: - * Closure argument that is passed on to 'consume_rxbuf()' callback; - * - * rx_ring_size, tx_ring_size: - * How many big to make the RX and TX descriptor rings. Note that the sizes - * may be 0 in which case a reasonable default will be used. - * If either ring size is < 0 then the RX or TX will be disabled. - * Note that it is illegal in this case to use BSP_mve_swipe_rx() or - * BSP_mve_swipe_tx(), respectively. - * - * irq_mask: - * Interrupts to enable. OR of flags from above. - * - */ -struct mveth_private * -BSP_mve_setup( - int unit, - rtems_id driver_tid, - void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred), - void *cleanup_txbuf_arg, - void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr), - void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len), - void *consume_rxbuf_arg, - int rx_ring_size, - int tx_ring_size, - int irq_mask -); - -/* - * Alternate 'setup' routine allowing the user to install an ISR rather - * than a task ID. - * All parameters (other than 'isr' / 'isr_arg') and the return value - * are identical to the BSP_mve_setup() entry point. - */ -struct mveth_private * -BSP_mve_setup_1( - int unit, - void (*isr)(void *isr_arg), - void *isr_arg, - void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred), - void *cleanup_txbuf_arg, - void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr), - void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len), - void *consume_rxbuf_arg, - int rx_ring_size, - int tx_ring_size, - int irq_mask -); - - -/* - * Initialize interface hardware - * - * 'mp' handle obtained by from BSP_mve_setup(). - * 'promisc' whether to set promiscuous flag. - * 'enaddr' pointer to six bytes with MAC address. Read - * from the device if NULL. - * - * Note: Multicast filters are cleared by this routine. - * However, in promiscuous mode the mcast filters - * are programmed to accept all multicast frames. - */ -void -BSP_mve_init_hw(struct mveth_private *mp, int promisc, unsigned char *enaddr); - -/* - * Clear multicast hash filter. No multicast frames are accepted - * after executing this routine (unless the hardware was initialized - * in 'promiscuous' mode). - */ -void -BSP_mve_mcast_filter_clear(struct mveth_private *mp); - -/* - * Program multicast filter to accept all multicast frames - */ -void -BSP_mve_mcast_filter_accept_all(struct mveth_private *mp); - -/* - * Add a MAC address to the multicast filter. - * Existing entries are not changed but note that - * the filter is imperfect, i.e., multiple MAC addresses - * may alias to a single filter entry. Hence software - * filtering must still be performed. - * - * If a higher-level driver implements IP multicasting - * then multiple IP addresses may alias to the same MAC - * address. This driver maintains a 'reference-count' - * which is incremented every time the same MAC-address - * is passed to this routine; the address is only removed - * from the filter if BSP_mve_mcast_filter_accept_del() - * is called the same number of times (or by BSP_mve_mcast_filter_clear). - */ -void -BSP_mve_mcast_filter_accept_add(struct mveth_private *mp, unsigned char *enaddr); - -/* - * Remove a MAC address from the multicast filter. - * This routine decrements the reference count of the given - * MAC-address and removes it from the filter once the - * count reaches zero. - */ -void -BSP_mve_mcast_filter_accept_del(struct mveth_private *mp, unsigned char *enaddr); - -/* - * Shutdown hardware and clean out the rings - */ -void -BSP_mve_stop_hw(struct mveth_private *mp); - -/* calls BSP_mve_stop_hw(), releases all resources and marks the interface - * as unused. - * RETURNS 0 on success, nonzero on failure. - * NOTE: the handle MUST NOT be used after successful execution of this - * routine. - */ -int -BSP_mve_detach(struct mveth_private *mp); - -int -BSP_mve_send_buf_raw(struct mveth_private *mp, void *head_p, int h_len, - void *data_p, int d_len); - -/* - * Enqueue a mbuf chain or a raw data buffer for transmission; - * RETURN: #bytes sent or -1 if there are not enough free descriptors - * - * If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain. - * OTOH, a raw data packet (or a different type of buffer) - * may be send (non-BSD driver) by pointing data_p to the start of - * the data and passing 'len' > 0. - * 'm_head' is passed back to the 'cleanup_txbuf()' callback. - * - * Comments: software cache-flushing incurs a penalty if the - * packet cannot be queued since it is flushed anyways. - * The algorithm is slightly more efficient in the normal - * case, though. - * - * RETURNS: # bytes enqueued to device for transmission or -1 if no - * space in the TX ring was available. - */ -int -BSP_mve_send_buf(struct mveth_private *mp, void *m_head, void *data_p, int len); - -/* Descriptor scavenger; cleanup the TX ring, passing all buffers - * that have been sent to the cleanup_tx() callback. - * This routine is called from BSP_mve_send_buf(), BSP_mve_init_hw(), - * BSP_mve_stop_hw(). - * - * RETURNS: number of buffers processed. - */ -int -BSP_mve_swipe_tx(struct mveth_private *mp); - -/* Retrieve all received buffers from the RX ring, replacing them - * by fresh ones (obtained from the alloc_rxbuf() callback). The - * received buffers are passed to consume_rxbuf(). - * - * RETURNS: number of buffers processed. - */ -int -BSP_mve_swipe_rx(struct mveth_private *mp); - -/* read ethernet address from hw to buffer */ -void -BSP_mve_read_eaddr(struct mveth_private *mp, unsigned char *eaddr); - -/* read/write media word. - * 'cmd': can be SIOCGIFMEDIA, SIOCSIFMEDIA, 0 or 1. The latter - * are aliased to the former for convenience. - * 'parg': pointer to media word. - * - * RETURNS: 0 on success, nonzero on error - * - * NOTE: This routine is thread-safe. - */ -int -BSP_mve_media_ioctl(struct mveth_private *mp, int cmd, int *parg); - -/* Interrupt related routines */ - -/* Note: the BSP_mve_enable/disable/ack_irqs() entry points - * are deprecated. - * The newer API where the user passes a mask allows - * for more selective control. - */ - -/* Enable all supported interrupts at device */ -void -BSP_mve_enable_irqs(struct mveth_private *mp); - -/* Disable all supported interrupts at device */ -void -BSP_mve_disable_irqs(struct mveth_private *mp); - -/* Acknowledge (and clear) all supported interrupts. - * RETURNS: interrupts that were raised. - */ -uint32_t -BSP_mve_ack_irqs(struct mveth_private *mp); - -/* Enable interrupts included in 'mask' (leaving - * already enabled interrupts on). If the mask - * includes bits that were not passed to the 'setup' - * routine then the behavior is undefined. - */ -void -BSP_mve_enable_irq_mask(struct mveth_private *mp, uint32_t irq_mask); - -/* Disable interrupts included in 'mask' (leaving - * other ones that are currently enabled on). If the - * mask includes bits that were not passed to the 'setup' - * routine then the behavior is undefined. - * - * RETURNS: Bitmask of interrupts that were enabled upon entry - * into this routine. This can be used to restore the - * previous state. - */ -uint32_t -BSP_mve_disable_irq_mask(struct mveth_private *mp, uint32_t irq_mask); - -/* Acknowledge and clear selected interrupts. - * - * RETURNS: All pending interrupts. - * - * NOTE: Only pending interrupts contained in 'mask' - * are cleared. Others are left pending. - * - * This routine can be used to check for pending - * interrupts (pass mask == 0) or to clear all - * interrupts (pass mask == -1). - */ -uint32_t -BSP_mve_ack_irq_mask(struct mveth_private *mp, uint32_t mask); - -/* If the PHY link status changes then some - * internal settings in the ethernet controller's - * serial port need to be updated to match the - * PHY settings. Use this routine to perform the - * necessary steps after a link change has been - * detected. - * - * RETURNS: 0 on success, -1 if the PHY state - * could not be determined. - * - * The current state of the media as read - * by BSP_mve_media_ioctl() is returned in - * *pmedia. - * - * NOTE: This routine calls BSP_mve_media_ioctl(). - */ -int -BSP_mve_ack_link_chg(struct mveth_private *mp, int *pmedia); - -/* Retrieve the driver daemon TID that was passed to - * BSP_mve_setup(). - */ - -rtems_id -BSP_mve_get_tid(struct mveth_private *mp); - -/* Dump statistics to file (stdout if NULL) - * - * NOTE: this routine is not thread safe - */ -void -BSP_mve_dump_stats(struct mveth_private *mp, FILE *f); - -/* - * - * Example driver task loop (note: no synchronization of - * buffer access shown!). - * RTEMS_EVENTx = 0,1 or 2 depending on IF unit. - * - * / * setup (obtain handle) and initialize hw here * / - * - * do { - * / * ISR disables IRQs and posts event * / - * rtems_event_receive( RTEMS_EVENTx, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs ); - * irqs = BSP_mve_ack_irqs(handle); - * if ( irqs & BSP_MVE_IRQ_TX ) { - * BSP_mve_swipe_tx(handle); / * cleanup_txbuf() callback executed * / - * } - * if ( irqs & BSP_MVE_IRQ_RX ) { - * BSP_mve_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * / - * } - * if ( irqs & BSP_MVE_IRQ_LINK ) { - * / * update serial port settings from current link status * / - * BSP_mve_ack_link_chg(handle, 0); - * } - * BSP_mve_enable_irqs(handle); - * } while (1); - * - */ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/bsps/shared/grlib/net/greth.c b/bsps/shared/grlib/net/greth.c deleted file mode 100644 index 84efcd74ab..0000000000 --- a/bsps/shared/grlib/net/greth.c +++ /dev/null @@ -1,1663 +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. - * 2007-09-07, Ported GBIT support from 4.6.5 - */ - -#include - -#include -#define CPU_U32_FIX -#include - -#ifdef GRETH_SUPPORTED - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef malloc -#undef malloc -#endif -#ifdef free -#undef free -#endif - -#include - -#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; - int num_descs; - - /* - * 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, tabsize; - - 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. - */ - tabsize = sc->num_descs * 8; - sc->txdesc = (greth_rxtxdesc *) almalloc(tabsize * 2, tabsize); - sc->rxdesc = (greth_rxtxdesc *) (tabsize + (void *)sc->txdesc); - 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, - tabsize * 2); - sc->rxdesc_remote = sc->txdesc_remote + tabsize; - 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)) { -#if CPU_LITTLE_ENDIAN == TRUE - memmove((caddr_t)(((int) m->m_data) + 2), m->m_data, m->m_len); -#else - last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) & ~3); - first = (unsigned int *) (((int) m->m_data) & ~3); - /* tmp = *first << 16; */ - tmp = GRETH_MEM_LOAD(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; - */ - data = GRETH_MEM_LOAD(first); - *first = tmp | (data >> 16); - tmp = data << 16; - first++; - } while (first <= last); -#endif - 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; - - 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; im_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 */ - tmp = GRETH_MEM_LOAD((uintptr_t)eh); - tmp = GRETH_MEM_LOAD(4+(uintptr_t)eh); - tmp = GRETH_MEM_LOAD(8+(uintptr_t)eh); - tmp = GRETH_MEM_LOAD(12+(uintptr_t)eh); - (void)tmp; - - 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;im_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; im_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; - int i, nrd; - - /* 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; - - /* Probe the number of descriptors available the */ - nrd = (sc->regs->status & GRETH_STATUS_NRD) >> 24; - for (sc->num_descs = 128, i = 0; i < nrd; i++) - sc->num_descs = sc->num_descs * 2; - - value = drvmgr_dev_key_get(sc->dev, "txDescs", DRVMGR_KT_INT); - if ( value && (value->i <= sc->num_descs) ) - sc->txbufs = value->i; - - value = drvmgr_dev_key_get(sc->dev, "rxDescs", DRVMGR_KT_INT); - if ( value && (value->i <= sc->num_descs) ) - 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 -- cgit v1.2.3