/****************************************************************************
 * **File:** csp/interfaces/csp_if_eth.h
 *
 * **Description:** Ethernet (ETH) interface.
 *
 * Ethernet frames holds up to 1500 bytes, and may be limited by an MTU value
 * that is lower, so in order to transmit CSP packets larger than this,
 * a segmentation protocol is required. The Ethernet standard assumes that this
 * is handled by an upper lat protocol, like bt the IP protocol. This Ethernet
 * driver therefore implements a CSP segmentation protocol that is called EFP.
 * It is similar to CAN CFP.
 *
 * Each packet segment is prepended an EFP header with the following content:
 *
 * - Version:           1 bit
 * - Unused:            2 bit
 * - SegmentId:         5 bit
 * - PacketId:          8 bit
 * - PacketLengthMSB:   8 bit
 * - PacketLengthLSB:   8 bit
 *
 * The Version is zero. EFP discard Ethernet frames with the leading bit being 1.
 * For a potential new protocol to coexist with EFP the first bit in the meader
 * must be 1. The Unused bits must be zero. The SegmentId is a sequential number
 * that starts at zero for each packet and increments by one for each segment.
 * It wraps around to zero at 32, implying that the larges CSP packet size that
 * can be handled is 32 * MTU. The PacketId is a sequential number that is same
 * for all segments of the same packet, and increments by one for every new packet.
 * It wraps around to zero at 256, implying that the protocol can handle up to
 * 256 packets that are processed in parallel. The PacketLengthMSB and
 * PacketLengthLSB holds the packet length most and least significant bits.
 *
 * The protocol assumes that a single segment is sent per Ethernet frame.
 * If smaller than the Ethernet payload length zero-padding is applied.
 * Padding may only occur when transferring the last segment. The protocol allows
 * for segments being received out of order.
 *
 * The protocol differs from CAN CFP by not explicitly storing CSP source and
 * destination addresses in the EFP header. The packets are processed individually,
 * not per CSP connection.
 ****************************************************************************/
#pragma once
#include <csp/csp_interface.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 0x88B5 : IEEE Std 802 - Local Experimental Ethertype  (RFC 5342) */
[docs]#define CSP_ETH_TYPE_CSP 0x88B5 
/* Size of buffer that must be greater than the size of an ethernet frame
   carrying a maximum sized (~2k) CSP packet */
[docs]#define CSP_ETH_BUF_SIZE    3000 
/* Max number of payload bytes per ETH frame, which is the Ethernet MTU */
[docs]#define CSP_ETH_FRAME_SIZE_MAX 1500 
[docs]/**
 * Declarations same as found in Linux net/ethernet.h and linux/if_ether.h
 */
#define CSP_ETH_ALEN	6		    /* Octets in one ethernet addr	 */ 
/**
 * Send ETH frame (implemented by driver).
 *
 * Used by csp_eth_tx() to send ETH frames.
 *
 * @param[in] driver_data driver data from #csp_iface_t
 * @param[in] eth_frame CSP Ethernet frame to transmit
 * @return #CSP_ERR_NONE on success, otherwise an error code.
 */
typedef int (*csp_eth_driver_tx_t)(void * driver_data, csp_eth_header_t * eth_frame);
/**
 * CSP Interface data.
 */
typedef struct {
	csp_iface_t iface;
	bool promisc;
	uint16_t tx_mtu;
	csp_eth_driver_tx_t tx_func;
	csp_eth_header_t * tx_buf;
	csp_packet_t * pbufs;
	uint8_t if_mac[CSP_ETH_ALEN];
} csp_eth_interface_data_t; 
[docs]/**
 * Store MAC address for given CSP node
 */
void csp_eth_arp_set_addr(uint8_t * mac_addr, uint16_t csp_addr); 
[docs]/**
 * Find MAC address for given CSP node
 */
void csp_eth_arp_get_addr(uint8_t * mac_addr, uint16_t csp_addr); 
[docs]/**
 * Send CSP packet over CAN (nexthop).
 *
 * This function will split the CSP packet into several fragments and call
 * csp_eth_tx_frame() for sending each fragment.
 *
 * @return #CSP_ERR_NONE on success, otherwise an error code.
 */
int csp_eth_tx(csp_iface_t * iface, uint16_t via, csp_packet_t * packet, int from_me); 
[docs]/**
 * Process received CSP ethernet frame.
 *
 * Called from driver when a single ethernet frame has been received.
 * The function will gather the fragments into a single CSP packet and route
 * it on when complete.
 *
 * @param[in] iface incoming interface.
 * @param[in] eth_frame received ETH data.
 * @param[in] received_len received ETH data length.
 * @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL!
 * @return #CSP_ERR_NONE on success, otherwise an error code.
 */
int csp_eth_rx(csp_iface_t * iface, csp_eth_header_t * eth_frame, uint32_t received_len, int * task_woken); 
#ifdef __cplusplus
}
#endif