Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block
[pandora-kernel.git] / net / batman-adv / soft-interface.c
1 /*
2  * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner, Simon Wunderlich
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  *
20  */
21
22 #include "main.h"
23 #include "soft-interface.h"
24 #include "hard-interface.h"
25 #include "routing.h"
26 #include "send.h"
27 #include "bat_debugfs.h"
28 #include "translation-table.h"
29 #include "types.h"
30 #include "hash.h"
31 #include "gateway_common.h"
32 #include "gateway_client.h"
33 #include "send.h"
34 #include "bat_sysfs.h"
35 #include <linux/slab.h>
36 #include <linux/ethtool.h>
37 #include <linux/etherdevice.h>
38 #include <linux/if_vlan.h>
39 #include "unicast.h"
40 #include "routing.h"
41
42
43 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
44 static void bat_get_drvinfo(struct net_device *dev,
45                             struct ethtool_drvinfo *info);
46 static u32 bat_get_msglevel(struct net_device *dev);
47 static void bat_set_msglevel(struct net_device *dev, u32 value);
48 static u32 bat_get_link(struct net_device *dev);
49 static u32 bat_get_rx_csum(struct net_device *dev);
50 static int bat_set_rx_csum(struct net_device *dev, u32 data);
51
52 static const struct ethtool_ops bat_ethtool_ops = {
53         .get_settings = bat_get_settings,
54         .get_drvinfo = bat_get_drvinfo,
55         .get_msglevel = bat_get_msglevel,
56         .set_msglevel = bat_set_msglevel,
57         .get_link = bat_get_link,
58         .get_rx_csum = bat_get_rx_csum,
59         .set_rx_csum = bat_set_rx_csum
60 };
61
62 int my_skb_head_push(struct sk_buff *skb, unsigned int len)
63 {
64         int result;
65
66         /**
67          * TODO: We must check if we can release all references to non-payload
68          * data using skb_header_release in our skbs to allow skb_cow_header to
69          * work optimally. This means that those skbs are not allowed to read
70          * or write any data which is before the current position of skb->data
71          * after that call and thus allow other skbs with the same data buffer
72          * to write freely in that area.
73          */
74         result = skb_cow_head(skb, len);
75         if (result < 0)
76                 return result;
77
78         skb_push(skb, len);
79         return 0;
80 }
81
82 static void softif_neigh_free_ref(struct kref *refcount)
83 {
84         struct softif_neigh *softif_neigh;
85
86         softif_neigh = container_of(refcount, struct softif_neigh, refcount);
87         kfree(softif_neigh);
88 }
89
90 static void softif_neigh_free_rcu(struct rcu_head *rcu)
91 {
92         struct softif_neigh *softif_neigh;
93
94         softif_neigh = container_of(rcu, struct softif_neigh, rcu);
95         kref_put(&softif_neigh->refcount, softif_neigh_free_ref);
96 }
97
98 void softif_neigh_purge(struct bat_priv *bat_priv)
99 {
100         struct softif_neigh *softif_neigh, *softif_neigh_tmp;
101         struct hlist_node *node, *node_tmp;
102
103         spin_lock_bh(&bat_priv->softif_neigh_lock);
104
105         hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
106                                   &bat_priv->softif_neigh_list, list) {
107
108                 if ((!time_after(jiffies, softif_neigh->last_seen +
109                                 msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
110                     (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
111                         continue;
112
113                 hlist_del_rcu(&softif_neigh->list);
114
115                 if (bat_priv->softif_neigh == softif_neigh) {
116                         bat_dbg(DBG_ROUTES, bat_priv,
117                                  "Current mesh exit point '%pM' vanished "
118                                  "(vid: %d).\n",
119                                  softif_neigh->addr, softif_neigh->vid);
120                         softif_neigh_tmp = bat_priv->softif_neigh;
121                         bat_priv->softif_neigh = NULL;
122                         kref_put(&softif_neigh_tmp->refcount,
123                                  softif_neigh_free_ref);
124                 }
125
126                 call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu);
127         }
128
129         spin_unlock_bh(&bat_priv->softif_neigh_lock);
130 }
131
132 static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
133                                              uint8_t *addr, short vid)
134 {
135         struct softif_neigh *softif_neigh;
136         struct hlist_node *node;
137
138         rcu_read_lock();
139         hlist_for_each_entry_rcu(softif_neigh, node,
140                                  &bat_priv->softif_neigh_list, list) {
141                 if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0)
142                         continue;
143
144                 if (softif_neigh->vid != vid)
145                         continue;
146
147                 softif_neigh->last_seen = jiffies;
148                 goto found;
149         }
150
151         softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC);
152         if (!softif_neigh)
153                 goto out;
154
155         memcpy(softif_neigh->addr, addr, ETH_ALEN);
156         softif_neigh->vid = vid;
157         softif_neigh->last_seen = jiffies;
158         kref_init(&softif_neigh->refcount);
159
160         INIT_HLIST_NODE(&softif_neigh->list);
161         spin_lock_bh(&bat_priv->softif_neigh_lock);
162         hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list);
163         spin_unlock_bh(&bat_priv->softif_neigh_lock);
164
165 found:
166         kref_get(&softif_neigh->refcount);
167 out:
168         rcu_read_unlock();
169         return softif_neigh;
170 }
171
172 int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
173 {
174         struct net_device *net_dev = (struct net_device *)seq->private;
175         struct bat_priv *bat_priv = netdev_priv(net_dev);
176         struct softif_neigh *softif_neigh;
177         struct hlist_node *node;
178         size_t buf_size, pos;
179         char *buff;
180
181         if (!bat_priv->primary_if) {
182                 return seq_printf(seq, "BATMAN mesh %s disabled - "
183                                "please specify interfaces to enable it\n",
184                                net_dev->name);
185         }
186
187         seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
188
189         buf_size = 1;
190         /* Estimate length for: "   xx:xx:xx:xx:xx:xx\n" */
191         rcu_read_lock();
192         hlist_for_each_entry_rcu(softif_neigh, node,
193                                  &bat_priv->softif_neigh_list, list)
194                 buf_size += 30;
195         rcu_read_unlock();
196
197         buff = kmalloc(buf_size, GFP_ATOMIC);
198         if (!buff)
199                 return -ENOMEM;
200
201         buff[0] = '\0';
202         pos = 0;
203
204         rcu_read_lock();
205         hlist_for_each_entry_rcu(softif_neigh, node,
206                                  &bat_priv->softif_neigh_list, list) {
207                 pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n",
208                                 bat_priv->softif_neigh == softif_neigh
209                                 ? "=>" : "  ", softif_neigh->addr,
210                                 softif_neigh->vid);
211         }
212         rcu_read_unlock();
213
214         seq_printf(seq, "%s", buff);
215         kfree(buff);
216         return 0;
217 }
218
219 static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
220                                short vid)
221 {
222         struct bat_priv *bat_priv = netdev_priv(dev);
223         struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
224         struct batman_packet *batman_packet;
225         struct softif_neigh *softif_neigh, *softif_neigh_tmp;
226
227         if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
228                 batman_packet = (struct batman_packet *)
229                                         (skb->data + ETH_HLEN + VLAN_HLEN);
230         else
231                 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
232
233         if (batman_packet->version != COMPAT_VERSION)
234                 goto err;
235
236         if (batman_packet->packet_type != BAT_PACKET)
237                 goto err;
238
239         if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
240                 goto err;
241
242         if (is_my_mac(batman_packet->orig))
243                 goto err;
244
245         softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
246
247         if (!softif_neigh)
248                 goto err;
249
250         if (bat_priv->softif_neigh == softif_neigh)
251                 goto out;
252
253         /* we got a neighbor but its mac is 'bigger' than ours  */
254         if (memcmp(bat_priv->primary_if->net_dev->dev_addr,
255                    softif_neigh->addr, ETH_ALEN) < 0)
256                 goto out;
257
258         /* switch to new 'smallest neighbor' */
259         if ((bat_priv->softif_neigh) &&
260             (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr,
261                                                         ETH_ALEN) < 0)) {
262                 bat_dbg(DBG_ROUTES, bat_priv,
263                         "Changing mesh exit point from %pM (vid: %d) "
264                         "to %pM (vid: %d).\n",
265                          bat_priv->softif_neigh->addr,
266                          bat_priv->softif_neigh->vid,
267                          softif_neigh->addr, softif_neigh->vid);
268                 softif_neigh_tmp = bat_priv->softif_neigh;
269                 bat_priv->softif_neigh = softif_neigh;
270                 kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref);
271                 /* we need to hold the additional reference */
272                 goto err;
273         }
274
275         /* close own batX device and use softif_neigh as exit node */
276         if ((!bat_priv->softif_neigh) &&
277             (memcmp(softif_neigh->addr,
278                     bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
279                 bat_dbg(DBG_ROUTES, bat_priv,
280                         "Setting mesh exit point to %pM (vid: %d).\n",
281                         softif_neigh->addr, softif_neigh->vid);
282                 bat_priv->softif_neigh = softif_neigh;
283                 /* we need to hold the additional reference */
284                 goto err;
285         }
286
287 out:
288         kref_put(&softif_neigh->refcount, softif_neigh_free_ref);
289 err:
290         kfree_skb(skb);
291         return;
292 }
293
294 static int interface_open(struct net_device *dev)
295 {
296         netif_start_queue(dev);
297         return 0;
298 }
299
300 static int interface_release(struct net_device *dev)
301 {
302         netif_stop_queue(dev);
303         return 0;
304 }
305
306 static struct net_device_stats *interface_stats(struct net_device *dev)
307 {
308         struct bat_priv *bat_priv = netdev_priv(dev);
309         return &bat_priv->stats;
310 }
311
312 static int interface_set_mac_addr(struct net_device *dev, void *p)
313 {
314         struct bat_priv *bat_priv = netdev_priv(dev);
315         struct sockaddr *addr = p;
316
317         if (!is_valid_ether_addr(addr->sa_data))
318                 return -EADDRNOTAVAIL;
319
320         /* only modify hna-table if it has been initialised before */
321         if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
322                 hna_local_remove(bat_priv, dev->dev_addr,
323                                  "mac address changed");
324                 hna_local_add(dev, addr->sa_data);
325         }
326
327         memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
328         return 0;
329 }
330
331 static int interface_change_mtu(struct net_device *dev, int new_mtu)
332 {
333         /* check ranges */
334         if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev)))
335                 return -EINVAL;
336
337         dev->mtu = new_mtu;
338
339         return 0;
340 }
341
342 int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
343 {
344         struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
345         struct bat_priv *bat_priv = netdev_priv(soft_iface);
346         struct bcast_packet *bcast_packet;
347         struct vlan_ethhdr *vhdr;
348         int data_len = skb->len, ret;
349         short vid = -1;
350         bool do_bcast = false;
351
352         if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
353                 goto dropped;
354
355         soft_iface->trans_start = jiffies;
356
357         switch (ntohs(ethhdr->h_proto)) {
358         case ETH_P_8021Q:
359                 vhdr = (struct vlan_ethhdr *)skb->data;
360                 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
361
362                 if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN)
363                         break;
364
365                 /* fall through */
366         case ETH_P_BATMAN:
367                 softif_batman_recv(skb, soft_iface, vid);
368                 goto end;
369         }
370
371         /**
372          * if we have a another chosen mesh exit node in range
373          * it will transport the packets to the mesh
374          */
375         if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid))
376                 goto dropped;
377
378         /* TODO: check this for locks */
379         hna_local_add(soft_iface, ethhdr->h_source);
380
381         if (is_multicast_ether_addr(ethhdr->h_dest)) {
382                 ret = gw_is_target(bat_priv, skb);
383
384                 if (ret < 0)
385                         goto dropped;
386
387                 if (ret == 0)
388                         do_bcast = true;
389         }
390
391         /* ethernet packet should be broadcasted */
392         if (do_bcast) {
393                 if (!bat_priv->primary_if)
394                         goto dropped;
395
396                 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
397                         goto dropped;
398
399                 bcast_packet = (struct bcast_packet *)skb->data;
400                 bcast_packet->version = COMPAT_VERSION;
401                 bcast_packet->ttl = TTL;
402
403                 /* batman packet type: broadcast */
404                 bcast_packet->packet_type = BAT_BCAST;
405
406                 /* hw address of first interface is the orig mac because only
407                  * this mac is known throughout the mesh */
408                 memcpy(bcast_packet->orig,
409                        bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
410
411                 /* set broadcast sequence number */
412                 bcast_packet->seqno =
413                         htonl(atomic_inc_return(&bat_priv->bcast_seqno));
414
415                 add_bcast_packet_to_list(bat_priv, skb);
416
417                 /* a copy is stored in the bcast list, therefore removing
418                  * the original skb. */
419                 kfree_skb(skb);
420
421         /* unicast packet */
422         } else {
423                 ret = unicast_send_skb(skb, bat_priv);
424                 if (ret != 0)
425                         goto dropped_freed;
426         }
427
428         bat_priv->stats.tx_packets++;
429         bat_priv->stats.tx_bytes += data_len;
430         goto end;
431
432 dropped:
433         kfree_skb(skb);
434 dropped_freed:
435         bat_priv->stats.tx_dropped++;
436 end:
437         return NETDEV_TX_OK;
438 }
439
440 void interface_rx(struct net_device *soft_iface,
441                   struct sk_buff *skb, struct batman_if *recv_if,
442                   int hdr_size)
443 {
444         struct bat_priv *bat_priv = netdev_priv(soft_iface);
445         struct unicast_packet *unicast_packet;
446         struct ethhdr *ethhdr;
447         struct vlan_ethhdr *vhdr;
448         short vid = -1;
449         int ret;
450
451         /* check if enough space is available for pulling, and pull */
452         if (!pskb_may_pull(skb, hdr_size))
453                 goto dropped;
454
455         skb_pull_rcsum(skb, hdr_size);
456         skb_reset_mac_header(skb);
457
458         ethhdr = (struct ethhdr *)skb_mac_header(skb);
459
460         switch (ntohs(ethhdr->h_proto)) {
461         case ETH_P_8021Q:
462                 vhdr = (struct vlan_ethhdr *)skb->data;
463                 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
464
465                 if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN)
466                         break;
467
468                 /* fall through */
469         case ETH_P_BATMAN:
470                 goto dropped;
471         }
472
473         /**
474          * if we have a another chosen mesh exit node in range
475          * it will transport the packets to the non-mesh network
476          */
477         if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) {
478                 skb_push(skb, hdr_size);
479                 unicast_packet = (struct unicast_packet *)skb->data;
480
481                 if ((unicast_packet->packet_type != BAT_UNICAST) &&
482                     (unicast_packet->packet_type != BAT_UNICAST_FRAG))
483                         goto dropped;
484
485                 skb_reset_mac_header(skb);
486
487                 memcpy(unicast_packet->dest,
488                        bat_priv->softif_neigh->addr, ETH_ALEN);
489                 ret = route_unicast_packet(skb, recv_if, hdr_size);
490                 if (ret == NET_RX_DROP)
491                         goto dropped;
492
493                 goto out;
494         }
495
496         /* skb->dev & skb->pkt_type are set here */
497         if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
498                 goto dropped;
499         skb->protocol = eth_type_trans(skb, soft_iface);
500
501         /* should not be neccesary anymore as we use skb_pull_rcsum()
502          * TODO: please verify this and remove this TODO
503          * -- Dec 21st 2009, Simon Wunderlich */
504
505 /*      skb->ip_summed = CHECKSUM_UNNECESSARY;*/
506
507         bat_priv->stats.rx_packets++;
508         bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
509
510         soft_iface->last_rx = jiffies;
511
512         netif_rx(skb);
513         return;
514
515 dropped:
516         kfree_skb(skb);
517 out:
518         return;
519 }
520
521 #ifdef HAVE_NET_DEVICE_OPS
522 static const struct net_device_ops bat_netdev_ops = {
523         .ndo_open = interface_open,
524         .ndo_stop = interface_release,
525         .ndo_get_stats = interface_stats,
526         .ndo_set_mac_address = interface_set_mac_addr,
527         .ndo_change_mtu = interface_change_mtu,
528         .ndo_start_xmit = interface_tx,
529         .ndo_validate_addr = eth_validate_addr
530 };
531 #endif
532
533 static void interface_setup(struct net_device *dev)
534 {
535         struct bat_priv *priv = netdev_priv(dev);
536         char dev_addr[ETH_ALEN];
537
538         ether_setup(dev);
539
540 #ifdef HAVE_NET_DEVICE_OPS
541         dev->netdev_ops = &bat_netdev_ops;
542 #else
543         dev->open = interface_open;
544         dev->stop = interface_release;
545         dev->get_stats = interface_stats;
546         dev->set_mac_address = interface_set_mac_addr;
547         dev->change_mtu = interface_change_mtu;
548         dev->hard_start_xmit = interface_tx;
549 #endif
550         dev->destructor = free_netdev;
551
552         /**
553          * can't call min_mtu, because the needed variables
554          * have not been initialized yet
555          */
556         dev->mtu = ETH_DATA_LEN;
557         dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
558                                                 * skbuff for our header */
559
560         /* generate random address */
561         random_ether_addr(dev_addr);
562         memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
563
564         SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
565
566         memset(priv, 0, sizeof(struct bat_priv));
567 }
568
569 struct net_device *softif_create(char *name)
570 {
571         struct net_device *soft_iface;
572         struct bat_priv *bat_priv;
573         int ret;
574
575         soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
576                                    interface_setup);
577
578         if (!soft_iface) {
579                 pr_err("Unable to allocate the batman interface: %s\n", name);
580                 goto out;
581         }
582
583         ret = register_netdev(soft_iface);
584         if (ret < 0) {
585                 pr_err("Unable to register the batman interface '%s': %i\n",
586                        name, ret);
587                 goto free_soft_iface;
588         }
589
590         bat_priv = netdev_priv(soft_iface);
591
592         atomic_set(&bat_priv->aggregated_ogms, 1);
593         atomic_set(&bat_priv->bonding, 0);
594         atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
595         atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
596         atomic_set(&bat_priv->gw_sel_class, 20);
597         atomic_set(&bat_priv->gw_bandwidth, 41);
598         atomic_set(&bat_priv->orig_interval, 1000);
599         atomic_set(&bat_priv->hop_penalty, 10);
600         atomic_set(&bat_priv->log_level, 0);
601         atomic_set(&bat_priv->fragmentation, 1);
602         atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
603         atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
604
605         atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
606         atomic_set(&bat_priv->bcast_seqno, 1);
607         atomic_set(&bat_priv->hna_local_changed, 0);
608
609         bat_priv->primary_if = NULL;
610         bat_priv->num_ifaces = 0;
611         bat_priv->softif_neigh = NULL;
612
613         ret = sysfs_add_meshif(soft_iface);
614         if (ret < 0)
615                 goto unreg_soft_iface;
616
617         ret = debugfs_add_meshif(soft_iface);
618         if (ret < 0)
619                 goto unreg_sysfs;
620
621         ret = mesh_init(soft_iface);
622         if (ret < 0)
623                 goto unreg_debugfs;
624
625         return soft_iface;
626
627 unreg_debugfs:
628         debugfs_del_meshif(soft_iface);
629 unreg_sysfs:
630         sysfs_del_meshif(soft_iface);
631 unreg_soft_iface:
632         unregister_netdev(soft_iface);
633         return NULL;
634
635 free_soft_iface:
636         free_netdev(soft_iface);
637 out:
638         return NULL;
639 }
640
641 void softif_destroy(struct net_device *soft_iface)
642 {
643         debugfs_del_meshif(soft_iface);
644         sysfs_del_meshif(soft_iface);
645         mesh_free(soft_iface);
646         unregister_netdevice(soft_iface);
647 }
648
649 /* ethtool */
650 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
651 {
652         cmd->supported = 0;
653         cmd->advertising = 0;
654         cmd->speed = SPEED_10;
655         cmd->duplex = DUPLEX_FULL;
656         cmd->port = PORT_TP;
657         cmd->phy_address = 0;
658         cmd->transceiver = XCVR_INTERNAL;
659         cmd->autoneg = AUTONEG_DISABLE;
660         cmd->maxtxpkt = 0;
661         cmd->maxrxpkt = 0;
662
663         return 0;
664 }
665
666 static void bat_get_drvinfo(struct net_device *dev,
667                             struct ethtool_drvinfo *info)
668 {
669         strcpy(info->driver, "B.A.T.M.A.N. advanced");
670         strcpy(info->version, SOURCE_VERSION);
671         strcpy(info->fw_version, "N/A");
672         strcpy(info->bus_info, "batman");
673 }
674
675 static u32 bat_get_msglevel(struct net_device *dev)
676 {
677         return -EOPNOTSUPP;
678 }
679
680 static void bat_set_msglevel(struct net_device *dev, u32 value)
681 {
682 }
683
684 static u32 bat_get_link(struct net_device *dev)
685 {
686         return 1;
687 }
688
689 static u32 bat_get_rx_csum(struct net_device *dev)
690 {
691         return 0;
692 }
693
694 static int bat_set_rx_csum(struct net_device *dev, u32 data)
695 {
696         return -EOPNOTSUPP;
697 }