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