add patch against ecos needed for the glue to wotk

This commit is contained in:
jani 2003-03-01 10:47:38 +00:00
parent d9d0f12c61
commit 9ac27f9860
2 changed files with 426 additions and 0 deletions

View File

@ -1,5 +1,7 @@
This part of the lwip-contrib section is the ecos glue
Check out latest ecos or beta 2 if available and apply ioeth.diff to packages/io/eth
You must have the current lwip sources checked out and the scripts here will hopefully generate
a correct EPK suitable for use with ecos.

424
ports/ecos/ioeth.diff Normal file
View File

@ -0,0 +1,424 @@
Index: io/eth/current//include/eth_drv.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/eth/current/include/eth_drv.h,v
retrieving revision 1.8
diff -u -r1.8 eth_drv.h
--- io/eth/current//include/eth_drv.h 13 Aug 2002 15:55:53 -0000 1.8
+++ io/eth/current//include/eth_drv.h 1 Mar 2003 10:36:59 -0000
@@ -81,6 +81,9 @@
#else // !CYGPKG_NET
#include <cyg/hal/drv_api.h>
#endif
+#ifdef CYGPKG_NET_LWIP
+#include "lwip/netif.h"
+#endif
struct eth_drv_sg {
CYG_ADDRESS buf;
@@ -141,6 +144,9 @@
#ifndef CYGPKG_NET
struct arpcom {
+#ifdef CYGPKG_NET_LWIP
+ struct netif ac_if;
+#endif
unsigned char esa[6];
};
#endif
Index: io/eth/current//src/lwip/eth_drv.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/eth/current/src/lwip/eth_drv.c,v
retrieving revision 1.2
diff -u -r1.2 eth_drv.c
--- io/eth/current//src/lwip/eth_drv.c 23 May 2002 23:06:02 -0000 1.2
+++ io/eth/current//src/lwip/eth_drv.c 1 Mar 2003 10:37:01 -0000
@@ -69,113 +69,149 @@
#include <cyg/hal/hal_tables.h>
#include <cyg/kernel/kapi.h>
+#include "lwip/opt.h"
+#include "lwip/ip.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+
+#include "netif/etharp.h"
+
+
+
// Define table boundaries
-CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
-CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
+CYG_HAL_TABLE_BEGIN(__NETDEVTAB__, netdev);
+CYG_HAL_TABLE_END(__NETDEVTAB_END__, netdev);
// Interfaces exported to drivers
static void eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr);
static void eth_drv_recv(struct eth_drv_sc *sc, int total_len);
-static void eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRWORD key, int status);
+static void eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRWORD key,
+ int status);
-struct eth_drv_funs eth_drv_funs = {eth_drv_init, eth_drv_recv, eth_drv_tx_done};
+struct eth_drv_funs eth_drv_funs =
+ { eth_drv_init, eth_drv_recv, eth_drv_tx_done };
-struct eth_drv_sc *__local_enet_sc;
-
-//this is where lwIP keeps hw address
-unsigned char *lwip_hw_addr;
cyg_sem_t delivery;
-//lwIP callback to pass received data to
-typedef void (*lwip_input_t)(char *,int);
-static lwip_input_t lwip_input;
-void input_thread(void * arg)
-{
- struct eth_drv_sc * sc;
- //sc = (struct eth_drv_sc *)arg;
- sc = __local_enet_sc;
- for(;;) {
- cyg_semaphore_wait(&delivery);
- (sc->funs->deliver)(sc);
- }
+//DSR called from the low level driver.Signals the input_thread
+void
+eth_drv_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *) data;
+ sc->state |= ETH_DRV_NEEDS_DELIVERY;
+ cyg_semaphore_post(&delivery);
+}
+
+//Input thread signalled by DSR calls deliver() on low level drivers
+static void
+input_thread(void *arg)
+{
+ cyg_netdevtab_entry_t *t;
+
+ for (;;) {
+ cyg_semaphore_wait(&delivery);
+
+ for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)t->device_instance;
+ if (sc->state & ETH_DRV_NEEDS_DELIVERY) {
+ sc->state &= ~ETH_DRV_NEEDS_DELIVERY;
+ (sc->funs->deliver) (sc);
+ }
+ }
+ }
}
-void
-eth_drv_dsr(cyg_vector_t vector,
- cyg_ucount32 count,
- cyg_addrword_t data)
+// Initialize all network devices
+static void
+init_hw_drivers(void)
{
- // struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
- // sc->state |= ETH_DRV_NEEDS_DELIVERY;
- cyg_semaphore_post(&delivery);
+ cyg_netdevtab_entry_t *t;
+
+ for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
+ if (t->init(t)) {
+ t->status = CYG_NETDEVTAB_STATUS_AVAIL;
+ } else {
+ // What to do if device init fails?
+ t->status = 0; // Device not [currently] available
+ }
+ }
}
+static void
+arp_timer(void *arg)
+{
+ etharp_tmr();
+ sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler) arp_timer, NULL);
+}
-//Called from lwIP init code to init the hw devices
-//and pass the lwip input callback address
-void init_hw_drivers(unsigned char *hw_addr,lwip_input_t input)
+void
+ecosglue_init(void)
{
- cyg_netdevtab_entry_t *t;
-
- lwip_hw_addr = hw_addr;
- lwip_input = input;
-
-// Initialize all network devices
- for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
- if (t->init(t)) {
- t->status = CYG_NETDEVTAB_STATUS_AVAIL;
- } else {
- // What to do if device init fails?
- t->status = 0; // Device not [currently] available
- }
- }
+ init_hw_drivers();
+ sys_thread_new(input_thread, (void*)0);
+ etharp_init();
+ sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler) arp_timer, NULL);
}
-//
+extern void lwip_set_addr(struct netif *);
+
+err_t
+ecosif_init(struct netif *netif);
+
+
+
// This function is called during system initialization to register a
// network interface with the system.
-//
static void
eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
{
- // enaddr == 0 -> hardware init was incomplete (no ESA)
- if (enaddr != 0) {
- // Set up hardware address
- memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN);
- memcpy(lwip_hw_addr, enaddr, ETHER_ADDR_LEN);
- __local_enet_sc = sc;
- // Perform any hardware initialization
- (sc->funs->start)(sc, (unsigned char *)&sc->sc_arpcom.esa, 0);
- }
- cyg_semaphore_init(&delivery,0);
+ struct netif *netif = &sc->sc_arpcom.ac_if;
+
+ netif->state = sc;
+ ecosif_init(netif);
+
+ // enaddr == 0 -> hardware init was incomplete (no ESA)
+ if (enaddr != 0) {
+ // Set up hardware address
+ memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN);
+ memcpy(netif->hwaddr, enaddr, ETHER_ADDR_LEN);
+ // Perform any hardware initialization
+ (sc->funs->start) (sc, (unsigned char *) &sc->sc_arpcom.esa, 0);
+ }
+
+// cyg_semaphore_init(&delivery, 0);
}
//
// Send a packet of data to the hardware
//
-cyg_sem_t packet_sent;
+cyg_sem_t packet_sent;
-void
-eth_drv_write(char *eth_hdr, char *buf, int len)
+static void
+eth_drv_send(struct netif *netif, struct pbuf *p)
{
- struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
- struct eth_drv_sc *sc = __local_enet_sc;
- int sg_len = 1;
+ struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
+ struct eth_drv_sc *sc = netif->state;
+ int sg_len = 0;
+ struct pbuf *q;
+
+ while (!(sc->funs->can_send) (sc)) {
+ cyg_thread_delay(1);
+ }
+
+ for (q = p; q != NULL; q = q->next) {
+ sg_list[sg_len].buf = (CYG_ADDRESS) q->payload;
+ sg_list[sg_len++].len = q->len;
+ }
+
+ (sc->funs->send) (sc, sg_list, sg_len, p->tot_len,
+ (CYG_ADDRWORD) & packet_sent);
- while (!(sc->funs->can_send)(sc)) {
- cyg_thread_delay(1);
- }
-
- sg_list[0].buf = (CYG_ADDRESS)buf;
- sg_list[0].len = len;
-// cyg_semaphore_init(&packet_sent,0);
- (sc->funs->send)(sc, sg_list, sg_len, len, (CYG_ADDRWORD)&packet_sent);
-
-// cyg_semaphore_wait(&packet_sent);
}
//
@@ -185,15 +221,16 @@
static void
eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRWORD key, int status)
{
-#if 0
- CYGARC_HAL_SAVE_GP();
- if (key == (CYG_ADDRWORD)&packet_sent) {
-// cyg_semaphore_post((cyg_sem_t *)&packet_sent);
- }
- CYGARC_HAL_RESTORE_GP();
-#endif
+#if 0
+ CYGARC_HAL_SAVE_GP();
+ if (key == (CYG_ADDRWORD) & packet_sent) {
+// cyg_semaphore_post((cyg_sem_t *)&packet_sent);
+ }
+ CYGARC_HAL_RESTORE_GP();
+#endif
}
+static void ecosif_input(struct netif *netif, struct pbuf* pbuf);
#define MAX_ETH_MSG 1540
//
@@ -204,23 +241,129 @@
static void
eth_drv_recv(struct eth_drv_sc *sc, int total_len)
{
- struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
- int sg_len = 0;
- unsigned char buf[MAX_ETH_MSG];
- CYGARC_HAL_SAVE_GP();
+ struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
+ struct netif *netif = &sc->sc_arpcom.ac_if;
+
+ struct pbuf *p, *q;
+
+ int sg_len = 0;
+ CYGARC_HAL_SAVE_GP();
+
+ if ((total_len > MAX_ETH_MSG) || (total_len < 0)) {
+ total_len = MAX_ETH_MSG;
+ }
+
+ p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL);
+
+ if (p == NULL) {
+ diag_printf("ecosif_input: low_level_input returned NULL\n");
+ return;
+ }
+
+ for (q = p; q != NULL; q = q->next) {
+ sg_list[sg_len].buf = (CYG_ADDRESS) q->payload;
+ sg_list[sg_len++].len = q->len;
+ }
+ (sc->funs->recv) (sc, sg_list, sg_len);
+ ecosif_input(netif, p);
+ CYGARC_HAL_RESTORE_GP();
+}
- if ((total_len > MAX_ETH_MSG) || (total_len < 0)) {
- total_len = MAX_ETH_MSG;
- }
- sg_list[0].buf = (CYG_ADDRESS)buf;
- sg_list[0].len = total_len;
- sg_len = 1;
+#define IFNAME0 'e'
+#define IFNAME1 't'
- (sc->funs->recv)(sc, sg_list, sg_len);
- (lwip_input)((char*)sg_list[0].buf,total_len);
- CYGARC_HAL_RESTORE_GP();
+
+
+/*
+ * low_level_output():
+ *
+ * Should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.We pass the data down to the eCos hw independent
+ * ethernet driver
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+ /* signal that packet should be sent(); */
+ eth_drv_send(netif, p);
+ return ERR_OK;
+}
+
+/*
+ * ecosif_output():
+ *
+ * This function is called by the TCP/IP stack when an IP packet
+ * should be sent. It calls the function called low_level_output() to
+ * do the actual transmission of the packet.
+ *
+ */
+static err_t
+ecosif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
+{
+
+ p = etharp_output(netif, ipaddr, p);
+ if (p) {
+ low_level_output(netif, p);
+ p = NULL;
+ }
+ return ERR_OK;
}
-// EOF src/lwip/eth_drv.c
+
+/*
+ * ecosif_input():
+ * This function is called when the eCos hw independent driver
+ * has some data to pass up to lwIP.It does it through ecosif_input.
+ */
+static void
+ecosif_input(struct netif *netif, struct pbuf *p)
+{
+ struct eth_drv_sc *sc;
+ struct eth_hdr *ethhdr;
+ struct pbuf *q;
+
+ sc = netif->state;
+ /* We allocate a pbuf chain of pbufs from the pool. */
+ ethhdr = p->payload;
+
+ q = NULL;
+
+ switch (htons(ethhdr->type)) {
+ case ETHTYPE_IP:
+ DEBUGF(0, ("ecosif_input: IP packet\n"));
+ q = etharp_ip_input(netif, p);
+ pbuf_header(p, -14);
+ netif->input(p, netif);
+ break;
+ case ETHTYPE_ARP:
+ DEBUGF(0, ("ecosif_input: ARP packet\n"));
+ q = etharp_arp_input(netif, (struct eth_addr *) &sc->sc_arpcom.esa, p);
+ break;
+ default:
+ pbuf_free(p);
+ break;
+ }
+
+ if (q != NULL) {
+ DEBUGF(0, ("ecosif_input: Sending ARP reply\n"));
+ low_level_output(netif, q);
+ pbuf_free(q);
+ }
+}
+
+err_t
+ecosif_init(struct netif *netif)
+{
+ netif->name[0] = IFNAME0;
+ netif->name[1] = IFNAME1;
+ netif->hwaddr_len = 6;
+ netif->output = ecosif_output;
+ netif->linkoutput = low_level_output;
+ netif->mtu = 1500;
+ lwip_set_addr(netif);
+ return ERR_OK;
+}