1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/netdevice.h>
29#include <linux/etherdevice.h>
30#include <linux/inetdevice.h>
31#include <linux/if_arp.h>
32#include <linux/module.h>
33#include <linux/sched.h>
34#include <net/arp.h>
35
36#include <net/irda/irda.h>
37#include <net/irda/irmod.h>
38#include <net/irda/irlan_common.h>
39#include <net/irda/irlan_client.h>
40#include <net/irda/irlan_event.h>
41#include <net/irda/irlan_eth.h>
42
43static int irlan_eth_open(struct net_device *dev);
44static int irlan_eth_close(struct net_device *dev);
45static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
46 struct net_device *dev);
47static void irlan_eth_set_multicast_list( struct net_device *dev);
48static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev);
49
50static const struct net_device_ops irlan_eth_netdev_ops = {
51 .ndo_open = irlan_eth_open,
52 .ndo_stop = irlan_eth_close,
53 .ndo_start_xmit = irlan_eth_xmit,
54 .ndo_get_stats = irlan_eth_get_stats,
55 .ndo_set_multicast_list = irlan_eth_set_multicast_list,
56 .ndo_change_mtu = eth_change_mtu,
57 .ndo_validate_addr = eth_validate_addr,
58};
59
60
61
62
63
64
65
66static void irlan_eth_setup(struct net_device *dev)
67{
68 ether_setup(dev);
69
70 dev->netdev_ops = &irlan_eth_netdev_ops;
71 dev->destructor = free_netdev;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 dev->tx_queue_len = 4;
91}
92
93
94
95
96
97
98
99struct net_device *alloc_irlandev(const char *name)
100{
101 return alloc_netdev(sizeof(struct irlan_cb), name,
102 irlan_eth_setup);
103}
104
105
106
107
108
109
110
111static int irlan_eth_open(struct net_device *dev)
112{
113 struct irlan_cb *self = netdev_priv(dev);
114
115 IRDA_DEBUG(2, "%s()\n", __func__ );
116
117
118 netif_stop_queue(dev);
119
120
121 self->disconnect_reason = 0;
122 irlan_client_wakeup(self, self->saddr, self->daddr);
123
124
125
126 return wait_event_interruptible(self->open_wait,
127 !self->tsap_data->connected);
128}
129
130
131
132
133
134
135
136
137
138static int irlan_eth_close(struct net_device *dev)
139{
140 struct irlan_cb *self = netdev_priv(dev);
141
142 IRDA_DEBUG(2, "%s()\n", __func__ );
143
144
145 netif_stop_queue(dev);
146
147 irlan_close_data_channel(self);
148 irlan_close_tsaps(self);
149
150 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
151 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
152
153
154 skb_queue_purge(&self->client.txq);
155
156 self->client.tx_busy = 0;
157
158 return 0;
159}
160
161
162
163
164
165
166
167static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
168 struct net_device *dev)
169{
170 struct irlan_cb *self = netdev_priv(dev);
171 int ret;
172
173
174 if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
175 struct sk_buff *new_skb =
176 skb_realloc_headroom(skb, self->max_header_size);
177
178
179 dev_kfree_skb(skb);
180
181
182 if (new_skb == NULL)
183 return NETDEV_TX_OK;
184
185
186 skb = new_skb;
187 }
188
189 dev->trans_start = jiffies;
190
191
192 if (self->use_udata)
193 ret = irttp_udata_request(self->tsap_data, skb);
194 else
195 ret = irttp_data_request(self->tsap_data, skb);
196
197 if (ret < 0) {
198
199
200
201
202
203
204
205
206
207
208
209 self->stats.tx_dropped++;
210 } else {
211 self->stats.tx_packets++;
212 self->stats.tx_bytes += skb->len;
213 }
214
215 return NETDEV_TX_OK;
216}
217
218
219
220
221
222
223
224int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
225{
226 struct irlan_cb *self = instance;
227
228 if (skb == NULL) {
229 ++self->stats.rx_dropped;
230 return 0;
231 }
232 if (skb->len < ETH_HLEN) {
233 IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n",
234 __func__, skb->len);
235 ++self->stats.rx_dropped;
236 dev_kfree_skb(skb);
237 return 0;
238 }
239
240
241
242
243
244
245 skb->protocol = eth_type_trans(skb, self->dev);
246
247 self->stats.rx_packets++;
248 self->stats.rx_bytes += skb->len;
249
250 netif_rx(skb);
251
252 return 0;
253}
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
270{
271 struct irlan_cb *self;
272 struct net_device *dev;
273
274 self = (struct irlan_cb *) instance;
275
276 IRDA_ASSERT(self != NULL, return;);
277 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
278
279 dev = self->dev;
280
281 IRDA_ASSERT(dev != NULL, return;);
282
283 IRDA_DEBUG(0, "%s() : flow %s ; running %d\n", __func__,
284 flow == FLOW_STOP ? "FLOW_STOP" : "FLOW_START",
285 netif_running(dev));
286
287 switch (flow) {
288 case FLOW_STOP:
289
290 netif_stop_queue(dev);
291 break;
292 case FLOW_START:
293 default:
294
295
296 netif_wake_queue(dev);
297 break;
298 }
299}
300
301
302
303
304
305
306
307#define HW_MAX_ADDRS 4
308static void irlan_eth_set_multicast_list(struct net_device *dev)
309{
310 struct irlan_cb *self = netdev_priv(dev);
311
312 IRDA_DEBUG(2, "%s()\n", __func__ );
313
314
315 if (self->client.state != IRLAN_DATA) {
316 IRDA_DEBUG(1, "%s(), delaying!\n", __func__ );
317 return;
318 }
319
320 if (dev->flags & IFF_PROMISC) {
321
322 IRDA_WARNING("Promiscuous mode not implemented by IrLAN!\n");
323 }
324 else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
325
326 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __func__ );
327
328
329 irlan_set_multicast_filter(self, TRUE);
330 }
331 else if (dev->mc_count) {
332 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __func__ );
333
334
335
336 irlan_set_multicast_filter(self, TRUE);
337 }
338 else {
339 IRDA_DEBUG(4, "%s(), Clearing multicast filter\n", __func__ );
340 irlan_set_multicast_filter(self, FALSE);
341 }
342
343 if (dev->flags & IFF_BROADCAST)
344 irlan_set_broadcast_filter(self, TRUE);
345 else
346 irlan_set_broadcast_filter(self, FALSE);
347}
348
349
350
351
352
353
354
355static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev)
356{
357 struct irlan_cb *self = netdev_priv(dev);
358
359 return &self->stats;
360}
361