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