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