|
Modules | |
| Private constants | |
| Typedefs | |
| Private functions | |
| Functions | |
| Constants | |
Functions | |
| i32 | __ethifOut (__PNETIF netif, u16 type, u8 *dest, __PNET_BUFFER nb, __BOOL freenb) |
| Queues or transmits a Network Buffer. | |
| __VOID | __ethifThread (__VOID) |
| The network interface thread. | |
| i32 __ethifOut | ( | __PNETIF | netif, |
| u16 | type, | ||
| u8 * | dest, | ||
| __PNET_BUFFER | nb, | ||
| __BOOL | freenb | ||
| ) |
Queues or transmits a Network Buffer.
The __NET_BUFFER will be reordered using the __nbReorder() function. The reordered buffer is allocated an deallocated locally.
| netif | Pointer to a network interface. |
| type | Type of protocol. See Protocols.
|
| dest | MAC address of the remote host. If null the packet will be sent to the broadcast address. |
| nb | Pointer to a Network Buffer to be sent. |
| freenb | If __TRUE, the nb Network Buffer will be deallocated (with __nbDealloc()) after queuing or transmission. Otherwise is up to the caller to free the buffer (useful for packet broadcasting). |
Definition at line 204 of file ethif.c.
{
__ETHERNET_HDR *hdr;
u8* ptr;
u32 size;
i32 ret = 0;
if (!__nbAlloc(nb, __NB_LAYER_DATALINK, sizeof(__ETHERNET_HDR)))
{
return -1;
}
hdr = (__ETHERNET_HDR*) nb->nl_dl.ptr;
__memCpy(hdr->shost, netif->addr.type.mac, 6);
if (dest)
{
__memCpy(hdr->dhost, dest, 6);
} else {
__memSet(hdr->dhost, 0xff, 6);
}
hdr->type = __htons(type);
/*
* Reorder the Network Buffer.
*/
ptr = __nbReorder(nb, &size);
if (ptr)
{
if (__lockOwn(netif->lock, 1000))
{
if (__deviceWrite(netif->dv, ptr, size) == size)
{
NETMSG(__NET_DEBUG_ETH, ("[ETH] (%s) frame written, size = %lu", netif->dv->dv_name, (u32) size));
} else {
ret = -1;
NETMSG(__NET_DEBUG_ETH, ("[ETH] (%s) error writing frame, size = %lu", netif->dv->dv_name, (u32) size));
}
__lockRelease(netif->lock);
} else {
ret = -1;
NETMSG(__NET_DEBUG_ETH, ("[ETH] (%s) error writing, device is busy", netif->dv->dv_name));
}
__heapFree(ptr);
}
if (freenb) __nbDealloc(nb);
return ret;
}

The network interface thread.
This thread will be created by calling the __netifInit() function.
The thread will initialize and open the underlying device (if not already initialized and opened) with default values.
By default the thread will check for the status of the Ethernet link, and switch between modes according to the status. If the link goes down and the interface was configured to work with DHCP, the DHCP reboot procedure is launched.
The main function of this thread is to read Ethernet frames from the underlying device.
It will also call the DHCP and ARP state machines.
Definition at line 276 of file ethif.c.
{
__PNET_BUFFER nb;
__PNETIF netif = __threadGetParameter();
u8 link_status = __ETHERNET_LINK_UNKNOWN;
u8 temp_status = 0;
u32 seconds = __systemGetTickCount();
/* Check if the device is initialized */
if (!__deviceInitialized(netif->dv))
{
/* Try to initialize the device with the default values */
if (__deviceInit(netif->dv, __NULL, 0) == __DEV_OK)
{
if (__deviceIOCtl(netif->dv, __IOCTL_GET_MAC_ADDRESS, 0, netif->addr.type.mac, 6) == __DEV_OK)
{
netif->addr.addr_type = __NET_ADDR_MAC;
}
} else {
NETMSG(__NET_DEBUG_ETH, ("[ETH] %s device initialization failed.", netif->dv->dv_name));
while (__TRUE) __threadSleep(1000);
}
}
/* Check if the device is opened */
if (!__deviceOpened(netif->dv))
{
while (__deviceOpen(netif->dv, 0) != __DEV_OK)
{
NETMSG(__NET_DEBUG_ETH, ("[ETH] %s device not ready.", netif->dv->dv_name));
__threadSleep(2000);
}
}
/* Set the RX timeout */
__deviceIOCtl(netif->dv, __IOCTL_SETRXTIMEOUT, 1000, __NULL, 0);
/* Allocate local buffer */
netif->params = __heapAlloc(netif->mtu);
for (;;)
{
/* Query for link status every two seconds */
if (__systemGetSecondsCount() - seconds > 2)
{
/* Check the device answer */
switch (__deviceIOCtl(netif->dv, __IOCTL_QUERY_LINK_STATUS, 0, &temp_status, 1))
{
case __DEV_UNK_IOCTL:
/* The device does not manage the __IOCTL_GET_LINK_STATUS ioctl,
* so assume the link is up. */
temp_status = 1;
break;
case __DEV_OK:
break;
/* If the device throws error or not ready, do nothing */
case __DEV_ERROR:
case __DEV_NOT_READY:
temp_status = 0;
break;
}
seconds = __systemGetSecondsCount();
/* Detect link status change */
switch (link_status)
{
case __ETHERNET_LINK_UNKNOWN:
if (temp_status) link_status = __ETHERNET_LINK_UP;
break;
case __ETHERNET_LINK_UP:
if (!temp_status)
{
NETMSG(__NET_DEBUG_ETH, ("[ETH] (%s) link lost", netif->dv->dv_name));
link_status = __ETHERNET_LINK_LOST;
}
break;
case __ETHERNET_LINK_LOST:
if (temp_status)
{
/* Link back */
NETMSG(__NET_DEBUG_ETH, ("[ETH] (%s) link back", netif->dv->dv_name));
link_status = __ETHERNET_LINK_UP;
if (netif->flags == __NETIF_FLAG_DHCP) __dhcpInitReboot(netif);
}
break;
}
}
if (link_status == __ETHERNET_LINK_UP)
{
/* Call the DHCP state machine, if configured with __NETIF_FLAG_DHCP */
if (netif->flags & __NETIF_FLAG_DHCP) __dhcpSm(netif);
/* Call the ARP state machine */
__arpSm(netif);
/* Get a frame from the device */
nb = __ethifGetFrame(netif);
if (nb)
{
/* Pass it to the Ethernet handler */
__ethifIn(netif, nb);
}
} else __threadSleep(1);
}
}
