![]() |
|
|||
File indexing completed on 2025-05-11 08:23:56
0001 /** 0002 * @file 0003 * 0004 * @ingroup powerpc_iftsecpub 0005 * 0006 * @brief IF_TSEC_PUB Support 0007 */ 0008 0009 #ifndef IF_TSEC_PUBLIC_INTERFACE_H 0010 #define IF_TSEC_PUBLIC_INTERFACE_H 0011 0012 /* 0013 * Authorship 0014 * ---------- 0015 * This software ('mvme3100' RTEMS BSP) was created by 0016 * 0017 * Till Straumann <strauman@slac.stanford.edu>, 2005-2007, 0018 * Stanford Linear Accelerator Center, Stanford University. 0019 * 0020 * Acknowledgement of sponsorship 0021 * ------------------------------ 0022 * The 'mvme3100' BSP was produced by 0023 * the Stanford Linear Accelerator Center, Stanford University, 0024 * under Contract DE-AC03-76SFO0515 with the Department of Energy. 0025 * 0026 * Government disclaimer of liability 0027 * ---------------------------------- 0028 * Neither the United States nor the United States Department of Energy, 0029 * nor any of their employees, makes any warranty, express or implied, or 0030 * assumes any legal liability or responsibility for the accuracy, 0031 * completeness, or usefulness of any data, apparatus, product, or process 0032 * disclosed, or represents that its use would not infringe privately owned 0033 * rights. 0034 * 0035 * Stanford disclaimer of liability 0036 * -------------------------------- 0037 * Stanford University makes no representations or warranties, express or 0038 * implied, nor assumes any liability for the use of this software. 0039 * 0040 * Stanford disclaimer of copyright 0041 * -------------------------------- 0042 * Stanford University, owner of the copyright, hereby disclaims its 0043 * copyright and all other rights in this software. Hence, anyone may 0044 * freely use it for any purpose without restriction. 0045 * 0046 * Maintenance of notices 0047 * ---------------------- 0048 * In the interest of clarity regarding the origin and status of this 0049 * SLAC software, this and all the preceding Stanford University notices 0050 * are to remain affixed to any copy or derivative of this software made 0051 * or distributed by the recipient and are to be affixed to any copy of 0052 * software made or distributed by the recipient that contains a copy or 0053 * derivative of this software. 0054 * 0055 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 0056 */ 0057 0058 #include <rtems.h> 0059 #include <stdio.h> 0060 #include <stdint.h> 0061 0062 #ifdef __cplusplus 0063 extern "C" { 0064 #endif 0065 0066 /* Opaque driver handle */ 0067 struct tsec_private; 0068 0069 /********** Low-level Driver API ****************/ 0070 0071 /** 0072 * @defgroup powerpc_iftsecpub Low-level Driver API 0073 * 0074 * @ingroup RTEMSBSPsPowerPCMVME3100 0075 * 0076 * @brief This API provides driver access to applications that 0077 * want to use e.g., the second ethernet interface 0078 * independently from the BSD TCP/IP stack. E.g., for 0079 * raw ethernet packet communication... 0080 */ 0081 0082 #define TSEC_TXIRQ ( (1<<(31-9)) | (1<<(31-11)) ) 0083 #define TSEC_RXIRQ ( (1<<(31-0)) | (1<<(31- 3)) | (1<<(31-24)) ) 0084 #define TSEC_LKIRQ ( 1<<(31- 4) ) 0085 /* 0086 * Setup an interface. 0087 * Allocates resources for descriptor rings and sets up the driver software structure. 0088 * 0089 * Arguments: 0090 * unit: 0091 * interface # (1..2). The interface must not be attached to BSD already. 0092 * 0093 * driver_tid: 0094 * ISR posts RTEMS event # ('unit' - 1) to task with ID 'driver_tid' and disables interrupts 0095 * from this interface. 0096 * 0097 * void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred): 0098 * Pointer to user-supplied callback to release a buffer that had been sent 0099 * by BSP_tsec_send_buf() earlier. The callback is passed 'cleanup_txbuf_arg' 0100 * and a flag indicating whether the send had been successful. 0101 * The driver no longer accesses 'user_buf' after invoking this callback. 0102 * CONTEXT: This callback is executed either by BSP_tsec_swipe_tx() or 0103 * BSP_tsec_send_buf(), BSP_tsec_init_hw(), BSP_tsec_stop_hw() (the latter 0104 * ones calling BSP_tsec_swipe_tx()). 0105 * void *cleanup_txbuf_arg: 0106 * Closure argument that is passed on to 'cleanup_txbuf()' callback; 0107 * 0108 * void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr), 0109 * Pointer to user-supplied callback to allocate a buffer for subsequent 0110 * insertion into the RX ring by the driver. 0111 * RETURNS: opaque handle to the buffer (which may be a more complex object 0112 * such as an 'mbuf'). The handle is not used by the driver directly 0113 * but passed back to the 'consume_rxbuf()' callback. 0114 * Size of the available data area and pointer to buffer's data area 0115 * in '*psize' and '*p_data_area', respectively. 0116 * If no buffer is available, this routine should return NULL in which 0117 * case the driver drops the last packet and re-uses the last buffer 0118 * instead of handing it out to 'consume_rxbuf()'. 0119 * CONTEXT: Called when initializing the RX ring (BSP_tsec_init_hw()) or when 0120 * swiping it (BSP_tsec_swipe_rx()). 0121 * 0122 * 0123 * void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len); 0124 * Pointer to user-supplied callback to pass a received buffer back to 0125 * the user. The driver no longer accesses the buffer after invoking this 0126 * callback (with 'len'>0, see below). 'user_buf' is the buffer handle 0127 * previously generated by 'alloc_rxbuf()'. 0128 * The callback is passed 'cleanup_rxbuf_arg' and a 'len' 0129 * argument giving the number of bytes that were received. 0130 * 'len' may be <=0 in which case the 'user_buf' argument is NULL. 0131 * 'len' == 0 means that the last 'alloc_rxbuf()' had failed, 0132 * 'len' < 0 indicates a receiver error. In both cases, the last packet 0133 * was dropped/missed and the last buffer will be re-used by the driver. 0134 * NOTE: the data are 'prefixed' with two bytes, i.e., the ethernet packet header 0135 * is stored at offset 2 in the buffer's data area. Also, the FCS (4 bytes) 0136 * is appended. 'len' accounts for both. 0137 * CONTEXT: Called from BSP_tsec_swipe_rx(). 0138 * void *cleanup_rxbuf_arg: 0139 * Closure argument that is passed on to 'consume_rxbuf()' callback; 0140 * 0141 * rx_ring_size, tx_ring_size: 0142 * How many big to make the RX and TX descriptor rings. Note that the sizes 0143 * may be 0 in which case a reasonable default will be used. 0144 * If either ring size is < 0 then the RX or TX will be disabled. 0145 * Note that it is illegal in this case to use BSP_tsec_swipe_rx() or 0146 * BSP_tsec_swipe_tx(), respectively. 0147 * 0148 * irq_mask: 0149 * Interrupts to enable. OR of flags from above. 0150 * 0151 */ 0152 struct tsec_private * 0153 BSP_tsec_setup( 0154 int unit, 0155 rtems_id driver_tid, 0156 void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred), 0157 void * cleanup_txbuf_arg, 0158 void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr), 0159 void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len), 0160 void * consume_rxbuf_arg, 0161 int rx_ring_size, 0162 int tx_ring_size, 0163 int irq_mask 0164 ); 0165 0166 /* 0167 * Alternate 'setup' routine allowing the user to install an ISR rather 0168 * than a task ID. 0169 * All parameters (other than 'isr' / 'isr_arg') and the return value 0170 * are identical to the BSP_tsec_setup() entry point. 0171 */ 0172 struct tsec_private * 0173 BSP_tsec_setup_1( 0174 int unit, 0175 void (*isr)(void *isr_arg), 0176 void * isr_arg, 0177 void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred), 0178 void * cleanup_txbuf_arg, 0179 void * (*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr), 0180 void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len), 0181 void * consume_rxbuf_arg, 0182 int rx_ring_size, 0183 int tx_ring_size, 0184 int irq_mask 0185 ); 0186 0187 0188 /* 0189 * Descriptor scavenger; cleanup the TX ring, passing all buffers 0190 * that have been sent to the cleanup_tx() callback. 0191 * This routine is called from BSP_tsec_send_buf(), BSP_tsec_init_hw(), 0192 * BSP_tsec_stop_hw(). 0193 * 0194 * RETURNS: number of buffers processed. 0195 */ 0196 0197 int 0198 BSP_tsec_swipe_tx(struct tsec_private *mp); 0199 0200 0201 /* 0202 * Reset statistics counters. 0203 */ 0204 void 0205 BSP_tsec_reset_stats(struct tsec_private *mp); 0206 0207 /* 0208 * Initialize interface hardware 0209 * 0210 * 'mp' handle obtained by from BSP_tsec_setup(). 0211 * 'promisc' whether to set promiscuous flag. 0212 * 'enaddr' pointer to six bytes with MAC address. Read 0213 * from the device if NULL. 0214 * NOTE: multicast filter is cleared by this routine. 0215 */ 0216 void 0217 BSP_tsec_init_hw(struct tsec_private *mp, int promisc, unsigned char *enaddr); 0218 0219 /* 0220 * Clear multicast hash filter. No multicast frames are accepted 0221 * after executing this routine (unless the hardware was initialized 0222 * in 'promiscuous' mode). 0223 * 0224 * Reset reference count for all hash-table entries 0225 * to zero (see BSP_tsec_mcast_filter_accept_del()). 0226 */ 0227 void 0228 BSP_tsec_mcast_filter_clear(struct tsec_private *mp); 0229 0230 /* 0231 * Program multicast filter to accept all multicast frames. 0232 * 0233 * Increment reference count for all hash-table entries 0234 * by one (see BSP_tsec_mcast_filter_accept_del()). 0235 */ 0236 void 0237 BSP_tsec_mcast_filter_accept_all(struct tsec_private *mp); 0238 0239 /* 0240 * Add a MAC address to the multicast filter and increment 0241 * the reference count for the matching hash-table entry 0242 * (see BSP_tsec_mcast_filter_accept_del()). 0243 * 0244 * Existing entries are not changed but note that 0245 * the filter is imperfect, i.e., multiple MAC addresses 0246 * may alias to a single filter entry. Hence software 0247 * filtering must still be performed. 0248 * 0249 */ 0250 void 0251 BSP_tsec_mcast_filter_accept_add(struct tsec_private *mp, unsigned char *enaddr); 0252 0253 /* 0254 * Remove a MAC address from the (imperfec) multicast 0255 * filter. 0256 * Note that the driver maintains an internal reference 0257 * counter for each multicast hash. The hash-table 0258 * entry is only cleared when the reference count 0259 * reaches zero ('del' has been called the same 0260 * amount of times as 'add' for an address (or 0261 * any alias) that matches a given table entry. 0262 * BSP_tsec_mcast_filter_clear() resets all reference 0263 * counters to zero. 0264 */ 0265 void 0266 BSP_tsec_mcast_filter_accept_del(struct tsec_private *mp, unsigned char *enaddr); 0267 0268 /* 0269 * Dump statistics to FILE 'f'. If NULL, stdout is used. 0270 */ 0271 void 0272 BSP_tsec_dump_stats(struct tsec_private *mp, FILE *f); 0273 0274 /* 0275 * Shutdown hardware and clean out the rings 0276 */ 0277 void 0278 BSP_tsec_stop_hw(struct tsec_private *mp); 0279 0280 /* 0281 * calls BSP_tsec_stop_hw(), releases all resources and marks the interface 0282 * as unused. 0283 * RETURNS 0 on success, nonzero on failure. 0284 * NOTE: the handle MUST NOT be used after successful execution of this 0285 * routine. 0286 */ 0287 int 0288 BSP_tsec_detach(struct tsec_private *mp); 0289 0290 /* 0291 * Enqueue a mbuf chain or a raw data buffer for transmission; 0292 * RETURN: #bytes sent or -1 if there are not enough free descriptors 0293 * 0294 * If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain. 0295 * OTOH, a raw data packet (or a different type of buffer) 0296 * may be sent (non-BSD driver) by pointing data_p to the start of 0297 * the data and passing 'len' > 0. 0298 * 'm_head' is passed back to the 'cleanup_txbuf()' callback. 0299 * 0300 * Comments: software cache-flushing incurs a penalty if the 0301 * packet cannot be queued since it is flushed anyways. 0302 * The algorithm is slightly more efficient in the normal 0303 * case, though. 0304 * 0305 * RETURNS: # bytes enqueued to device for transmission or -1 if no 0306 * space in the TX ring was available. 0307 */ 0308 0309 int 0310 BSP_tsec_send_buf(struct tsec_private *mp, void *m_head, void *data_p, int len); 0311 0312 /* 0313 * Retrieve all received buffers from the RX ring, replacing them 0314 * by fresh ones (obtained from the alloc_rxbuf() callback). The 0315 * received buffers are passed to consume_rxbuf(). 0316 * 0317 * RETURNS: number of buffers processed. 0318 */ 0319 int 0320 BSP_tsec_swipe_rx(struct tsec_private *mp); 0321 0322 /* read ethernet address from hw to buffer */ 0323 void 0324 BSP_tsec_read_eaddr(struct tsec_private *mp, unsigned char *eaddr); 0325 0326 /* Read MII register */ 0327 uint32_t 0328 BSP_tsec_mdio_rd(struct tsec_private *mp, unsigned reg); 0329 0330 /* Write MII register */ 0331 int 0332 BSP_tsec_mdio_wr(struct tsec_private *mp, unsigned reg, uint32_t val); 0333 0334 /* 0335 * read/write media word. 0336 * 'cmd': can be SIOCGIFMEDIA, SIOCSIFMEDIA, 0 or 1. The latter 0337 * are aliased to the former for convenience. 0338 * 'parg': pointer to media word. 0339 * 0340 * RETURNS: 0 on success, nonzero on error 0341 */ 0342 int 0343 BSP_tsec_media_ioctl(struct tsec_private *mp, int cmd, int *parg); 0344 0345 /* Interrupt related routines */ 0346 0347 /* 0348 * When it comes to interrupts the chip has two rather 0349 * annoying features: 0350 * 1 once an IRQ is pending, clearing the IMASK does not 0351 * de-assert the interrupt line. 0352 * 2 the chip has three physical interrupt lines even though 0353 * all events are reported in a single register. Rather 0354 * useless; we must hook 3 ISRs w/o any real benefit. 0355 * In fact, it makes our life a bit more difficult: 0356 * 0357 * Hence, for (1) we would have to mask interrupts at the PIC 0358 * but to re-enable them we would have to do that three times 0359 * because of (2). 0360 * 0361 * Therefore, we take the following approach: 0362 * 0363 * ISR masks all interrupts on the TSEC, acks/clears them 0364 * and stores the acked irqs in the device struct where 0365 * it is picked up by BSP_tsec_ack_irqs(). 0366 * Since all interrupts are disabled until the daemon 0367 * re-enables them after calling BSP_tsec_ack_irqs() 0368 * no interrupts are lost. 0369 * 0370 * BUT: NO isr (including PHY isrs) MUST INTERRUPT ANY 0371 * OTHER ONE, i.e., they all must have the same 0372 * priority. Otherwise, integrity of the cached 0373 * irq_pending variable may be compromised. 0374 */ 0375 0376 /* Note: the BSP_tsec_enable/disable/ack_irqs() entry points 0377 * are deprecated. 0378 * The newer API where the user passes a mask allows 0379 * for more selective control. 0380 */ 0381 0382 /* Enable interrupts at device */ 0383 void 0384 BSP_tsec_enable_irqs(struct tsec_private *mp); 0385 0386 /* Disable interrupts at device */ 0387 void 0388 BSP_tsec_disable_irqs(struct tsec_private *mp); 0389 0390 /* 0391 * Acknowledge (and clear) interrupts. 0392 * RETURNS: interrupts that were raised. 0393 */ 0394 uint32_t 0395 BSP_tsec_ack_irqs(struct tsec_private *mp); 0396 0397 /* Enable interrupts included in 'mask' (leaving 0398 * already enabled interrupts on). If the mask includes 0399 * bits that were not passed to the 'setup' routine then 0400 * the behavior is undefined. 0401 */ 0402 void 0403 BSP_tsec_enable_irq_mask(struct tsec_private *mp, uint32_t irq_mask); 0404 0405 /* Disable interrupts included in 'mask' (leaving 0406 * other ones that are currently enabled on). If the mask 0407 * includes bits that were not passed to the 'setup' routine 0408 * then the behavior is undefined. 0409 0410 * RETURNS: Bitmask of interrupts that were enabled upon entry 0411 * into this routine. This can be used to restore the previous 0412 * state. 0413 */ 0414 uint32_t 0415 BSP_tsec_disable_irq_mask(struct tsec_private *mp, uint32_t irq_mask); 0416 0417 /* Acknowledge and clear selected interrupts. 0418 * 0419 * RETURNS: All pending interrupts. 0420 * 0421 * NOTE: Only pending interrupts contained in 'mask' 0422 * are cleared. Others are left pending. 0423 * 0424 * This routine can be used to check for pending 0425 * interrupts (pass mask == 0) or to clear all 0426 * interrupts (pass mask == -1). 0427 */ 0428 uint32_t 0429 BSP_tsec_ack_irq_mask(struct tsec_private *mp, uint32_t mask); 0430 0431 0432 /* Retrieve the driver daemon TID that was passed to 0433 * BSP_tsec_setup(). 0434 */ 0435 0436 rtems_id 0437 BSP_tsec_get_tid(struct tsec_private *mp); 0438 0439 struct tsec_private * 0440 BSP_tsec_getp(unsigned index); 0441 0442 /* 0443 * 0444 * Example driver task loop (note: no synchronization of 0445 * buffer access shown!). 0446 * RTEMS_EVENTx = 0,1 or 2 depending on IF unit. 0447 * 0448 * / * setup (obtain handle) and initialize hw here * / 0449 * 0450 * do { 0451 * / * ISR disables IRQs and posts event * / 0452 * rtems_event_receive( RTEMS_EVENTx, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs ); 0453 * irqs = BSP_tsec_ack_irqs(handle); 0454 * if ( irqs & BSP_TSEC_IRQ_TX ) { 0455 * BSP_tsec_swipe_tx(handle); / * cleanup_txbuf() callback executed * / 0456 * } 0457 * if ( irqs & BSP_TSEC_IRQ_RX ) { 0458 * BSP_tsec_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * / 0459 * } 0460 * BSP_tsec_enable_irqs(handle); 0461 * } while (1); 0462 * 0463 */ 0464 0465 /* PUBLIC RTEMS BSDNET ATTACH FUNCTION */ 0466 struct rtems_bsdnet_ifconfig; 0467 0468 int 0469 rtems_tsec_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching); 0470 0471 #ifdef __cplusplus 0472 } 0473 #endif 0474 0475 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |