xref: /FreeRTOS-Plus-TCP-v3.1.0/source/portable/NetworkInterface/DriverSAM/gmac_SAM.h (revision a4124602cc584fa0658448c229f48a459a84fbb1)
1 /**
2  * \file
3  *
4  * \brief GMAC (Ethernet MAC) driver for SAM.
5  *
6  * Copyright (c) 2013-2016 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 /*
45  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46  */
47 
48 #ifndef GMAC_H_INCLUDED
49     #define GMAC_H_INCLUDED
50 
51     #include "compiler.h"
52 
53 /*/ @cond 0 */
54 /**INDENT-OFF**/
55     #ifdef __cplusplus
56         extern "C" {
57     #endif
58 /**INDENT-ON**/
59 /*/ @endcond */
60 
61 /** The buffer addresses written into the descriptors must be aligned, so the
62  *  last few bits are zero.  These bits have special meaning for the GMAC
63  *  peripheral and cannot be used as part of the address. */
64     #define GMAC_RXD_ADDR_MASK         0xFFFFFFFC
65     #define GMAC_RXD_WRAP              ( 1ul << 1 )  /**< Wrap bit */
66     #define GMAC_RXD_OWNERSHIP         ( 1ul << 0 )  /**< Ownership bit */
67 
68     #define GMAC_RXD_BROADCAST         ( 1ul << 31 ) /**< Broadcast detected */
69     #define GMAC_RXD_MULTIHASH         ( 1ul << 30 ) /**< Multicast hash match */
70     #define GMAC_RXD_UNIHASH           ( 1ul << 29 ) /**< Unicast hash match */
71     #define GMAC_RXD_ADDR_FOUND        ( 1ul << 27 ) /**< Specific address match found */
72     #define GMAC_RXD_ADDR              ( 3ul << 25 ) /**< Address match */
73     #define GMAC_RXD_RXCOEN            ( 1ul << 24 ) /**< RXCOEN related function */
74     #define GMAC_RXD_TYPE              ( 3ul << 22 ) /**< Type ID match */
75     #define GMAC_RXD_VLAN              ( 1ul << 21 ) /**< VLAN tag detected */
76     #define GMAC_RXD_PRIORITY          ( 1ul << 20 ) /**< Priority tag detected */
77     #define GMAC_RXD_PRIORITY_MASK     ( 3ul << 17 ) /**< VLAN priority */
78     #define GMAC_RXD_CFI               ( 1ul << 16 ) /**< Concatenation Format Indicator only if bit 21 is set */
79     #define GMAC_RXD_EOF               ( 1ul << 15 ) /**< End of frame */
80     #define GMAC_RXD_SOF               ( 1ul << 14 ) /**< Start of frame */
81     #define GMAC_RXD_FCS               ( 1ul << 13 ) /**< Frame check sequence */
82     #define GMAC_RXD_OFFSET_MASK                     /**< Receive buffer offset */
83     #define GMAC_RXD_LEN_MASK          ( 0xFFF )     /**< Length of frame including FCS (if selected) */
84     #define GMAC_RXD_LENJUMBO_MASK     ( 0x3FFF )    /**< Jumbo frame length */
85 
86     #define GMAC_TXD_USED              ( 1ul << 31 ) /**< Frame is transmitted */
87     #define GMAC_TXD_WRAP              ( 1ul << 30 ) /**< Last descriptor */
88     #define GMAC_TXD_ERROR             ( 1ul << 29 ) /**< Retry limit exceeded, error */
89     #define GMAC_TXD_UNDERRUN          ( 1ul << 28 ) /**< Transmit underrun */
90     #define GMAC_TXD_EXHAUSTED         ( 1ul << 27 ) /**< Buffer exhausted */
91     #define GMAC_TXD_LATE              ( 1ul << 26 ) /**< Late collision,transmit  error  */
92     #define GMAC_TXD_CHECKSUM_ERROR    ( 7ul << 20 ) /**< Checksum error */
93     #define GMAC_TXD_NOCRC             ( 1ul << 16 ) /**< No CRC */
94     #define GMAC_TXD_LAST              ( 1ul << 15 ) /**< Last buffer in frame */
95     #define GMAC_TXD_LEN_MASK          ( 0x1FFF )    /**< Length of buffer */
96 
97 /** The MAC can support frame lengths up to 1536 bytes */
98     #define GMAC_FRAME_LENTGH_MAX      1536
99 
100 /*#define GMAC_RX_UNITSIZE            128     / **< Fixed size for RX buffer  * / */
101     #define GMAC_RX_UNITSIZE           1536 /**< Fixed size for RX buffer  */
102 
103 /*#define GMAC_TX_UNITSIZE            1518    / **< Size for ETH frame length * / */
104     #define GMAC_TX_UNITSIZE           1536 /**< Size for ETH frame length */
105 
106 /** GMAC clock speed */
107     #define GMAC_MCK_SPEED_240MHZ      ( 240 * 1000 * 1000 )
108     #define GMAC_MCK_SPEED_160MHZ      ( 160 * 1000 * 1000 )
109     #define GMAC_MCK_SPEED_120MHZ      ( 120 * 1000 * 1000 )
110     #define GMAC_MCK_SPEED_80MHZ       ( 80 * 1000 * 1000 )
111     #define GMAC_MCK_SPEED_40MHZ       ( 40 * 1000 * 1000 )
112     #define GMAC_MCK_SPEED_20MHZ       ( 20 * 1000 * 1000 )
113 
114 /** GMAC maintain code default value*/
115     #define GMAC_MAN_CODE_VALUE        ( 10 )
116 
117 /** GMAC maintain start of frame default value*/
118     #define GMAC_MAN_SOF_VALUE         ( 1 )
119 
120 /** GMAC maintain read/write*/
121     #define GMAC_MAN_RW_TYPE           ( 2 )
122 
123 /** GMAC maintain read only*/
124     #define GMAC_MAN_READ_ONLY         ( 1 )
125 
126 /** GMAC address length */
127     #define GMAC_ADDR_LENGTH           ( 6 )
128 
129 
130     #define GMAC_DUPLEX_HALF           0
131     #define GMAC_DUPLEX_FULL           1
132 
133     #define GMAC_SPEED_10M             0
134     #define GMAC_SPEED_100M            1
135 
136 /**
137  * \brief Return codes for GMAC APIs.
138  */
139     typedef enum
140     {
141         GMAC_OK = 0,         /** 0  Operation OK */
142         GMAC_TIMEOUT = 1,    /** 1  GMAC operation timeout */
143         GMAC_TX_BUSY,        /** 2  TX in progress */
144         GMAC_RX_NO_DATA,     /** 3  No data received */
145         GMAC_SIZE_TOO_SMALL, /** 4  Buffer size not enough */
146         GMAC_PARAM,          /** 5  Parameter error, TX packet invalid or RX size too small */
147         GMAC_RX_ERROR,       /** 6  RX error */
148         GMAC_INVALID = 0xFF, /* Invalid */
149     } gmac_status_t;
150 
151 /**
152  * \brief Media Independent Interface (MII) type.
153  */
154     typedef enum
155     {
156         GMAC_PHY_MII = 0,        /** MII mode */
157         GMAC_PHY_RMII = 1,       /** Reduced MII mode */
158         GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
159     } gmac_mii_mode_t;
160 
161 /* This is the list of GMAC priority queue */
162     typedef enum
163     {
164         GMAC_QUE_0 = 0,
165         #if !( SAM4E )
166             GMAC_QUE_1 = 1,
167             GMAC_QUE_2 = 2,
168             /* Only SAM E70 Rev-B. */
169             GMAC_QUE_3 = 3,
170             GMAC_QUE_4 = 4,
171             GMAC_QUE_5 = 5,
172         #endif
173         #if !defined( __DOXYGEN__ )
174             GMAC_QUE_N,
175         #endif
176     } gmac_quelist_t;
177 
178 /** Receive buffer descriptor struct */
179     COMPILER_PACK_SET( 8 )
180     typedef struct gmac_rx_descriptor
181     {
182         union gmac_rx_addr
183         {
184             uint32_t val;
185             struct gmac_rx_addr_bm
186             {
187                 uint32_t b_ownership : 1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
188                          b_wrap : 1,      /**< Marks last descriptor in receive buffer */
189                          addr_dw : 30;    /**< Address in number of DW */
190             } bm;
191         } addr;                           /**< Address, Wrap & Ownership */
192         union gmac_rx_status
193         {
194             uint32_t val;
195             struct gmac_rx_status_bm
196             {
197                 uint32_t b_len : 13,              /**  0..12  Length of frame including FCS */
198                          b_fcs : 1,               /**  13     Receive buffer offset,  bits 13:12 of frame length for jumbo frame */
199                          b_sof : 1,               /**  14     Start of frame */
200                          b_eof : 1,               /**  15     End of frame */
201                          b_cfi : 1,               /**  16     Concatenation Format Indicator */
202                          b_vlan_priority : 3,     /**  17..19 VLAN priority (if VLAN detected) */
203                          b_priority_detected : 1, /**  20     Priority tag detected */
204                          b_vlan_detected : 1,     /**  21     VLAN tag detected */
205                          b_type_id_match : 2,     /**  22..23 Type ID match */
206                          b_checksumoffload : 1,   /**  24     Checksum offload specific function */
207                          b_addrmatch : 2,         /**  25..26 Address register match */
208                          b_ext_addr_match : 1,    /**  27     External address match found */
209                          reserved : 1,            /**  28     */
210                          b_uni_hash_match : 1,    /**  29     Unicast hash match */
211                          b_multi_hash_match : 1,  /**  30     Multicast hash match */
212                          b_boardcast_detect : 1;  /**  31     Global broadcast address detected */
213             } bm;
214         } status;
215     } gmac_rx_descriptor_t;
216 
217 /** Transmit buffer descriptor struct */
218     COMPILER_PACK_SET( 8 )
219     typedef struct gmac_tx_descriptor
220     {
221         uint32_t addr;
222         union gmac_tx_status
223         {
224             uint32_t val;
225             struct gmac_tx_status_bm
226             {
227                 uint32_t b_len : 14,            /**  0..13 Length of buffer */
228                          reserved : 1,          /** 14            */
229                          b_last_buffer : 1,     /** 15     Last buffer (in the current frame) */
230                          b_no_crc : 1,          /** 16     No CRC */
231                          reserved1 : 3,         /** 17..19        */
232                          b_checksumoffload : 3, /** 20..22 Transmit checksum generation offload errors */
233                          reserved2 : 3,         /** 23..25        */
234                          b_lco : 1,             /** 26     Late collision, transmit error detected */
235                          b_exhausted : 1,       /** 27     Buffer exhausted in mid frame */
236                          b_underrun : 1,        /** 28     Transmit underrun */
237                          b_error : 1,           /** 29     Retry limit exceeded, error detected */
238                          b_wrap : 1,            /** 30     Marks last descriptor in TD list */
239                          b_used : 1;            /** 31     User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
240             } bm;
241         } status;
242     } gmac_tx_descriptor_t;
243 
244     COMPILER_PACK_RESET()
245 
246 /**
247  * \brief Input parameters when initializing the gmac module mode.
248  */
249     typedef struct gmac_options
250     {
251         /*  Enable/Disable CopyAllFrame */
252         uint8_t uc_copy_all_frame;
253         /* Enable/Disable NoBroadCast */
254         uint8_t uc_no_boardcast;
255         /* MAC address */
256         uint8_t uc_mac_addr[ GMAC_ADDR_LENGTH ];
257     } gmac_options_t;
258 
259 /** Wakeup callback */
260     typedef void (* gmac_dev_wakeup_cb_t) ( void );
261 
262 /**
263  * GMAC driver structure.
264  */
265     typedef struct gmac_device
266     {
267         /** Pointer to HW register base */
268         Gmac * p_hw;
269 
270         /**
271          * Pointer to allocated TX buffer.
272          * Section 3.6 of AMBA 2.0 spec states that burst should not cross
273          * 1K Boundaries.
274          * Receive buffer manager writes are burst of 2 words => 3 lsb bits
275          * of the address shall be set to 0.
276          */
277         #if ( GMAC_USES_WAKEUP_CALLBACK != 0 )
278             /** Optional callback to be invoked once several TDs have been released */
279             gmac_dev_wakeup_cb_t func_wakeup_cb;
280         #endif
281         /** RX index for current processing TD */
282         uint32_t ul_rx_idx;
283         /** Circular buffer head pointer by upper layer (buffer to be sent) */
284         int32_t l_tx_head;
285         /** Circular buffer tail pointer incremented by handlers (buffer sent) */
286         int32_t l_tx_tail;
287 
288         /** Number of free TD before wakeup callback is invoked */
289         uint32_t ul_wakeup_threshold;
290     } gmac_device_t;
291 
292     uint8_t gmac_wait_phy( Gmac * p_gmac,
293                            const uint32_t ul_retry );
294 
295 /**
296  * \brief Write network control value.
297  *
298  * \param p_gmac   Pointer to the GMAC instance.
299  * \param ul_ncr   Network control value.
300  */
gmac_network_control(Gmac * p_gmac,uint32_t ul_ncr)301     static inline void gmac_network_control( Gmac * p_gmac,
302                                              uint32_t ul_ncr )
303     {
304         p_gmac->GMAC_NCR = ul_ncr;
305     }
306 
307 /**
308  * \brief Get network control value.
309  *
310  * \param p_gmac   Pointer to the GMAC instance.
311  */
312 
gmac_get_network_control(Gmac * p_gmac)313     static inline uint32_t gmac_get_network_control( Gmac * p_gmac )
314     {
315         return p_gmac->GMAC_NCR;
316     }
317 
318 /**
319  * \brief Enable/Disable GMAC receive.
320  *
321  * \param p_gmac   Pointer to the GMAC instance.
322  * \param uc_enable   0 to disable GMAC receiver, else to enable it.
323  */
gmac_enable_receive(Gmac * p_gmac,uint8_t uc_enable)324     static inline void gmac_enable_receive( Gmac * p_gmac,
325                                             uint8_t uc_enable )
326     {
327         if( uc_enable )
328         {
329             p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
330         }
331         else
332         {
333             p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
334         }
335     }
336 
337 /**
338  * \brief Enable/Disable GMAC transmit.
339  *
340  * \param p_gmac   Pointer to the GMAC instance.
341  * \param uc_enable   0 to disable GMAC transmit, else to enable it.
342  */
gmac_enable_transmit(Gmac * p_gmac,uint8_t uc_enable)343     static inline void gmac_enable_transmit( Gmac * p_gmac,
344                                              uint8_t uc_enable )
345     {
346         if( uc_enable )
347         {
348             p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
349         }
350         else
351         {
352             p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
353         }
354     }
355 
356 /**
357  * \brief Enable/Disable GMAC management.
358  *
359  * \param p_gmac   Pointer to the GMAC instance.
360  * \param uc_enable   0 to disable GMAC management, else to enable it.
361  */
gmac_enable_management(Gmac * p_gmac,uint8_t uc_enable)362     static inline void gmac_enable_management( Gmac * p_gmac,
363                                                uint8_t uc_enable )
364     {
365         if( uc_enable )
366         {
367             p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
368         }
369         else
370         {
371             p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
372         }
373     }
374 
375 /**
376  * \brief Clear all statistics registers.
377  *
378  * \param p_gmac   Pointer to the GMAC instance.
379  */
gmac_clear_statistics(Gmac * p_gmac)380     static inline void gmac_clear_statistics( Gmac * p_gmac )
381     {
382         p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
383     }
384 
385 /**
386  * \brief Increase all statistics registers.
387  *
388  * \param p_gmac   Pointer to the GMAC instance.
389  */
gmac_increase_statistics(Gmac * p_gmac)390     static inline void gmac_increase_statistics( Gmac * p_gmac )
391     {
392         p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
393     }
394 
395 /**
396  * \brief Enable/Disable statistics registers writing.
397  *
398  * \param p_gmac   Pointer to the GMAC instance.
399  * \param uc_enable   0 to disable the statistics registers writing, else to enable it.
400  */
gmac_enable_statistics_write(Gmac * p_gmac,uint8_t uc_enable)401     static inline void gmac_enable_statistics_write( Gmac * p_gmac,
402                                                      uint8_t uc_enable )
403     {
404         if( uc_enable )
405         {
406             p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
407         }
408         else
409         {
410             p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
411         }
412     }
413 
414 /**
415  * \brief In half-duplex mode, forces collisions on all received frames.
416  *
417  * \param p_gmac   Pointer to the GMAC instance.
418  * \param uc_enable   0 to disable the back pressure, else to enable it.
419  */
gmac_enable_back_pressure(Gmac * p_gmac,uint8_t uc_enable)420     static inline void gmac_enable_back_pressure( Gmac * p_gmac,
421                                                   uint8_t uc_enable )
422     {
423         if( uc_enable )
424         {
425             p_gmac->GMAC_NCR |= GMAC_NCR_BP;
426         }
427         else
428         {
429             p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
430         }
431     }
432 
433 /**
434  * \brief Start transmission.
435  *
436  * \param p_gmac   Pointer to the GMAC instance.
437  */
gmac_start_transmission(Gmac * p_gmac)438     static inline void gmac_start_transmission( Gmac * p_gmac )
439     {
440         __DSB();
441         p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
442     }
443 
444 /**
445  * \brief Halt transmission.
446  *
447  * \param p_gmac   Pointer to the GMAC instance.
448  */
gmac_halt_transmission(Gmac * p_gmac)449     static inline void gmac_halt_transmission( Gmac * p_gmac )
450     {
451         p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
452     }
453 
454 /**
455  * \brief Transmit pause frame.
456  *
457  * \param p_gmac   Pointer to the GMAC instance.
458  */
gmac_tx_pause_frame(Gmac * p_gmac)459     static inline void gmac_tx_pause_frame( Gmac * p_gmac )
460     {
461         p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
462     }
463 
464 /**
465  * \brief Transmit zero quantum pause frame.
466  *
467  * \param p_gmac   Pointer to the GMAC instance.
468  */
gmac_tx_pause_zero_quantum_frame(Gmac * p_gmac)469     static inline void gmac_tx_pause_zero_quantum_frame( Gmac * p_gmac )
470     {
471         p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
472     }
473 
474 /**
475  * \brief Store receivetime stamp to memory.
476  *
477  * \param p_gmac   Pointer to the GMAC instance.
478  * \param uc_enable   0 to normal operation, else to enable the store.
479  */
gmac_store_rx_time_stamp(Gmac * p_gmac,uint8_t uc_enable)480     static inline void gmac_store_rx_time_stamp( Gmac * p_gmac,
481                                                  uint8_t uc_enable )
482     {
483         if( uc_enable )
484         {
485             p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
486         }
487         else
488         {
489             p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
490         }
491     }
492 
493 /**
494  * \brief Enable PFC priority-based pause reception.
495  *
496  * \param p_gmac   Pointer to the GMAC instance.
497  * \param uc_enable   1 to set the reception, 0 to disable.
498  */
gmac_enable_pfc_pause_frame(Gmac * p_gmac,uint8_t uc_enable)499     static inline void gmac_enable_pfc_pause_frame( Gmac * p_gmac,
500                                                     uint8_t uc_enable )
501     {
502         if( uc_enable )
503         {
504             p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
505         }
506         else
507         {
508             p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
509         }
510     }
511 
512 /**
513  * \brief Transmit PFC priority-based pause reception.
514  *
515  * \param p_gmac   Pointer to the GMAC instance.
516  */
gmac_transmit_pfc_pause_frame(Gmac * p_gmac)517     static inline void gmac_transmit_pfc_pause_frame( Gmac * p_gmac )
518     {
519         p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
520     }
521 
522 /**
523  * \brief Flush next packet.
524  *
525  * \param p_gmac   Pointer to the GMAC instance.
526  */
gmac_flush_next_packet(Gmac * p_gmac)527     static inline void gmac_flush_next_packet( Gmac * p_gmac )
528     {
529         p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
530     }
531 
532 /**
533  * \brief Set up network configuration register.
534  *
535  * \param p_gmac   Pointer to the GMAC instance.
536  * \param ul_cfg   Network configuration value.
537  */
gmac_set_config(Gmac * p_gmac,uint32_t ul_cfg)538     static inline void gmac_set_config( Gmac * p_gmac,
539                                         uint32_t ul_cfg )
540     {
541         p_gmac->GMAC_NCFGR = ul_cfg;
542     }
543 
544 /* Get and set DMA Configuration Register */
gmac_set_dma(Gmac * p_gmac,uint32_t ul_cfg)545     static inline void gmac_set_dma( Gmac * p_gmac,
546                                      uint32_t ul_cfg )
547     {
548         p_gmac->GMAC_DCFGR = ul_cfg;
549     }
550 
gmac_get_dma(Gmac * p_gmac)551     static inline uint32_t gmac_get_dma( Gmac * p_gmac )
552     {
553         return p_gmac->GMAC_DCFGR;
554     }
555 
556 /**
557  * \brief Get network configuration.
558  *
559  * \param p_gmac   Pointer to the GMAC instance.
560  *
561  * \return Network configuration.
562  */
gmac_get_config(Gmac * p_gmac)563     static inline uint32_t gmac_get_config( Gmac * p_gmac )
564     {
565         return p_gmac->GMAC_NCFGR;
566     }
567 
568 /**
569  * \brief Set speed.
570  *
571  * \param p_gmac   Pointer to the GMAC instance.
572  * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
573  */
gmac_set_speed(Gmac * p_gmac,uint8_t uc_speed)574     static inline void gmac_set_speed( Gmac * p_gmac,
575                                        uint8_t uc_speed )
576     {
577         if( uc_speed )
578         {
579             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
580         }
581         else
582         {
583             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
584         }
585     }
586 
587 /**
588  * \brief Enable/Disable Full-Duplex mode.
589  *
590  * \param p_gmac   Pointer to the GMAC instance.
591  * \param uc_enable   0 to disable the Full-Duplex mode, else to enable it.
592  */
gmac_enable_full_duplex(Gmac * p_gmac,uint8_t uc_enable)593     static inline void gmac_enable_full_duplex( Gmac * p_gmac,
594                                                 uint8_t uc_enable )
595     {
596         if( uc_enable )
597         {
598             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
599         }
600         else
601         {
602             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
603         }
604     }
605 
606 /**
607  * \brief Enable/Disable Copy(Receive) All Valid Frames.
608  *
609  * \param p_gmac   Pointer to the GMAC instance.
610  * \param uc_enable   0 to disable copying all valid frames, else to enable it.
611  */
gmac_enable_copy_all(Gmac * p_gmac,uint8_t uc_enable)612     static inline void gmac_enable_copy_all( Gmac * p_gmac,
613                                              uint8_t uc_enable )
614     {
615         if( uc_enable )
616         {
617             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
618         }
619         else
620         {
621             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
622         }
623     }
624 
625 /**
626  * \brief Enable/Disable jumbo frames (up to 10240 bytes).
627  *
628  * \param p_gmac   Pointer to the GMAC instance.
629  * \param uc_enable   0 to disable the jumbo frames, else to enable it.
630  */
gmac_enable_jumbo_frames(Gmac * p_gmac,uint8_t uc_enable)631     static inline void gmac_enable_jumbo_frames( Gmac * p_gmac,
632                                                  uint8_t uc_enable )
633     {
634         if( uc_enable )
635         {
636             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
637         }
638         else
639         {
640             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
641         }
642     }
643 
644 /**
645  * \brief Disable/Enable broadcast receiving.
646  *
647  * \param p_gmac   Pointer to the GMAC instance.
648  * \param uc_enable   1 to disable the broadcast, else to enable it.
649  */
gmac_disable_broadcast(Gmac * p_gmac,uint8_t uc_enable)650     static inline void gmac_disable_broadcast( Gmac * p_gmac,
651                                                uint8_t uc_enable )
652     {
653         if( uc_enable )
654         {
655             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
656         }
657         else
658         {
659             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
660         }
661     }
662 
663 /**
664  * \brief Enable/Disable multicast hash.
665  *
666  * \param p_gmac   Pointer to the GMAC instance.
667  * \param uc_enable   0 to disable the multicast hash, else to enable it.
668  */
gmac_enable_multicast_hash(Gmac * p_gmac,uint8_t uc_enable)669     static inline void gmac_enable_multicast_hash( Gmac * p_gmac,
670                                                    uint8_t uc_enable )
671     {
672         if( uc_enable )
673         {
674             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
675         }
676         else
677         {
678             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
679         }
680     }
681 
682 /**
683  * \brief Enable/Disable big frames (over 1518, up to 1536).
684  *
685  * \param p_gmac   Pointer to the GMAC instance.
686  * \param uc_enable   0 to disable big frames else to enable it.
687  */
gmac_enable_big_frame(Gmac * p_gmac,uint8_t uc_enable)688     static inline void gmac_enable_big_frame( Gmac * p_gmac,
689                                               uint8_t uc_enable )
690     {
691         if( uc_enable )
692         {
693             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
694         }
695         else
696         {
697             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
698         }
699     }
700 
701 /**
702  * \brief Set MDC clock divider.
703  *
704  * \param p_gmac   Pointer to the GMAC instance.
705  * \param ul_mck   GMAC MCK.
706  *
707  * \return GMAC_OK if successfully.
708  */
gmac_set_mdc_clock(Gmac * p_gmac,uint32_t ul_mck)709     static inline uint8_t gmac_set_mdc_clock( Gmac * p_gmac,
710                                               uint32_t ul_mck )
711     {
712         uint32_t ul_clk, ul_value;
713 
714         if( ul_mck > GMAC_MCK_SPEED_240MHZ )
715         {
716             return GMAC_INVALID;
717         }
718         else if( ul_mck > GMAC_MCK_SPEED_160MHZ )
719         {
720             ul_clk = GMAC_NCFGR_CLK_MCK_96;
721         }
722         else if( ul_mck > GMAC_MCK_SPEED_120MHZ )
723         {
724             ul_clk = GMAC_NCFGR_CLK_MCK_64;
725         }
726         else if( ul_mck > GMAC_MCK_SPEED_80MHZ )
727         {
728             ul_clk = GMAC_NCFGR_CLK_MCK_48;
729         }
730         else if( ul_mck > GMAC_MCK_SPEED_40MHZ )
731         {
732             ul_clk = GMAC_NCFGR_CLK_MCK_32;
733         }
734         else if( ul_mck > GMAC_MCK_SPEED_20MHZ )
735         {
736             ul_clk = GMAC_NCFGR_CLK_MCK_16;
737         }
738         else
739         {
740             ul_clk = GMAC_NCFGR_CLK_MCK_8;
741         }
742 
743         ul_value = p_gmac->GMAC_NCFGR;
744         ul_value &= ~GMAC_NCFGR_CLK_Msk;
745         ul_value |= ul_clk;
746         p_gmac->GMAC_NCFGR = ul_value;
747         return GMAC_OK;
748     }
749 
750 /**
751  * \brief Enable/Disable retry test.
752  *
753  * \param p_gmac   Pointer to the GMAC instance.
754  * \param uc_enable   0 to disable the GMAC receiver, else to enable it.
755  */
gmac_enable_retry_test(Gmac * p_gmac,uint8_t uc_enable)756     static inline void gmac_enable_retry_test( Gmac * p_gmac,
757                                                uint8_t uc_enable )
758     {
759         if( uc_enable )
760         {
761             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
762         }
763         else
764         {
765             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
766         }
767     }
768 
769 /**
770  * \brief Enable/Disable pause (when a valid pause frame is received).
771  *
772  * \param p_gmac   Pointer to the GMAC instance.
773  * \param uc_enable   0 to disable pause frame, else to enable it.
774  */
gmac_enable_pause_frame(Gmac * p_gmac,uint8_t uc_enable)775     static inline void gmac_enable_pause_frame( Gmac * p_gmac,
776                                                 uint8_t uc_enable )
777     {
778         if( uc_enable )
779         {
780             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
781         }
782         else
783         {
784             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
785         }
786     }
787 
788 /**
789  * \brief Set receive buffer offset to 0 ~ 3.
790  *
791  * \param p_gmac   Pointer to the GMAC instance.
792  */
gmac_set_rx_buffer_offset(Gmac * p_gmac,uint8_t uc_offset)793     static inline void gmac_set_rx_buffer_offset( Gmac * p_gmac,
794                                                   uint8_t uc_offset )
795     {
796         p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
797         p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO( uc_offset );
798     }
799 
800 /**
801  * \brief Enable/Disable receive length field checking.
802  *
803  * \param p_gmac   Pointer to the GMAC instance.
804  * \param uc_enable   0 to disable receive length field checking, else to enable it.
805  */
gmac_enable_rx_length_check(Gmac * p_gmac,uint8_t uc_enable)806     static inline void gmac_enable_rx_length_check( Gmac * p_gmac,
807                                                     uint8_t uc_enable )
808     {
809         if( uc_enable )
810         {
811             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
812         }
813         else
814         {
815             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
816         }
817     }
818 
819 /**
820  * \brief Enable/Disable discarding FCS field of received frames.
821  *
822  * \param p_gmac   Pointer to the GMAC instance.
823  * \param uc_enable   0 to disable discarding FCS field of received frames, else to enable it.
824  */
gmac_enable_discard_fcs(Gmac * p_gmac,uint8_t uc_enable)825     static inline void gmac_enable_discard_fcs( Gmac * p_gmac,
826                                                 uint8_t uc_enable )
827     {
828         if( uc_enable )
829         {
830             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
831         }
832         else
833         {
834             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
835         }
836     }
837 
838 
839 /**
840  * \brief Enable/Disable frames to be received in half-duplex mode
841  * while transmitting.
842  *
843  * \param p_gmac   Pointer to the GMAC instance.
844  * \param uc_enable   0 to disable the received in half-duplex mode, else to enable it.
845  */
gmac_enable_efrhd(Gmac * p_gmac,uint8_t uc_enable)846     static inline void gmac_enable_efrhd( Gmac * p_gmac,
847                                           uint8_t uc_enable )
848     {
849         if( uc_enable )
850         {
851             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
852         }
853         else
854         {
855             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
856         }
857     }
858 
859 /**
860  * \brief Enable/Disable ignore RX FCS.
861  *
862  * \param p_gmac   Pointer to the GMAC instance.
863  * \param uc_enable   0 to disable ignore RX FCS, else to enable it.
864  */
gmac_enable_ignore_rx_fcs(Gmac * p_gmac,uint8_t uc_enable)865     static inline void gmac_enable_ignore_rx_fcs( Gmac * p_gmac,
866                                                   uint8_t uc_enable )
867     {
868         if( uc_enable )
869         {
870             p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
871         }
872         else
873         {
874             p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
875         }
876     }
877 
878 /**
879  * \brief Get Network Status.
880  *
881  * \param p_gmac   Pointer to the GMAC instance.
882  *
883  * \return Network status.
884  */
gmac_get_status(Gmac * p_gmac)885     static inline uint32_t gmac_get_status( Gmac * p_gmac )
886     {
887         return p_gmac->GMAC_NSR;
888     }
889 
890 /**
891  * \brief Get MDIO IN pin status.
892  *
893  * \param p_gmac   Pointer to the GMAC instance.
894  *
895  * \return MDIO IN pin status.
896  */
gmac_get_MDIO(Gmac * p_gmac)897     static inline uint8_t gmac_get_MDIO( Gmac * p_gmac )
898     {
899         return( ( p_gmac->GMAC_NSR & GMAC_NSR_MDIO ) > 0 );
900     }
901 
902 /**
903  * \brief Check if PHY is idle.
904  *
905  * \param p_gmac   Pointer to the GMAC instance.
906  *
907  * \return  1 if PHY is idle.
908  */
gmac_is_phy_idle(Gmac * p_gmac)909     static inline uint8_t gmac_is_phy_idle( Gmac * p_gmac )
910     {
911         return( ( p_gmac->GMAC_NSR & GMAC_NSR_IDLE ) > 0 );
912     }
913 
914 /**
915  * \brief Return transmit status.
916  *
917  * \param p_gmac   Pointer to the GMAC instance.
918  *
919  * \return  Transmit status.
920  */
gmac_get_tx_status(Gmac * p_gmac)921     static inline uint32_t gmac_get_tx_status( Gmac * p_gmac )
922     {
923         return p_gmac->GMAC_TSR;
924     }
925 
926 /**
927  * \brief Clear transmit status.
928  *
929  * \param p_gmac   Pointer to the GMAC instance.
930  * \param ul_status   Transmit status.
931  */
gmac_clear_tx_status(Gmac * p_gmac,uint32_t ul_status)932     static inline void gmac_clear_tx_status( Gmac * p_gmac,
933                                              uint32_t ul_status )
934     {
935         p_gmac->GMAC_TSR = ul_status;
936     }
937 
938 /**
939  * \brief Return receive status.
940  *
941  * \param p_gmac   Pointer to the GMAC instance.
942  */
gmac_get_rx_status(Gmac * p_gmac)943     static inline uint32_t gmac_get_rx_status( Gmac * p_gmac )
944     {
945         return p_gmac->GMAC_RSR;
946     }
947 
948 /**
949  * \brief Clear receive status.
950  *
951  * \param p_gmac   Pointer to the GMAC instance.
952  * \param ul_status   Receive status.
953  */
gmac_clear_rx_status(Gmac * p_gmac,uint32_t ul_status)954     static inline void gmac_clear_rx_status( Gmac * p_gmac,
955                                              uint32_t ul_status )
956     {
957         p_gmac->GMAC_RSR = ul_status;
958     }
959 
960 /**
961  * \brief Set Rx Queue.
962  *
963  * \param p_gmac   Pointer to the GMAC instance.
964  * \param ul_addr   Rx queue address.
965  */
gmac_set_rx_queue(Gmac * p_gmac,uint32_t ul_addr)966     static inline void gmac_set_rx_queue( Gmac * p_gmac,
967                                           uint32_t ul_addr )
968     {
969         p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
970     }
971 
972 /**
973  * \brief Set Rx buffer size.
974  *
975  * \param p_gmac   Pointer to the GMAC instance.
976  * \param ul_addr   Rx buffer.
977  */
gmac_set_rx_bufsize(Gmac * p_gmac,uint32_t ul_code)978     static inline void gmac_set_rx_bufsize( Gmac * p_gmac,
979                                             uint32_t ul_code )
980     {
981         p_gmac->GMAC_DCFGR = ( p_gmac->GMAC_DCFGR & ~GMAC_DCFGR_DRBS_Msk )
982                              | GMAC_DCFGR_DRBS( ul_code );
983     }
984 
985 /**
986  * \brief Get Rx Queue Address.
987  *
988  * \param p_gmac   Pointer to the GMAC instance.
989  *
990  * \return  Rx queue address.
991  */
gmac_get_rx_queue(Gmac * p_gmac)992     static inline uint32_t gmac_get_rx_queue( Gmac * p_gmac )
993     {
994         return p_gmac->GMAC_RBQB;
995     }
996 
997 /**
998  * \brief Set Tx Queue.
999  *
1000  * \param p_gmac   Pointer to the GMAC instance.
1001  * \param ul_addr  Tx queue address.
1002  */
gmac_set_tx_queue(Gmac * p_gmac,uint32_t ul_addr)1003     static inline void gmac_set_tx_queue( Gmac * p_gmac,
1004                                           uint32_t ul_addr )
1005     {
1006         p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
1007     }
1008 
1009 /**
1010  * \brief Get Tx Queue.
1011  *
1012  * \param p_gmac   Pointer to the GMAC instance.
1013  *
1014  * \return  Rx queue address.
1015  */
gmac_get_tx_queue(Gmac * p_gmac)1016     static inline uint32_t gmac_get_tx_queue( Gmac * p_gmac )
1017     {
1018         return p_gmac->GMAC_TBQB;
1019     }
1020 
1021 /**
1022  * \brief Enable interrupt(s).
1023  *
1024  * \param p_gmac   Pointer to the GMAC instance.
1025  * \param ul_source   Interrupt source(s) to be enabled.
1026  */
gmac_enable_interrupt(Gmac * p_gmac,uint32_t ul_source)1027     static inline void gmac_enable_interrupt( Gmac * p_gmac,
1028                                               uint32_t ul_source )
1029     {
1030         p_gmac->GMAC_IER = ul_source;
1031     }
1032 
1033 /**
1034  * \brief Disable interrupt(s).
1035  *
1036  * \param p_gmac   Pointer to the GMAC instance.
1037  * \param ul_source   Interrupt source(s) to be disabled.
1038  */
gmac_disable_interrupt(Gmac * p_gmac,uint32_t ul_source)1039     static inline void gmac_disable_interrupt( Gmac * p_gmac,
1040                                                uint32_t ul_source )
1041     {
1042         p_gmac->GMAC_IDR = ul_source;
1043     }
1044 
1045 /**
1046  * \brief Return interrupt status.
1047  *
1048  * \param p_gmac   Pointer to the GMAC instance.
1049  *
1050  * \return Interrupt status.
1051  */
gmac_get_interrupt_status(Gmac * p_gmac)1052     static inline uint32_t gmac_get_interrupt_status( Gmac * p_gmac )
1053     {
1054         return p_gmac->GMAC_ISR;
1055     }
1056 
1057 /**
1058  * \brief Return interrupt mask.
1059  *
1060  * \param p_gmac   Pointer to the GMAC instance.
1061  *
1062  * \return Interrupt mask.
1063  */
gmac_get_interrupt_mask(Gmac * p_gmac)1064     static inline uint32_t gmac_get_interrupt_mask( Gmac * p_gmac )
1065     {
1066         return p_gmac->GMAC_IMR;
1067     }
1068 
1069 /**
1070  * \brief Execute PHY maintenance command.
1071  *
1072  * \param p_gmac   Pointer to the GMAC instance.
1073  * \param uc_phy_addr   PHY address.
1074  * \param uc_reg_addr   Register address.
1075  * \param uc_rw   1 to Read, 0 to write.
1076  * \param us_data   Data to be performed, write only.
1077  */
gmac_maintain_phy(Gmac * p_gmac,uint8_t uc_phy_addr,uint8_t uc_reg_addr,uint8_t uc_rw,uint16_t us_data)1078     static inline void gmac_maintain_phy( Gmac * p_gmac,
1079                                           uint8_t uc_phy_addr,
1080                                           uint8_t uc_reg_addr,
1081                                           uint8_t uc_rw,
1082                                           uint16_t us_data )
1083     {
1084         /* Wait until bus idle */
1085         while( ( p_gmac->GMAC_NSR & GMAC_NSR_IDLE ) == 0 )
1086         {
1087         }
1088 
1089         /* Write maintain register */
1090         p_gmac->GMAC_MAN = GMAC_MAN_WTN( GMAC_MAN_CODE_VALUE )
1091                            | GMAC_MAN_CLTTO
1092                            | GMAC_MAN_PHYA( uc_phy_addr )
1093                            | GMAC_MAN_REGA( uc_reg_addr )
1094                            | GMAC_MAN_OP( ( uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY ) )
1095                            | GMAC_MAN_DATA( us_data );
1096     }
1097 
1098 /**
1099  * \brief Get PHY maintenance data returned.
1100  *
1101  * \param p_gmac   Pointer to the GMAC instance.
1102  *
1103  * \return Get PHY data.
1104  */
gmac_get_phy_data(Gmac * p_gmac)1105     static inline uint16_t gmac_get_phy_data( Gmac * p_gmac )
1106     {
1107         /* Wait until bus idle */
1108         while( ( p_gmac->GMAC_NSR & GMAC_NSR_IDLE ) == 0 )
1109         {
1110         }
1111 
1112         /* Return data */
1113         return ( uint16_t ) ( p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk );
1114     }
1115 
1116 /**
1117  * \brief Set Hash.
1118  *
1119  * \param p_gmac   Pointer to the GMAC instance.
1120  * \param ul_hash_top   Hash top.
1121  * \param ul_hash_bottom   Hash bottom.
1122  */
gmac_set_hash(Gmac * p_gmac,uint32_t ul_hash_top,uint32_t ul_hash_bottom)1123     static inline void gmac_set_hash( Gmac * p_gmac,
1124                                       uint32_t ul_hash_top,
1125                                       uint32_t ul_hash_bottom )
1126     {
1127         p_gmac->GMAC_HRB = ul_hash_bottom;
1128         p_gmac->GMAC_HRT = ul_hash_top;
1129     }
1130 
1131 /**
1132  * \brief Set 64 bits Hash.
1133  *
1134  * \param p_gmac   Pointer to the GMAC instance.
1135  * \param ull_hash   64 bits hash value.
1136  */
gmac_set_hash64(Gmac * p_gmac,uint64_t ull_hash)1137     static inline void gmac_set_hash64( Gmac * p_gmac,
1138                                         uint64_t ull_hash )
1139     {
1140         p_gmac->GMAC_HRB = ( uint32_t ) ull_hash;
1141         p_gmac->GMAC_HRT = ( uint32_t ) ( ull_hash >> 32 );
1142     }
1143 
1144 /**
1145  * \brief Set MAC Address.
1146  *
1147  * \param p_gmac   Pointer to the GMAC instance.
1148  * \param uc_index  GMAC specific address register index.
1149  * \param p_mac_addr  GMAC address.
1150  */
gmac_set_address(Gmac * p_gmac,uint8_t uc_index,const uint8_t * p_mac_addr)1151     static inline void gmac_set_address( Gmac * p_gmac,
1152                                          uint8_t uc_index,
1153                                          const uint8_t * p_mac_addr )
1154     {
1155         p_gmac->GMAC_SA[ uc_index ].GMAC_SAB = ( p_mac_addr[ 3 ] << 24 )
1156                                                | ( p_mac_addr[ 2 ] << 16 )
1157                                                | ( p_mac_addr[ 1 ] << 8 )
1158                                                | ( p_mac_addr[ 0 ] );
1159         p_gmac->GMAC_SA[ uc_index ].GMAC_SAT = ( p_mac_addr[ 5 ] << 8 )
1160                                                | ( p_mac_addr[ 4 ] );
1161     }
1162 
1163 /**
1164  * \brief Set MAC Address via 2 dword.
1165  *
1166  * \param p_gmac   Pointer to the GMAC instance.
1167  * \param uc_index  GMAC specific address register index.
1168  * \param ul_mac_top  GMAC top address.
1169  * \param ul_mac_bottom  GMAC bottom address.
1170  */
gmac_set_address32(Gmac * p_gmac,uint8_t uc_index,uint32_t ul_mac_top,uint32_t ul_mac_bottom)1171     static inline void gmac_set_address32( Gmac * p_gmac,
1172                                            uint8_t uc_index,
1173                                            uint32_t ul_mac_top,
1174                                            uint32_t ul_mac_bottom )
1175     {
1176         p_gmac->GMAC_SA[ uc_index ].GMAC_SAB = ul_mac_bottom;
1177         p_gmac->GMAC_SA[ uc_index ].GMAC_SAT = ul_mac_top;
1178     }
1179 
1180 /**
1181  * \brief Set MAC Address via int64.
1182  *
1183  * \param p_gmac   Pointer to the GMAC instance.
1184  * \param uc_index  GMAC specific address register index.
1185  * \param ull_mac  64-bit GMAC address.
1186  */
gmac_set_address64(Gmac * p_gmac,uint8_t uc_index,uint64_t ull_mac)1187     static inline void gmac_set_address64( Gmac * p_gmac,
1188                                            uint8_t uc_index,
1189                                            uint64_t ull_mac )
1190     {
1191         p_gmac->GMAC_SA[ uc_index ].GMAC_SAB = ( uint32_t ) ull_mac;
1192         p_gmac->GMAC_SA[ uc_index ].GMAC_SAT = ( uint32_t ) ( ull_mac >> 32 );
1193     }
1194 
1195 /**
1196  * \brief Select media independent interface mode.
1197  *
1198  * \param p_gmac   Pointer to the GMAC instance.
1199  * \param mode   Media independent interface mode.
1200  */
1201     #if ( SAM4E )
gmac_select_mii_mode(Gmac * p_gmac,gmac_mii_mode_t mode)1202         static inline void gmac_select_mii_mode( Gmac * p_gmac,
1203                                                  gmac_mii_mode_t mode )
1204         {
1205             switch( mode )
1206             {
1207                 case GMAC_PHY_MII:
1208                 case GMAC_PHY_RMII:
1209                     p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
1210                     break;
1211 
1212                 default:
1213                     p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
1214                     break;
1215             }
1216         }
1217     #else /* if ( SAM4E ) */
gmac_select_mii_mode(Gmac * p_gmac,gmac_mii_mode_t mode)1218         static inline void gmac_select_mii_mode( Gmac * p_gmac,
1219                                                  gmac_mii_mode_t mode )
1220         {
1221             switch( mode )
1222             {
1223                 case GMAC_PHY_MII:
1224                     p_gmac->GMAC_UR |= GMAC_UR_RMII;
1225                     break;
1226 
1227                 case GMAC_PHY_RMII:
1228                 default:
1229                     p_gmac->GMAC_UR &= ~GMAC_UR_RMII;
1230                     break;
1231             }
1232         }
1233     #endif /* if ( SAM4E ) */
1234 
1235     #if !( SAM4E )
1236 
1237 /**
1238  * \brief Set 1588 timer comparison.
1239  *
1240  * \param p_gmac   Pointer to the GMAC instance.
1241  * \param seconds47   Second comparison high
1242  * \param seconds31   Second comparison low
1243  * \param nanosec     Nanosecond Comparison
1244  */
gmac_set_tsu_compare(Gmac * p_gmac,uint32_t seconds47,uint32_t seconds31,uint32_t nanosec)1245         static inline void gmac_set_tsu_compare( Gmac * p_gmac,
1246                                                  uint32_t seconds47,
1247                                                  uint32_t seconds31,
1248                                                  uint32_t nanosec )
1249         {
1250             p_gmac->GMAC_SCH = seconds47;
1251             p_gmac->GMAC_SCL = seconds31;
1252             p_gmac->GMAC_NSC = nanosec;
1253         }
1254 
1255 /**
1256  * \brief Get interrupt status.
1257  *
1258  * \param p_gmac   Pointer to the GMAC instance.
1259  * \param queue_idx   Index of queue, start from 1
1260  *
1261  * \return Interrupt status.
1262  */
gmac_get_priority_interrupt_status(Gmac * p_gmac,gmac_quelist_t queue_idx)1263         static inline uint32_t gmac_get_priority_interrupt_status( Gmac * p_gmac,
1264                                                                    gmac_quelist_t queue_idx )
1265         {
1266             return p_gmac->GMAC_ISRPQ[ queue_idx - 1 ];
1267         }
1268 
1269 /**
1270  * \brief Set base address of TX buffer.
1271  *
1272  * \param p_gmac   Pointer to the GMAC instance.
1273  * \param queue_idx   Index of queue, start from 1
1274  */
gmac_set_tx_priority_queue(Gmac * p_gmac,uint32_t ul_addr,gmac_quelist_t queue_idx)1275         static inline void gmac_set_tx_priority_queue( Gmac * p_gmac,
1276                                                        uint32_t ul_addr,
1277                                                        gmac_quelist_t queue_idx )
1278         {
1279             p_gmac->GMAC_TBQBAPQ[ queue_idx - 1 ] = GMAC_TBQB_ADDR_Msk & ul_addr;
1280         }
1281 
1282 /**
1283  * \brief Get base address of TX buffer.
1284  *
1285  * \param p_gmac   Pointer to the GMAC instance.
1286  * \param queue_idx   Index of queue, start from 1
1287  *
1288  * \return Base address.
1289  */
gmac_get_tx_priority_queue(Gmac * p_gmac,gmac_quelist_t queue_idx)1290         static inline uint32_t gmac_get_tx_priority_queue( Gmac * p_gmac,
1291                                                            gmac_quelist_t queue_idx )
1292         {
1293             return p_gmac->GMAC_TBQBAPQ[ queue_idx - 1 ];
1294         }
1295 
1296 /**
1297  * \brief Set base address of RX buffer.
1298  *
1299  * \param p_gmac   Pointer to the GMAC instance.
1300  * \param queue_idx   Index of queue, start from 1
1301  */
gmac_set_rx_priority_queue(Gmac * p_gmac,uint32_t ul_addr,gmac_quelist_t queue_idx)1302         static inline void gmac_set_rx_priority_queue( Gmac * p_gmac,
1303                                                        uint32_t ul_addr,
1304                                                        gmac_quelist_t queue_idx )
1305         {
1306             p_gmac->GMAC_RBQBAPQ[ queue_idx - 1 ] = GMAC_RBQB_ADDR_Msk & ul_addr;
1307         }
1308 
1309 /**
1310  * \brief Get base address of RX buffer.
1311  *
1312  * \param p_gmac   Pointer to the GMAC instance.
1313  * \param queue_idx   Index of queue, start from 1
1314  *
1315  * \return Base address.
1316  */
gmac_get_rx_priority_queue(Gmac * p_gmac,gmac_quelist_t queue_idx)1317         static inline uint32_t gmac_get_rx_priority_queue( Gmac * p_gmac,
1318                                                            gmac_quelist_t queue_idx )
1319         {
1320             return p_gmac->GMAC_RBQBAPQ[ queue_idx - 1 ];
1321         }
1322 
1323 /**
1324  * \brief Set size of RX buffer.
1325  *
1326  * \param p_gmac   Pointer to the GMAC instance.
1327  * \param queue_idx   Index of queue, start from 1
1328  */
gmac_set_rx_priority_bufsize(Gmac * p_gmac,uint32_t ul_size,gmac_quelist_t queue_idx)1329         static inline void gmac_set_rx_priority_bufsize( Gmac * p_gmac,
1330                                                          uint32_t ul_size,
1331                                                          gmac_quelist_t queue_idx )
1332         {
1333             p_gmac->GMAC_RBSRPQ[ queue_idx - 1 ] = ul_size;
1334         }
1335 
1336 /**
1337  * \brief Enable or disable credit-based shaping on the second highest priority queue.
1338  *
1339  * \param p_gmac   Pointer to the GMAC instance.
1340  * \param uc_enable   0 to disable, 1 to enable it
1341  */
gmac_enable_cbsque_a(Gmac * p_gmac,uint8_t uc_enable)1342         static inline void gmac_enable_cbsque_a( Gmac * p_gmac,
1343                                                  uint8_t uc_enable )
1344         {
1345             if( uc_enable )
1346             {
1347                 p_gmac->GMAC_CBSCR |= GMAC_CBSCR_QAE;
1348             }
1349             else
1350             {
1351                 p_gmac->GMAC_CBSCR &= ~GMAC_CBSCR_QAE;
1352             }
1353         }
1354 
1355 /**
1356  * \brief Enable or disable credit-based shaping on the highest priority queue.
1357  *
1358  * \param p_gmac   Pointer to the GMAC instance.
1359  * \param uc_enable   0 to disable, 1 to enable it
1360  */
gmac_enable_cbsque_b(Gmac * p_gmac,uint8_t uc_enable)1361         static inline void gmac_enable_cbsque_b( Gmac * p_gmac,
1362                                                  uint8_t uc_enable )
1363         {
1364             if( uc_enable )
1365             {
1366                 p_gmac->GMAC_CBSCR |= GMAC_CBSCR_QBE;
1367             }
1368             else
1369             {
1370                 p_gmac->GMAC_CBSCR &= ~GMAC_CBSCR_QBE;
1371             }
1372         }
1373 
1374 /**
1375  * \brief Set credit-based shaping on the highest priority queue.
1376  *
1377  * \param p_gmac   Pointer to the GMAC instance.
1378  * \param idleslope_a   Value for queue A in bytes/second
1379  */
gmac_config_idleslope_a(Gmac * p_gmac,uint32_t idleslope_a)1380         static inline void gmac_config_idleslope_a( Gmac * p_gmac,
1381                                                     uint32_t idleslope_a )
1382         {
1383             p_gmac->GMAC_CBSISQA = idleslope_a;
1384         }
1385 
1386 /**
1387  * \brief Set credit-based shaping on the highest priority queue.
1388  *
1389  * \param p_gmac   Pointer to the GMAC instance.
1390  * \param idleslope_b   Value for queue B in bytes/second
1391  */
gmac_config_idleslope_b(Gmac * p_gmac,uint32_t idleslope_b)1392         static inline void gmac_config_idleslope_b( Gmac * p_gmac,
1393                                                     uint32_t idleslope_b )
1394         {
1395             p_gmac->GMAC_CBSISQB = idleslope_b;
1396         }
1397 
1398 /**
1399  * \brief Set screening type 1 register.
1400  *
1401  * \param p_gmac   Pointer to the GMAC instance.
1402  * \param reg_val  Value for screening type 1
1403  * \param index    Index of register
1404  */
gmac_write_screener_reg_1(Gmac * p_gmac,uint32_t reg_val,uint32_t index)1405         static inline void gmac_write_screener_reg_1( Gmac * p_gmac,
1406                                                       uint32_t reg_val,
1407                                                       uint32_t index )
1408         {
1409             p_gmac->GMAC_ST1RPQ[ index ] = reg_val;
1410         }
1411 
1412 /**
1413  * \brief Set screening type 2 register.
1414  *
1415  * \param p_gmac   Pointer to the GMAC instance.
1416  * \param reg_val  Value for screening type 2
1417  * \param index    Index of register
1418  */
gmac_write_screener_reg_2(Gmac * p_gmac,uint32_t reg_val,uint32_t index)1419         static inline void gmac_write_screener_reg_2( Gmac * p_gmac,
1420                                                       uint32_t reg_val,
1421                                                       uint32_t index )
1422         {
1423             p_gmac->GMAC_ST2RPQ[ index ] = reg_val;
1424         }
1425 
1426 /**
1427  * \brief Enable interrupt(s).
1428  *
1429  * \param p_gmac   Pointer to the GMAC instance.
1430  * \param ul_source   Interrupt source(s) to be enabled.
1431  * \param queue_idx   Index of queue, start from 1
1432  */
gmac_enable_priority_interrupt(Gmac * p_gmac,uint32_t ul_source,gmac_quelist_t queue_idx)1433         static inline void gmac_enable_priority_interrupt( Gmac * p_gmac,
1434                                                            uint32_t ul_source,
1435                                                            gmac_quelist_t queue_idx )
1436         {
1437             p_gmac->GMAC_IERPQ[ queue_idx - 1 ] = ul_source;
1438         }
1439 
1440 /**
1441  * \brief Disable interrupt(s).
1442  *
1443  * \param p_gmac   Pointer to the GMAC instance.
1444  * \param ul_source   Interrupt source(s) to be disabled.
1445  * \param queue_idx   Index of queue, start from 1
1446  */
gmac_disable_priority_interrupt(Gmac * p_gmac,uint32_t ul_source,gmac_quelist_t queue_idx)1447         static inline void gmac_disable_priority_interrupt( Gmac * p_gmac,
1448                                                             uint32_t ul_source,
1449                                                             gmac_quelist_t queue_idx )
1450         {
1451             p_gmac->GMAC_IDRPQ[ queue_idx - 1 ] = ul_source;
1452         }
1453 
1454 /**
1455  * \brief Get interrupt mask.
1456  *
1457  * \param p_gmac   Pointer to the GMAC instance.
1458  * \param queue_idx   Index of queue, start from 1
1459  *
1460  * \return Interrupt mask.
1461  */
gmac_get_priority_interrupt_mask(Gmac * p_gmac,gmac_quelist_t queue_idx)1462         static inline uint32_t gmac_get_priority_interrupt_mask( Gmac * p_gmac,
1463                                                                  gmac_quelist_t queue_idx )
1464         {
1465             return p_gmac->GMAC_IMRPQ[ queue_idx - 1 ];
1466         }
1467 
1468 /**
1469  * \brief Set screening type 2 eherType register.
1470  *
1471  * \param p_gmac   Pointer to the GMAC instance.
1472  * \param ethertype  Ethertype compare value
1473  * \param index    Index of register
1474  */
gmac_write_ethtype_reg(Gmac * p_gmac,uint16_t ethertype,uint32_t index)1475         static inline void gmac_write_ethtype_reg( Gmac * p_gmac,
1476                                                    uint16_t ethertype,
1477                                                    uint32_t index )
1478         {
1479             p_gmac->GMAC_ST2ER[ index ] = ( uint32_t ) ethertype;
1480         }
1481 
1482 /**
1483  * \brief Set screening type 2 compare word register.
1484  *
1485  * \param p_gmac   Pointer to the GMAC instance.
1486  * \param c0reg    Compare value 0
1487  * \param c1reg    Compare value 1
1488  * \param index    Index of register
1489  */
gmac_write_screen_compare_reg(Gmac * p_gmac,uint32_t c0reg,uint16_t c1reg,uint32_t index)1490         static inline void gmac_write_screen_compare_reg( Gmac * p_gmac,
1491                                                           uint32_t c0reg,
1492                                                           uint16_t c1reg,
1493                                                           uint32_t index )
1494         {
1495             volatile uint32_t * p_PRAS;
1496             uint32_t ul_dlt;
1497 
1498             ul_dlt = ( uint32_t ) &( p_gmac->GMAC_ST2CW01 );
1499             ul_dlt = ul_dlt - ( uint32_t ) &( p_gmac->GMAC_ST2CW00 );
1500 
1501             p_PRAS = ( volatile uint32_t * ) ( ( uint32_t ) &( p_gmac->GMAC_ST2CW00 ) +
1502                                                index * ul_dlt );
1503             *p_PRAS = c0reg;
1504             p_PRAS = ( volatile uint32_t * ) ( ( uint32_t ) &( p_gmac->GMAC_ST2CW10 ) +
1505                                                index * ul_dlt );
1506             *p_PRAS = ( uint32_t ) c1reg;
1507         }
1508 
1509     #endif /* !(SAM4E) */
1510 
1511     uint8_t gmac_phy_read( Gmac * p_gmac,
1512                            uint8_t uc_phy_address,
1513                            uint8_t uc_address,
1514                            uint32_t * p_value );
1515     uint8_t gmac_phy_write( Gmac * p_gmac,
1516                             uint8_t uc_phy_address,
1517                             uint8_t uc_address,
1518                             uint32_t ul_value );
1519     void gmac_dev_init( Gmac * p_gmac,
1520                         gmac_device_t * p_gmac_dev,
1521                         gmac_options_t * p_opt );
1522     uint32_t gmac_dev_read( gmac_device_t * p_gmac_dev,
1523                             uint8_t * p_frame,
1524                             uint32_t ul_frame_size,
1525                             uint32_t * p_rcv_size,
1526                             uint8_t ** pp_recv_frame );
1527     uint32_t gmac_dev_write( gmac_device_t * p_gmac_dev,
1528                              void * p_buffer,
1529                              uint32_t ul_size );
1530     uint32_t gmac_dev_get_tx_load( gmac_device_t * p_gmac_dev );
1531     uint8_t gmac_dev_set_tx_wakeup_callback( gmac_device_t * p_gmac_dev,
1532                                              gmac_dev_wakeup_cb_t func_wakeup,
1533                                              uint8_t uc_threshold );
1534     void gmac_dev_reset( gmac_device_t * p_gmac_dev );
1535     void gmac_handler( gmac_device_t * p_gmac_dev );
1536 
1537     void gmac_reset_tx_mem( gmac_device_t * p_dev );
1538 
1539 /*/ @cond 0 */
1540 /**INDENT-OFF**/
1541     #ifdef __cplusplus
1542         }
1543     #endif
1544 /**INDENT-ON**/
1545 /*/ @endcond */
1546 
1547 
1548     #define GMAC_STATS    0
1549 
1550     #if ( GMAC_STATS != 0 )
1551 
1552 /* Here below some code to study the types and
1553  * frequencies of  GMAC interrupts. */
1554         #define GMAC_IDX_RXUBR    0
1555         #define GMAC_IDX_TUR      1
1556         #define GMAC_IDX_RLEX     2
1557         #define GMAC_IDX_TFC      3
1558         #define GMAC_IDX_RCOMP    4
1559         #define GMAC_IDX_TCOMP    5
1560         #define GMAC_IDX_ROVR     6
1561         #define GMAC_IDX_HRESP    7
1562         #define GMAC_IDX_PFNZ     8
1563         #define GMAC_IDX_PTZ      9
1564 
1565         struct SGmacStats
1566         {
1567             unsigned recvCount;
1568             unsigned rovrCount;
1569             unsigned bnaCount;
1570             unsigned sendCount;
1571             unsigned sovrCount;
1572             unsigned incompCount;
1573             unsigned truncCount;
1574 
1575             unsigned intStatus[ 10 ];
1576         };
1577         extern struct SGmacStats gmacStats;
1578 
1579         struct SIntPair
1580         {
1581             const char * name;
1582             unsigned mask;
1583             int index;
1584         };
1585 
1586         #define MK_PAIR( NAME )    # NAME, GMAC_IER_ ## NAME, GMAC_IDX_ ## NAME
1587         static const struct SIntPair intPairs[] = {
1588             { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
1589             { MK_PAIR( TUR )   }, /* Enable transmit underrun interrupt. */
1590             { MK_PAIR( RLEX )  }, /* Enable retry limit  exceeded interrupt. */
1591             { MK_PAIR( TFC )   }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
1592             { MK_PAIR( RCOMP ) }, /* Receive complete */
1593             { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
1594             { MK_PAIR( ROVR )  }, /* Enable receive overrun interrupt. */
1595             { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
1596             { MK_PAIR( PFNZ )  }, /* Enable pause frame received interrupt. */
1597             { MK_PAIR( PTZ )   } /* Enable pause time zero interrupt. */
1598         };
1599 
1600         void gmac_show_irq_counts();
1601 
1602     #endif /* if ( GMAC_STATS != 0 ) */
1603 
1604 #endif /* GMAC_H_INCLUDED */
1605