mirror of
https://github.com/ep00ch/lwip-contrib-mac.git
synced 2024-10-30 03:26:22 +00:00
401 lines
11 KiB
Diff
401 lines
11 KiB
Diff
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.9
|
|
diff -u -r1.9 eth_drv.h
|
|
--- io/eth//current/include/eth_drv.h 11 Mar 2003 15:41:12 -0000 1.9
|
|
+++ io/eth//current/include/eth_drv.h 21 Mar 2003 16:30:52 -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/README
|
|
===================================================================
|
|
RCS file: /cvs/ecos/ecos/packages/io/eth/current/src/lwip/README,v
|
|
retrieving revision 1.1
|
|
diff -u -r1.1 README
|
|
--- io/eth//current/src/lwip/README 20 May 2002 22:24:21 -0000 1.1
|
|
+++ io/eth//current/src/lwip/README 21 Mar 2003 16:30:52 -0000
|
|
@@ -1,10 +1,2 @@
|
|
An EPK of lwip is available from http://humans.iv.ro/jani which has the most
|
|
up-to-date package (at least until it all gets integrated).
|
|
-
|
|
-It has just been tested on another ARM similar to the EB40 with CS89000
|
|
-and it works there too (that board has 128K of RAM).
|
|
-
|
|
-Alternatively, lw.diff is the diff against the lwip-0.5.3 tree. It contains
|
|
-eCos support + an eCos project sample based on unixsim. Look at
|
|
-lwip-0.5.3/proj/ecos to see how to use it. Modify the Makefile to suit
|
|
-your needs and to reflect your eCos project dir.
|
|
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 21 Mar 2003 16:30:53 -0000
|
|
@@ -47,7 +47,6 @@
|
|
// Description: Based on the standalone driver for RedBoot.
|
|
//
|
|
// TODO:
|
|
-// support more than 1 lowlevel device
|
|
// play nice with RedBoot too
|
|
//
|
|
//####DESCRIPTIONEND####
|
|
@@ -69,113 +68,92 @@
|
|
#include <cyg/hal/hal_tables.h>
|
|
#include <cyg/kernel/kapi.h>
|
|
|
|
-// Define table boundaries
|
|
-CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
|
|
-CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
|
|
+#include "lwip/opt.h"
|
|
+#include "lwip/ip.h"
|
|
+#include "lwip/mem.h"
|
|
+#include "lwip/pbuf.h"
|
|
+#include "lwip/sys.h"
|
|
+
|
|
+#include "netif/etharp.h"
|
|
+
|
|
+
|
|
+
|
|
|
|
// 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);
|
|
-
|
|
-struct eth_drv_funs eth_drv_funs = {eth_drv_init, eth_drv_recv, eth_drv_tx_done};
|
|
+static void eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRWORD key,
|
|
+ int status);
|
|
|
|
-struct eth_drv_sc *__local_enet_sc;
|
|
+struct eth_drv_funs eth_drv_funs =
|
|
+ { eth_drv_init, eth_drv_recv, eth_drv_tx_done };
|
|
|
|
-//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)
|
|
+extern void lwip_dsr_stuff(void);
|
|
+//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;
|
|
- //sc = (struct eth_drv_sc *)arg;
|
|
- sc = __local_enet_sc;
|
|
- for(;;) {
|
|
- cyg_semaphore_wait(&delivery);
|
|
- (sc->funs->deliver)(sc);
|
|
- }
|
|
-
|
|
+ struct eth_drv_sc *sc = (struct eth_drv_sc *) data;
|
|
+ sc->state |= ETH_DRV_NEEDS_DELIVERY;
|
|
+ lwip_dsr_stuff();
|
|
}
|
|
|
|
-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);
|
|
-}
|
|
|
|
|
|
+extern void lwip_set_addr(struct netif *);
|
|
|
|
-//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)
|
|
-{
|
|
- 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
|
|
- }
|
|
- }
|
|
-}
|
|
+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;
|
|
-
|
|
- 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);
|
|
+ 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);
|
|
+
|
|
}
|
|
|
|
//
|
|
@@ -185,15 +163,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 +183,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;
|
|
|
|
- if ((total_len > MAX_ETH_MSG) || (total_len < 0)) {
|
|
- total_len = MAX_ETH_MSG;
|
|
- }
|
|
+ int sg_len = 0;
|
|
+ CYGARC_HAL_SAVE_GP();
|
|
|
|
- sg_list[0].buf = (CYG_ADDRESS)buf;
|
|
- sg_list[0].len = total_len;
|
|
- sg_len = 1;
|
|
+ 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();
|
|
+}
|
|
+
|
|
+
|
|
+#define IFNAME0 'e'
|
|
+#define IFNAME1 't'
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * 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;
|
|
+}
|
|
|
|
- (sc->funs->recv)(sc, sg_list, sg_len);
|
|
- (lwip_input)((char*)sg_list[0].buf,total_len);
|
|
- CYGARC_HAL_RESTORE_GP();
|
|
+/*
|
|
+ * 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:
|
|
+ LWIP_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:
|
|
+ LWIP_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) {
|
|
+ LWIP_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;
|
|
+}
|