]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/dev.c
Reverted the removal of dev->get_stats = can_get_stats for kernels < 2.6.23
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / dev.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
5  * Copyright (C) 2006 Andrey Volkov, Varma Electronics
6  * Copyright (C) 2008 Wolfgang Grandegger <wg@grandegger.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the version 2 of the GNU General Public License
10  * as published by the Free Software Foundation
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <linux/module.h>
23 #include <linux/netdevice.h>
24 #include <linux/if_arp.h>
25 #include <linux/can.h>
26 #include <linux/can/dev.h>
27 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
28 #include <net/rtnetlink.h>
29 #endif
30
31 #include "sysfs.h"
32
33 #define MOD_DESC "CAN netdevice library"
34
35 MODULE_DESCRIPTION(MOD_DESC);
36 MODULE_LICENSE("GPL v2");
37 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
38
39 #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
40
41 /*
42  * Bit-timing calculation derived from:
43  *
44  * Code based on LinCAN sources and H8S2638 project
45  * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
46  * Copyright 2005      Stanislav Marek
47  * email: pisa@cmp.felk.cvut.cz
48  */
49 static int can_update_spt(const struct can_bittiming_const *btc,
50                           int sampl_pt, int tseg, int *tseg1, int *tseg2)
51 {
52         *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
53         if (*tseg2 < btc->tseg2_min)
54                 *tseg2 = btc->tseg2_min;
55         if (*tseg2 > btc->tseg2_max)
56                 *tseg2 = btc->tseg2_max;
57         *tseg1 = tseg - *tseg2;
58         if (*tseg1 > btc->tseg1_max) {
59                 *tseg1 = btc->tseg1_max;
60                 *tseg2 = tseg - *tseg1;
61         }
62         return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
63 }
64
65 static int can_calc_bittiming(struct net_device *dev)
66 {
67         struct can_priv *priv = netdev_priv(dev);
68         struct can_bittiming *bt = &priv->bittiming;
69         const struct can_bittiming_const *btc = priv->bittiming_const;
70         long rate, best_rate = 0;
71         long best_error = 1000000000, error = 0;
72         int best_tseg = 0, best_brp = 0, brp = 0;
73         int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
74         int spt_error = 1000, spt = 0, sampl_pt;
75         uint64_t v64;
76
77         if (!priv->bittiming_const)
78                 return -ENOTSUPP;
79
80         /* Use CIA recommended sample points */
81         if (bt->sample_point) {
82                 sampl_pt = bt->sample_point;
83         } else {
84                 if (bt->bitrate > 800000)
85                         sampl_pt = 750;
86                 else if (bt->bitrate > 500000)
87                         sampl_pt = 800;
88                 else
89                         sampl_pt = 875;
90         }
91
92         /* tseg even = round down, odd = round up */
93         for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
94              tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
95                 tsegall = 1 + tseg / 2;
96                 /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
97                 brp = bt->clock / (tsegall * bt->bitrate) + tseg % 2;
98                 /* chose brp step which is possible in system */
99                 brp = (brp / btc->brp_inc) * btc->brp_inc;
100                 if ((brp < btc->brp_min) || (brp > btc->brp_max))
101                         continue;
102                 rate = bt->clock / (brp * tsegall);
103                 error = bt->bitrate - rate;
104                 /* tseg brp biterror */
105                 if (error < 0)
106                         error = -error;
107                 if (error > best_error)
108                         continue;
109                 best_error = error;
110                 if (error == 0) {
111                         spt = can_update_spt(btc, sampl_pt, tseg / 2,
112                                              &tseg1, &tseg2);
113                         error = sampl_pt - spt;
114                         if (error < 0)
115                                 error = -error;
116                         if (error > spt_error)
117                                 continue;
118                         spt_error = error;
119                 }
120                 best_tseg = tseg / 2;
121                 best_brp = brp;
122                 best_rate = rate;
123                 if (error == 0)
124                         break;
125         }
126
127         if (best_error) {
128                 /* Error in one-tenth of a percent */
129                 error = (best_error * 1000) / bt->bitrate;
130                 if (error > CAN_CALC_MAX_ERROR) {
131                         dev_err(ND2D(dev), "bitrate error %ld.%ld%% too high\n",
132                                 error / 10, error % 10);
133                         return -EDOM;
134                 } else {
135                         dev_warn(ND2D(dev), "bitrate error %ld.%ld%%\n",
136                                  error / 10, error % 10);
137                 }
138         }
139
140         spt = can_update_spt(btc, sampl_pt, best_tseg, &tseg1, &tseg2);
141
142         v64 = (u64)best_brp * 1000000000UL;
143         do_div(v64, bt->clock);
144         bt->tq = (u32)v64;
145         bt->prop_seg = tseg1 / 2;
146         bt->phase_seg1 = tseg1 - bt->prop_seg;
147         bt->phase_seg2 = tseg2;
148         bt->sjw = 1;
149         bt->brp = best_brp;
150
151         return 0;
152 }
153
154 int can_sample_point(struct can_bittiming *bt)
155 {
156         return ((bt->prop_seg + bt->phase_seg1 + 1) * 1000) /
157                 (bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1);
158 }
159
160 int can_fixup_bittiming(struct net_device *dev)
161 {
162         struct can_priv *priv = netdev_priv(dev);
163         struct can_bittiming *bt = &priv->bittiming;
164         const struct can_bittiming_const *btc = priv->bittiming_const;
165         int tseg1, alltseg;
166         u32 bitrate;
167         u64 brp64;
168
169         if (!priv->bittiming_const)
170                 return -ENOTSUPP;
171
172         tseg1 = bt->prop_seg + bt->phase_seg1;
173         if (bt->sjw > btc->sjw_max ||
174             tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
175             bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
176                 return -EINVAL;
177
178         brp64 = (u64)bt->clock * (u64)bt->tq;
179         if (btc->brp_inc > 1)
180                 do_div(brp64, btc->brp_inc);
181         brp64 += 500000000UL - 1;
182         do_div(brp64, 1000000000UL); /* the practicable BRP */
183         if (btc->brp_inc > 1)
184                 brp64 *= btc->brp_inc;
185         bt->brp = (u32)brp64;
186
187         if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
188                 return -EINVAL;
189
190         alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
191         bitrate = bt->clock / (bt->brp * alltseg);
192         bt->bitrate = bitrate;
193
194         return 0;
195 }
196
197 int can_set_bittiming(struct net_device *dev)
198 {
199         struct can_priv *priv = netdev_priv(dev);
200         int err;
201
202         /* Check if bit-timing parameters have been pre-defined */
203         if (!priv->bittiming.tq && !priv->bittiming.bitrate)
204                 return -EINVAL;
205
206         /* Check if the CAN device has bit-timing parameters */
207         if (priv->bittiming_const) {
208
209                 /* Check if bit-timing parameters have already been set */
210                 if (priv->bittiming.tq && priv->bittiming.bitrate)
211                         return 0;
212
213                 /* Non-expert mode? Check if the bitrate has been pre-defined */
214                 if (!priv->bittiming.tq)
215                         /* Determine bit-timing parameters */
216                         err = can_calc_bittiming(dev);
217                 else
218                         /* Check bit-timing params and calculate proper brp */
219                         err = can_fixup_bittiming(dev);
220                 if (err)
221                         return err;
222         }
223
224         if (priv->do_set_bittiming) {
225                 /* Finally, set the bit-timing registers */
226                 err = priv->do_set_bittiming(dev);
227                 if (err)
228                         return err;
229         }
230
231         return 0;
232 }
233 EXPORT_SYMBOL(can_set_bittiming);
234
235 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
236 struct net_device_stats *can_get_stats(struct net_device *dev)
237 {
238         struct can_priv *priv = netdev_priv(dev);
239
240         return &priv->net_stats;
241 }
242 EXPORT_SYMBOL(can_get_stats);
243 #endif
244
245 static void can_setup(struct net_device *dev)
246 {
247         dev->type = ARPHRD_CAN;
248         dev->mtu = sizeof(struct can_frame);
249         dev->hard_header_len = 0;
250         dev->addr_len = 0;
251         dev->tx_queue_len = 10;
252
253         /* New-style flags. */
254         dev->flags = IFF_NOARP;
255         dev->features = NETIF_F_NO_CSUM;
256 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
257         dev->get_stats = can_get_stats;
258 #endif
259 }
260
261 /*
262  * Function  alloc_candev
263  *      Allocates and sets up an CAN device
264  */
265 struct net_device *alloc_candev(int sizeof_priv)
266 {
267         struct net_device *dev;
268         struct can_priv *priv;
269
270         dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
271         if (!dev)
272                 return NULL;
273
274         priv = netdev_priv(dev);
275
276         priv->state = CAN_STATE_STOPPED;
277         spin_lock_init(&priv->irq_lock);
278
279         init_timer(&priv->timer);
280         priv->timer.expires = 0;
281
282         return dev;
283 }
284 EXPORT_SYMBOL(alloc_candev);
285
286 void free_candev(struct net_device *dev)
287 {
288         free_netdev(dev);
289 }
290 EXPORT_SYMBOL(free_candev);
291
292 /*
293  * Local echo of CAN messages
294  *
295  * CAN network devices *should* support a local echo functionality
296  * (see Documentation/networking/can.txt). To test the handling of CAN
297  * interfaces that do not support the local echo both driver types are
298  * implemented. In the case that the driver does not support the echo
299  * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
300  * to perform the echo as a fallback solution.
301  */
302
303 void can_flush_echo_skb(struct net_device *dev)
304 {
305         struct can_priv *priv = netdev_priv(dev);
306 #ifdef FIXME
307 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
308         struct net_device_stats *stats = can_get_stats(dev);
309 #else
310         struct net_device_stats *stats = &dev->stats;
311 #endif
312 #endif
313         int i;
314
315         for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
316                 if (priv->echo_skb[i]) {
317                         kfree_skb(priv->echo_skb[i]);
318                         priv->echo_skb[i] = NULL;
319 #ifdef FIXME
320                         stats->tx_dropped++;
321                         stats->tx_aborted_errors++;
322 #endif
323                 }
324         }
325 }
326
327 void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
328 {
329         struct can_priv *priv = netdev_priv(dev);
330
331         /* set flag whether this packet has to be looped back */
332         if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
333                 kfree_skb(skb);
334                 return;
335         }
336
337         if (!priv->echo_skb[idx]) {
338                 struct sock *srcsk = skb->sk;
339
340                 if (atomic_read(&skb->users) != 1) {
341                         struct sk_buff *old_skb = skb;
342
343                         skb = skb_clone(old_skb, GFP_ATOMIC);
344                         kfree_skb(old_skb);
345                         if (!skb)
346                                 return;
347                 } else
348                         skb_orphan(skb);
349
350                 skb->sk = srcsk;
351
352                 /* make settings for echo to reduce code in irq context */
353                 skb->protocol = htons(ETH_P_CAN);
354                 skb->pkt_type = PACKET_BROADCAST;
355                 skb->ip_summed = CHECKSUM_UNNECESSARY;
356                 skb->dev = dev;
357
358                 /* save this skb for tx interrupt echo handling */
359                 priv->echo_skb[idx] = skb;
360         } else {
361                 /* locking problem with netif_stop_queue() ?? */
362                 printk(KERN_ERR "%s: %s: BUG! echo_skb is occupied!\n",
363                        dev->name, __func__);
364                 kfree_skb(skb);
365         }
366 }
367 EXPORT_SYMBOL(can_put_echo_skb);
368
369 void can_get_echo_skb(struct net_device *dev, int idx)
370 {
371         struct can_priv *priv = netdev_priv(dev);
372
373         if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
374                 netif_rx(priv->echo_skb[idx]);
375                 priv->echo_skb[idx] = NULL;
376         }
377 }
378 EXPORT_SYMBOL(can_get_echo_skb);
379
380 /*
381  * CAN bus-off handling
382  * FIXME: we need some synchronization
383  */
384 int can_restart_now(struct net_device *dev)
385 {
386         struct can_priv *priv = netdev_priv(dev);
387 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
388         struct net_device_stats *stats = can_get_stats(dev);
389 #else
390         struct net_device_stats *stats = &dev->stats;
391 #endif
392         struct sk_buff *skb;
393         struct can_frame *cf;
394         int err;
395
396         if (netif_carrier_ok(dev))
397                 netif_carrier_off(dev);
398
399         /* Cancel restart in progress */
400         if (priv->timer.expires) {
401                 del_timer(&priv->timer);
402                 priv->timer.expires = 0; /* mark inactive timer */
403         }
404
405         can_flush_echo_skb(dev);
406
407         err = priv->do_set_mode(dev, CAN_MODE_START);
408         if (err)
409                 return err;
410
411         netif_carrier_on(dev);
412
413         priv->can_stats.restarts++;
414
415         /* send restart message upstream */
416         skb = dev_alloc_skb(sizeof(struct can_frame));
417         if (skb == NULL)
418                 return -ENOMEM;
419         skb->dev = dev;
420         skb->protocol = htons(ETH_P_CAN);
421         cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
422         memset(cf, 0, sizeof(struct can_frame));
423         cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
424         cf->can_dlc = CAN_ERR_DLC;
425
426         netif_rx(skb);
427
428         dev->last_rx = jiffies;
429         stats->rx_packets++;
430         stats->rx_bytes += cf->can_dlc;
431
432         return 0;
433 }
434
435 static void can_restart_after(unsigned long data)
436 {
437         struct net_device *dev = (struct net_device *)data;
438         struct can_priv *priv = netdev_priv(dev);
439
440         priv->timer.expires = 0; /* mark inactive timer */
441         can_restart_now(dev);
442 }
443
444 void can_bus_off(struct net_device *dev)
445 {
446         struct can_priv *priv = netdev_priv(dev);
447
448         netif_carrier_off(dev);
449
450         if (priv->restart_ms > 0 && !priv->timer.expires) {
451
452                 priv->timer.function = can_restart_after;
453                 priv->timer.data = (unsigned long)dev;
454                 priv->timer.expires =
455                         jiffies + (priv->restart_ms * HZ) / 1000;
456                 add_timer(&priv->timer);
457         }
458 }
459 EXPORT_SYMBOL(can_bus_off);
460
461 void can_close_cleanup(struct net_device *dev)
462 {
463         struct can_priv *priv = netdev_priv(dev);
464
465         if (priv->timer.expires) {
466                 del_timer(&priv->timer);
467                 priv->timer.expires = 0;
468         }
469
470         can_flush_echo_skb(dev);
471 }
472 EXPORT_SYMBOL(can_close_cleanup);
473
474 static int can_netdev_notifier_call(struct notifier_block *nb,
475                                     unsigned long state,
476                                     void *ndev)
477 {
478         struct net_device *dev = ndev;
479
480         if (dev->type != ARPHRD_CAN)
481                 return 0;
482
483 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
484         /* omit virtual CAN software network devices */
485         if (dev->rtnl_link_ops) {
486                 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
487                 if (!strcmp(ops->kind, "vcan"))
488                         return 0;
489         }
490 #else
491         /* software CAN devices like 'vcan' do not have private data */
492         if (!dev->priv)
493                 return 0;
494 #endif
495
496         switch (state) {
497         case NETDEV_REGISTER:
498 #ifdef CONFIG_SYSFS
499                 can_create_sysfs(dev);
500 #endif
501                 break;
502         case NETDEV_UNREGISTER:
503 #ifdef CONFIG_SYSFS
504                 can_remove_sysfs(dev);
505 #endif
506                 break;
507         }
508         return 0;
509 }
510
511 static struct notifier_block can_netdev_notifier = {
512         .notifier_call = can_netdev_notifier_call,
513 };
514
515 static __init int can_dev_init(void)
516 {
517         printk(KERN_INFO MOD_DESC "\n");
518
519         return register_netdevice_notifier(&can_netdev_notifier);
520 }
521 module_init(can_dev_init);
522
523 static __exit void can_dev_exit(void)
524 {
525         unregister_netdevice_notifier(&can_netdev_notifier);
526 }
527 module_exit(can_dev_exit);