?? pkthandler.c
字號(hào):
/*
* Descripton:
* Contains packet callbacks, dhcp, buffer handling functionlity
*/
#include "lwip/debug.h"
#include "lwip/ip.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include <cglobals.h>
#include <kernel_abs.h>
#include <sys/exception.h>
#include <services/services.h>
#include <drivers/adi_dev.h>
#include <services/adi_dcb.h>
#include <services/adi_dma.h>
#include <services/adi_int.h>
#include <services/adi_ebiu.h>
#include "netif/nifce_driver.h"
#include <ADI_ETHER.h>
// Enable it to print the obtained IP address.
//#define _LWIP_DEBUG_
// Maximum number of supported interfaces.
#define MAX_NETWORK_IF 2
// struct to hold network driver instance specific information.
//
struct network_info {
int num_if;
int imask[MAX_NETWORK_IF];
struct nifce_info vinfo[MAX_NETWORK_IF];
struct netif* netif[MAX_NETWORK_IF];
struct ip_addr ipaddr[MAX_NETWORK_IF];
struct ip_addr netmask[MAX_NETWORK_IF];
struct ip_addr gateway[MAX_NETWORK_IF];
};
// The below two external variables will be defined in the generated user
// configuration file
//
extern net_config_info user_net_config_info[];
extern int user_net_num_ifces;
// global statics
static struct network_info netinfo = {0};
static ADI_DEV_DEVICE_HANDLE pli_services[MAX_NETWORK_IF];
ADI_ETHER_BUFFER *rcv_list=NULL,*xmt_list=NULL;
void lwip_init(u8_t *lwip_memory);
void dhcp_timer_init(void);
void etharp_timer_init();
int dhcp_configure(void);
void nifce_driver_poll(void*);
/****************************************************************
*
* Append the packet the passed list. list could be recv list
* or transmit list.must be called in critical region.
* list could be rcv_list or xmt_list
****************************************************************/
static void append_list(ADI_ETHER_BUFFER **list,ADI_ETHER_BUFFER *b)
{
ADI_ETHER_BUFFER *t;
if(*list == NULL)
*list = b;
else
{
t = *list;
while(t->pNext != NULL)
t= t->pNext;
t->pNext = b;
}
}
/****************************************************************
*
* callback function that puts in poll function in the tcpip queue.
* the enqued callback function is exectued by the tcpip thread.
* enques callbacks for all n/w interfaces.
****************************************************************/
void tcpip_q_callback(void *in_args)
{
int i,poll_period = (int)in_args;
if(poll_period == 0) poll_period = 10;
while (1)
{
ker_sleep(poll_period);
for (i = 0; i < netinfo.num_if; i += 1)
tcpip_callback(nifce_driver_poll, netinfo.netif[i]);
}
}
/****************************************************************
*
* Deffered callback handler. Called in-response to device drivers
* Post call.
* TODO: Optimize to process xmt packets in the callback
****************************************************************/
void stack_callback_handler(void *arg1,unsigned int event,void* pack_list)
{
if((ADI_ETHER_BUFFER*)pack_list != NULL)
{
int int_sts = ker_disable_interrupts(ker_kPriorityLevelAll);
switch(event)
{
case ADI_ETHER_EVENT_FRAME_RCVD:
append_list(&rcv_list,(ADI_ETHER_BUFFER*)pack_list);
break;
case ADI_ETHER_EVENT_FRAME_XMIT:
append_list(&xmt_list,(ADI_ETHER_BUFFER*)pack_list);
break;
case ADI_ETHER_EVENT_INTERRUPT:
break;
}
ker_enable_interrupts(int_sts);
}
}
/****************************************************************
* Initializes the stack and starts the packet handler thread
* with the supplied priority and the supplied thread pool time
*
* Buffer structure
*
* --------- ---------- --------------- --------------->
* buffer_t buffer_info buffer overhead actual buffer
* --------- ---------- --------------- -------------->
****************************************************************/
int init_stack(int inThreadPriority, int inThreadPollTime, int inMemSize, char *MemArea)
{
int i,overhead=0;
int nw_ifce_buffer_length = 0;
int total_buffer_length =0;
unsigned int LWIP_AREA_START=0;
unsigned int BUFF_AREA_START=0;
unsigned int BUFF_AREA_LEN=0;
unsigned int buff_overhead;
BUFF_AREA_START = (unsigned int)MemArea;
BUFF_AREA_LEN = (unsigned int)inMemSize;
overhead = sizeof(ADI_ETHER_BUFFER) + sizeof(struct buffer_info);
// defined in the user configruation file.
netinfo.num_if = user_net_num_ifces;
nw_ifce_buffer_length = 0;
// Caluculate the total buffer space for rx/tx and for all n/w interfaces.
//
for (i = 0; i < netinfo.num_if; i += 1)
{
nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * user_net_config_info[i].rx_buff_datalen;
nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * user_net_config_info[i].tx_buff_datalen;
nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * overhead;
nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * overhead;
}
// base address for major lwip data areas
//
LWIP_AREA_START = BUFF_AREA_START+nw_ifce_buffer_length;
// Initialize lwip stack modules.
//
lwip_init((u8_t*)LWIP_AREA_START);
// Setup interface's and their associated buffers.
//
for (i = 0; i < netinfo.num_if; i += 1)
{
struct nifce_info* nip = &netinfo.vinfo[i];
struct netif* ni;
void *handle = pli_services[i];
nip->handle = handle;
// Compute the size of the memory area with the user given pli buffer
// size and its length.
nw_ifce_buffer_length = 0;
// Add rx buffer area
nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * user_net_config_info[i].rx_buff_datalen;
// Add Tx buffer area.
nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * user_net_config_info[i].tx_buff_datalen;
// reserve space for overhead also.
nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * overhead;
nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * overhead;
nip->rx_buffs = user_net_config_info[i].rx_buffs;
nip->tx_buffs = user_net_config_info[i].tx_buffs;
nip->rx_buff_datalen = user_net_config_info[i].rx_buff_datalen;
nip->tx_buff_datalen = user_net_config_info[i].tx_buff_datalen;
nip->buff_area = (char*)(BUFF_AREA_START + total_buffer_length);
nip->buff_area_size = nw_ifce_buffer_length;
nip->use_DHCP = user_net_config_info[i].use_dhcp;
// add it to the total length
total_buffer_length += nw_ifce_buffer_length;
// If DHCP is not enabled then we have user specified IP address,
// Subnet mask, Gateway
//
if(nip->use_DHCP == 0)
{
IP4_ADDR(&netinfo.ipaddr[i],
(user_net_config_info[i].ipaddr >> 24) & 0x000000ff ,
(user_net_config_info[i].ipaddr >> 16) & 0x000000ff,
( user_net_config_info[i].ipaddr>> 8) & 0x000000ff,
( user_net_config_info[i].ipaddr >> 0) & 0x000000ff);
IP4_ADDR(&netinfo.netmask[i],
(user_net_config_info[i].netmask >> 24) & 0x000000ff ,
(user_net_config_info[i].netmask >> 16) & 0x000000ff,
( user_net_config_info[i].netmask>> 8) & 0x000000ff,
( user_net_config_info[i].netmask >> 0) & 0x000000ff);
IP4_ADDR(&netinfo.gateway[i],
(user_net_config_info[i].gateway >> 24) & 0x000000ff ,
(user_net_config_info[i].gateway >> 16) & 0x000000ff,
( user_net_config_info[i].gateway>> 8) & 0x000000ff,
( user_net_config_info[i].gateway >> 0) & 0x000000ff);
}
// get if Mac address is specified. If user specified is 0 then
// we will query the supllied IPLI to get the actual address.
//
if(memcmp(user_net_config_info[i].mac_addr,"\x00\x00\x00\x00\x00\x00",6))
{
memcpy(&netinfo.vinfo[i].ia[0], user_net_config_info[i].mac_addr, 6);
adi_dev_Control(pli_services[i],ADI_ETHER_CMD_SET_MAC_ADDR,(void*)&user_net_config_info[i].mac_addr);
}
else
{
// Applicatons must set up the physical address of the interface
// before.
char m_addr[] = { 0,0,0,0,0,0 };
adi_dev_Control(pli_services[i],ADI_ETHER_CMD_GET_MAC_ADDR,(void*)&m_addr);
memcpy(&netinfo.vinfo[i].ia[0],m_addr,6);
}
adi_dev_Control(pli_services[i],ADI_ETHER_CMD_GET_BUFFER_PREFIX,(void*)&buff_overhead);
nip->buff_overhead = (size_t)buff_overhead;
ni = netinfo.netif[i] = netif_add(
&netinfo.ipaddr[i],
&netinfo.netmask[i],
&netinfo.gateway[i],
&netinfo.vinfo[i],
nifce_driver_init,
ip_input
);
LWIP_ASSERT("boot thread: failed to add network interface", ni != NULL);
#ifdef LWIP_DEBUG
printf(
"Network Interface %c%c%d: %d.%d.%d.%d : "
"%02X-%02X-%02X-%02X-%02X-%02X : RX buffs = %d : TX buffs = %d\n",
ni->name[0], ni->name[1], ni->num,
ip4_addr1(&ni->ip_addr), ip4_addr2(&ni->ip_addr),
ip4_addr3(&ni->ip_addr), ip4_addr4(&ni->ip_addr),
ni->hwaddr[0], ni->hwaddr[1], ni->hwaddr[2],
ni->hwaddr[3], ni->hwaddr[4], ni->hwaddr[5],
((struct nifce_info*)ni->state)->rx_buffs,
((struct nifce_info*)ni->state)->tx_buffs
);
#endif /* LWIP_DEBUG */
}
// set the default network interface
//
netif_set_default(netinfo.netif[0]);
// start the ARP update thread
etharp_timer_init();
// Create pkthandler thread that processes the packets.
//
sys_thread_new(tcpip_q_callback,(void*)inThreadPollTime,inThreadPriority);
return 1;
}
/****************************************************************
* Invoked when users calls StartStack on the TCP/IP component.
* Currently only DHCP configuration is checked. If DHCP is enabled
* stack checks the DHCP server and gets the addres.
****************************************************************/
int start_stack()
{
return dhcp_configure();
}
/****************************************************************
* Gets the address from the DHCP server. DHCP is checked for only
* the interface on which the DHCP is enabled in the UI.
****************************************************************/
int dhcp_configure(void)
{
int i;
long time_slept=0;
int success_flag = 1;
dhcp_timer_init();
for (i = 0; i < netinfo.num_if; i += 1) {
struct netif* ni = netinfo.netif[i];
if(user_net_config_info[i].use_dhcp == 1)
{
dhcp_start(ni);
// Wait for 50ms and check for the DHCP status.
//
ker_sleep(50);
while (*(volatile u8_t*)&ni->dhcp->state != DHCP_BOUND) {
// sleep for 500ms and check again, for 2 min..
ker_sleep(500);
time_slept += 500;
if(time_slept > 120*1000)
{
success_flag = 0;
break;
}
}
#ifdef _LWIP_DEBUG_
printf(
"Network Interface %c%c%d: %d.%d.%d.%d : "
"%02X-%02X-%02X-%02X-%02X-%02X : RX buffs = %d : TX buffs = %d\n",
ni->name[0], ni->name[1], ni->num,
ip4_addr1(&ni->ip_addr), ip4_addr2(&ni->ip_addr),
ip4_addr3(&ni->ip_addr), ip4_addr4(&ni->ip_addr),
ni->hwaddr[0], ni->hwaddr[1], ni->hwaddr[2],
ni->hwaddr[3], ni->hwaddr[4], ni->hwaddr[5],
((struct nifce_info*)ni->state)->rx_buffs,
((struct nifce_info*)ni->state)->tx_buffs
);
#endif /* _LWIP_DEBUG_ */
}
}
return success_flag;
}
/****************************************************************
* gethostaddr() gets the primary network interfaces IP address
* in dot notation form.
****************************************************************/
int gethostaddr(int nwifce_no,char *host_addr)
{
if(nwifce_no >= 0 && nwifce_no < netinfo.num_if)
{
struct netif* ni = netinfo.netif[nwifce_no];
u32_t ipaddr = ni->ip_addr.addr;
u8_t *ip_in_dot = inet_ntoa(ipaddr);
memcpy(host_addr,ip_in_dot,16);
return 1;
}
return -1;
}
// sets the pli services for stack to use
int set_pli_services(int num_services, ADI_DEV_DEVICE_HANDLE *pservices)
{
int i=0;
for (i=0; i<num_services; i++)
pli_services[i]= (ADI_DEV_DEVICE_HANDLE)pservices[i];
return 1;
}
// return default gateway
struct ip_addr get_default_gateway()
{
struct netif* ni = netinfo.netif[0];
return (ni->gw);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -