]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
d741a2a0a96c038ce58f56578a18868a39b5c8f2
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / ATSAM4E / gmac.h
1  /**
2  * \file
3  *
4  * \brief GMAC (Ethernet MAC) driver for SAM.
5  *
6  * Copyright (c) 2013 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43
44 #ifndef GMAC_H_INCLUDED
45 #define GMAC_H_INCLUDED
46
47 #include "compiler.h"
48
49 /// @cond 0
50 /**INDENT-OFF**/
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54 /**INDENT-ON**/
55 /// @endcond
56
57 /** The buffer addresses written into the descriptors must be aligned, so the
58     last few bits are zero.  These bits have special meaning for the GMAC
59     peripheral and cannot be used as part of the address. */
60 #define GMAC_RXD_ADDR_MASK      0xFFFFFFFC
61 #define GMAC_RXD_WRAP         (1ul << 1)  /**< Wrap bit */
62 #define GMAC_RXD_OWNERSHIP    (1ul << 0)  /**< Ownership bit */
63
64 #define GMAC_RXD_BROADCAST    (1ul << 31) /**< Broadcast detected */
65 #define GMAC_RXD_MULTIHASH    (1ul << 30) /**< Multicast hash match */
66 #define GMAC_RXD_UNIHASH      (1ul << 29) /**< Unicast hash match */
67 #define GMAC_RXD_ADDR_FOUND      (1ul << 27) /**< Specific address match found */
68 #define GMAC_RXD_ADDR        (3ul << 25) /**< Address match */
69 #define GMAC_RXD_RXCOEN        (1ul << 24) /**< RXCOEN related function */
70 #define GMAC_RXD_TYPE         (3ul << 22) /**< Type ID match */
71 #define GMAC_RXD_VLAN         (1ul << 21) /**< VLAN tag detected */
72 #define GMAC_RXD_PRIORITY     (1ul << 20) /**< Priority tag detected */
73 #define GMAC_RXD_PRIORITY_MASK  (3ul << 17) /**< VLAN priority */
74 #define GMAC_RXD_CFI          (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
75 #define GMAC_RXD_EOF          (1ul << 15) /**< End of frame */
76 #define GMAC_RXD_SOF          (1ul << 14) /**< Start of frame */
77 #define GMAC_RXD_FCS          (1ul << 13) /**< Frame check sequence */
78 #define GMAC_RXD_OFFSET_MASK                /**< Receive buffer offset */
79 #define GMAC_RXD_LEN_MASK       (0xFFF)     /**< Length of frame including FCS (if selected) */
80 #define GMAC_RXD_LENJUMBO_MASK  (0x3FFF)    /**< Jumbo frame length */
81
82 #define GMAC_TXD_USED         (1ul << 31) /**< Frame is transmitted */
83 #define GMAC_TXD_WRAP         (1ul << 30) /**< Last descriptor */
84 #define GMAC_TXD_ERROR        (1ul << 29) /**< Retry limit exceeded, error */
85 #define GMAC_TXD_UNDERRUN     (1ul << 28) /**< Transmit underrun */
86 #define GMAC_TXD_EXHAUSTED    (1ul << 27) /**< Buffer exhausted */
87 #define GMAC_TXD_LATE    (1ul << 26) /**< Late collision,transmit  error  */
88 #define GMAC_TXD_CHECKSUM_ERROR   (7ul << 20) /**< Checksum error */
89 #define GMAC_TXD_NOCRC        (1ul << 16) /**< No CRC */
90 #define GMAC_TXD_LAST         (1ul << 15) /**< Last buffer in frame */
91 #define GMAC_TXD_LEN_MASK       (0x1FFF)     /**< Length of buffer */
92
93 /** The MAC can support frame lengths up to 1536 bytes */
94 #define GMAC_FRAME_LENTGH_MAX       1536
95
96 #define GMAC_RX_UNITSIZE            128     /**< Fixed size for RX buffer  */
97 #define GMAC_TX_UNITSIZE            1518    /**< Size for ETH frame length */
98
99 /** GMAC clock speed */
100 #define GMAC_MCK_SPEED_240MHZ        (240*1000*1000)
101 #define GMAC_MCK_SPEED_160MHZ        (160*1000*1000)
102 #define GMAC_MCK_SPEED_120MHZ        (120*1000*1000)
103 #define GMAC_MCK_SPEED_80MHZ          (80*1000*1000)
104 #define GMAC_MCK_SPEED_40MHZ          (40*1000*1000)
105 #define GMAC_MCK_SPEED_20MHZ          (20*1000*1000)
106
107 /** GMAC maintain code default value*/
108 #define GMAC_MAN_CODE_VALUE    (10)
109
110 /** GMAC maintain start of frame default value*/
111 #define GMAC_MAN_SOF_VALUE     (1)
112
113 /** GMAC maintain read/write*/
114 #define GMAC_MAN_RW_TYPE       (2)
115
116 /** GMAC maintain read only*/
117 #define GMAC_MAN_READ_ONLY     (1)
118
119 /** GMAC address length */
120 #define GMAC_ADDR_LENGTH       (6)
121
122
123 #define GMAC_DUPLEX_HALF 0
124 #define GMAC_DUPLEX_FULL 1
125
126 #define GMAC_SPEED_10M      0
127 #define GMAC_SPEED_100M     1
128
129 /**
130  * \brief Return codes for GMAC APIs.
131  */
132 typedef enum {
133         GMAC_OK = 0,         /** 0  Operation OK */
134         GMAC_TIMEOUT = 1,    /** 1  GMAC operation timeout */
135         GMAC_TX_BUSY,        /** 2  TX in progress */
136         GMAC_RX_NULL,        /** 3  No data received */
137         GMAC_SIZE_TOO_SMALL, /** 4  Buffer size not enough */
138         GMAC_PARAM,          /** 5  Parameter error, TX packet invalid or RX size too small */
139         GMAC_INVALID = 0xFF, /* Invalid */
140 } gmac_status_t;
141
142 /**
143  * \brief Media Independent Interface (MII) type.
144  */
145 typedef enum {
146         GMAC_PHY_MII = 0,         /** MII mode */
147         GMAC_PHY_RMII = 1,    /** Reduced MII mode */
148         GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
149 } gmac_mii_mode_t;
150
151 /** Receive buffer descriptor struct */
152 COMPILER_PACK_SET(8)
153 typedef struct gmac_rx_descriptor {
154         union gmac_rx_addr {
155                 uint32_t val;
156                 struct gmac_rx_addr_bm {
157                         uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
158                         b_wrap:1,   /**< Marks last descriptor in receive buffer */
159                         addr_dw:30; /**< Address in number of DW */
160                 } bm;
161         } addr; /**< Address, Wrap & Ownership */
162         union gmac_rx_status {
163                 uint32_t val;
164                 struct gmac_rx_status_bm {
165                         uint32_t len:13,       /**  0..12  Length of frame including FCS */
166                         b_fcs:1,               /**  13     Receive buffer offset,  bits 13:12 of frame length for jumbo frame */
167                         b_sof:1,               /**  14     Start of frame */
168                         b_eof:1,               /**  15     End of frame */
169                         b_cfi:1,               /**  16     Concatenation Format Indicator */
170                         vlan_priority:3,       /**  17..19 VLAN priority (if VLAN detected) */
171                         b_priority_detected:1, /**  20     Priority tag detected */
172                         b_vlan_detected:1,     /**  21     VLAN tag detected */
173                         b_type_id_match:2,     /**  22..23 Type ID match */
174                         b_checksumoffload:1,   /**  24     Checksum offload specific function */
175                         b_addrmatch:2,         /**  25..26 Address register match */
176                         b_ext_addr_match:1,    /**  27     External address match found */
177                         reserved:1,            /**  28     */
178                         b_uni_hash_match:1,    /**  29     Unicast hash match */
179                         b_multi_hash_match:1,  /**  30     Multicast hash match */
180                         b_boardcast_detect:1;  /**  31     Global broadcast address detected */
181                 } bm;
182         } status;
183 } gmac_rx_descriptor_t;
184
185 /** Transmit buffer descriptor struct */
186 COMPILER_PACK_SET(8)
187 typedef struct gmac_tx_descriptor {
188         uint32_t addr;
189         union gmac_tx_status {
190                 uint32_t val;
191                 struct gmac_tx_status_bm {
192                         uint32_t len:14,     /**  0..13 Length of buffer */
193                         reserved:1,          /** 14            */
194                         b_last_buffer:1,     /** 15     Last buffer (in the current frame) */
195                         b_no_crc:1,          /** 16     No CRC */
196                         reserved1:3,         /** 17..19        */
197                         b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
198                         reserved2:3,         /** 23..25        */
199                         b_lco:1,             /** 26     Late collision, transmit error detected */
200                         b_exhausted:1,       /** 27     Buffer exhausted in mid frame */
201                         b_underrun:1,        /** 28     Transmit underrun */
202                         b_error:1,           /** 29     Retry limit exceeded, error detected */
203                         b_wrap:1,            /** 30     Marks last descriptor in TD list */
204                         b_used:1;            /** 31     User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
205                 } bm;
206         } status;
207 } gmac_tx_descriptor_t;
208
209 COMPILER_PACK_RESET()
210
211 /**
212  * \brief Input parameters when initializing the gmac module mode.
213  */
214 typedef struct gmac_options {
215         /*  Enable/Disable CopyAllFrame */
216         uint8_t uc_copy_all_frame;
217         /* Enable/Disable NoBroadCast */
218         uint8_t uc_no_boardcast;
219         /* MAC address */
220         uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
221 } gmac_options_t;
222
223 /** RX callback */
224 typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
225 /** Wakeup callback */
226 typedef void (*gmac_dev_wakeup_cb_t) (void);
227
228 /**
229  * GMAC driver structure.
230  */
231 typedef struct gmac_device {
232
233         /** Pointer to HW register base */
234         Gmac *p_hw;
235         /**
236          * Pointer to allocated TX buffer.
237          * Section 3.6 of AMBA 2.0 spec states that burst should not cross
238          * 1K Boundaries.
239          * Receive buffer manager writes are burst of 2 words => 3 lsb bits
240          * of the address shall be set to 0.
241          */
242         uint8_t *p_tx_buffer;
243         /** Pointer to allocated RX buffer */
244         uint8_t *p_rx_buffer;
245         /** Pointer to Rx TDs (must be 8-byte aligned) */
246         gmac_rx_descriptor_t *p_rx_dscr;
247         /** Pointer to Tx TDs (must be 8-byte aligned) */
248         gmac_tx_descriptor_t *p_tx_dscr;
249         /** Optional callback to be invoked once a frame has been received */
250         gmac_dev_tx_cb_t func_rx_cb;
251 #if( GMAC_USES_WAKEUP_CALLBACK )
252         /** Optional callback to be invoked once several TDs have been released */
253         gmac_dev_wakeup_cb_t func_wakeup_cb;
254 #endif
255 #if( GMAC_USES_TX_CALLBACK != 0 )
256         /** Optional callback list to be invoked once TD has been processed */
257         gmac_dev_tx_cb_t *func_tx_cb_list;
258 #endif
259         /** RX TD list size */
260         uint32_t ul_rx_list_size;
261         /** RX index for current processing TD */
262         uint32_t ul_rx_idx;
263         /** TX TD list size */
264         uint32_t ul_tx_list_size;
265         /** Circular buffer head pointer by upper layer (buffer to be sent) */
266         int32_t l_tx_head;
267         /** Circular buffer tail pointer incremented by handlers (buffer sent) */
268         int32_t l_tx_tail;
269
270         /** Number of free TD before wakeup callback is invoked */
271         uint32_t uc_wakeup_threshold;
272 } gmac_device_t;
273
274 /**
275  * \brief Write network control value.
276  *
277  * \param p_gmac   Pointer to the GMAC instance.
278  * \param ul_ncr   Network control value.
279  */
280 static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
281 {
282         p_gmac->GMAC_NCR = ul_ncr;
283 }
284
285 /**
286  * \brief Get network control value.
287  *
288  * \param p_gmac   Pointer to the GMAC instance.
289  */
290
291 static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
292 {
293         return p_gmac->GMAC_NCR;
294 }
295
296 /**
297  * \brief Enable/Disable GMAC receive.
298  *
299  * \param p_gmac   Pointer to the GMAC instance.
300  * \param uc_enable   0 to disable GMAC receiver, else to enable it.
301  */
302 static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
303 {
304         if (uc_enable) {
305                 p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
306         } else {
307                 p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
308         }
309 }
310
311 /**
312  * \brief Enable/Disable GMAC transmit.
313  *
314  * \param p_gmac   Pointer to the GMAC instance.
315  * \param uc_enable   0 to disable GMAC transmit, else to enable it.
316  */
317 static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
318 {
319         if (uc_enable) {
320                 p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
321         } else {
322                 p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
323         }
324 }
325
326 /**
327  * \brief Enable/Disable GMAC management.
328  *
329  * \param p_gmac   Pointer to the GMAC instance.
330  * \param uc_enable   0 to disable GMAC management, else to enable it.
331  */
332 static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
333 {
334         if (uc_enable) {
335                 p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
336         } else {
337                 p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
338         }
339 }
340
341 /**
342  * \brief Clear all statistics registers.
343  *
344  * \param p_gmac   Pointer to the GMAC instance.
345  */
346 static inline void gmac_clear_statistics(Gmac* p_gmac)
347 {
348         p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
349 }
350
351 /**
352  * \brief Increase all statistics registers.
353  *
354  * \param p_gmac   Pointer to the GMAC instance.
355  */
356 static inline void gmac_increase_statistics(Gmac* p_gmac)
357 {
358         p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
359 }
360
361 /**
362  * \brief Enable/Disable statistics registers writing.
363  *
364  * \param p_gmac   Pointer to the GMAC instance.
365  * \param uc_enable   0 to disable the statistics registers writing, else to enable it.
366  */
367 static inline void gmac_enable_statistics_write(Gmac* p_gmac,
368                 uint8_t uc_enable)
369 {
370         if (uc_enable) {
371                 p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
372         } else {
373                 p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
374         }
375 }
376
377 /**
378  * \brief In half-duplex mode, forces collisions on all received frames.
379  *
380  * \param p_gmac   Pointer to the GMAC instance.
381  * \param uc_enable   0 to disable the back pressure, else to enable it.
382  */
383 static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
384 {
385         if (uc_enable) {
386                 p_gmac->GMAC_NCR |= GMAC_NCR_BP;
387         } else {
388                 p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
389         }
390 }
391
392 /**
393  * \brief Start transmission.
394  *
395  * \param p_gmac   Pointer to the GMAC instance.
396  */
397 static inline void gmac_start_transmission(Gmac* p_gmac)
398 {
399         p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
400 }
401
402 /**
403  * \brief Halt transmission.
404  *
405  * \param p_gmac   Pointer to the GMAC instance.
406  */
407 static inline void gmac_halt_transmission(Gmac* p_gmac)
408 {
409         p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
410 }
411
412 /**
413  * \brief Transmit pause frame.
414  *
415  * \param p_gmac   Pointer to the GMAC instance.
416  */
417 static inline void gmac_tx_pause_frame(Gmac* p_gmac)
418 {
419         p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
420 }
421
422 /**
423  * \brief Transmit zero quantum pause frame.
424  *
425  * \param p_gmac   Pointer to the GMAC instance.
426  */
427 static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
428 {
429         p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
430 }
431
432 /**
433  * \brief Read snapshot.
434  *
435  * \param p_gmac   Pointer to the GMAC instance.
436  */
437 static inline void gmac_read_snapshot(Gmac* p_gmac)
438 {
439         p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
440 }
441
442 /**
443  * \brief Store receivetime stamp to memory.
444  *
445  * \param p_gmac   Pointer to the GMAC instance.
446  * \param uc_enable   0 to normal operation, else to enable the store.
447  */
448 static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
449 {
450         if (uc_enable) {
451                 p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
452         } else {
453                 p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
454         }
455 }
456
457 /**
458  * \brief Enable PFC priority-based pause reception.
459  *
460  * \param p_gmac   Pointer to the GMAC instance.
461  * \param uc_enable   1 to set the reception, 0 to disable.
462  */
463 static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
464 {
465         if (uc_enable) {
466                 p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
467         } else {
468                 p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
469         }
470 }
471
472 /**
473  * \brief Transmit PFC priority-based pause reception.
474  *
475  * \param p_gmac   Pointer to the GMAC instance.
476  */
477 static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
478 {
479                 p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
480 }
481
482 /**
483  * \brief Flush next packet.
484  *
485  * \param p_gmac   Pointer to the GMAC instance.
486  */
487 static inline void gmac_flush_next_packet(Gmac* p_gmac)
488 {
489                 p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
490 }
491
492 /**
493  * \brief Set up network configuration register.
494  *
495  * \param p_gmac   Pointer to the GMAC instance.
496   * \param ul_cfg   Network configuration value.
497  */
498 static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
499 {
500         p_gmac->GMAC_NCFGR = ul_cfg;
501 }
502
503 /**
504  * \brief Get network configuration.
505  *
506  * \param p_gmac   Pointer to the GMAC instance.
507  *
508  * \return Network configuration.
509  */
510 static inline uint32_t gmac_get_configure(Gmac* p_gmac)
511 {
512         return p_gmac->GMAC_NCFGR;
513 }
514
515
516 /* Get and set DMA Configuration Register */
517 static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
518 {
519         p_gmac->GMAC_DCFGR = ul_cfg;
520 }
521
522 static inline uint32_t gmac_get_dma(Gmac* p_gmac)
523 {
524         return p_gmac->GMAC_DCFGR;
525 }
526
527 /**
528  * \brief Set speed.
529  *
530  * \param p_gmac   Pointer to the GMAC instance.
531  * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
532  */
533 static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
534 {
535         if (uc_speed) {
536                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
537         } else {
538                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
539         }
540 }
541
542 /**
543  * \brief Enable/Disable Full-Duplex mode.
544  *
545  * \param p_gmac   Pointer to the GMAC instance.
546  * \param uc_enable   0 to disable the Full-Duplex mode, else to enable it.
547  */
548 static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
549 {
550         if (uc_enable) {
551                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
552         } else {
553                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
554         }
555 }
556
557 /**
558  * \brief Enable/Disable Copy(Receive) All Valid Frames.
559  *
560  * \param p_gmac   Pointer to the GMAC instance.
561  * \param uc_enable   0 to disable copying all valid frames, else to enable it.
562  */
563 static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
564 {
565         if (uc_enable) {
566                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
567         } else {
568                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
569         }
570 }
571
572 /**
573  * \brief Enable/Disable jumbo frames (up to 10240 bytes).
574  *
575  * \param p_gmac   Pointer to the GMAC instance.
576  * \param uc_enable   0 to disable the jumbo frames, else to enable it.
577  */
578 static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
579 {
580         if (uc_enable) {
581                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
582         } else {
583                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
584         }
585 }
586
587 /**
588  * \brief Disable/Enable broadcast receiving.
589  *
590  * \param p_gmac   Pointer to the GMAC instance.
591  * \param uc_enable   1 to disable the broadcast, else to enable it.
592  */
593 static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
594 {
595         if (uc_enable) {
596                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
597         } else {
598                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
599         }
600 }
601
602 /**
603  * \brief Enable/Disable multicast hash.
604  *
605  * \param p_gmac   Pointer to the GMAC instance.
606  * \param uc_enable   0 to disable the multicast hash, else to enable it.
607  */
608 static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
609 {
610         if (uc_enable) {
611                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
612         } else {
613                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
614         }
615 }
616
617 /**
618  * \brief Enable/Disable big frames (over 1518, up to 1536).
619  *
620  * \param p_gmac   Pointer to the GMAC instance.
621  * \param uc_enable   0 to disable big frames else to enable it.
622  */
623 static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
624 {
625         if (uc_enable) {
626                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
627         } else {
628                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
629         }
630 }
631
632 /**
633  * \brief Set MDC clock divider.
634  *
635  * \param p_gmac   Pointer to the GMAC instance.
636  * \param ul_mck   GMAC MCK.
637  *
638  * \return GMAC_OK if successfully.
639  */
640 static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
641 {
642         uint32_t ul_clk;
643         
644         if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
645                 return GMAC_INVALID;
646         } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
647                 ul_clk = GMAC_NCFGR_CLK_MCK_96;
648         } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
649                 ul_clk = GMAC_NCFGR_CLK_MCK_64;
650         } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
651                 ul_clk = GMAC_NCFGR_CLK_MCK_48;
652         } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
653                 ul_clk = GMAC_NCFGR_CLK_MCK_32;
654         } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
655                 ul_clk = GMAC_NCFGR_CLK_MCK_16;
656         } else {
657                 ul_clk = GMAC_NCFGR_CLK_MCK_8;
658         }
659         ;
660         p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
661         return GMAC_OK;
662 }
663
664 /**
665  * \brief Enable/Disable retry test.
666  *
667  * \param p_gmac   Pointer to the GMAC instance.
668  * \param uc_enable   0 to disable the GMAC receiver, else to enable it.
669  */
670 static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
671 {
672         if (uc_enable) {
673                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
674         } else {
675                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
676         }
677 }
678
679 /**
680  * \brief Enable/Disable pause (when a valid pause frame is received).
681  *
682  * \param p_gmac   Pointer to the GMAC instance.
683  * \param uc_enable   0 to disable pause frame, else to enable it.
684  */
685 static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
686 {
687         if (uc_enable) {
688                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
689         } else {
690                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
691         }
692 }
693
694 /**
695  * \brief Set receive buffer offset to 0 ~ 3.
696  *
697  * \param p_gmac   Pointer to the GMAC instance.
698  */
699 static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
700 {
701         p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
702         p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
703 }
704
705 /**
706  * \brief Enable/Disable receive length field checking.
707  *
708  * \param p_gmac   Pointer to the GMAC instance.
709  * \param uc_enable   0 to disable receive length field checking, else to enable it.
710  */
711 static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
712 {
713         if (uc_enable) {
714                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
715         } else {
716                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
717         }
718 }
719
720 /**
721  * \brief Enable/Disable discarding FCS field of received frames.
722  *
723  * \param p_gmac   Pointer to the GMAC instance.
724  * \param uc_enable   0 to disable discarding FCS field of received frames, else to enable it.
725  */
726 static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
727 {
728         if (uc_enable) {
729                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
730         } else {
731                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
732         }
733 }
734
735
736 /**
737  * \brief Enable/Disable frames to be received in half-duplex mode
738  * while transmitting.
739  *
740  * \param p_gmac   Pointer to the GMAC instance.
741  * \param uc_enable   0 to disable the received in half-duplex mode, else to enable it.
742  */
743 static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
744 {
745         if (uc_enable) {
746                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
747         } else {
748                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
749         }
750 }
751
752 /**
753  * \brief Enable/Disable ignore RX FCS.
754  *
755  * \param p_gmac   Pointer to the GMAC instance.
756  * \param uc_enable   0 to disable ignore RX FCS, else to enable it.
757  */
758 static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
759 {
760         if (uc_enable) {
761                 p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
762         } else {
763                 p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
764         }
765 }
766
767 /**
768  * \brief Get Network Status.
769  *
770  * \param p_gmac   Pointer to the GMAC instance.
771  *
772  * \return Network status.
773  */
774 static inline uint32_t gmac_get_status(Gmac* p_gmac)
775 {
776         return p_gmac->GMAC_NSR;
777 }
778
779 /**
780  * \brief Get MDIO IN pin status.
781  *
782  * \param p_gmac   Pointer to the GMAC instance.
783  *
784  * \return MDIO IN pin status.
785  */
786 static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
787 {
788         return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
789 }
790
791 /**
792  * \brief Check if PHY is idle.
793  *
794  * \param p_gmac   Pointer to the GMAC instance.
795  *
796  * \return  1 if PHY is idle.
797  */
798 static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
799 {
800         return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
801 }
802
803 /**
804  * \brief Return transmit status.
805  *
806  * \param p_gmac   Pointer to the GMAC instance.
807  *
808  * \return  Transmit status.
809  */
810 static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
811 {
812         return p_gmac->GMAC_TSR;
813 }
814
815 /**
816  * \brief Clear transmit status.
817  *
818  * \param p_gmac   Pointer to the GMAC instance.
819  * \param ul_status   Transmit status.
820  */
821 static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
822 {
823         p_gmac->GMAC_TSR = ul_status;
824 }
825
826 /**
827  * \brief Return receive status.
828  *
829  * \param p_gmac   Pointer to the GMAC instance.
830  */
831 static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
832 {
833         return p_gmac->GMAC_RSR;
834 }
835
836 /**
837  * \brief Clear receive status.
838  *
839  * \param p_gmac   Pointer to the GMAC instance.
840  * \param ul_status   Receive status.
841  */
842 static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
843 {
844         p_gmac->GMAC_RSR = ul_status;
845 }
846
847 /**
848  * \brief Set Rx Queue.
849  *
850  * \param p_gmac   Pointer to the GMAC instance.
851  * \param ul_addr   Rx queue address.
852  */
853 static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
854 {
855         p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
856 }
857
858 /**
859  * \brief Get Rx Queue Address.
860  *
861  * \param p_gmac   Pointer to the GMAC instance.
862  *
863  * \return  Rx queue address.
864  */
865 static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
866 {
867         return p_gmac->GMAC_RBQB;
868 }
869
870 /**
871  * \brief Set Tx Queue.
872  *
873  * \param p_gmac   Pointer to the GMAC instance.
874  * \param ul_addr  Tx queue address.
875  */
876 static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
877 {
878         p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
879 }
880
881 /**
882  * \brief Get Tx Queue.
883  *
884  * \param p_gmac   Pointer to the GMAC instance.
885  *
886  * \return  Rx queue address.
887  */
888 static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
889 {
890         return p_gmac->GMAC_TBQB;
891 }
892
893 /**
894  * \brief Enable interrupt(s).
895  *
896  * \param p_gmac   Pointer to the GMAC instance.
897  * \param ul_source   Interrupt source(s) to be enabled.
898  */
899 static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
900 {
901         p_gmac->GMAC_IER = ul_source;
902 }
903
904 /**
905  * \brief Disable interrupt(s).
906  *
907  * \param p_gmac   Pointer to the GMAC instance.
908  * \param ul_source   Interrupt source(s) to be disabled.
909  */
910 static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
911 {
912         p_gmac->GMAC_IDR = ul_source;
913 }
914
915 /**
916  * \brief Return interrupt status.
917  *
918  * \param p_gmac   Pointer to the GMAC instance.
919  *
920  * \return Interrupt status.
921  */
922 static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
923 {
924         return p_gmac->GMAC_ISR;
925 }
926
927 /**
928  * \brief Return interrupt mask.
929  *
930  * \param p_gmac   Pointer to the GMAC instance.
931  *
932  * \return Interrupt mask.
933  */
934 static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
935 {
936         return p_gmac->GMAC_IMR;
937 }
938
939 /**
940  * \brief Execute PHY maintenance command.
941  *
942  * \param p_gmac   Pointer to the GMAC instance.
943  * \param uc_phy_addr   PHY address.
944  * \param uc_reg_addr   Register address.
945  * \param uc_rw   1 to Read, 0 to write.
946  * \param us_data   Data to be performed, write only.
947  */
948 static inline void gmac_maintain_phy(Gmac* p_gmac,
949                 uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
950                 uint16_t us_data)
951 {
952         /* Wait until bus idle */
953         while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
954         /* Write maintain register */
955         p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
956                         | GMAC_MAN_CLTTO 
957                         | GMAC_MAN_PHYA(uc_phy_addr)
958                         | GMAC_MAN_REGA(uc_reg_addr)
959                         | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
960                         | GMAC_MAN_DATA(us_data);
961 }
962
963 /**
964  * \brief Get PHY maintenance data returned.
965  *
966  * \param p_gmac   Pointer to the GMAC instance.
967  *
968  * \return Get PHY data.
969  */
970 static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
971 {
972         /* Wait until bus idle */
973         while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
974         /* Return data */
975         return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
976 }
977
978 /**
979  * \brief Set Hash.
980  *
981  * \param p_gmac   Pointer to the GMAC instance.
982  * \param ul_hash_top   Hash top.
983  * \param ul_hash_bottom   Hash bottom.
984  */
985 static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
986                 uint32_t ul_hash_bottom)
987 {
988         p_gmac->GMAC_HRB = ul_hash_bottom;
989         p_gmac->GMAC_HRT = ul_hash_top;
990 }
991
992 /**
993  * \brief Set 64 bits Hash.
994  *
995  * \param p_gmac   Pointer to the GMAC instance.
996  * \param ull_hash   64 bits hash value.
997  */
998 static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
999 {
1000         p_gmac->GMAC_HRB = (uint32_t) ull_hash;
1001         p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
1002 }
1003
1004 /**
1005  * \brief Set MAC Address.
1006  *
1007  * \param p_gmac   Pointer to the GMAC instance.
1008  * \param uc_index  GMAC specific address register index.
1009  * \param p_mac_addr  GMAC address.
1010  */
1011 static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
1012                 uint8_t* p_mac_addr)
1013 {
1014         p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
1015                         | (p_mac_addr[2] << 16)
1016                         | (p_mac_addr[1] << 8)
1017                         | (p_mac_addr[0]);
1018         p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
1019                         | (p_mac_addr[4]);
1020 }
1021
1022 /**
1023  * \brief Set MAC Address via 2 dword.
1024   *
1025  * \param p_gmac   Pointer to the GMAC instance.
1026  * \param uc_index  GMAC specific address register index.
1027  * \param ul_mac_top  GMAC top address.
1028  * \param ul_mac_bottom  GMAC bottom address.
1029  */
1030 static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
1031                 uint32_t ul_mac_top, uint32_t ul_mac_bottom)
1032 {
1033         p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
1034         p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
1035 }
1036
1037 /**
1038  * \brief Set MAC Address via int64.
1039  *
1040  * \param p_gmac   Pointer to the GMAC instance.
1041  * \param uc_index  GMAC specific address register index.
1042  * \param ull_mac  64-bit GMAC address.
1043  */
1044 static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
1045                 uint64_t ull_mac)
1046 {
1047         p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
1048         p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
1049 }
1050
1051 /**
1052  * \brief Select media independent interface mode.
1053  *
1054  * \param p_gmac   Pointer to the GMAC instance.
1055  * \param mode   Media independent interface mode.
1056  */
1057 static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
1058 {
1059         switch (mode) {
1060                 case GMAC_PHY_MII:
1061                 case GMAC_PHY_RMII:
1062                         p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
1063                 break;
1064
1065                 default:
1066                         p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
1067                 break;
1068         }
1069 }
1070
1071 uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
1072                 uint32_t* p_value);
1073 uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
1074                 uint8_t uc_address, uint32_t ul_value);
1075 void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
1076                 gmac_options_t* p_opt);
1077 uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
1078                 uint32_t ul_frame_size, uint32_t* p_rcv_size);
1079 uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
1080                 uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
1081 uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
1082 void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
1083                 gmac_dev_tx_cb_t func_rx_cb);
1084 uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
1085                 gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
1086 void gmac_dev_reset(gmac_device_t* p_gmac_dev);
1087 void gmac_handler(gmac_device_t* p_gmac_dev);
1088
1089 /// @cond 0
1090 /**INDENT-OFF**/
1091 #ifdef __cplusplus
1092 }
1093 #endif
1094 /**INDENT-ON**/
1095 /// @endcond
1096
1097 /**
1098  * \page gmac_quickstart Quickstart guide for GMAC driver.
1099  *
1100  * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
1101  * with step-by-step instructions on how to configure and use the driver in a
1102  * selection of use cases.
1103  *
1104  * The use cases contain several code fragments. The code fragments in the
1105  * steps for setup can be copied into a custom initialization function, while
1106  * the steps for usage can be copied into, e.g., the main application function.
1107  *
1108  * \section gmac_basic_use_case Basic use case
1109  * In the basic use case, the GMAC driver are configured for:
1110  * - PHY component KSZ8051MNL is used
1111  * - GMAC uses MII mode
1112  * - The number of receive buffer is 16
1113  * - The number of transfer buffer is 8
1114  * - MAC address is set to 00-04-25-1c-a0-02
1115  * - IP address is set to 192.168.0.2
1116  * - IP address is set to 192.168.0.2
1117  * - Gateway is set to 192.168.0.1
1118  * - Network mask is 255.255.255.0
1119  * - PHY operation max retry count is 1000000
1120  * - GMAC is configured to not support copy all frame and support broadcast
1121  * - The data will be read from the ethernet
1122  *
1123  * \section gmac_basic_use_case_setup Setup steps
1124  *
1125  * \subsection gmac_basic_use_case_setup_prereq Prerequisites
1126  * -# \ref sysclk_group "System Clock Management (sysclock)"
1127  * -# \ref pmc_group "Power Management Controller (pmc)"
1128  * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
1129  *
1130  * \subsection gmac_basic_use_case_setup_code Example code
1131  * Content of conf_eth.h
1132  * \code
1133  * #define GMAC_RX_BUFFERS                               16
1134  * #define GMAC_TX_BUFFERS                               8
1135  * #define MAC_PHY_RETRY_MAX                             1000000
1136  * #define ETHERNET_CONF_ETHADDR0                        0x00
1137  * #define ETHERNET_CONF_ETHADDR0                        0x00
1138  * #define ETHERNET_CONF_ETHADDR1                        0x04
1139  * #define ETHERNET_CONF_ETHADDR2                        0x25
1140  * #define ETHERNET_CONF_ETHADDR3                        0x1C
1141  * #define ETHERNET_CONF_ETHADDR4                        0xA0
1142  * #define ETHERNET_CONF_ETHADDR5                        0x02
1143  * #define ETHERNET_CONF_IPADDR0                         192
1144  * #define ETHERNET_CONF_IPADDR1                         168
1145  * #define ETHERNET_CONF_IPADDR2                         0
1146  * #define ETHERNET_CONF_IPADDR3                         2
1147  * #define ETHERNET_CONF_GATEWAY_ADDR0                   192
1148  * #define ETHERNET_CONF_GATEWAY_ADDR1                   168
1149  * #define ETHERNET_CONF_GATEWAY_ADDR2                   0
1150  * #define ETHERNET_CONF_GATEWAY_ADDR3                   1
1151  * #define ETHERNET_CONF_NET_MASK0                       255
1152  * #define ETHERNET_CONF_NET_MASK1                       255
1153  * #define ETHERNET_CONF_NET_MASK2                       255
1154  * #define ETHERNET_CONF_NET_MASK3                       0
1155  * #define ETH_PHY_MODE                                  ETH_PHY_MODE
1156  * \endcode
1157  *
1158  * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
1159  * to trace the actual size of the data received.
1160  * \code
1161  * static gmac_device_t gs_gmac_dev;
1162  * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
1163  *
1164  * uint32_t ul_frm_size;
1165  * \endcode
1166  *
1167  * Add to application C-file:
1168  * \code
1169  *   void gmac_init(void)
1170  *   {
1171  *       sysclk_init();
1172  *
1173  *       board_init();
1174  *
1175  *       pmc_enable_periph_clk(ID_GMAC);
1176  *
1177  *       gmac_option.uc_copy_all_frame = 0;
1178  *       gmac_option.uc_no_boardcast = 0;
1179  *       memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
1180  *       gs_gmac_dev.p_hw = GMAC;
1181  *
1182  *       gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
1183  *
1184  *       NVIC_EnableIRQ(GMAC_IRQn);
1185  *
1186  *       ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
1187  * 
1188  *       ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
1189  *
1190  *       ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
1191  * \endcode
1192  *
1193  * \subsection gmac_basic_use_case_setup_flow Workflow
1194  * - Ensure that conf_eth.h is present and contains the
1195  * following configuration symbol. This configuration file is used
1196  * by the driver and should not be included by the application.
1197  * -# Define the receiving buffer size used in the internal GMAC driver.
1198  * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
1199  * If it was supposed receiving a large number of frame, the
1200  * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
1201  * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least 
1202  * (2048/128)=16, and as there are additional frames coming, a preferred
1203  * number is 24 depending on a normal Ethernet throughput.
1204  *   - \code
1205  *        #define GMAC_RX_BUFFERS                               16
1206  *   \endcode
1207  * -# Define the transmitting buffer size used in the internal GMAC driver.
1208  * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
1209  *   - \code
1210  *        #define GMAC_TX_BUFFERS                               8
1211  *   \endcode
1212  * -# Define maximum retry time for a PHY read/write operation.
1213  *   - \code
1214  *        #define MAC_PHY_RETRY_MAX                             1000000
1215  *   \endcode
1216  * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
1217  * for ATMEL, application should always change this address to its' own.
1218  *   - \code
1219  *        #define ETHERNET_CONF_ETHADDR0                        0x00
1220  *        #define ETHERNET_CONF_ETHADDR1                        0x04
1221  *        #define ETHERNET_CONF_ETHADDR2                        0x25
1222  *        #define ETHERNET_CONF_ETHADDR3                        0x1C
1223  *        #define ETHERNET_CONF_ETHADDR4                        0xA0
1224  *        #define ETHERNET_CONF_ETHADDR5                        0x02
1225  *   \endcode
1226  * -# Define the IP address configration used in the application. When DHCP
1227  *  is enabled, this configuration is not effected.
1228  *   - \code
1229  *        #define ETHERNET_CONF_IPADDR0                         192
1230  *        #define ETHERNET_CONF_IPADDR1                         168
1231  *        #define ETHERNET_CONF_IPADDR2                         0
1232  *        #define ETHERNET_CONF_IPADDR3                         2
1233  *        #define ETHERNET_CONF_GATEWAY_ADDR0                   192
1234  *        #define ETHERNET_CONF_GATEWAY_ADDR1                   168
1235  *        #define ETHERNET_CONF_GATEWAY_ADDR2                   0
1236  *        #define ETHERNET_CONF_GATEWAY_ADDR3                   1
1237  *        #define ETHERNET_CONF_NET_MASK0                       255
1238  *        #define ETHERNET_CONF_NET_MASK1                       255
1239  *        #define ETHERNET_CONF_NET_MASK2                       255
1240  *        #define ETHERNET_CONF_NET_MASK3                       0
1241  *   \endcode
1242  * -# Configure the PHY maintainance interface.
1243  *   - \code
1244  *        #define ETH_PHY_MODE                                  GMAC_PHY_MII
1245  *   \endcode
1246  * -# Enable the system clock:
1247  *   - \code sysclk_init(); \endcode
1248  * -# Enable PIO configurations for GMAC:
1249  *   - \code board_init(); \endcode
1250  * -# Enable PMC clock for GMAC:
1251  *   - \code pmc_enable_periph_clk(ID_GMAC); \endcode
1252  * -# Set the GMAC options; it's set to copy all frame and support broadcast:
1253  *   - \code
1254  *         gmac_option.uc_copy_all_frame = 0;
1255  *         gmac_option.uc_no_boardcast = 0;
1256  *         memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
1257  *         gs_gmac_dev.p_hw = GMAC;
1258  * \endcode
1259  * -# Initialize GMAC device with the filled option:
1260  *   - \code
1261  *         gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
1262  * \endcode
1263  * -# Enable the interrupt service for GMAC:
1264  *   - \code
1265  *         NVIC_EnableIRQ(GMAC_IRQn);
1266  * \endcode
1267  * -# Initialize the PHY component:
1268  *   - \code
1269  *         ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
1270  * \endcode
1271   * -# The link will be established based on auto negotiation.
1272  *   - \code
1273  *         ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
1274  * \endcode
1275  * -# Establish the ethernet link; the network can be worked from now on:
1276  *   - \code
1277  *         ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
1278  * \endcode
1279  *
1280  * \section gmac_basic_use_case_usage Usage steps
1281  * \subsection gmac_basic_use_case_usage_code Example code
1282  * Add to, e.g., main loop in application C-file:
1283  * \code
1284  *    gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
1285  * \endcode
1286  *
1287  * \subsection gmac_basic_use_case_usage_flow Workflow
1288  * -# Start reading the data from the ethernet:
1289  *   - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
1290  */
1291
1292 #       define GMAC_STATS 0
1293
1294 #if( GMAC_STATS != 0 )
1295
1296         /* Here below some code to study the types and
1297         frequencies of  GMAC interrupts. */
1298         #define GMAC_IDX_RXUBR 0
1299         #define GMAC_IDX_TUR   1
1300         #define GMAC_IDX_RLEX  2
1301         #define GMAC_IDX_TFC   3
1302         #define GMAC_IDX_RCOMP 4
1303         #define GMAC_IDX_TCOMP 5
1304         #define GMAC_IDX_ROVR  6
1305         #define GMAC_IDX_HRESP 7
1306         #define GMAC_IDX_PFNZ  8
1307         #define GMAC_IDX_PTZ   9
1308
1309         struct SGmacStats {
1310                 unsigned recvCount;
1311                 unsigned rovrCount;
1312                 unsigned bnaCount;
1313                 unsigned sendCount;
1314                 unsigned sovrCount;
1315                 unsigned incompCount;
1316                 unsigned truncCount;
1317
1318                 unsigned intStatus[10];
1319         };
1320         extern struct SGmacStats gmacStats;
1321
1322         struct SIntPair {
1323                 const char *name;
1324                 unsigned mask;
1325                 int index;
1326         };
1327
1328         #define MK_PAIR( NAME )   #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
1329         static const struct SIntPair intPairs[] = {
1330                 { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
1331                 { MK_PAIR( TUR   ) }, /* Enable transmit underrun interrupt. */
1332                 { MK_PAIR( RLEX  ) }, /* Enable retry limit  exceeded interrupt. */
1333                 { MK_PAIR( TFC   ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
1334                 { MK_PAIR( RCOMP ) }, /* Receive complete */
1335                 { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
1336                 { MK_PAIR( ROVR  ) }, /* Enable receive overrun interrupt. */
1337                 { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
1338                 { MK_PAIR( PFNZ  ) }, /* Enable pause frame received interrupt. */
1339                 { MK_PAIR( PTZ   ) }  /* Enable pause time zero interrupt. */
1340         };
1341
1342         void gmac_show_irq_counts ();
1343
1344 #endif
1345
1346 #endif /* GMAC_H_INCLUDED */