1 /***************************************************************************//**
\r
3 * SmartFusion MSS Ethernet MAC driver implementation.
\r
5 * (c) Copyright 2007 Actel Corporation
\r
7 * SVN $Revision: 2369 $
\r
8 * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $
\r
10 ******************************************************************************/
\r
19 #include "mss_ethernet_mac.h"
\r
20 #include "mss_ethernet_mac_regs.h"
\r
21 #include "mss_ethernet_mac_desc.h"
\r
22 #include "mss_ethernet_mac_conf.h"
\r
23 #include "../../CMSIS/mss_assert.h"
\r
27 /**************************** INTERNAL DEFINES ********************************/
\r
29 #define MAC_CHECK(CHECK,ERRNO) \
\r
30 {if(!(CHECK)){g_mss_mac.last_error=(ERRNO); ASSERT((CHECK));}}
\r
35 #define FLAG_MAC_INIT_DONE 1u
\r
36 #define FLAG_PERFECT_FILTERING 2u
\r
37 #define FLAG_CRC_DISABLE 4u
\r
38 #define FLAG_EXCEED_LIMIT 8u
\r
44 #define MAC_FAIL (-1)
\r
45 #define MAC_WRONG_PARAMETER (-2)
\r
46 #define MAC_TOO_BIG_PACKET (-3)
\r
47 #define MAC_BUFFER_IS_FULL (-4)
\r
48 #define MAC_NOT_ENOUGH_SPACE (-5)
\r
49 #define MAC_TIME_OUT (-6)
\r
50 #define MAC_TOO_SMALL_PACKET (-7)
\r
52 /***************************************************************/
\r
53 MAC_instance_t g_mss_mac;
\r
55 /**************************** INTERNAL DATA ***********************************/
\r
56 #define ERROR_MESSAGE_COUNT 8
\r
57 #define MAX_ERROR_MESSAGE_WIDTH 40
\r
58 static const int8_t unknown_error[] = "Unknown error";
\r
59 static const int8_t ErrorMessages[][MAX_ERROR_MESSAGE_WIDTH] = {
\r
62 "Wrong parameter pased to function",
\r
63 "Frame is too long",
\r
64 "Not enough space in buffer",
\r
65 "Not enough space in buffer",
\r
67 "Frame is too small"
\r
73 static MAC_instance_t* NULL_instance;
\r
74 static uint8_t* NULL_buffer;
\r
75 static MSS_MAC_callback_t NULL_callback;
\r
77 /**************************** INTERNAL FUNCTIONS ******************************/
\r
79 static int32_t MAC_test_instance( void );
\r
81 static int32_t MAC_dismiss_bad_frames( void );
\r
82 static int32_t MAC_send_setup_frame( void );
\r
84 static int32_t MAC_stop_transmission( void );
\r
85 static void MAC_start_transmission( void );
\r
86 static int32_t MAC_stop_receiving( void );
\r
87 static void MAC_start_receiving( void );
\r
89 static void MAC_set_time_out( uint32_t time_out );
\r
90 static uint32_t MAC_get_time_out( void );
\r
92 static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n);
\r
93 static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n);
\r
94 static void MAC_memset_All(MAC_instance_t *s, uint32_t c);
\r
96 /***************************************************************************//**
\r
97 * Initializes the Ethernet Controller.
\r
98 * This function will prepare the Ethernet Controller for first time use in a
\r
99 * given hardware/software configuration. This function should be called before
\r
100 * any other Ethernet API functions are called.
\r
102 * Initialization of registers - config registers, enable Tx/Rx interrupts,
\r
103 * enable Tx/Rx, initialize MAC addr, init PHY, autonegotiation, MAC address
\r
104 * filter table (unicats/multicast)/hash init
\r
109 uint8_t phy_address
\r
112 const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS };
\r
116 /* Try to reset chip */
\r
117 MAC_BITBAND->CSR0_SWR = 1u;
\r
119 while ( 1u == MAC_BITBAND->CSR0_SWR )
\r
124 /* Check reset values of some registers to constrol
\r
125 * base address validity */
\r
126 ASSERT( MAC->CSR0 == 0xFE000000uL );
\r
127 ASSERT( MAC->CSR5 == 0xF0000000uL );
\r
128 ASSERT( MAC->CSR6 == 0x32000040uL );
\r
130 /* Instance setup */
\r
131 MAC_memset_All( &g_mss_mac, 0u );
\r
133 g_mss_mac.base_address = MAC_BASE;
\r
134 g_mss_mac.phy_address = phy_address;
\r
136 for( a=0; a<RX_RING_SIZE; a++ )
\r
138 /* Give the ownership to the MAC */
\r
139 g_mss_mac.rx_descriptors[a].descriptor_0 = RDES0_OWN;
\r
140 g_mss_mac.rx_descriptors[a].descriptor_1 = (MSS_RX_BUFF_SIZE << RDES1_RBS1_OFFSET);
\r
141 g_mss_mac.rx_descriptors[a].buffer_1 = (uint32_t)g_mss_mac.rx_buffers[a];
\r
143 g_mss_mac.rx_descriptors[RX_RING_SIZE-1].descriptor_1 |= RDES1_RER;
\r
145 for( a = 0; a < TX_RING_SIZE; a++ )
\r
147 g_mss_mac.tx_descriptors[a].buffer_1 = (uint32_t)g_mss_mac.tx_buffers[a];
\r
149 g_mss_mac.tx_descriptors[TX_RING_SIZE - 1].descriptor_1 |= TDES1_TER;
\r
151 /* Configurable settings */
\r
152 MAC_BITBAND->CSR0_DBO = DESCRIPTOR_BYTE_ORDERING_MODE;
\r
153 MAC->CSR0 = (MAC->CSR0 & ~CSR0_PBL_MASK) | ((uint32_t)PROGRAMMABLE_BURST_LENGTH << CSR0_PBL_SHIFT);
\r
154 MAC_BITBAND->CSR0_BLE = BUFFER_BYTE_ORDERING_MODE;
\r
155 MAC_BITBAND->CSR0_BAR = (uint32_t)BUS_ARBITRATION_SCHEME;
\r
157 /* Fixed settings */
\r
158 /* No automatic polling */
\r
159 MAC->CSR0 = MAC->CSR0 &~ CSR0_TAP_MASK;
\r
160 /* No space between descriptors */
\r
161 MAC->CSR0 = MAC->CSR0 &~ CSR0_DSL_MASK;
\r
162 /* General-purpose timer works in continuous mode */
\r
163 MAC_BITBAND->CSR11_CON = 1u;
\r
164 /* Start general-purpose */
\r
165 MAC->CSR11 = (MAC->CSR11 & ~CSR11_TIM_MASK) | (0x0000FFFFuL << CSR11_TIM_SHIFT);
\r
167 /* Disable promiscuous mode */
\r
168 MAC_BITBAND->CSR6_PR = 0u;
\r
170 /* Enable store and forward */
\r
171 MAC_BITBAND->CSR6_SF = 1u;
\r
173 /* Set descriptors */
\r
174 MAC->CSR3 = (uint32_t)&(g_mss_mac.rx_descriptors[0].descriptor_0);
\r
175 MAC->CSR4 = (uint32_t)&(g_mss_mac.tx_descriptors[0].descriptor_0);
\r
177 /* enable normal interrupts */
\r
178 MAC_BITBAND->CSR7_NIE = 1u;
\r
181 if( g_mss_mac.phy_address > MSS_PHY_ADDRESS_MAX )
\r
184 ASSERT( g_mss_mac.phy_address <= MSS_PHY_ADDRESS_MAX );
\r
191 g_mss_mac.flags = FLAG_MAC_INIT_DONE | FLAG_PERFECT_FILTERING;
\r
193 /* Configure chip according to PHY status */
\r
194 MSS_MAC_auto_setup_link();
\r
196 /* Set default MAC address and reset mac filters */
\r
197 MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u );
\r
198 MSS_MAC_set_mac_filters( 0u, NULL_buffer );
\r
201 /* Start receiving and transmission */
\r
202 MAC_start_receiving();
\r
203 MAC_start_transmission();
\r
207 /***************************************************************************//**
\r
208 * Sets the configuration of the Ethernet Controller.
\r
209 * After the EthernetInit function has been called, this API function can be
\r
210 * used to configure the various features of the Ethernet Controller.
\r
212 * @param instance Pointer to a MAC_instance_t structure
\r
213 * @param config The logical OR of the following values:
\r
214 * - #MSS_MAC_CFG_RECEIVE_ALL
\r
215 * - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE
\r
216 * - #MSS_MSS_MAC_CFG_STORE_AND_FORWARD
\r
217 * - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]
\r
218 * - #MSS_MAC_CFG_FULL_DUPLEX_MODE
\r
219 * - #MSS_MAC_CFG_PASS_ALL_MULTICAST
\r
220 * - #MSS_MAC_CFG_PROMISCUOUS_MODE
\r
221 * - #MSS_MAC_CFG_PASS_BAD_FRAMES
\r
222 * @see MAC_get_configuration()
\r
227 uint32_t configuration
\r
232 ASSERT( MAC_test_instance() == MAC_OK );
\r
234 ret = MAC_stop_transmission();
\r
235 ASSERT( ret == MAC_OK );
\r
237 ret = MAC_stop_receiving();
\r
238 ASSERT( ret == MAC_OK );
\r
240 MAC_BITBAND->CSR6_RA = (uint32_t)(((configuration & MSS_MAC_CFG_RECEIVE_ALL) != 0u) ? 1u : 0u );
\r
241 MAC_BITBAND->CSR6_TTM = (((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? 1u : 0u );
\r
242 MAC_BITBAND->CSR6_SF = (uint32_t)(((configuration & MSS_MAC_CFG_STORE_AND_FORWARD) != 0u) ? 1u : 0u );
\r
244 switch( configuration & MSS_MAC_CFG_THRESHOLD_CONTROL_11 ) {
\r
245 case MSS_MAC_CFG_THRESHOLD_CONTROL_00:
\r
246 MAC->CSR6 = MAC->CSR6 & ~CSR6_TR_MASK;
\r
248 case MSS_MAC_CFG_THRESHOLD_CONTROL_01:
\r
249 MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)1 << CSR6_TR_SHIFT );
\r
251 case MSS_MAC_CFG_THRESHOLD_CONTROL_10:
\r
252 MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)2 << CSR6_TR_SHIFT );
\r
254 case MSS_MAC_CFG_THRESHOLD_CONTROL_11:
\r
255 MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)3 << CSR6_TR_SHIFT );
\r
260 MAC_BITBAND->CSR6_FD = (uint32_t)(((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? 1u : 0u );
\r
261 MAC_BITBAND->CSR6_PM = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_ALL_MULTICAST) != 0u) ? 1u : 0u );
\r
262 MAC_BITBAND->CSR6_PR = (uint32_t)(((configuration & MSS_MAC_CFG_PROMISCUOUS_MODE) != 0u) ? 1u : 0u );
\r
263 MAC_BITBAND->CSR6_PB = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_BAD_FRAMES) != 0u) ? 1u : 0u );
\r
264 PHY_set_link_type( (uint8_t)
\r
265 ((((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? MSS_MAC_LINK_STATUS_100MB : 0u ) |
\r
266 (((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? MSS_MAC_LINK_STATUS_FDX : 0u )) );
\r
268 MAC_start_transmission();
\r
269 MAC_start_receiving();
\r
271 MSS_MAC_auto_setup_link();
\r
275 /***************************************************************************//**
\r
276 * Returns the configuration of the Ethernet Controller.
\r
278 * @param instance Pointer to a MAC_instance_t structure
\r
279 * @return The logical OR of the following values:
\r
280 * - #MSS_MAC_CFG_RECEIVE_ALL
\r
281 * - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE
\r
282 * - #MSS_MAC_CFG_STORE_AND_FORWARD
\r
283 * - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]
\r
284 * - #MSS_MAC_CFG_FULL_DUPLEX_MODE
\r
285 * - #MSS_MAC_CFG_PASS_ALL_MULTICAST
\r
286 * - #MSS_MAC_CFG_PROMISCUOUS_MODE
\r
287 * - #MSS_MAC_CFG_INVERSE_FILTERING
\r
288 * - #MSS_MAC_CFG_PASS_BAD_FRAMES
\r
289 * - #MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE
\r
290 * - #MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE
\r
291 * @see MAC_configure()
\r
294 MSS_MAC_get_configuration( void )
\r
296 uint32_t configuration;
\r
298 ASSERT( MAC_test_instance() == MAC_OK );
\r
300 configuration = 0u;
\r
301 if( MAC_BITBAND->CSR6_RA != 0u ) {
\r
302 configuration |= MSS_MAC_CFG_RECEIVE_ALL;
\r
305 if( MAC_BITBAND->CSR6_TTM != 0u ) {
\r
306 configuration |= MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE;
\r
309 if( MAC_BITBAND->CSR6_SF != 0u ) {
\r
310 configuration |= MSS_MAC_CFG_STORE_AND_FORWARD;
\r
313 switch( (MAC->CSR6 & CSR6_TR_MASK) >> CSR6_TR_SHIFT ) {
\r
314 case 1: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_01; break;
\r
315 case 2: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_10; break;
\r
316 case 3: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_11; break;
\r
319 if( MAC_BITBAND->CSR6_FD != 0u ) {
\r
320 configuration |= MSS_MAC_CFG_FULL_DUPLEX_MODE;
\r
323 if( MAC_BITBAND->CSR6_PM != 0u ) {
\r
324 configuration |= MSS_MAC_CFG_PASS_ALL_MULTICAST;
\r
327 if( MAC_BITBAND->CSR6_PR != 0u ) {
\r
328 configuration |= MSS_MAC_CFG_PROMISCUOUS_MODE;
\r
331 if( MAC_BITBAND->CSR6_IF != 0u ) {
\r
332 configuration |= MSS_MAC_CFG_INVERSE_FILTERING;
\r
335 if( MAC_BITBAND->CSR6_PB != 0u ) {
\r
336 configuration |= MSS_MAC_CFG_PASS_BAD_FRAMES;
\r
339 if( MAC_BITBAND->CSR6_HO != 0u ) {
\r
340 configuration |= MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE;
\r
343 if( MAC_BITBAND->CSR6_HP != 0u ) {
\r
344 configuration |= MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE;
\r
347 return (int32_t)configuration;
\r
351 /***************************************************************************//**
\r
352 Sends a packet to the Ethernet Controller.
\r
353 The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet
\r
354 MAC. This function writes pacLen bytes of the packet contained in pacData into
\r
355 the transmit FIFO and then activates the transmitter for this packet. If space
\r
356 is available in the FIFO, the function will return once pacLen bytes of the
\r
357 packet have been placed into the FIFO and the transmitter has been started.
\r
358 This function will not wait for the transmission to complete. If space is not
\r
359 available in FIFO, the function will keep trying until time_out expires. The
\r
360 function will wait for the transmission to complete when the time_out parameter
\r
361 is set to MSS_MAC_BLOCKING.
\r
364 The pacData parameter is a pointer to the packet data to be transmitted.
\r
367 The pacLen parameter is the number of bytes in the packet to be transmitted.
\r
370 The time_out parameter is the timeout value for the transmission in milliseconds.
\r
371 The time_out parameter value can be one of the following values:
\r
372 \95 Unsigned integer greater than 0 and less than 0x01000000
\r
373 \95 MSS_MAC_BLOCKING
\96 there will be no timeout.
\r
374 \95 MSS_MAC_NONBLOCKING
\96 the function will return immediately if the MSS Ethernet
\r
375 MAC does not have any available transmit descriptor. This would happen when
\r
376 several packets are already queued into the MSS Ethernet MAC transmit descriptor FIFO.
\r
379 The function returns zero if a timeout occurs otherwise it returns size of the packet.
\r
381 @see MAC_rx_packet()
\r
387 const uint8_t *pacData,
\r
393 int32_t error = MAC_OK;
\r
395 ASSERT( MAC_test_instance() == MAC_OK );
\r
397 ASSERT( pacData != NULL_buffer );
\r
399 ASSERT( pacLen >= 12 );
\r
401 if( (g_mss_mac.flags & FLAG_EXCEED_LIMIT) == 0u )
\r
403 ASSERT( pacLen <= MSS_MAX_PACKET_SIZE );
\r
406 ASSERT( (time_out == MSS_MAC_BLOCKING) ||
\r
407 (time_out == MSS_MAC_NONBLOCKING) ||
\r
408 ((time_out >= 1) && (time_out <= 0x01000000uL)) );
\r
410 if( time_out == MSS_MAC_NONBLOCKING )
\r
412 /* Check if current descriptor is free */
\r
413 if(((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
\r
415 error = MAC_BUFFER_IS_FULL;
\r
420 /* Wait until descriptor is free */
\r
421 if( time_out != MSS_MAC_BLOCKING ) {
\r
422 MAC_set_time_out( time_out );
\r
425 while( (((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
\r
426 && (error == MAC_OK) )
\r
428 /* transmit poll demand */
\r
431 if(time_out != MSS_MAC_BLOCKING){
\r
432 if(MAC_get_time_out() == 0u) {
\r
433 error = MAC_TIME_OUT;
\r
439 if( error == MAC_OK ) {
\r
441 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u;
\r
443 if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
\r
444 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC;
\r
447 /* Every buffer can hold a full frame so they are always first and last
\r
449 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS;
\r
451 /* set data size */
\r
452 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= pacLen;
\r
454 /* reset end of ring */
\r
455 g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
\r
457 /* copy data into buffer */
\r
458 if( pacLen > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
\r
460 pacLen = (uint16_t)MSS_TX_BUFF_SIZE;
\r
464 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1,
\r
465 pacData, (uint32_t)pacLen );
\r
467 /* update counters */
\r
468 desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0;
\r
469 if( (desc & TDES0_LO) != 0u ) {
\r
470 g_mss_mac.statistics.tx_loss_of_carrier++;
\r
472 if( (desc & TDES0_NC) != 0u ) {
\r
473 g_mss_mac.statistics.tx_no_carrier++;
\r
475 if( (desc & TDES0_LC) != 0u ) {
\r
476 g_mss_mac.statistics.tx_late_collision++;
\r
478 if( (desc & TDES0_EC) != 0u ) {
\r
479 g_mss_mac.statistics.tx_excessive_collision++;
\r
481 if( (desc & TDES0_UF) != 0u ) {
\r
482 g_mss_mac.statistics.tx_underflow_error++;
\r
484 g_mss_mac.statistics.tx_collision_count +=
\r
485 (desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;
\r
487 /* Give ownership of descriptor to the MAC */
\r
488 g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0 = RDES0_OWN;
\r
490 g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE;
\r
492 /* Start transmission */
\r
493 MAC_start_transmission();
\r
495 /* transmit poll demand */
\r
499 if (error == MAC_OK)
\r
501 error = (int32_t)pacLen;
\r
511 /***************************************************************************//**
\r
512 * Returns available packet size.
\r
514 * @param instance Pointer to a MAC_instance_t structure
\r
515 * @return size of packet, bigger than 0, if a packet is available.
\r
516 * If not, returns 0.
\r
517 * @see MAC_rx_packet()
\r
520 MSS_MAC_rx_pckt_size
\r
526 ASSERT( MAC_test_instance() == MAC_OK );
\r
528 MAC_dismiss_bad_frames();
\r
530 if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) != 0u )
\r
532 /* Current descriptor is empty */
\r
537 uint32_t frame_length;
\r
538 frame_length = ( g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >> RDES0_FL_OFFSET ) & RDES0_FL_MASK;
\r
539 retval = (int32_t)( frame_length );
\r
545 /***************************************************************************//**
\r
546 * Receives a packet from the Ethernet Controller.
\r
547 * This function reads a packet from the receive FIFO of the controller and
\r
548 * places it into pacData. If time_out parameter is zero the function will return
\r
549 * immediately (after the copy operation if data is available. Otherwise the function
\r
550 * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING
\r
551 * value is given as time_out, function will wait for the reception to complete.
\r
553 * @param instance Pointer to a MAC_instance_t structure
\r
554 * @param pacData The pointer to the packet data.
\r
555 * @param pacLen The pacLen parameter is the size in bytes of the pacData
\r
556 * buffer where the received data will be copied.
\r
557 * @param time_out Time out value in milli seconds for receiving.
\r
558 * if value is #MSS_MAC_BLOCKING, there will be no time out.
\r
559 * if value is #MSS_MAC_NONBLOCKING, function will return immediately
\r
560 * if there is no packet waiting.
\r
561 * Otherwise value must be greater than 0 and smaller than
\r
563 * @return Size of packet if packet fits in pacData.
\r
564 * 0 if there is no received packet.
\r
565 * @see MAC_rx_pckt_size()
\r
566 * @see MAC_tx_packet()
\r
576 uint16_t frame_length=0u;
\r
579 ASSERT( MAC_test_instance() == MAC_OK );
\r
581 ASSERT( pacData != NULL_buffer );
\r
583 ASSERT( (time_out == MSS_MAC_BLOCKING) ||
\r
584 (time_out == MSS_MAC_NONBLOCKING) ||
\r
585 ((time_out >= 1) && (time_out <= 0x01000000UL)) );
\r
587 MAC_dismiss_bad_frames();
\r
589 /* wait for a packet */
\r
590 if( time_out != MSS_MAC_BLOCKING ) {
\r
591 if( time_out == MSS_MAC_NONBLOCKING ) {
\r
592 MAC_set_time_out( 0u );
\r
594 MAC_set_time_out( time_out );
\r
598 while( ((g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &
\r
599 RDES0_OWN) != 0u) && (exit == 0) )
\r
601 if( time_out != MSS_MAC_BLOCKING )
\r
603 if( MAC_get_time_out() == 0u ) {
\r
612 g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>
\r
613 RDES0_FL_OFFSET ) & RDES0_FL_MASK );
\r
616 frame_length -= 4u;
\r
618 if( frame_length > pacLen ) {
\r
619 return MAC_NOT_ENOUGH_SPACE;
\r
622 MAC_memcpy( pacData,
\r
624 g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1,
\r
625 (uint32_t)frame_length );
\r
627 MSS_MAC_prepare_rx_descriptor();
\r
630 return ((int32_t)frame_length);
\r
634 /***************************************************************************//**
\r
635 * Receives a packet from the Ethernet Controller.
\r
636 * This function reads a packet from the receive FIFO of the controller and
\r
637 * sets the address of pacData to the received data.
\r
638 * If time_out parameter is zero the function will return
\r
639 * immediately (after the copy operation if data is available. Otherwise the function
\r
640 * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING
\r
641 * value is given as time_out, function will wait for the reception to complete.
\r
643 * @param instance Pointer to a MAC_instance_t structure
\r
644 * @param pacData The pointer to the packet data.
\r
645 * @param time_out Time out value in milli seconds for receiving.
\r
646 * if value is #MSS_MAC_BLOCKING, there will be no time out.
\r
647 * if value is #MSS_MAC_NONBLOCKING, function will return immediately
\r
648 * if there is no packet waiting.
\r
649 * Otherwise value must be greater than 0 and smaller than
\r
651 * @return Size of packet if packet fits in pacData.
\r
652 * 0 if there is no received packet.
\r
653 * @see MAC_rx_pckt_size()
\r
654 * @see MAC_tx_packet()
\r
657 MSS_MAC_rx_packet_ptrset
\r
663 uint16_t frame_length = 0u;
\r
666 ASSERT( MAC_test_instance() == MAC_OK );
\r
668 ASSERT( (time_out == MSS_MAC_BLOCKING) ||
\r
669 (time_out == MSS_MAC_NONBLOCKING) ||
\r
670 ((time_out >= 1) && (time_out <= 0x01000000UL)) );
\r
672 MAC_dismiss_bad_frames();
\r
674 /* wait for a packet */
\r
675 if( time_out != MSS_MAC_BLOCKING ) {
\r
676 if( time_out == MSS_MAC_NONBLOCKING ) {
\r
677 MAC_set_time_out( 0u );
\r
679 MAC_set_time_out( time_out );
\r
683 while( ((g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &
\r
684 RDES0_OWN) != 0u) && (exit == 0) )
\r
686 if( time_out != MSS_MAC_BLOCKING )
\r
688 if( MAC_get_time_out() == 0u ) {
\r
697 g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>
\r
698 RDES0_FL_OFFSET ) & RDES0_FL_MASK );
\r
701 frame_length -= 4u;
\r
703 /* Here we are setting the buffer 'pacData' address to the address
\r
704 RX descriptor address. After this is called, the following function
\r
705 must be called 'MAC_prepare_rx_descriptor'
\r
706 to prepare the current rx descriptor for receiving the next packet.
\r
708 *pacData = (uint8_t *)g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 ;
\r
711 return ((int32_t)frame_length);
\r
714 /***************************************************************************//**
\r
715 * Returns the status of connection.
\r
717 * @return the logical OR of the following values:
\r
718 * #MSS_MAC_LINK_STATUS_LINK - Link up/down
\r
719 * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb
\r
720 * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex
\r
721 * @see MAC_auto_setup_link()
\r
724 MSS_MAC_link_status
\r
731 ASSERT( MAC_test_instance() == MAC_OK );
\r
733 link = PHY_link_status();
\r
734 if( link == MSS_MAC_LINK_STATUS_LINK ) {
\r
735 link |= PHY_link_type();
\r
738 return ((int32_t)link);
\r
742 /***************************************************************************//**
\r
743 * Setups the link between PHY and MAC and returns the status of connection.
\r
745 * @return the logical OR of the following values:
\r
746 * #MSS_MAC_LINK_STATUS_LINK - Link up/down
\r
747 * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb
\r
748 * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex
\r
749 * @see MAC_link_status()
\r
752 MSS_MAC_auto_setup_link
\r
758 ASSERT( MAC_test_instance() == MAC_OK );
\r
760 PHY_auto_negotiate();
\r
762 link = MSS_MAC_link_status();
\r
764 if( (link & MSS_MAC_LINK_STATUS_LINK) != 0u ) {
\r
766 ret = MAC_stop_transmission();
\r
767 MAC_CHECK( ret == MAC_OK, ret );
\r
769 ret = MAC_stop_receiving();
\r
770 MAC_CHECK( ret == MAC_OK, ret );
\r
771 MAC_BITBAND->CSR6_TTM = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_100MB) != 0u) ? 1u : 0u );
\r
772 MAC_BITBAND->CSR6_FD = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_FDX) != 0u) ? 1u : 1u );
\r
773 MAC_start_transmission();
\r
774 MAC_start_receiving();
\r
781 /***************************************************************************//**
\r
782 * Sets mac address. New address must be unicast.
\r
784 * @param new_address Pointer to a MAC_instance_t structure
\r
785 * @see MAC_get_mac_address()
\r
788 MSS_MAC_set_mac_address
\r
790 const uint8_t *new_address
\r
793 ASSERT( MAC_test_instance() == MAC_OK );
\r
794 /* Check if the new address is unicast */
\r
795 ASSERT( (new_address[0]&1) == 0 );
\r
797 MAC_memcpy( g_mss_mac.mac_address, new_address, 6u );
\r
799 if((g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) {
\r
801 /* set unused filters to the new mac address */
\r
802 for( a=14*6; a>=0; a-=6 ) {
\r
803 if( (g_mss_mac.mac_filter_data[a] & 1u) != 0u ) {
\r
804 /* Filters with multicast addresses are used */
\r
807 MAC_memcpy( &(g_mss_mac.mac_filter_data[a]),
\r
808 g_mss_mac.mac_address, 6u );
\r
813 MAC_send_setup_frame();
\r
817 /***************************************************************************//**
\r
818 * Returns mac address.
\r
820 * @param address Pointer to receive the MAC address
\r
821 * @see MAC_set_mac_address()
\r
824 MSS_MAC_get_mac_address
\r
829 ASSERT( MAC_test_instance() == MAC_OK );
\r
831 MAC_memcpy( address, g_mss_mac.mac_address, 6u );
\r
835 /***************************************************************************//**
\r
836 * Sets mac address filters. Addresses must be multicast.
\r
838 * @param filter_count number of addresses
\r
839 * @param filters Pointer to addresses to be filtered
\r
842 MSS_MAC_set_mac_filters
\r
844 uint16_t filter_count,
\r
845 const uint8_t *filters
\r
848 ASSERT( MAC_test_instance() == MAC_OK );
\r
849 ASSERT( (filter_count==0) || (filters != NULL_buffer) );
\r
850 /* Check if the mac addresses is multicast */
\r
853 for( a = 0u; a < filter_count; a++ ) {
\r
854 ASSERT( (filters[a*6]&1) == 1 );
\r
858 if( filter_count <= 15 ){
\r
860 g_mss_mac.flags |= FLAG_PERFECT_FILTERING;
\r
862 /* copy new filters */
\r
863 MAC_memcpy( g_mss_mac.mac_filter_data, filters, (uint32_t)(filter_count*6));
\r
865 /* set unused filters to our mac address */
\r
866 for( a=filter_count; a<15; a++ ) {
\r
867 MAC_memcpy( &(g_mss_mac.mac_filter_data[a*6]),
\r
868 g_mss_mac.mac_address, 6 );
\r
874 g_mss_mac.flags &= ~FLAG_PERFECT_FILTERING;
\r
876 /* reset hash table */
\r
877 MAC_memset( g_mss_mac.mac_filter_data, 0u, 64u );
\r
879 for( a=0, b=0; a<filter_count; a++, b+=6 ) {
\r
880 hash = mss_ethernet_crc( &(filters[b]), 6 ) & 0x1FF;
\r
881 g_mss_mac.mac_filter_data[ hash / 8 ] |= 1 << (hash & 0x7);
\r
885 MAC_send_setup_frame();
\r
889 /***************************************************************************//**
\r
890 * MAC interrupt service routine.
\r
892 * @param instance Pointer to a MAC_instance_t structure
\r
893 * @see MAC_set_callback()
\r
895 #if defined(__GNUC__)
\r
896 __attribute__((__interrupt__)) void EthernetMAC_IRQHandler( void )
\r
898 void EthernetMAC_IRQHandler( void )
\r
902 uint32_t intr_status;
\r
904 ASSERT( MAC_test_instance() == MAC_OK );
\r
907 intr_status = MAC->CSR5;
\r
909 if( (intr_status & CSR5_NIS_MASK) != 0u ) {
\r
910 if( (intr_status & CSR5_TI_MASK) != 0u ) { /* Transmit */
\r
911 g_mss_mac.statistics.tx_interrupts++;
\r
912 events |= MSS_MAC_EVENT_PACKET_SEND;
\r
915 if( (intr_status & CSR5_RI_MASK) != 0u ) { /* Receive */
\r
916 g_mss_mac.statistics.rx_interrupts++;
\r
917 events |= MSS_MAC_EVENT_PACKET_RECEIVED;
\r
921 /* Clear interrupts */
\r
922 MAC->CSR5 = CSR5_INT_BITS;
\r
924 if( (events != 0u) && (g_mss_mac.listener != NULL_callback) ) {
\r
925 g_mss_mac.listener( events );
\r
930 /***************************************************************************//**
\r
931 * Sets MAC event listener.
\r
932 * Sets the given event listener function to be triggered inside MAC_isr().
\r
933 * Assigning NULL pointer as the listener function will disable it.
\r
935 * @param instance Pointer to a MAC_instance_t structure
\r
936 * @param listener function pointer to a MAC_callback_t function
\r
937 * @return #MAC_OK if everything is OK
\r
938 * #MAC_WRONG_PARAMETER if instance is null or hasn't been
\r
943 MSS_MAC_set_callback
\r
945 MSS_MAC_callback_t listener
\r
948 ASSERT( MAC_test_instance() == MAC_OK );
\r
950 /* disable tx and rx interrupts */
\r
951 MAC_BITBAND->CSR7_RIE = 0u;
\r
952 MAC_BITBAND->CSR7_TIE = 0u;
\r
954 g_mss_mac.listener = listener;
\r
956 if( listener != NULL_callback ) {
\r
957 /* enable tx and rx interrupts */
\r
958 MAC_BITBAND->CSR7_RIE = 1u;
\r
959 MAC_BITBAND->CSR7_TIE = 1u;
\r
964 /***************************************************************************//**
\r
965 * Returns description of last error.
\r
967 * @param instance Pointer to a MAC_instance_t structure
\r
968 * @return A string describing the error. This string must not be
\r
969 * modified by the application.
\r
970 * #MAC_WRONG_PARAMETER if instance is null or hasn't been
\r
979 int8_t error_msg_nb;
\r
980 const int8_t* returnvalue;
\r
982 ASSERT( MAC_test_instance() == MAC_OK );
\r
984 error_msg_nb = -(g_mss_mac.last_error);
\r
985 if( error_msg_nb >= ERROR_MESSAGE_COUNT ) {
\r
986 returnvalue = unknown_error;
\r
988 returnvalue = ErrorMessages[error_msg_nb];
\r
990 return returnvalue;
\r
994 /***************************************************************************//**
\r
995 * Returns statistics counter of stat_id identifier.
\r
997 * @param instance Pointer to a MAC_instance_t structure
\r
998 * @param stat_id Identifier of statistics counter.
\r
999 * @return Statistics counter of stat_id identifier.
\r
1000 * On error returns 0.
\r
1003 MSS_MAC_get_statistics
\r
1005 mss_mac_statistics_id_t stat_id
\r
1008 uint32_t returnval = 0u;
\r
1009 ASSERT( MAC_test_instance() == MAC_OK );
\r
1011 switch( stat_id ) {
\r
1012 case MSS_MAC_RX_INTERRUPTS:
\r
1013 returnval = g_mss_mac.statistics.rx_interrupts;
\r
1015 case MSS_MAC_RX_FILTERING_FAIL:
\r
1016 returnval = g_mss_mac.statistics.rx_filtering_fail;
\r
1018 case MSS_MAC_RX_DESCRIPTOR_ERROR:
\r
1019 returnval = g_mss_mac.statistics.rx_descriptor_error;
\r
1021 case MSS_MAC_RX_RUNT_FRAME:
\r
1022 returnval = g_mss_mac.statistics.rx_runt_frame;
\r
1024 case MSS_MAC_RX_NOT_FIRST:
\r
1025 returnval = g_mss_mac.statistics.rx_not_first;
\r
1027 case MSS_MAC_RX_NOT_LAST:
\r
1028 returnval = g_mss_mac.statistics.rx_not_last;
\r
1030 case MSS_MAC_RX_FRAME_TOO_LONG:
\r
1031 returnval = g_mss_mac.statistics.rx_frame_too_long;
\r
1033 case MSS_MAC_RX_COLLISION_SEEN:
\r
1034 returnval = g_mss_mac.statistics.rx_collision_seen;
\r
1036 case MSS_MAC_RX_CRC_ERROR:
\r
1037 returnval = g_mss_mac.statistics.rx_crc_error;
\r
1039 case MSS_MAC_RX_FIFO_OVERFLOW:
\r
1040 returnval = g_mss_mac.statistics.rx_fifo_overflow;
\r
1042 case MSS_MAC_RX_MISSED_FRAME:
\r
1043 returnval = g_mss_mac.statistics.rx_missed_frame;
\r
1045 case MSS_MAC_TX_INTERRUPTS:
\r
1046 returnval = g_mss_mac.statistics.tx_interrupts;
\r
1048 case MSS_MAC_TX_LOSS_OF_CARRIER:
\r
1049 returnval = g_mss_mac.statistics.tx_loss_of_carrier;
\r
1051 case MSS_MAC_TX_NO_CARRIER:
\r
1052 returnval = g_mss_mac.statistics.tx_no_carrier;
\r
1054 case MSS_MAC_TX_LATE_COLLISION:
\r
1055 returnval = g_mss_mac.statistics.tx_late_collision;
\r
1057 case MSS_MAC_TX_EXCESSIVE_COLLISION:
\r
1058 returnval = g_mss_mac.statistics.tx_excessive_collision;
\r
1060 case MSS_MAC_TX_COLLISION_COUNT:
\r
1061 returnval = g_mss_mac.statistics.tx_collision_count;
\r
1063 case MSS_MAC_TX_UNDERFLOW_ERROR:
\r
1064 returnval = g_mss_mac.statistics.tx_underflow_error;
\r
1074 /**************************** INTERNAL FUNCTIONS ******************************/
\r
1076 /***************************************************************************//**
\r
1077 * Checks if instace is valid.
\r
1087 int32_t retval = MAC_WRONG_PARAMETER;
\r
1092 if( (&g_mss_mac != NULL_instance) &&
\r
1093 ((g_mss_mac.flags & FLAG_MAC_INIT_DONE) != 0u) &&
\r
1094 ( val1 == (uint32_t)g_mss_mac.rx_descriptors) &&
\r
1095 (val2 == (uint32_t)g_mss_mac.tx_descriptors ) )
\r
1102 /***************************************************************************//**
\r
1103 * Prepares current rx descriptor for receiving.
\r
1106 MSS_MAC_prepare_rx_descriptor
\r
1113 /* update counters */
\r
1114 desc = g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0;
\r
1115 if( (desc & RDES0_FF) != 0u ) {
\r
1116 g_mss_mac.statistics.rx_filtering_fail++;
\r
1118 if( (desc & RDES0_DE) != 0u ) {
\r
1119 g_mss_mac.statistics.rx_descriptor_error++;
\r
1121 if( (desc & RDES0_RF) != 0u ) {
\r
1122 g_mss_mac.statistics.rx_runt_frame++;
\r
1124 if( (desc & RDES0_FS) == 0u ) {
\r
1125 g_mss_mac.statistics.rx_not_first++;
\r
1127 if( (desc & RDES0_LS) == 0u ) {
\r
1128 g_mss_mac.statistics.rx_not_last++;
\r
1130 if( (desc & RDES0_TL) != 0u ) {
\r
1131 g_mss_mac.statistics.rx_frame_too_long++;
\r
1133 if( (desc & RDES0_CS) != 0u ) {
\r
1134 g_mss_mac.statistics.rx_collision_seen++;
\r
1136 if( (desc & RDES0_CE) != 0u ) {
\r
1137 g_mss_mac.statistics.rx_crc_error++;
\r
1141 g_mss_mac.statistics.rx_fifo_overflow +=
\r
1142 (desc & (CSR8_OCO_MASK|CSR8_FOC_MASK)) >> CSR8_FOC_SHIFT;
\r
1143 g_mss_mac.statistics.rx_missed_frame +=
\r
1144 (desc & (CSR8_MFO_MASK|CSR8_MFC_MASK));
\r
1146 /* Give ownership of descriptor to the MAC */
\r
1147 g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 =
\r
1149 g_mss_mac.rx_desc_index = (g_mss_mac.rx_desc_index + 1u) % RX_RING_SIZE;
\r
1151 /* Start receive */
\r
1152 MAC_start_receiving();
\r
1156 /***************************************************************************//**
\r
1157 * Prepares a setup frame and sends it to MAC.
\r
1158 * This function is blocking.
\r
1159 * @return #MAC_OK if everything is ok.
\r
1160 * #MAC_TIME_OUT if timed out before packet send.
\r
1163 MAC_send_setup_frame
\r
1168 volatile MAC_descriptor_t descriptor;
\r
1169 uint8_t frame_data[192];
\r
1174 /* prepare descriptor */
\r
1175 descriptor.descriptor_0 = TDES0_OWN;
\r
1176 descriptor.descriptor_1 = TDES1_SET | TDES1_TER |
\r
1177 (sizeof(frame_data) << TDES1_TBS1_OFFSET);
\r
1179 if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) == 0u ) {
\r
1180 descriptor.descriptor_1 |= TDES1_FT0;
\r
1183 descriptor.buffer_1 = (uint32_t)frame_data;
\r
1184 descriptor.buffer_2 = 0u;
\r
1186 /* prepare frame */
\r
1187 if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) {
\r
1197 data = g_mss_mac.mac_address;
\r
1198 frame_data[b] = data[0];
\r
1199 frame_data[b+1] = data[1];
\r
1200 frame_data[b+4] = data[2];
\r
1201 frame_data[b+5] = data[3];
\r
1202 frame_data[b+8] = data[4];
\r
1203 frame_data[b+9] = data[5];
\r
1205 data = g_mss_mac.mac_filter_data;
\r
1206 for( a = 0; a < c; ) {
\r
1207 frame_data[d] = data[a++];
\r
1208 frame_data[d+1] = data[a++];
\r
1209 frame_data[d+4] = data[a++];
\r
1210 frame_data[d+5] = data[a++];
\r
1211 frame_data[d+8] = data[a++];
\r
1212 frame_data[d+9] = data[a++];
\r
1216 /* Stop transmission */
\r
1217 ret = MAC_stop_transmission();
\r
1218 ASSERT( ret == MAC_OK );
\r
1220 ret = MAC_stop_receiving();
\r
1221 ASSERT( ret == MAC_OK );
\r
1223 /* Set descriptor */
\r
1224 MAC->CSR4 = (uint32_t)&descriptor;
\r
1226 /* Start transmission */
\r
1227 MAC_start_transmission();
\r
1229 /* Wait until transmission over */
\r
1231 MAC_set_time_out( (uint32_t)SETUP_FRAME_TIME_OUT );
\r
1233 while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) !=
\r
1234 CSR5_TS_SUSPENDED) && (MAC_OK == ret) )
\r
1236 /* transmit poll demand */
\r
1238 if( MAC_get_time_out() == 0u ) {
\r
1239 ret = MAC_TIME_OUT;
\r
1243 MAC_CHECK( MAC_stop_transmission() == MAC_OK, MAC_FAIL );
\r
1245 /* Set tx descriptor */
\r
1246 MAC->CSR4 = (uint32_t)g_mss_mac.tx_descriptors;
\r
1248 /* Start receiving and transmission */
\r
1249 MAC_start_receiving();
\r
1250 MAC_start_transmission();
\r
1256 /***************************************************************************//**
\r
1257 * Stops transmission.
\r
1258 * Function will wait until transmit operation enters stop state.
\r
1260 * @return #MAC_OK if everything is ok.
\r
1261 * #MAC_TIME_OUT if timed out.
\r
1264 MAC_stop_transmission
\r
1269 int32_t retval = MAC_OK;
\r
1270 MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT );
\r
1272 while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) !=
\r
1273 CSR5_TS_STOPPED) && (retval == MAC_OK) )
\r
1275 MAC_BITBAND->CSR6_ST = 0u;
\r
1276 if( MAC_get_time_out() == 0u ) {
\r
1277 retval = MAC_TIME_OUT;
\r
1284 /***************************************************************************//**
\r
1285 * Starts transmission.
\r
1288 MAC_start_transmission
\r
1293 MAC_BITBAND->CSR6_ST = 1u;
\r
1297 /***************************************************************************//**
\r
1298 * Stops transmission.
\r
1299 * Function will wait until transmit operation enters stop state.
\r
1301 * @return #MAC_OK if everything is ok.
\r
1302 * #MAC_TIME_OUT if timed out.
\r
1305 MAC_stop_receiving
\r
1310 int32_t retval = MAC_OK;
\r
1311 MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT );
\r
1313 while( (((MAC->CSR5 & CSR5_RS_MASK) >> CSR5_RS_SHIFT) != CSR5_RS_STOPPED)
\r
1314 && (retval == MAC_OK) )
\r
1316 MAC_BITBAND->CSR6_SR = 0u;
\r
1317 if( MAC_get_time_out() == 0u ) {
\r
1318 retval = MAC_TIME_OUT;
\r
1326 /***************************************************************************//**
\r
1327 * Starts transmission.
\r
1330 MAC_start_receiving
\r
1335 MAC_BITBAND->CSR6_SR = 1u;
\r
1339 /***************************************************************************//**
\r
1340 * Dismisses bad frames.
\r
1342 * @return dismissed frame count.
\r
1345 MAC_dismiss_bad_frames
\r
1353 if( MAC_BITBAND->CSR6_PB != 0u ) {
\r
1354 /* User wants bad frames too, don't dismiss anything */
\r
1358 while( ( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &
\r
1359 RDES0_OWN) == 0u) && (cont == 1) ) /* Host owns this descriptor */
\r
1361 /* check error summary */
\r
1362 if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &
\r
1363 (RDES0_ES | RDES0_LS | RDES0_FS)) != (RDES0_LS | RDES0_FS) )
\r
1365 MSS_MAC_prepare_rx_descriptor();
\r
1377 /***************************************************************************//**
\r
1378 * Sets time out value.
\r
1379 * #MAC_get_time_out must be called frequently to make time out value updated.
\r
1380 * Because of user may not be using ISR, we can not update time out in ISR.
\r
1382 * @time_out time out value in milli seconds.
\r
1383 * Must be smaller than 0x01000000.
\r
1391 g_mss_mac.time_out_value = (time_out * 122u) / 10u;
\r
1393 g_mss_mac.last_timer_value = (uint16_t)( MAC->CSR11 & CSR11_TIM_MASK );
\r
1396 /***************************************************************************//**
\r
1397 * Returns time out value.
\r
1399 * @return timer out value in milli seconds.
\r
1408 uint32_t time = 0u;
\r
1410 timer = ( MAC->CSR11 & CSR11_TIM_MASK );
\r
1412 if( timer > g_mss_mac.last_timer_value ) {
\r
1413 time = 0x0000ffffUL;
\r
1415 time += g_mss_mac.last_timer_value - timer;
\r
1417 if( MAC_BITBAND->CSR6_TTM == 0u ) {
\r
1420 if( g_mss_mac.time_out_value <= time ){
\r
1421 g_mss_mac.time_out_value = 0u;
\r
1423 g_mss_mac.time_out_value -= time;
\r
1426 g_mss_mac.last_timer_value = (uint16_t)timer;
\r
1428 return ((g_mss_mac.time_out_value * 10u) / 122u);
\r
1431 /***************************************************************************//**
\r
1432 * Fills the first n bytes of the memory area pointed to by s with the constant
\r
1435 static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n)
\r
1445 /***************************************************************************//**
\r
1446 * Fills all fields of MAC_instance_t with c.
\r
1448 * @return a pointer to the given MAC_instance_t s.
\r
1450 static void MAC_memset_All(MAC_instance_t *s, uint32_t c)
\r
1453 s->base_address = (addr_t)c;
\r
1454 s->flags = (uint8_t)c;
\r
1455 s->last_error = (int8_t)c;
\r
1456 s->last_timer_value = (uint16_t)c;
\r
1457 s->listener = NULL_callback;
\r
1458 MAC_memset( s->mac_address, (uint8_t)c, 6u );
\r
1459 MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );
\r
1460 s->phy_address = (uint8_t)c;
\r
1461 for(count = 0; count<RX_RING_SIZE ;count++)
\r
1463 MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
\r
1465 s->rx_desc_index =c;
\r
1466 for(count = 0; count<RX_RING_SIZE ;count++)
\r
1468 s->rx_descriptors[count].buffer_1 = c;
\r
1469 s->rx_descriptors[count].buffer_2 = c;
\r
1470 s->rx_descriptors[count].descriptor_0 = c;
\r
1471 s->rx_descriptors[count].descriptor_1 = c;
\r
1473 s->statistics.rx_collision_seen =c;
\r
1474 s->statistics.rx_crc_error = c;
\r
1475 s->statistics.rx_descriptor_error = c;
\r
1476 s->statistics.rx_fifo_overflow = c;
\r
1477 s->statistics.rx_filtering_fail = c;
\r
1478 s->statistics.rx_frame_too_long = c;
\r
1479 s->statistics.rx_interrupts = c;
\r
1480 s->statistics.rx_missed_frame = c;
\r
1481 s->statistics.rx_not_first = c;
\r
1482 s->statistics.rx_not_last = c;
\r
1483 s->statistics.rx_runt_frame = c;
\r
1484 s->statistics.tx_collision_count = c;
\r
1485 s->statistics.tx_excessive_collision = c;
\r
1486 s->statistics.tx_interrupts = c;
\r
1487 s->statistics.tx_late_collision = c;
\r
1488 s->statistics.tx_loss_of_carrier = c;
\r
1489 s->statistics.tx_no_carrier = c;
\r
1490 s->statistics.tx_underflow_error = c;
\r
1491 s->time_out_value = c;
\r
1492 for(count = 0; count < TX_RING_SIZE ;count++)
\r
1494 MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );
\r
1496 s->tx_desc_index = c;
\r
1497 for(count = 0; count < TX_RING_SIZE ;count++)
\r
1499 s->tx_descriptors[count].buffer_1 = c;
\r
1500 s->tx_descriptors[count].buffer_2 = c;
\r
1501 s->tx_descriptors[count].descriptor_0 = c;
\r
1502 s->tx_descriptors[count].descriptor_1 = c;
\r
1506 /***************************************************************************//**
\r
1507 * Copies n bytes from memory area src to memory area dest.
\r
1508 * The memory areas should not overlap.
\r
1510 * @return a pointer to the memory area dest.
\r
1512 static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n)
\r
1514 uint8_t *d = dest;
\r
1522 #ifdef __cplusplus
\r
1526 /******************************** END OF FILE *********************************/
\r