#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); /* * 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