source: rtems/c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h @ 0a8f902e

4.104.115
Last change on this file since 0a8f902e was 0a8f902e, checked in by Till Straumann <strauman@…>, on 10/17/09 at 22:24:55

2009-10-17 Till Straumann <strauman@…>

*network/if_tsec_pub.h, network/tsec.c: Enhanced low-level
API allowing the user to selectively enable/disable/acknowledge
interrupts and to install their own ISR (rather than having
the driver posting an event to a single task).

  • Property mode set to 100644
File size: 15.3 KB
Line 
1#ifndef IF_TSEC_PUBLIC_INTERFACE_H
2#define IF_TSEC_PUBLIC_INTERFACE_H
3
4/*
5 * Authorship
6 * ----------
7 * This software ('mvme3100' RTEMS BSP) was created by
8 *
9 *     Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
10 *         Stanford Linear Accelerator Center, Stanford University.
11 *
12 * Acknowledgement of sponsorship
13 * ------------------------------
14 * The 'mvme3100' BSP was produced by
15 *     the Stanford Linear Accelerator Center, Stanford University,
16 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
17 *
18 * Government disclaimer of liability
19 * ----------------------------------
20 * Neither the United States nor the United States Department of Energy,
21 * nor any of their employees, makes any warranty, express or implied, or
22 * assumes any legal liability or responsibility for the accuracy,
23 * completeness, or usefulness of any data, apparatus, product, or process
24 * disclosed, or represents that its use would not infringe privately owned
25 * rights.
26 *
27 * Stanford disclaimer of liability
28 * --------------------------------
29 * Stanford University makes no representations or warranties, express or
30 * implied, nor assumes any liability for the use of this software.
31 *
32 * Stanford disclaimer of copyright
33 * --------------------------------
34 * Stanford University, owner of the copyright, hereby disclaims its
35 * copyright and all other rights in this software.  Hence, anyone may
36 * freely use it for any purpose without restriction. 
37 *
38 * Maintenance of notices
39 * ----------------------
40 * In the interest of clarity regarding the origin and status of this
41 * SLAC software, this and all the preceding Stanford University notices
42 * are to remain affixed to any copy or derivative of this software made
43 * or distributed by the recipient and are to be affixed to any copy of
44 * software made or distributed by the recipient that contains a copy or
45 * derivative of this software.
46 *
47 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
48 */
49
50#include <rtems.h>
51#include <stdio.h>
52#include <stdint.h>
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58/* Opaque driver handle */
59struct tsec_private;
60
61/********** Low-level Driver API ****************/
62
63/*
64 * This API provides driver access to applications that
65 * want to use e.g., the second ethernet interface
66 * independently from the BSD TCP/IP stack. E.g., for
67 * raw ethernet packet communication...
68 */
69
70#define TSEC_TXIRQ ( (1<<(31-9)) | (1<<(31-11))                )
71#define TSEC_RXIRQ ( (1<<(31-0)) | (1<<(31- 3)) | (1<<(31-24)) )
72#define TSEC_LKIRQ (  1<<(31- 4)                               )
73/*
74 * Setup an interface.
75 * Allocates resources for descriptor rings and sets up the driver software structure.
76 *
77 * Arguments:
78 *      unit:
79 *              interface # (1..2). The interface must not be attached to BSD already.
80 *
81 *  driver_tid:
82 *              ISR posts RTEMS event # ('unit' - 1) to task with ID 'driver_tid' and disables interrupts
83 *              from this interface.
84 *
85 *      void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred):
86 *              Pointer to user-supplied callback to release a buffer that had been sent
87 *              by BSP_tsec_send_buf() earlier. The callback is passed 'cleanup_txbuf_arg'
88 *              and a flag indicating whether the send had been successful.
89 *              The driver no longer accesses 'user_buf' after invoking this callback.
90 *              CONTEXT: This callback is executed either by BSP_tsec_swipe_tx() or
91 *              BSP_tsec_send_buf(), BSP_tsec_init_hw(), BSP_tsec_stop_hw() (the latter
92 *              ones calling BSP_tsec_swipe_tx()).
93 *      void *cleanup_txbuf_arg:
94 *              Closure argument that is passed on to 'cleanup_txbuf()' callback;
95 *
96 *      void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
97 *              Pointer to user-supplied callback to allocate a buffer for subsequent
98 *              insertion into the RX ring by the driver.
99 *              RETURNS: opaque handle to the buffer (which may be a more complex object
100 *                               such as an 'mbuf'). The handle is not used by the driver directly
101 *                               but passed back to the 'consume_rxbuf()' callback.
102 *                               Size of the available data area and pointer to buffer's data area
103 *                               in '*psize' and '*p_data_area', respectively.
104 *                               If no buffer is available, this routine should return NULL in which
105 *                               case the driver drops the last packet and re-uses the last buffer
106 *                               instead of handing it out to 'consume_rxbuf()'.
107 *              CONTEXT: Called when initializing the RX ring (BSP_tsec_init_hw()) or when
108 *                               swiping it (BSP_tsec_swipe_rx()).
109 *             
110 *
111 *      void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len);
112 *              Pointer to user-supplied callback to pass a received buffer back to
113 *              the user. The driver no longer accesses the buffer after invoking this
114 *              callback (with 'len'>0, see below). 'user_buf' is the buffer handle
115 *              previously generated by 'alloc_rxbuf()'.
116 *              The callback is passed 'cleanup_rxbuf_arg' and a 'len'
117 *              argument giving the number of bytes that were received.
118 *              'len' may be <=0 in which case the 'user_buf' argument is NULL.
119 *              'len' == 0 means that the last 'alloc_rxbuf()' had failed,
120 *              'len' < 0 indicates a receiver error. In both cases, the last packet
121 *              was dropped/missed and the last buffer will be re-used by the driver.
122 *              NOTE: the data are 'prefixed' with two bytes, i.e., the ethernet packet header
123 *                    is stored at offset 2 in the buffer's data area. Also, the FCS (4 bytes)
124 *                    is appended. 'len' accounts for both.
125 *              CONTEXT: Called from BSP_tsec_swipe_rx().
126 *      void *cleanup_rxbuf_arg:
127 *              Closure argument that is passed on to 'consume_rxbuf()' callback;
128 *
129 *  rx_ring_size, tx_ring_size:
130 *              How many big to make the RX and TX descriptor rings. Note that the sizes
131 *              may be 0 in which case a reasonable default will be used.
132 *              If either ring size is < 0 then the RX or TX will be disabled.
133 *              Note that it is illegal in this case to use BSP_tsec_swipe_rx() or
134 *              BSP_tsec_swipe_tx(), respectively.
135 *
136 *  irq_mask:
137 *              Interrupts to enable. OR of flags from above.
138 *
139 */
140struct tsec_private *
141BSP_tsec_setup(
142        int              unit,
143        rtems_id driver_tid,
144        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
145        void *   cleanup_txbuf_arg,
146        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
147        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
148        void *   consume_rxbuf_arg,
149        int              rx_ring_size,
150        int              tx_ring_size,
151        int              irq_mask
152);
153
154/*
155 * Alternate 'setup' routine allowing the user to install an ISR rather
156 * than a task ID.
157 * All parameters (other than 'isr' / 'isr_arg') and the return value
158 * are identical to the BSP_tsec_setup() entry point.
159 */
160struct tsec_private *
161BSP_tsec_setup_1(
162        int              unit,
163        void     (*isr)(void *isr_arg),
164        void *   isr_arg,
165        void     (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
166        void *   cleanup_txbuf_arg,
167        void *   (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
168        void     (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
169        void *   consume_rxbuf_arg,
170        int              rx_ring_size,
171        int              tx_ring_size,
172        int              irq_mask
173);
174
175
176/*
177 * Descriptor scavenger; cleanup the TX ring, passing all buffers
178 * that have been sent to the cleanup_tx() callback.
179 * This routine is called from BSP_tsec_send_buf(), BSP_tsec_init_hw(),
180 * BSP_tsec_stop_hw().
181 *
182 * RETURNS: number of buffers processed.
183 */
184
185int
186BSP_tsec_swipe_tx(struct tsec_private *mp);
187
188
189/*
190 * Reset statistics counters.
191 */
192void
193BSP_tsec_reset_stats(struct tsec_private *mp);
194
195/*
196 * Initialize interface hardware
197 *
198 * 'mp'                 handle obtained by from BSP_tsec_setup().
199 * 'promisc'    whether to set promiscuous flag.
200 * 'enaddr'             pointer to six bytes with MAC address. Read
201 *                              from the device if NULL.
202 * NOTE:        multicast filter is cleared by this routine.
203 */
204void
205BSP_tsec_init_hw(struct tsec_private *mp, int promisc, unsigned char *enaddr);
206
207/*
208 * Clear multicast hash filter. No multicast frames are accepted
209 * after executing this routine (unless the hardware was initialized
210 * in 'promiscuous' mode).
211 *
212 * Reset reference count for all hash-table entries
213 * to zero (see BSP_tsec_mcast_filter_accept_del()).
214 */
215void
216BSP_tsec_mcast_filter_clear(struct tsec_private *mp);
217
218/*
219 * Program multicast filter to accept all multicast frames.
220 *
221 * Increment reference count for all hash-table entries
222 * by one (see BSP_tsec_mcast_filter_accept_del()).
223 */
224void
225BSP_tsec_mcast_filter_accept_all(struct tsec_private *mp);
226
227/*
228 * Add a MAC address to the multicast filter and increment
229 * the reference count for the matching hash-table entry
230 * (see BSP_tsec_mcast_filter_accept_del()).
231 *
232 * Existing entries are not changed but note that
233 * the filter is imperfect, i.e., multiple MAC addresses
234 * may alias to a single filter entry. Hence software
235 * filtering must still be performed.
236 *
237 */
238void
239BSP_tsec_mcast_filter_accept_add(struct tsec_private *mp, unsigned char *enaddr);
240
241/*
242 * Remove a MAC address from the (imperfec) multicast
243 * filter.
244 * Note that the driver maintains an internal reference
245 * counter for each multicast hash. The hash-table
246 * entry is only cleared when the reference count
247 * reaches zero ('del' has been called the same
248 * amount of times as 'add' for an address (or
249 * any alias) that matches a given table entry.
250 * BSP_tsec_mcast_filter_clear() resets all reference
251 * counters to zero.
252 */
253void
254BSP_tsec_mcast_filter_accept_del(struct tsec_private *mp, unsigned char *enaddr);
255
256/*
257 * Dump statistics to FILE 'f'. If NULL, stdout is used.
258 */
259void
260BSP_tsec_dump_stats(struct tsec_private *mp, FILE *f);
261
262/*
263 * Shutdown hardware and clean out the rings
264 */
265void
266BSP_tsec_stop_hw(struct tsec_private *mp);
267
268/*
269 * calls BSP_tsec_stop_hw(), releases all resources and marks the interface
270 * as unused.
271 * RETURNS 0 on success, nonzero on failure.
272 * NOTE:   the handle MUST NOT be used after successful execution of this
273 *         routine.
274 */
275int
276BSP_tsec_detach(struct tsec_private *mp);
277
278/*
279 * Enqueue a mbuf chain or a raw data buffer for transmission;
280 * RETURN: #bytes sent or -1 if there are not enough free descriptors
281 *
282 * If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain.
283 * OTOH, a raw data packet (or a different type of buffer)
284 * may be sent (non-BSD driver) by pointing data_p to the start of
285 * the data and passing 'len' > 0.
286 * 'm_head' is passed back to the 'cleanup_txbuf()' callback.
287 *
288 * Comments: software cache-flushing incurs a penalty if the
289 *           packet cannot be queued since it is flushed anyways.
290 *           The algorithm is slightly more efficient in the normal
291 *                       case, though.
292 *
293 * RETURNS: # bytes enqueued to device for transmission or -1 if no
294 *          space in the TX ring was available.
295 */
296
297int
298BSP_tsec_send_buf(struct tsec_private *mp, void *m_head, void *data_p, int len);
299
300/*
301 * Retrieve all received buffers from the RX ring, replacing them
302 * by fresh ones (obtained from the alloc_rxbuf() callback). The
303 * received buffers are passed to consume_rxbuf().
304 *
305 * RETURNS: number of buffers processed.
306 */
307int
308BSP_tsec_swipe_rx(struct tsec_private *mp);
309
310/* read ethernet address from hw to buffer */
311void
312BSP_tsec_read_eaddr(struct tsec_private *mp, unsigned char *eaddr);
313
314/* Read MII register */
315uint32_t
316BSP_tsec_mdio_rd(struct tsec_private *mp, unsigned reg);
317
318/* Write MII register */
319int
320BSP_tsec_mdio_wr(struct tsec_private *mp, unsigned reg, uint32_t val);
321
322/*
323 * read/write media word.
324 *   'cmd': can be SIOCGIFMEDIA, SIOCSIFMEDIA, 0 or 1. The latter
325 *          are aliased to the former for convenience.
326 *  'parg': pointer to media word.
327 *
328 * RETURNS: 0 on success, nonzero on error
329 */
330int
331BSP_tsec_media_ioctl(struct tsec_private *mp, int cmd, int *parg);
332
333/* Interrupt related routines */
334
335/*
336 * When it comes to interrupts the chip has two rather
337 * annoying features:
338 *   1 once an IRQ is pending, clearing the IMASK does not
339 *     de-assert the interrupt line.
340 *   2 the chip has three physical interrupt lines even though
341 *     all events are reported in a single register. Rather
342 *     useless; we must hook 3 ISRs w/o any real benefit.
343 *     In fact, it makes our life a bit more difficult:
344 *
345 * Hence, for (1) we would have to mask interrupts at the PIC
346 * but to re-enable them we would have to do that three times
347 * because of (2).
348 *
349 * Therefore, we take the following approach:
350 *
351 *   ISR masks all interrupts on the TSEC, acks/clears them
352 *   and stores the acked irqs in the device struct where
353 *   it is picked up by BSP_tsec_ack_irqs().
354 *   Since all interrupts are disabled until the daemon
355 *   re-enables them after calling BSP_tsec_ack_irqs()
356 *   no interrupts are lost.
357 *
358 * BUT:  NO isr (including PHY isrs) MUST INTERRUPT ANY
359 *       OTHER ONE, i.e., they all must have the same
360 *       priority. Otherwise, integrity of the cached
361 *       irq_pending variable may be compromised.
362 */
363
364/* Note: the BSP_tsec_enable/disable/ack_irqs() entry points
365 *       are deprecated.
366 *       The newer API where the user passes a mask allows
367 *       for more selective control.
368 */
369
370/* Enable interrupts at device */
371void
372BSP_tsec_enable_irqs(struct tsec_private *mp);
373
374/* Disable interrupts at device */
375void
376BSP_tsec_disable_irqs(struct tsec_private *mp);
377
378/*
379 * Acknowledge (and clear) interrupts.
380 * RETURNS: interrupts that were raised.
381 */
382uint32_t
383BSP_tsec_ack_irqs(struct tsec_private *mp);
384
385/* Enable interrupts included in 'mask' (leaving
386 * already enabled interrupts on). If the mask includes
387 * bits that were not passed to the 'setup' routine then
388 * the behavior is undefined.
389 */
390void
391BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
392
393/* Disable interrupts included in 'mask' (leaving
394 * other ones that are currently enabled on). If the mask
395 * includes bits that were not passed to the 'setup' routine
396 * then the behavior is undefined.
397
398 * RETURNS: Bitmask of interrupts that were enabled upon entry
399 *          into this routine. This can be used to restore the previous
400 *          state.
401 */
402uint32_t
403BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t irq_mask);
404
405/* Acknowledge and clear selected interrupts.
406 *
407 * RETURNS: All pending interrupts.
408 *
409 * NOTE:    Only pending interrupts contained in 'mask'
410 *          are cleared. Others are left pending.
411 *
412 *          This routine can be used to check for pending
413 *          interrupts (pass mask ==  0) or to clear all
414 *          interrupts (pass mask == -1).
415 */
416uint32_t
417BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask);
418
419
420/* Retrieve the driver daemon TID that was passed to
421 * BSP_tsec_setup().
422 */
423
424rtems_id
425BSP_tsec_get_tid(struct tsec_private *mp);
426
427struct tsec_private *
428BSP_tsec_getp(unsigned index);
429
430/*
431 *
432 * Example driver task loop (note: no synchronization of
433 * buffer access shown!).
434 * RTEMS_EVENTx = 0,1 or 2 depending on IF unit.
435 *
436 *    / * setup (obtain handle) and initialize hw here * /
437 *
438 *    do {
439 *      / * ISR disables IRQs and posts event * /
440 *              rtems_event_receive( RTEMS_EVENTx, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs );
441 *              irqs = BSP_tsec_ack_irqs(handle);
442 *      if ( irqs & BSP_TSEC_IRQ_TX ) {
443 *                      BSP_tsec_swipe_tx(handle); / * cleanup_txbuf() callback executed * /
444 *              }
445 *      if ( irqs & BSP_TSEC_IRQ_RX ) {
446 *                      BSP_tsec_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * /
447 *              }
448 *              BSP_tsec_enable_irqs(handle);
449 *    } while (1);
450 *
451 */
452
453/* PUBLIC RTEMS BSDNET ATTACH FUNCTION */
454struct rtems_bsdnet_ifconfig;
455
456int
457rtems_tsec_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching);
458
459#ifdef __cplusplus
460}
461#endif
462
463#endif
Note: See TracBrowser for help on using the repository browser.