uint32_t ENET_send ( /* [IN] the Ethernet state structure */ _enet_handle handle, /* [IN] the packet to send */ PCB_PTR packet, /* [IN] the protocol */ uint16_t type, /* [IN] the destination Ethernet address */ _enet_address dest, /* [IN] optional flags, zero = default */ uint32_t flags ) { ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle; ENET_HEADER_PTR packet_ptr; unsigned char *type_ptr; PCB_FRAGMENT_PTR frag_ptr; uint32_t swhdr, size, frags; uint32_t error; _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE6(KLOG_ENET_send, handle, packet, type, dest, flags); if (flags & ENET_OPT_8021QTAG) { swhdr = ENET_FRAMESIZE_HEAD_VLAN; } else { swhdr = ENET_FRAMESIZE_HEAD; } /* ** Make sure the first fragment is long enough for the Ethernet ** frame header. This isn't strictly necessary, but it's impractical ** to split a 14-26 byte header over multiple fragments. */ #if MQX_CHECK_ERRORS if (packet->FRAG[0].LENGTH < swhdr) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_SHORT; goto ERROR; } #endif /* ** Make sure that no fragment exceeds a maximum packet length. ** We check every fragment because we want to prevent something ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000. This ** situation would not be detected if we only check the total ** length. */ size = frags = 0; for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) { #if MQX_CHECK_ERRORS if (frag_ptr->LENGTH > enet_ptr->MaxTxFrameSize) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_LONG; goto ERROR; } #endif size += frag_ptr->LENGTH; frags++; } /* ** Make sure that the total sum of the fragments doesn't exceed ** a maximum packet length. */ #if MQX_CHECK_ERRORS if (size > enet_ptr->MaxTxFrameSize) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_LONG; goto ERROR; } #endif /* ** Everything checks out -- fill in the header. */ packet_ptr = (ENET_HEADER_PTR)packet->FRAG[0].FRAGMENT; htone(packet_ptr->DEST, dest); htone(packet_ptr->SOURCE, enet_ptr->ADDRESS); type_ptr = packet_ptr->TYPE; if (flags & ENET_OPT_8021QTAG) { ENET_8021QTAG_HEADER_PTR tag_ptr = (ENET_8021QTAG_HEADER_PTR)(type_ptr+2); uint16_t tag; tag = ENET_GETOPT_8021QPRIO(flags) << 13; mqx_htons(type_ptr, ENETPROT_8021Q); mqx_htons(tag_ptr->TAG, tag); type_ptr = tag_ptr->TYPE; } if (flags & ENET_OPT_8023) { ENET_8022_HEADER_PTR llc_ptr = (ENET_8022_HEADER_PTR)(type_ptr+2); (void)mqx_htons(type_ptr, size - swhdr); mqx_htonc(llc_ptr->DSAP, 0xAA); mqx_htonc(llc_ptr->SSAP, 0xAA); mqx_htonc(llc_ptr->COMMAND, 0x03); mqx_htonc(&llc_ptr->OUI[0], 0x00); mqx_htonc(&llc_ptr->OUI[1], 0x00); mqx_htonc(&llc_ptr->OUI[2], 0x00); type_ptr = llc_ptr->TYPE; } mqx_htons(type_ptr, type); /* ** This function can be called from any context, and it needs mutual ** exclusion with itself, and with ENET_ISR(). */ ENET_lock_context(enet_ptr); error = (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->SEND)(handle, packet, size, frags, flags); ENET_unlock_context(enet_ptr); if (error) { ERROR: PCB_free(packet); } _KLOGX4(KLOG_ENET_send, handle, packet, error); return error; }
_mqx_uint _lwmsgq_receive ( /* Handle to the queue */ pointer handle, /* location of message to copy to */ _mqx_max_type_ptr message, /* flags for blocking on empty */ _mqx_uint flags, /* Timeout for receive if using ticks if 0, ignored */ _mqx_uint ticks, /* Timeout if receive timout using tick struct must have flags set */ MQX_TICK_STRUCT_PTR tick_ptr ) {/* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; LWMSGQ_STRUCT_PTR q_ptr = (LWMSGQ_STRUCT_PTR)handle; _mqx_uint i; _mqx_max_type_ptr from_ptr; _mqx_max_type_ptr to_ptr; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwmsgq_receive(handle, message, flags, ticks, tick_ptr); } #endif /* Start CR 1944 */ _GET_KERNEL_DATA(kernel_data); _KLOGE6(KLOG_lwmsgq_receive, handle, message, flags, ticks, tick_ptr); /* End CR 1944 */ _int_disable(); #if MQX_CHECK_VALIDITY if (q_ptr->VALID != LWMSGQ_VALID){ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID); /* End CR 1944 */ return LWMSGQ_INVALID; } /* Endif */ #endif if (LWMSGQ_IS_EMPTY(q_ptr)) { if (flags & LWMSGQ_RECEIVE_BLOCK_ON_EMPTY) { td_ptr = kernel_data->ACTIVE_PTR; while (LWMSGQ_IS_EMPTY(q_ptr)) { td_ptr->STATE = LWMSGQ_READ_BLOCKED; td_ptr->INFO = (_mqx_uint)&q_ptr->WAITING_READERS; _QUEUE_UNLINK(td_ptr); _QUEUE_ENQUEUE(&q_ptr->WAITING_READERS, &td_ptr->AUX_QUEUE); if (ticks || (flags & (LWMSGQ_TIMEOUT_UNTIL | LWMSGQ_TIMEOUT_FOR))){ if (ticks) { PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, ticks, &td_ptr->TIMEOUT); } else if (flags & LWMSGQ_TIMEOUT_UNTIL){ td_ptr->TIMEOUT = *tick_ptr; } else { PSP_ADD_TICKS(tick_ptr, &kernel_data->TIME, &td_ptr->TIMEOUT); } /* Endif */ _time_delay_internal(td_ptr); if (td_ptr->INFO != 0) { _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_TIMEOUT); /* End CR 1944 */ return LWMSGQ_TIMEOUT; } /* Endif */ } else { _sched_execute_scheduler_internal(); /* Let other tasks run */ } /* Endif */ } /* Endwhile */ } else { _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_EMPTY); /* End CR 1944 */ return LWMSGQ_EMPTY; } /* Endif */ }/* Endif */ from_ptr = q_ptr->MSG_READ_LOC; to_ptr = message; i = q_ptr->MSG_SIZE+1; while (--i) { *to_ptr++ = *from_ptr++; } /* Endwhile */ q_ptr->MSG_READ_LOC += q_ptr->MSG_SIZE; if (q_ptr->MSG_READ_LOC >= q_ptr->MSG_END_LOC) { q_ptr->MSG_READ_LOC = q_ptr->MSG_START_LOC; } /* Endif */ q_ptr->CURRENT_SIZE--; if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_WRITERS)) { _QUEUE_DEQUEUE(&q_ptr->WAITING_WRITERS, td_ptr); _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE); td_ptr->INFO = 0; /* Signal that post is activating the task */ _TASK_READY(td_ptr, kernel_data); _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */ } /* Endif */ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, MQX_OK); /* End CR 1944 */ return MQX_OK; }/* Endbody */