diff options
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r-- | drivers/net/can/dev.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index f0b9a1e1db46..39b99f57c265 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct net_device *dev) | |||
245 | struct net_device_stats *stats = &dev->stats; | 245 | struct net_device_stats *stats = &dev->stats; |
246 | int i; | 246 | int i; |
247 | 247 | ||
248 | for (i = 0; i < CAN_ECHO_SKB_MAX; i++) { | 248 | for (i = 0; i < priv->echo_skb_max; i++) { |
249 | if (priv->echo_skb[i]) { | 249 | if (priv->echo_skb[i]) { |
250 | kfree_skb(priv->echo_skb[i]); | 250 | kfree_skb(priv->echo_skb[i]); |
251 | priv->echo_skb[i] = NULL; | 251 | priv->echo_skb[i] = NULL; |
@@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct net_device *dev) | |||
262 | * of the device driver. The driver must protect access to | 262 | * of the device driver. The driver must protect access to |
263 | * priv->echo_skb, if necessary. | 263 | * priv->echo_skb, if necessary. |
264 | */ | 264 | */ |
265 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx) | 265 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, |
266 | unsigned int idx) | ||
266 | { | 267 | { |
267 | struct can_priv *priv = netdev_priv(dev); | 268 | struct can_priv *priv = netdev_priv(dev); |
268 | 269 | ||
270 | BUG_ON(idx >= priv->echo_skb_max); | ||
271 | |||
269 | /* check flag whether this packet has to be looped back */ | 272 | /* check flag whether this packet has to be looped back */ |
270 | if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { | 273 | if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { |
271 | kfree_skb(skb); | 274 | kfree_skb(skb); |
@@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); | |||
311 | * is handled in the device driver. The driver must protect | 314 | * is handled in the device driver. The driver must protect |
312 | * access to priv->echo_skb, if necessary. | 315 | * access to priv->echo_skb, if necessary. |
313 | */ | 316 | */ |
314 | void can_get_echo_skb(struct net_device *dev, int idx) | 317 | void can_get_echo_skb(struct net_device *dev, unsigned int idx) |
315 | { | 318 | { |
316 | struct can_priv *priv = netdev_priv(dev); | 319 | struct can_priv *priv = netdev_priv(dev); |
317 | 320 | ||
321 | BUG_ON(idx >= priv->echo_skb_max); | ||
322 | |||
318 | if (priv->echo_skb[idx]) { | 323 | if (priv->echo_skb[idx]) { |
319 | netif_rx(priv->echo_skb[idx]); | 324 | netif_rx(priv->echo_skb[idx]); |
320 | priv->echo_skb[idx] = NULL; | 325 | priv->echo_skb[idx] = NULL; |
@@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb); | |||
327 | * | 332 | * |
328 | * The function is typically called when TX failed. | 333 | * The function is typically called when TX failed. |
329 | */ | 334 | */ |
330 | void can_free_echo_skb(struct net_device *dev, int idx) | 335 | void can_free_echo_skb(struct net_device *dev, unsigned int idx) |
331 | { | 336 | { |
332 | struct can_priv *priv = netdev_priv(dev); | 337 | struct can_priv *priv = netdev_priv(dev); |
333 | 338 | ||
339 | BUG_ON(idx >= priv->echo_skb_max); | ||
340 | |||
334 | if (priv->echo_skb[idx]) { | 341 | if (priv->echo_skb[idx]) { |
335 | kfree_skb(priv->echo_skb[idx]); | 342 | kfree_skb(priv->echo_skb[idx]); |
336 | priv->echo_skb[idx] = NULL; | 343 | priv->echo_skb[idx] = NULL; |
@@ -445,17 +452,30 @@ static void can_setup(struct net_device *dev) | |||
445 | /* | 452 | /* |
446 | * Allocate and setup space for the CAN network device | 453 | * Allocate and setup space for the CAN network device |
447 | */ | 454 | */ |
448 | struct net_device *alloc_candev(int sizeof_priv) | 455 | struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max) |
449 | { | 456 | { |
450 | struct net_device *dev; | 457 | struct net_device *dev; |
451 | struct can_priv *priv; | 458 | struct can_priv *priv; |
459 | int size; | ||
452 | 460 | ||
453 | dev = alloc_netdev(sizeof_priv, "can%d", can_setup); | 461 | if (echo_skb_max) |
462 | size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) + | ||
463 | echo_skb_max * sizeof(struct sk_buff *); | ||
464 | else | ||
465 | size = sizeof_priv; | ||
466 | |||
467 | dev = alloc_netdev(size, "can%d", can_setup); | ||
454 | if (!dev) | 468 | if (!dev) |
455 | return NULL; | 469 | return NULL; |
456 | 470 | ||
457 | priv = netdev_priv(dev); | 471 | priv = netdev_priv(dev); |
458 | 472 | ||
473 | if (echo_skb_max) { | ||
474 | priv->echo_skb_max = echo_skb_max; | ||
475 | priv->echo_skb = (void *)priv + | ||
476 | ALIGN(sizeof_priv, sizeof(struct sk_buff *)); | ||
477 | } | ||
478 | |||
459 | priv->state = CAN_STATE_STOPPED; | 479 | priv->state = CAN_STATE_STOPPED; |
460 | 480 | ||
461 | init_timer(&priv->restart_timer); | 481 | init_timer(&priv->restart_timer); |