2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "fsl_enet_hal.h"
35 /*******************************************************************************
37 ******************************************************************************/
39 /*******************************************************************************
41 ******************************************************************************/
43 /*FUNCTION****************************************************************
45 * Function Name: enet_hal_set_mac_address
46 * Description: Set ENET mac physical address.
48 *END*********************************************************************/
49 void enet_hal_set_mac_address(uint32_t instance
, enetMacAddr hwAddr
)
51 // assert(instance < HW_ENET_INSTANCE_COUNT);
53 uint32_t address
, data
;
55 address
= (uint32_t)(((uint32_t)hwAddr
[0] << 24U)|((uint32_t)hwAddr
[1] << 16U)|((uint32_t)hwAddr
[2] << 8U)| (uint32_t)hwAddr
[3]) ;
56 HW_ENET_PALR_WR(instance
,address
); /* Set low physical address */
57 address
= (uint32_t)(((uint32_t)hwAddr
[4] << 24U)|((uint32_t)hwAddr
[5] << 16U)) ;
58 data
= HW_ENET_PAUR_RD(instance
) & BM_ENET_PAUR_TYPE
;
59 HW_ENET_PAUR_WR(instance
, (data
| address
)); /* Set high physical address */
62 /*FUNCTION****************************************************************
64 * Function Name: enet_hal_set_group_hashtable
65 * Description: Set multicast group address hash value to the mac register
66 * To join the multicast group address.
67 *END*********************************************************************/
68 void enet_hal_set_group_hashtable(uint32_t instance
, uint32_t crcValue
, enet_special_address_filter_t mode
)
70 // assert(instance < HW_ENET_INSTANCE_COUNT);
74 case kEnetSpecialAddressInit
: /* Clear group address register on ENET initialize */
75 HW_ENET_GALR_WR(instance
,0);
76 HW_ENET_GAUR_WR(instance
,0);
78 case kEnetSpecialAddressEnable
: /* Enable a multicast group address*/
79 if (!((crcValue
>> 31) & 1U))
81 HW_ENET_GALR_SET(instance
,(1U << ((crcValue
>> 26) & kEnetHashValMask
)));
85 HW_ENET_GAUR_SET(instance
,(1U << ((crcValue
>> 26) & kEnetHashValMask
)));
88 case kEnetSpecialAddressDisable
: /* Disable a multicast group address*/
89 if (!((crcValue
>> 31) & 1U))
91 HW_ENET_GALR_CLR(instance
,(1U << ((crcValue
>> 26) & kEnetHashValMask
)));
95 HW_ENET_GAUR_CLR(instance
,(1U << ((crcValue
>>26) & kEnetHashValMask
)));
103 /*FUNCTION****************************************************************
105 * Function Name: enet_hal_set_individual_hashtable
106 * Description: Set a specific unicast address hash value to the mac register
107 * To receive frames with the individual destination address.
108 *END*********************************************************************/
109 void enet_hal_set_individual_hashtable(uint32_t instance
, uint32_t crcValue
, enet_special_address_filter_t mode
)
111 // assert(instance < HW_ENET_INSTANCE_COUNT);
115 case kEnetSpecialAddressInit
: /* Clear individual address register on ENET initialize */
116 HW_ENET_IALR_WR(instance
,0);
117 HW_ENET_IAUR_WR(instance
,0);
119 case kEnetSpecialAddressEnable
: /* Enable a special address*/
120 if (((crcValue
>>31) & 1U) == 0)
122 HW_ENET_IALR_SET(instance
,(1U << ((crcValue
>>26)& kEnetHashValMask
)));
126 HW_ENET_IAUR_SET(instance
,(1U << ((crcValue
>>26)& kEnetHashValMask
)));
129 case kEnetSpecialAddressDisable
: /* Disable a special address*/
130 if (((crcValue
>>31) & 1U) == 0)
132 HW_ENET_IALR_CLR(instance
,(1U << ((crcValue
>>26)& kEnetHashValMask
)));
136 HW_ENET_IAUR_CLR(instance
,(1U << ((crcValue
>>26)& kEnetHashValMask
)));
144 /*FUNCTION****************************************************************
146 * Function Name: enet_hal_config_tx_fifo
147 * Description: Configure ENET transmit FIFO.
148 *END*********************************************************************/
149 void enet_hal_config_tx_fifo(uint32_t instance
, enet_config_tx_fifo_t
*thresholdCfg
)
151 // assert(instance < HW_ENET_INSTANCE_COUNT);
152 assert(thresholdCfg
);
154 BW_ENET_TFWR_STRFWD(instance
, thresholdCfg
->isStoreForwardEnabled
); /* Set store and forward mode*/
155 if(!thresholdCfg
->isStoreForwardEnabled
)
157 assert(thresholdCfg
->txFifoWrite
<= BM_ENET_TFWR_TFWR
);
158 BW_ENET_TFWR_TFWR(instance
, thresholdCfg
->txFifoWrite
); /* Set transmit FIFO write bytes*/
160 BW_ENET_TSEM_TX_SECTION_EMPTY(instance
,thresholdCfg
->txEmpty
); /* Set transmit FIFO empty threshold*/
161 BW_ENET_TAEM_TX_ALMOST_EMPTY(instance
,thresholdCfg
->txAlmostEmpty
); /* Set transmit FIFO almost empty threshold*/
162 BW_ENET_TAFL_TX_ALMOST_FULL(instance
,thresholdCfg
->txAlmostFull
); /* Set transmit FIFO almost full threshold*/
165 /*FUNCTION****************************************************************
167 * Function Name: enet_hal_config_rx_fifo
168 * Description: Configure ENET receive FIFO.
169 *END*********************************************************************/
170 void enet_hal_config_rx_fifo(uint32_t instance
,enet_config_rx_fifo_t
*thresholdCfg
)
172 // assert(instance < HW_ENET_INSTANCE_COUNT);
173 assert(thresholdCfg
);
174 if(thresholdCfg
->rxFull
> 0)
176 assert(thresholdCfg
->rxFull
> thresholdCfg
->rxAlmostEmpty
);
179 BW_ENET_RSFL_RX_SECTION_FULL(instance
,thresholdCfg
->rxFull
); /* Set receive FIFO full threshold*/
180 BW_ENET_RSEM_RX_SECTION_EMPTY(instance
,thresholdCfg
->rxEmpty
); /* Set receive FIFO empty threshold*/
181 BW_ENET_RAEM_RX_ALMOST_EMPTY(instance
,thresholdCfg
->rxAlmostEmpty
); /* Set receive FIFO almost empty threshold*/
182 BW_ENET_RAFL_RX_ALMOST_FULL(instance
,thresholdCfg
->rxAlmostFull
); /* Set receive FIFO almost full threshold*/
185 /*FUNCTION****************************************************************
187 * Function Name: enet_hal_init_rxbds
188 * Description: Initialize ENET receive buffer descriptors.
189 *END*********************************************************************/
190 void enet_hal_init_rxbds(void *rxBds
, uint8_t *buffer
, bool isLastBd
)
195 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)rxBds
;
197 bdPtr
->buffer
= (uint8_t *)NTOHL((uint32_t)buffer
); /* Set data buffer address */
198 bdPtr
->length
= 0; /* Initialize data length*/
200 /*The last buffer descriptor should be set with the wrap flag*/
203 bdPtr
->control
|= kEnetRxBdWrap
;
205 bdPtr
->control
|= kEnetRxBdEmpty
; /* Initialize bd with empty bit*/
206 bdPtr
->controlExtend1
|= kEnetRxBdIntrrupt
;/* Enable receive interrupt*/
209 /*FUNCTION****************************************************************
211 * Function Name: enet_hal_init_txbds
212 * Description: Initialize ENET transmit buffer descriptors.
213 *END*********************************************************************/
214 void enet_hal_init_txbds(void *txBds
, bool isLastBd
)
218 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)txBds
;
220 bdPtr
->length
= 0; /* Initialize data length*/
222 /*The last buffer descriptor should be set with the wrap flag*/
225 bdPtr
->control
|= kEnetTxBdWrap
;
229 /*FUNCTION****************************************************************
231 * Function Name: enet_hal_update_rxbds
232 * Description: Update ENET receive buffer descriptors.
233 *END*********************************************************************/
234 void enet_hal_update_rxbds(void *rxBds
, uint8_t *data
, bool isbufferUpdate
)
238 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)rxBds
;
242 bdPtr
->buffer
= (uint8_t *)HTONL((uint32_t)data
);
244 bdPtr
->control
&= kEnetRxBdWrap
; /* Clear status*/
245 bdPtr
->control
|= kEnetRxBdEmpty
; /* Set rx bd empty*/
246 bdPtr
->controlExtend1
|= kEnetRxBdIntrrupt
;/* Enable interrupt*/
249 /*FUNCTION****************************************************************
251 * Function Name: enet_hal_update_txbds
252 * Description: Update ENET transmit buffer descriptors.
253 *END*********************************************************************/
254 void enet_hal_update_txbds(void *txBds
,uint8_t *buffer
, uint16_t length
, bool isTxtsCfged
)
259 volatile enet_bd_struct_t
* bdPtr
= (enet_bd_struct_t
*)txBds
;
261 bdPtr
->length
= HTONS(length
); /* Set data length*/
262 bdPtr
->buffer
= (uint8_t *)HTONL((uint32_t)buffer
); /* Set data buffer*/
263 bdPtr
->control
|= kEnetTxBdLast
| kEnetTxBdTransmitCrc
| kEnetTxBdReady
;/* set control */
266 /* Set receive and timestamp interrupt*/
267 bdPtr
->controlExtend1
|= (kEnetTxBdTxInterrupt
| kEnetTxBdTimeStamp
);
271 /* Set receive interrupt*/
272 bdPtr
->controlExtend1
|= kEnetTxBdTxInterrupt
;
276 /*FUNCTION****************************************************************
278 * Function Name: enet_hal_get_rxbd_control
279 * Description: Get receive buffer descriptor control and status region.
280 *END*********************************************************************/
281 uint16_t enet_hal_get_rxbd_control(void *curBd
)
285 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
286 return bdPtr
->control
;
289 /*FUNCTION****************************************************************
291 * Function Name: enet_hal_get_txbd_control
292 * Description: Get ENET transmit buffer descriptor control and status data.
293 *END*********************************************************************/
294 uint16_t enet_hal_get_txbd_control(void *curBd
)
297 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
298 return bdPtr
->control
;
301 /*FUNCTION****************************************************************
303 * Function Name: enet_hal_get_bd_length
304 * Description: Get ENET data length of buffer descriptors.
305 *END*********************************************************************/
306 uint16_t enet_hal_get_bd_length(void *curBd
)
311 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
312 length
= bdPtr
->length
;
313 return NTOHS(length
);
316 /*FUNCTION****************************************************************
318 * Function Name: enet_hal_get_bd_buffer
319 * Description: Get the buffer address of buffer descriptors.
320 *END*********************************************************************/
321 uint8_t* enet_hal_get_bd_buffer(void *curBd
)
325 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
326 uint32_t buffer
= (uint32_t)(bdPtr
->buffer
);
327 return (uint8_t *)NTOHL(buffer
);
330 /*FUNCTION****************************************************************
332 * Function Name: enet_hal_get_bd_timestamp
333 * Description: Get the timestamp of buffer descriptors.
334 *END*********************************************************************/
335 uint32_t enet_hal_get_bd_timestamp(void *curBd
)
338 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
339 uint32_t timestamp
= bdPtr
->timestamp
;
340 return NTOHL(timestamp
);
343 /*FUNCTION****************************************************************
345 * Function Name: enet_hal_get_rxbd_control_extend
346 * Description: Get ENET receive buffer descriptor extended control region.
347 *END*********************************************************************/
348 bool enet_hal_get_rxbd_control_extend(void *curBd
,enet_rx_bd_control_extend_t controlRegion
)
352 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
354 #if SYSTEM_LITTLE_ENDIAN && FSL_FEATURE_ENET_DMA_BIG_ENDIAN_ONLY
355 if (((uint16_t)controlRegion
> kEnetRxBdCtlJudge1
) && ((uint16_t)controlRegion
< kEnetRxBdCtlJudge2
))
357 return ((bdPtr
->controlExtend0
& controlRegion
) != 0); /* Control extended0 region*/
361 return ((bdPtr
->controlExtend1
& controlRegion
) != 0); /* Control extended1 region*/
364 if( (uint16_t)controlRegion
< kEnetRxBdCtlJudge1
)
366 return ((bdPtr
->controlExtend0
& controlRegion
) != 0); /* Control extended0 region*/
370 return ((bdPtr
->controlExtend1
& controlRegion
) != 0);/* Control extended1 region*/
375 /*FUNCTION****************************************************************
377 * Function Name: enet_hal_get_txbd_control_extend
378 * Description: Get ENET transmit buffer descriptor extended control region.
379 *END*********************************************************************/
380 uint16_t enet_hal_get_txbd_control_extend(void *curBd
)
383 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
385 return bdPtr
->controlExtend0
;
388 /*FUNCTION****************************************************************
390 * Function Name: enet_hal_get_txbd_timestamp_flag
391 * Description: Get ENET transmit buffer descriptor timestamp region.
392 *END*********************************************************************/
393 bool enet_hal_get_txbd_timestamp_flag(void *curBd
)
396 volatile enet_bd_struct_t
*bdPtr
= (enet_bd_struct_t
*)curBd
;
397 return ((bdPtr
->controlExtend1
& kEnetTxBdTimeStamp
) != 0);
400 /*FUNCTION****************************************************************
402 * Function Name: enet_hal_config_rmii
403 * Description: Configure (R)MII mode.
404 *END*********************************************************************/
405 void enet_hal_config_rmii(uint32_t instance
, enet_config_rmii_t mode
, enet_config_speed_t speed
, enet_config_duplex_t duplex
, bool isRxOnTxDisabled
, bool isLoopEnabled
)
407 // assert(instance < HW_ENET_INSTANCE_COUNT);
409 BW_ENET_RCR_MII_MODE(instance
,1); /* Set mii mode */
410 BW_ENET_RCR_RMII_MODE(instance
,mode
);
411 BW_ENET_RCR_RMII_10T(instance
,speed
); /* Set speed mode */
412 BW_ENET_TCR_FDEN(instance
,duplex
); /* Set duplex mode*/
413 if ((!duplex
) && isRxOnTxDisabled
)
415 BW_ENET_RCR_DRT(instance
,1); /* Disable receive on transmit*/
418 if (mode
== kEnetCfgMii
) /* Set internal loop only for mii mode*/
420 BW_ENET_RCR_LOOP(instance
,isLoopEnabled
);
424 BW_ENET_RCR_LOOP(instance
, 0); /* Clear internal loop for rmii mode*/
428 /*FUNCTION****************************************************************
430 * Function Name: enet_hal_set_mii_command
431 * Description: Set MII command.
432 *END*********************************************************************/
433 void enet_hal_set_mii_command(uint32_t instance
, uint32_t phyAddr
, uint32_t phyReg
, enet_mii_operation_t operation
, uint32_t data
)
435 // assert(instance < HW_ENET_INSTANCE_COUNT);
436 uint32_t mmfrValue
= 0 ;
438 mmfrValue
= BF_ENET_MMFR_ST(1)| BF_ENET_MMFR_OP(operation
)| BF_ENET_MMFR_PA(phyAddr
) | BF_ENET_MMFR_RA(phyReg
)| BF_ENET_MMFR_TA(2) | (data
&0xFFFF); /* mii command*/
439 HW_ENET_MMFR_WR(instance
,mmfrValue
);
442 /*FUNCTION****************************************************************
444 * Function Name: enet_hal_config_ethernet
445 * Description: Enable or disable normal Ethernet mode and enhanced mode.
446 *END*********************************************************************/
447 void enet_hal_config_ethernet(uint32_t instance
, bool isEnhanced
, bool isEnabled
)
449 // assert(instance < HW_ENET_INSTANCE_COUNT);
451 BW_ENET_ECR_ETHEREN(instance
,isEnabled
); /* Enable/Disable Ethernet module*/
454 BW_ENET_ECR_EN1588(instance
,isEnabled
); /* Enable/Disable enhanced frame feature*/
456 #if SYSTEM_LITTLE_ENDIAN && !FSL_FEATURE_ENET_DMA_BIG_ENDIAN_ONLY
457 BW_ENET_ECR_DBSWP(instance
,1); /* buffer descriptor byte swapping for little-endian system and endianness configurable IP*/
461 /*FUNCTION****************************************************************
463 * Function Name: enet_hal_config_interrupt
464 * Description: Enable or disable different Ethernet interrupts.
465 * the parameter source is the interrupt source and enet_interrupt_request_t
466 * enum types is recommended to be used as the interrupt sources.
467 *END*********************************************************************/
468 void enet_hal_config_interrupt(uint32_t instance
, uint32_t source
, bool isEnabled
)
470 // assert(instance < HW_ENET_INSTANCE_COUNT);
474 HW_ENET_EIMR_SET(instance
,source
); /* Enable interrupt */
478 HW_ENET_EIMR_CLR(instance
,source
); /* Disable interrupt*/
482 /*FUNCTION****************************************************************
484 * Function Name: enet_hal_config_tx_accelerator
485 * Description: Configure Ethernet transmit accelerator features.
486 *END*********************************************************************/
487 void enet_hal_config_tx_accelerator(uint32_t instance
, enet_config_tx_accelerator_t
*txCfgPtr
)
489 // assert(instance < HW_ENET_INSTANCE_COUNT);
492 HW_ENET_TACC_WR(instance
,0); /* Clear all*/
493 BW_ENET_TACC_IPCHK(instance
,txCfgPtr
->isIpCheckEnabled
); /* Insert ipheader checksum */
494 BW_ENET_TACC_PROCHK(instance
,txCfgPtr
->isProtocolCheckEnabled
); /* Insert protocol checksum*/
495 BW_ENET_TACC_SHIFT16(instance
,txCfgPtr
->isShift16Enabled
); /* Set tx fifo shift-16*/
498 /*FUNCTION****************************************************************
500 * Function Name: enet_hal_config_rx_accelerator
501 * Description: Configure Ethernet receive accelerator features.
502 *END*********************************************************************/
503 void enet_hal_config_rx_accelerator(uint32_t instance
, enet_config_rx_accelerator_t
*rxCfgPtr
)
505 // assert(instance < HW_ENET_INSTANCE_COUNT);
508 HW_ENET_RACC_WR(instance
,0); /* Clear all*/
509 BW_ENET_RACC_IPDIS(instance
,rxCfgPtr
->isIpcheckEnabled
); /* Set ipchecksum field*/
510 BW_ENET_RACC_PRODIS(instance
,rxCfgPtr
->isProtocolCheckEnabled
); /* Set protocol field*/
511 BW_ENET_RACC_LINEDIS(instance
,rxCfgPtr
->isMacCheckEnabled
); /* Set maccheck field*/
512 BW_ENET_RACC_SHIFT16(instance
,rxCfgPtr
->isShift16Enabled
); /* Set rx fifo shift field*/
513 BW_ENET_RACC_PADREM(instance
,rxCfgPtr
->isPadRemoveEnabled
); /* Set rx padding remove field*/
516 /*FUNCTION****************************************************************
518 * Function Name: enet_hal_set_txpause
519 * Return Value: The execution status.
520 * Description: Set the ENET transmit controller with pause duration and
521 * Set enet transmit PAUSE frame transmission.
522 * This should be called when a PAUSE frame is dynamically wanted.
523 *END*********************************************************************/
524 void enet_hal_set_txpause(uint32_t instance
, uint32_t pauseDuration
)
526 // assert(instance < HW_ENET_INSTANCE_COUNT);
527 assert(pauseDuration
<= BM_ENET_OPD_PAUSE_DUR
);
528 BW_ENET_OPD_PAUSE_DUR(instance
, pauseDuration
);
529 BW_ENET_TCR_TFC_PAUSE(instance
, 1);
532 /*FUNCTION****************************************************************
534 * Function Name: enet_hal_init_ptp_timer
535 * Description: Initialize Ethernet ptp timer.
536 *END*********************************************************************/
537 void enet_hal_init_ptp_timer(uint32_t instance
,enet_config_ptp_timer_t
*ptpCfgPtr
)
539 // assert(instance < HW_ENET_INSTANCE_COUNT);
542 BW_ENET_ATINC_INC(instance
, ptpCfgPtr
->clockIncease
); /* Set increase value for ptp timer*/
543 HW_ENET_ATPER_WR(instance
, ptpCfgPtr
->period
); /* Set wrap time for ptp timer*/
544 /* set periodical event and the event signal output assertion*/
545 BW_ENET_ATCR_PEREN(instance
, 1);
546 BW_ENET_ATCR_PINPER(instance
, 1);
547 /* Set ptp timer slave/master mode*/
548 BW_ENET_ATCR_SLAVE(instance
, ptpCfgPtr
->isSlaveEnabled
);
551 #endif /* MBED_NO_ENET */
554 /*******************************************************************************
556 ******************************************************************************/