/*	
 *	app.h
 *
 *	PceEth - P/ECE NDIS-WDM 儈僯億乕僩僪儔僀僶
 *	Copyright (C) 2005 Naoyuki Sawa
 *
 *	* Tue Aug 16 06:19:00 JST 2005 Naoyuki Sawa
 *	- 1st 儕儕乕僗丅
 */
#ifndef __APP_H__
#define __APP_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <ndis.h>
#include <usbdi.h>
#include <usbdlib.h>

#define VERBOSE /* 偙偺僔儞儃儖傪掕媊偡傞偲丄徻嵶側僨僶僢僌弌椡傪峴偄傑偡 */

/*****************************************************************************
 *	
 *****************************************************************************/

/*  ==========================[ Ethernet腾把峔憿 ]==========================
 *
 *           |<----- NDIS衅芜澳霓撞兽偑埖偆晹暘 (60-1514 byte) ----->|
 *           |                                                       |
 *  +--------+--------------+--------------+--------+----------------+-----+
 *  | 8 byte |    6 byte    |    6 byte    | 2 byte |  46-1500 byte  |4byte|
 *  +--------+--------------+--------------+--------+----------------+-----+
 *  |踢乇萏拶|埗偰愭MAC蹦挹絴憲怣尦MAC蹦挹絴腾把啦踢|      棉袄      | FCS |
 *  +--------+--------------+--------------+--------+----------------+-----+
 *       A                                                              A
 *       |                                                              |
 *       +-- NIC拾霓唱眰獣t壛/彍嫀偡傞偺偱つ拮彩蘅棠唱眰艂蛵l椂偟側偄 --+
 */

/*****************************************************************************
 *	
 *****************************************************************************/

typedef struct _MINIPORT_ADAPTER {
	NDIS_HANDLE miniport_adapter_handle;		/* 儈僯億乕僩傾僟僾僞僴儞僪儖 */

	DEVICE_OBJECT* physical_device_object;		/* 暔棟僨僶僀僗僆僽僕僃僋僩 (USB?) */
	DEVICE_OBJECT* functional_device_object;	/* 偙偺僨僶僀僗僆僽僕僃僋僩 (NIC)  */
	DEVICE_OBJECT* next_device_object;		/* 壓埵僨僶僀僗僆僽僕僃僋僩 (USBD) */

	KSPIN_LOCK spin_lock;				/* 嫟桳僗僺儞儘僢僋 */
	KEVENT abort_event;				/* 拞抐捠抦僀儀儞僩 */

	unsigned char address[6];			/* MAC傾僪儗僗 */
	int packet_filter;				/* 僷働僢僩僼傿儖僞 */
	int xmit_ok;					/* 憲怣惉岟僷働僢僩悢 */
	int rcv_ok;					/* 庴怣惉岟僷働僢僩悢 */
	int xmit_error;					/* 憲怣幐攕僷働僢僩悢 */
	int rcv_error;					/* 庴怣幐攕僷働僢僩悢 */

	USBD_PIPE_INFORMATION tx_pipe;			/* 僶儖僋憲怣僷僀僾 */
	KEVENT tx_event;				/* 憲怣斈梡僀儀儞僩 */
	PKTHREAD tx_thread;				/* 憲怣僗儗僢僪 */
	LIST_ENTRY tx_queue;				/* 憲怣僷働僢僩僉儏乕 */

	USBD_PIPE_INFORMATION rx_pipe;			/* 僶儖僋庴怣僷僀僾 */
	KEVENT rx_event;				/* 庴怣斈梡僀儀儞僩 */
	PKTHREAD rx_thread;				/* 庴怣僗儗僢僪 */
	NDIS_HANDLE rx_packet_pool_handle;		/* 庴怣僷働僢僩僾乕儖 */
	NDIS_HANDLE rx_buffer_pool_handle;		/* 庴怣僶僢僼傽僾乕儖 */
} MINIPORT_ADAPTER;

/*****************************************************************************
 *	main.c
 *****************************************************************************/

extern NDIS_HANDLE ndis_wrapper_handle;

NDIS_STATUS miniport_initialize(
	NDIS_STATUS* open_error_status,
	UINT* selected_medium_index,
	NDIS_MEDIUM* medium_array,
	UINT medium_array_size,
	NDIS_HANDLE miniport_adapter_handle,
	NDIS_HANDLE wrapper_configuration_context);

NDIS_STATUS miniport_reset(
	BOOLEAN* addressing_reset,
	NDIS_HANDLE miniport_adapter_context);

void miniport_halt(
	NDIS_HANDLE miniport_adapter_context);

NDIS_STATUS miniport_query_information(
	NDIS_HANDLE miniport_adapter_context,
	NDIS_OID oid,
	void* information_buffer,
	ULONG information_buffer_length,
	ULONG* bytes_written,
	ULONG* bytes_needed);

NDIS_STATUS miniport_set_information(
	NDIS_HANDLE miniport_adapter_context,
	NDIS_OID oid,
	void* information_buffer,
	ULONG information_buffer_length,
	ULONG* bytes_read,
	ULONG* bytes_needed);

void miniport_send_packets(
	NDIS_HANDLE miniport_adapter_context,
	NDIS_PACKET* packet_array[],
	UINT number_of_packets);

void miniport_return_packet(
	NDIS_HANDLE miniport_adapter_context,
	NDIS_PACKET* packet);

/*****************************************************************************
 *	adapter.c
 *****************************************************************************/

MINIPORT_ADAPTER* create_miniport_adapter(
	NDIS_HANDLE miniport_adapter_handle,
	NDIS_HANDLE wrapper_configuration_context);

void delete_miniport_adapter(
	MINIPORT_ADAPTER* miniport_adapter);

/*****************************************************************************
 *	tx.c
 *****************************************************************************/

NTSTATUS tx_init(MINIPORT_ADAPTER* miniport_adapter);
void tx_exit(MINIPORT_ADAPTER* miniport_adapter);
void tx_cancel_packets(MINIPORT_ADAPTER* miniport_adapter);

/*****************************************************************************
 *	rx.c
 *****************************************************************************/

NTSTATUS rx_init(MINIPORT_ADAPTER* miniport_adapter);
void rx_exit(MINIPORT_ADAPTER* miniport_adapter);
NDIS_PACKET* rx_allocate_packet(MINIPORT_ADAPTER* miniport_adapter, const void* data, int length);
void rx_free_packet(MINIPORT_ADAPTER* miniport_adapter, NDIS_PACKET* packet);
void rx_recall_packets(MINIPORT_ADAPTER* miniport_adapter);

/*****************************************************************************
 *	util.c
 *****************************************************************************/

const char* oid_name(int code);
PKTHREAD create_thread(void (*start_routine)(void*), void* start_context);
void delete_thread(PKTHREAD thread_object);
NTSTATUS call_usbd(DEVICE_OBJECT* usbd, URB* urb);
USB_CONFIGURATION_DESCRIPTOR* get_configuration_descriptor(DEVICE_OBJECT* usbd, int i_configuration);
int set_configuration(DEVICE_OBJECT* usbd, USBD_PIPE_INFORMATION pipes[/*max_pipes*/], int max_pipes);
void clear_configuration(DEVICE_OBJECT* usbd);
NTSTATUS usb_transfer(DEVICE_OBJECT* device_object, URB* urb, KEVENT* cancel_event);
NTSTATUS set_device_address(DEVICE_OBJECT* usbd, const unsigned char address[6]);

/*****************************************************************************
 *	
 *****************************************************************************/

#endif /*__APP_H__*/
