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