blob: 922126318991b98f0eefc7ad8ecf9f1118edfa47 [file] [log] [blame]
adamdunkels45c1f132004-02-16 20:59:49 +00001/*
2 * Copyright (c) 2001, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior
15 * written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * This file is part of the uIP TCP/IP stack.
30 *
31 * $Id: lan91c96-drv.c,v 1.2 2004/02/16 20:59:49 adamdunkels Exp $
32 *
33 */
34
35
36#include "uip.h"
37#include "uip_arp.h"
38#include "uip-signal.h"
39#include "loader.h"
40#include "lan91c96.h"
41
42#include "dispatcher.h"
43#include "ek.h"
44
45#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
46
47static u8_t i, arptimer;
48static u16_t start, current;
49
50static void lan91c96_drv_idle(void);
51static DISPATCHER_SIGHANDLER(lan91c96_drv_sighandler, s, data);
52static struct dispatcher_proc p =
53 {DISPATCHER_PROC("TCP/IP/LAN91C96 driver", lan91c96_drv_idle,
54 lan91c96_drv_sighandler, NULL)};
55static ek_id_t id;
56
57/*-----------------------------------------------------------------------------------*/
58static void
59send(void)
60{
61 if(uip_len > 0) {
62 uip_arp_out();
63 lan91c96_send();
64 }
65}
66/*-----------------------------------------------------------------------------------*/
67static void
68timer(void)
69{
70 for(i = 0; i < UIP_CONNS; ++i) {
71 uip_periodic(i);
72 send();
73 }
74
75 for(i = 0; i < UIP_UDP_CONNS; i++) {
76 uip_udp_periodic(i);
77 /* If the above function invocation resulted in data that
78 should be sent out on the network, the global variable
79 uip_len is set to a value > 0. */
80 send();
81 }
82}
83/*-----------------------------------------------------------------------------------*/
84static void
85lan91c96_drv_idle(void)
86{
87 /* Poll Ethernet device to see if there is a frame avaliable. */
88 uip_len = lan91c96_poll();
89 if(uip_len > 0) {
90 /* A frame was avaliable (and is now read into the uip_buf), so
91 we process it. */
92 if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
93 uip_arp_ipin();
94 uip_len -= sizeof(struct uip_eth_hdr);
95 uip_input();
96 /* If the above function invocation resulted in data that
97 should be sent out on the network, the global variable
98 uip_len is set to a value > 0. */
99 send();
100 } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
101 uip_arp_arpin();
102 /* If the above function invocation resulted in data that
103 should be sent out on the network, the global variable
104 uip_len is set to a value > 0. */
105 if(uip_len > 0) {
106 lan91c96_send();
107 }
108 }
109 }
110 /* Check the clock so see if we should call the periodic uIP
111 processing. */
112 current = ek_clock();
113
114 if((current - start) >= CLK_TCK/2) {
115 timer();
116 start = current;
117 }
118}
119/*-----------------------------------------------------------------------------------*/
120LOADER_INIT_FUNC(lan91c96_drv_init, arg)
121{
122 arg_free(arg);
123
124 if(id == EK_ID_NONE) {
125 id = dispatcher_start(&p);
126
127 arptimer = 0;
128 start = ek_clock();
129
130 lan91c96_init();
131
132 dispatcher_listen(uip_signal_poll);
133 dispatcher_listen(uip_signal_poll_udp);
134 dispatcher_listen(uip_signal_uninstall);
135 }
136}
137/*-----------------------------------------------------------------------------------*/
138static
139DISPATCHER_SIGHANDLER(lan91c96_drv_sighandler, s, data)
140{
141 DISPATCHER_SIGHANDLER_ARGS(s, data);
142
143 if(s == uip_signal_poll) {
144 uip_periodic_conn(data);
145 send();
146 } else if(s == uip_signal_poll_udp) {
147 uip_udp_periodic_conn(data);
148 send();
149 } else if(s == dispatcher_signal_quit ||
150 s == uip_signal_uninstall) {
151 dispatcher_exit(&p);
152 id = EK_ID_NONE;
153 LOADER_UNLOAD();
154 }
155}
156/*-----------------------------------------------------------------------------------*/