/*
 * IEthernetDevice.h
 *
 *  Created on: 2011/12/06
 * MiMicのイーサネットドライバインタフェイスを定義する。
 */
#ifndef IEthernetDevice_h
#define IEthernetDevice_h
#include "../../uip/NyLPC_uip.h"
#include "NyLPC_stdlib.h"


/**
 * 送信バッフメモリのヘッダ。
 * この構造体は、TXバッファメモリブロックのヘッダーです。
 * TXバッファメモリブロックは、この構造体の後ろに、sizeに一致したメモリを連結したもので表現します。
 * <pre>
 * buffer=[struct NyLPC_TTxBufferHeader][n]
 * </pre>
 */
struct NyLPC_TTxBufferHeader
{
	NyLPC_TInt8  ref;
	//送信用にロックしたかを示すフラグ
	NyLPC_TUInt8 is_lock;
	//32ビット境界に合わせるためのパディングです。
	NyLPC_TUInt16 padding;
};


/**
 * 受信キューの先頭にあるデータを返す。
 * 関数は、受信キューのポインタを操作しない。続けて読み出したとしても、同じポインターを返す。
 * 次のデータを得るには、nextRxEthFrameを呼び出す。
 * #制限として、返却したポインタの内容は、一時的に書き換え可としてください。（この制限は将来削除します。）
 * @return
 * 成功した場合、受信データを格納したバッファポインタ。返却値は、nextRxEthFrameをコールするまで有効である。
 * 存在しない場合NULL。
 */
typedef void* (*NyLPC_TiEthernetDevice_getRxEthFrame)(unsigned short* o_len_of_data);

/**
 * getRxEthFrameで得たメモリを破棄して、次のRXデータを準備する。
 * getRxEthFrameで返したメモリの内容の有効期間はここで終了するので注意すること。
 */
typedef void (*NyLPC_TiEthernetDevice_nextRxEthFrame)(void);


/**
 * 送信バッファを得る。
 * 関数は、i_hintで示されるサイズのメモリブロックを確保しようとするが、実際にはそれよりも小さいことがある。
 * @param i_hint
 * 確保してほしいメモリサイズ
 * @param o_size
 * 実際に割り当てたメモリのサイズ
 * @return
 * 割り当てたメモリブロックのヘッダ。
 */
typedef struct NyLPC_TTxBufferHeader* (*NyLPC_TiEthernetDevice_allocTxBuf)(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size);


/**
 * alloc_TxBufで得た送信バッファを開放する。
 */
typedef void (*NyLPC_TiEthernetDevice_releaseTxBuf)(struct NyLPC_TTxBufferHeader* i_buf);

/**
 * イーサネットパケット構造体i_bufの内容を送信する。
 * @param i_buf
 * allocTxBufで得たメモリか、初期化したNyLPC_TTxBufferHeaderメモリブロックを指定する。
 * 送信が終わるまでの間、メモリを開放してはならない。
 * #外部で確保したメモリについては、利用不能なケースがあるかもしれない。現在のMiMicでは、使用できることを前提としている。
 */
typedef void (*NyLPC_TiEthernetDevice_sendTxEthFrame)(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size);
/**
 * この関数は、送信キューの状態を進行させるタイミングを与える。
 * 外部関数が、送信キューにセットしたパケットの送信待ちをするときに呼び出す。
 */
typedef void (*NyLPC_TiEthernetDevice_processTx)(void);

typedef NyLPC_TBool(*NyLPC_TiEthernetDevice_start)(const struct NyLPC_TEthAddr* i_eth_addr);
typedef void(*NyLPC_TiEthernetDevice_stop)(void);

/**
 * イーサネットデバイスのアクセスインターフェイス構造体。
 * イーサネットデバイスの管理するメモリブロック、ペリフェラル制御のインタフェイスを提供する。
 */
struct TiEthernetDevice
{
	const char* device_name;//pointer to device name.
	NyLPC_TiEthernetDevice_start start;
	NyLPC_TiEthernetDevice_stop stop;
	NyLPC_TiEthernetDevice_getRxEthFrame getRxEthFrame;
	NyLPC_TiEthernetDevice_nextRxEthFrame nextRxEthFrame; //nextRxEthFrame;
	NyLPC_TiEthernetDevice_allocTxBuf allocTxBuf;
	NyLPC_TiEthernetDevice_releaseTxBuf releaseTxBuf;
	NyLPC_TiEthernetDevice_sendTxEthFrame sendTxEthFrame;
	NyLPC_TiEthernetDevice_processTx processTx;
};

#endif
