1 /* $Id: xemacps_bd.h,v 1.1.2.1 2011/01/20 03:39:02 sadanan Exp $ */
2 /******************************************************************************
4 * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * Use of the Software is limited solely to applications:
17 * (a) running on a Xilinx device, or
18 * (b) that interact with a Xilinx device through a bus or interconnect.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 * Except as contained in this notice, the name of the Xilinx shall not be used
29 * in advertising or otherwise to promote the sale, use or other dealings in
30 * this Software without prior written authorization from Xilinx.
32 ******************************************************************************/
33 /*****************************************************************************/
37 * @addtogroup emacps_v2_0
40 * This header provides operations to manage buffer descriptors in support
41 * of scatter-gather DMA.
43 * The API exported by this header defines abstracted macros that allow the
44 * user to read/write specific BD fields.
46 * <b>Buffer Descriptors</b>
48 * A buffer descriptor (BD) defines a DMA transaction. The macros defined by
49 * this header file allow access to most fields within a BD to tailor a DMA
50 * transaction according to user and hardware requirements. See the hardware
51 * IP DMA spec for more information on BD fields and how they affect transfers.
53 * The XEmacPs_Bd structure defines a BD. The organization of this structure
54 * is driven mainly by the hardware for use in scatter-gather DMA transfers.
58 * Limiting I/O to BDs can improve overall performance of the DMA channel.
61 * MODIFICATION HISTORY:
63 * Ver Who Date Changes
64 * ----- ---- -------- -------------------------------------------------------
65 * 1.00a wsy 01/10/10 First release
68 * ***************************************************************************
71 #ifndef XEMACPS_BD_H /* prevent circular inclusions */
72 #define XEMACPS_BD_H /* by using protection macros */
78 /***************************** Include Files *********************************/
81 #include "xil_types.h"
82 #include "xil_assert.h"
84 /************************** Constant Definitions *****************************/
86 /**************************** Type Definitions *******************************/
88 /* Minimum BD alignment */
89 #define XEMACPS_DMABD_MINIMUM_ALIGNMENT 4
92 * The XEmacPs_Bd is the type for buffer descriptors (BDs).
94 #define XEMACPS_BD_NUM_WORDS 2
95 typedef u32 XEmacPs_Bd[XEMACPS_BD_NUM_WORDS];
98 /***************** Macros (Inline Functions) Definitions *********************/
100 /*****************************************************************************/
104 * @param BdPtr is the BD pointer to operate on
110 * void XEmacPs_BdClear(XEmacPs_Bd* BdPtr)
112 *****************************************************************************/
113 #define XEmacPs_BdClear(BdPtr) \
114 memset((BdPtr), 0, sizeof(XEmacPs_Bd))
116 /****************************************************************************/
119 * Read the given Buffer Descriptor word.
121 * @param BaseAddress is the base address of the BD to read
122 * @param Offset is the word offset to be read
124 * @return The 32-bit value of the field
128 * u32 XEmacPs_BdRead(u32 BaseAddress, u32 Offset)
130 *****************************************************************************/
131 #define XEmacPs_BdRead(BaseAddress, Offset) \
132 (*(u32*)((u32)(BaseAddress) + (u32)(Offset)))
134 /****************************************************************************/
137 * Write the given Buffer Descriptor word.
139 * @param BaseAddress is the base address of the BD to write
140 * @param Offset is the word offset to be written
141 * @param Data is the 32-bit value to write to the field
147 * void XEmacPs_BdWrite(u32 BaseAddress, u32 Offset, u32 Data)
149 *****************************************************************************/
150 #define XEmacPs_BdWrite(BaseAddress, Offset, Data) \
151 (*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
153 /*****************************************************************************/
155 * Set the BD's Address field (word 0).
157 * @param BdPtr is the BD pointer to operate on
158 * @param Addr is the value to write to BD's status field.
163 * void XEmacPs_BdSetAddressTx(XEmacPs_Bd* BdPtr, u32 Addr)
165 *****************************************************************************/
166 #define XEmacPs_BdSetAddressTx(BdPtr, Addr) \
167 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, (u32)(Addr)))
170 /*****************************************************************************/
172 * Set the BD's Address field (word 0).
174 * @param BdPtr is the BD pointer to operate on
175 * @param Addr is the value to write to BD's status field.
177 * @note : Due to some bits are mixed within recevie BD's address field,
178 * read-modify-write is performed.
181 * void XEmacPs_BdSetAddressRx(XEmacPs_Bd* BdPtr, u32 Addr)
183 *****************************************************************************/
184 #define XEmacPs_BdSetAddressRx(BdPtr, Addr) \
185 XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
186 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
187 ~XEMACPS_RXBUF_ADD_MASK) | (u32)(Addr)))
190 /*****************************************************************************/
192 * Set the BD's Status field (word 1).
194 * @param BdPtr is the BD pointer to operate on
195 * @param Data is the value to write to BD's status field.
199 * void XEmacPs_BdSetStatus(XEmacPs_Bd* BdPtr, u32 Data)
201 *****************************************************************************/
202 #define XEmacPs_BdSetStatus(BdPtr, Data) \
203 XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
204 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | Data)
207 /*****************************************************************************/
209 * Retrieve the BD's Packet DMA transfer status word (word 1).
211 * @param BdPtr is the BD pointer to operate on
213 * @return Status word
217 * u32 XEmacPs_BdGetStatus(XEmacPs_Bd* BdPtr)
219 * Due to the BD bit layout differences in transmit and receive. User's
220 * caution is required.
221 *****************************************************************************/
222 #define XEmacPs_BdGetStatus(BdPtr) \
223 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET)
226 /*****************************************************************************/
228 * Get the address (bits 0..31) of the BD's buffer address (word 0)
230 * @param BdPtr is the BD pointer to operate on
234 * u32 XEmacPs_BdGetBufAddr(XEmacPs_Bd* BdPtr)
236 *****************************************************************************/
237 #define XEmacPs_BdGetBufAddr(BdPtr) \
238 (XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET))
241 /*****************************************************************************/
243 * Set transfer length in bytes for the given BD. The length must be set each
244 * time a BD is submitted to hardware.
246 * @param BdPtr is the BD pointer to operate on
247 * @param LenBytes is the number of bytes to transfer.
251 * void XEmacPs_BdSetLength(XEmacPs_Bd* BdPtr, u32 LenBytes)
253 *****************************************************************************/
254 #define XEmacPs_BdSetLength(BdPtr, LenBytes) \
255 XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
256 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
257 ~XEMACPS_TXBUF_LEN_MASK) | (LenBytes)))
260 /*****************************************************************************/
262 * Retrieve the BD length field.
264 * For Tx channels, the returned value is the same as that written with
265 * XEmacPs_BdSetLength().
267 * For Rx channels, the returned value is the size of the received packet.
269 * @param BdPtr is the BD pointer to operate on
271 * @return Length field processed by hardware or set by
272 * XEmacPs_BdSetLength().
276 * u32 XEmacPs_BdGetLength(XEmacPs_Bd* BdPtr)
277 * XEAMCPS_RXBUF_LEN_MASK is same as XEMACPS_TXBUF_LEN_MASK.
279 *****************************************************************************/
280 #define XEmacPs_BdGetLength(BdPtr) \
281 (XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
282 XEMACPS_RXBUF_LEN_MASK)
285 /*****************************************************************************/
287 * Test whether the given BD has been marked as the last BD of a packet.
289 * @param BdPtr is the BD pointer to operate on
291 * @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
295 * u32 XEmacPs_BdIsLast(XEmacPs_Bd* BdPtr)
297 *****************************************************************************/
298 #define XEmacPs_BdIsLast(BdPtr) \
299 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
300 XEMACPS_RXBUF_EOF_MASK) ? TRUE : FALSE)
303 /*****************************************************************************/
305 * Tell the DMA engine that the given transmit BD marks the end of the current
306 * packet to be processed.
308 * @param BdPtr is the BD pointer to operate on
312 * void XEmacPs_BdSetLast(XEmacPs_Bd* BdPtr)
314 *****************************************************************************/
315 #define XEmacPs_BdSetLast(BdPtr) \
316 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
317 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
318 XEMACPS_TXBUF_LAST_MASK))
321 /*****************************************************************************/
323 * Tell the DMA engine that the current packet does not end with the given
326 * @param BdPtr is the BD pointer to operate on
330 * void XEmacPs_BdClearLast(XEmacPs_Bd* BdPtr)
332 *****************************************************************************/
333 #define XEmacPs_BdClearLast(BdPtr) \
334 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
335 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
336 ~XEMACPS_TXBUF_LAST_MASK))
339 /*****************************************************************************/
341 * Set this bit to mark the last descriptor in the receive buffer descriptor
344 * @param BdPtr is the BD pointer to operate on
348 * void XEmacPs_BdSetRxWrap(XEmacPs_Bd* BdPtr)
350 *****************************************************************************/
351 #define XEmacPs_BdSetRxWrap(BdPtr) \
352 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
353 XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
354 XEMACPS_RXBUF_WRAP_MASK))
357 /*****************************************************************************/
359 * Determine the wrap bit of the receive BD which indicates end of the
362 * @param BdPtr is the BD pointer to operate on
366 * u32 XEmacPs_BdIsRxWrap(XEmacPs_Bd* BdPtr)
368 *****************************************************************************/
369 #define XEmacPs_BdIsRxWrap(BdPtr) \
370 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
371 XEMACPS_RXBUF_WRAP_MASK) ? TRUE : FALSE)
374 /*****************************************************************************/
376 * Sets this bit to mark the last descriptor in the transmit buffer
379 * @param BdPtr is the BD pointer to operate on
383 * void XEmacPs_BdSetTxWrap(XEmacPs_Bd* BdPtr)
385 *****************************************************************************/
386 #define XEmacPs_BdSetTxWrap(BdPtr) \
387 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
388 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
389 XEMACPS_TXBUF_WRAP_MASK))
392 /*****************************************************************************/
394 * Determine the wrap bit of the transmit BD which indicates end of the
397 * @param BdPtr is the BD pointer to operate on
401 * u32 XEmacPs_BdGetTxWrap(XEmacPs_Bd* BdPtr)
403 *****************************************************************************/
404 #define XEmacPs_BdIsTxWrap(BdPtr) \
405 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
406 XEMACPS_TXBUF_WRAP_MASK) ? TRUE : FALSE)
409 /*****************************************************************************/
411 * Must clear this bit to enable the MAC to write data to the receive
412 * buffer. Hardware sets this bit once it has successfully written a frame to
413 * memory. Once set, software has to clear the bit before the buffer can be
414 * used again. This macro clear the new bit of the receive BD.
416 * @param BdPtr is the BD pointer to operate on
420 * void XEmacPs_BdClearRxNew(XEmacPs_Bd* BdPtr)
422 *****************************************************************************/
423 #define XEmacPs_BdClearRxNew(BdPtr) \
424 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
425 XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
426 ~XEMACPS_RXBUF_NEW_MASK))
429 /*****************************************************************************/
431 * Determine the new bit of the receive BD.
433 * @param BdPtr is the BD pointer to operate on
437 * u32 XEmacPs_BdIsRxNew(XEmacPs_Bd* BdPtr)
439 *****************************************************************************/
440 #define XEmacPs_BdIsRxNew(BdPtr) \
441 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
442 XEMACPS_RXBUF_NEW_MASK) ? TRUE : FALSE)
445 /*****************************************************************************/
447 * Software sets this bit to disable the buffer to be read by the hardware.
448 * Hardware sets this bit for the first buffer of a frame once it has been
449 * successfully transmitted. This macro sets this bit of transmit BD to avoid
452 * @param BdPtr is the BD pointer to operate on
456 * void XEmacPs_BdSetTxUsed(XEmacPs_Bd* BdPtr)
458 *****************************************************************************/
459 #define XEmacPs_BdSetTxUsed(BdPtr) \
460 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
461 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
462 XEMACPS_TXBUF_USED_MASK))
465 /*****************************************************************************/
467 * Software clears this bit to enable the buffer to be read by the hardware.
468 * Hardware sets this bit for the first buffer of a frame once it has been
469 * successfully transmitted. This macro clears this bit of transmit BD.
471 * @param BdPtr is the BD pointer to operate on
475 * void XEmacPs_BdClearTxUsed(XEmacPs_Bd* BdPtr)
477 *****************************************************************************/
478 #define XEmacPs_BdClearTxUsed(BdPtr) \
479 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
480 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
481 ~XEMACPS_TXBUF_USED_MASK))
484 /*****************************************************************************/
486 * Determine the used bit of the transmit BD.
488 * @param BdPtr is the BD pointer to operate on
492 * u32 XEmacPs_BdIsTxUsed(XEmacPs_Bd* BdPtr)
494 *****************************************************************************/
495 #define XEmacPs_BdIsTxUsed(BdPtr) \
496 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
497 XEMACPS_TXBUF_USED_MASK) ? TRUE : FALSE)
500 /*****************************************************************************/
502 * Determine if a frame fails to be transmitted due to too many retries.
504 * @param BdPtr is the BD pointer to operate on
508 * u32 XEmacPs_BdIsTxRetry(XEmacPs_Bd* BdPtr)
510 *****************************************************************************/
511 #define XEmacPs_BdIsTxRetry(BdPtr) \
512 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
513 XEMACPS_TXBUF_RETRY_MASK) ? TRUE : FALSE)
516 /*****************************************************************************/
518 * Determine if a frame fails to be transmitted due to data can not be
519 * feteched in time or buffers are exhausted.
521 * @param BdPtr is the BD pointer to operate on
525 * u32 XEmacPs_BdIsTxUrun(XEmacPs_Bd* BdPtr)
527 *****************************************************************************/
528 #define XEmacPs_BdIsTxUrun(BdPtr) \
529 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
530 XEMACPS_TXBUF_URUN_MASK) ? TRUE : FALSE)
533 /*****************************************************************************/
535 * Determine if a frame fails to be transmitted due to buffer is exhausted
538 * @param BdPtr is the BD pointer to operate on
542 * u32 XEmacPs_BdIsTxExh(XEmacPs_Bd* BdPtr)
544 *****************************************************************************/
545 #define XEmacPs_BdIsTxExh(BdPtr) \
546 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
547 XEMACPS_TXBUF_EXH_MASK) ? TRUE : FALSE)
550 /*****************************************************************************/
552 * Sets this bit, no CRC will be appended to the current frame. This control
553 * bit must be set for the first buffer in a frame and will be ignored for
554 * the subsequent buffers of a frame.
556 * @param BdPtr is the BD pointer to operate on
559 * This bit must be clear when using the transmit checksum generation offload,
560 * otherwise checksum generation and substitution will not occur.
563 * u32 XEmacPs_BdSetTxNoCRC(XEmacPs_Bd* BdPtr)
565 *****************************************************************************/
566 #define XEmacPs_BdSetTxNoCRC(BdPtr) \
567 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
568 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
569 XEMACPS_TXBUF_NOCRC_MASK))
572 /*****************************************************************************/
574 * Clear this bit, CRC will be appended to the current frame. This control
575 * bit must be set for the first buffer in a frame and will be ignored for
576 * the subsequent buffers of a frame.
578 * @param BdPtr is the BD pointer to operate on
581 * This bit must be clear when using the transmit checksum generation offload,
582 * otherwise checksum generation and substitution will not occur.
585 * u32 XEmacPs_BdClearTxNoCRC(XEmacPs_Bd* BdPtr)
587 *****************************************************************************/
588 #define XEmacPs_BdClearTxNoCRC(BdPtr) \
589 (XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
590 XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
591 ~XEMACPS_TXBUF_NOCRC_MASK))
594 /*****************************************************************************/
596 * Determine the broadcast bit of the receive BD.
598 * @param BdPtr is the BD pointer to operate on
602 * u32 XEmacPs_BdIsRxBcast(XEmacPs_Bd* BdPtr)
604 *****************************************************************************/
605 #define XEmacPs_BdIsRxBcast(BdPtr) \
606 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
607 XEMACPS_RXBUF_BCAST_MASK) ? TRUE : FALSE)
610 /*****************************************************************************/
612 * Determine the multicast hash bit of the receive BD.
614 * @param BdPtr is the BD pointer to operate on
618 * u32 XEmacPs_BdIsRxMultiHash(XEmacPs_Bd* BdPtr)
620 *****************************************************************************/
621 #define XEmacPs_BdIsRxMultiHash(BdPtr) \
622 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
623 XEMACPS_RXBUF_MULTIHASH_MASK) ? TRUE : FALSE)
626 /*****************************************************************************/
628 * Determine the unicast hash bit of the receive BD.
630 * @param BdPtr is the BD pointer to operate on
634 * u32 XEmacPs_BdIsRxUniHash(XEmacPs_Bd* BdPtr)
636 *****************************************************************************/
637 #define XEmacPs_BdIsRxUniHash(BdPtr) \
638 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
639 XEMACPS_RXBUF_UNIHASH_MASK) ? TRUE : FALSE)
642 /*****************************************************************************/
644 * Determine if the received frame is a VLAN Tagged frame.
646 * @param BdPtr is the BD pointer to operate on
650 * u32 XEmacPs_BdIsRxVlan(XEmacPs_Bd* BdPtr)
652 *****************************************************************************/
653 #define XEmacPs_BdIsRxVlan(BdPtr) \
654 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
655 XEMACPS_RXBUF_VLAN_MASK) ? TRUE : FALSE)
658 /*****************************************************************************/
660 * Determine if the received frame has Type ID of 8100h and null VLAN
661 * identifier(Priority tag).
663 * @param BdPtr is the BD pointer to operate on
667 * u32 XEmacPs_BdIsRxPri(XEmacPs_Bd* BdPtr)
669 *****************************************************************************/
670 #define XEmacPs_BdIsRxPri(BdPtr) \
671 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
672 XEMACPS_RXBUF_PRI_MASK) ? TRUE : FALSE)
675 /*****************************************************************************/
677 * Determine if the received frame's Concatenation Format Indicator (CFI) of
678 * the frames VLANTCI field was set.
680 * @param BdPtr is the BD pointer to operate on
684 * u32 XEmacPs_BdIsRxCFI(XEmacPs_Bd* BdPtr)
686 *****************************************************************************/
687 #define XEmacPs_BdIsRxCFI(BdPtr) \
688 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
689 XEMACPS_RXBUF_CFI_MASK) ? TRUE : FALSE)
692 /*****************************************************************************/
694 * Determine the End Of Frame (EOF) bit of the receive BD.
696 * @param BdPtr is the BD pointer to operate on
700 * u32 XEmacPs_BdGetRxEOF(XEmacPs_Bd* BdPtr)
702 *****************************************************************************/
703 #define XEmacPs_BdIsRxEOF(BdPtr) \
704 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
705 XEMACPS_RXBUF_EOF_MASK) ? TRUE : FALSE)
708 /*****************************************************************************/
710 * Determine the Start Of Frame (SOF) bit of the receive BD.
712 * @param BdPtr is the BD pointer to operate on
716 * u32 XEmacPs_BdGetRxSOF(XEmacPs_Bd* BdPtr)
718 *****************************************************************************/
719 #define XEmacPs_BdIsRxSOF(BdPtr) \
720 ((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
721 XEMACPS_RXBUF_SOF_MASK) ? TRUE : FALSE)
724 /************************** Function Prototypes ******************************/
730 #endif /* end of protection macro */