diff options
Diffstat (limited to 'drivers/net/can/sja1000/sja1000.c')
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 16d2ecd2a3b7..145b1a731a53 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -130,8 +130,12 @@ static void set_normal_mode(struct net_device *dev) | |||
130 | /* check reset bit */ | 130 | /* check reset bit */ |
131 | if ((status & MOD_RM) == 0) { | 131 | if ((status & MOD_RM) == 0) { |
132 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 132 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
133 | /* enable all interrupts */ | 133 | /* enable interrupts */ |
134 | priv->write_reg(priv, REG_IER, IRQ_ALL); | 134 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
135 | priv->write_reg(priv, REG_IER, IRQ_ALL); | ||
136 | else | ||
137 | priv->write_reg(priv, REG_IER, | ||
138 | IRQ_ALL & ~IRQ_BEI); | ||
135 | return; | 139 | return; |
136 | } | 140 | } |
137 | 141 | ||
@@ -203,6 +207,17 @@ static int sja1000_set_bittiming(struct net_device *dev) | |||
203 | return 0; | 207 | return 0; |
204 | } | 208 | } |
205 | 209 | ||
210 | static int sja1000_get_berr_counter(const struct net_device *dev, | ||
211 | struct can_berr_counter *bec) | ||
212 | { | ||
213 | struct sja1000_priv *priv = netdev_priv(dev); | ||
214 | |||
215 | bec->txerr = priv->read_reg(priv, REG_TXERR); | ||
216 | bec->rxerr = priv->read_reg(priv, REG_RXERR); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
206 | /* | 221 | /* |
207 | * initialize SJA1000 chip: | 222 | * initialize SJA1000 chip: |
208 | * - reset chip | 223 | * - reset chip |
@@ -249,6 +264,9 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, | |||
249 | uint8_t dreg; | 264 | uint8_t dreg; |
250 | int i; | 265 | int i; |
251 | 266 | ||
267 | if (can_dropped_invalid_skb(dev, skb)) | ||
268 | return NETDEV_TX_OK; | ||
269 | |||
252 | netif_stop_queue(dev); | 270 | netif_stop_queue(dev); |
253 | 271 | ||
254 | fi = dlc = cf->can_dlc; | 272 | fi = dlc = cf->can_dlc; |
@@ -293,17 +311,14 @@ static void sja1000_rx(struct net_device *dev) | |||
293 | uint8_t fi; | 311 | uint8_t fi; |
294 | uint8_t dreg; | 312 | uint8_t dreg; |
295 | canid_t id; | 313 | canid_t id; |
296 | uint8_t dlc; | ||
297 | int i; | 314 | int i; |
298 | 315 | ||
299 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 316 | /* create zero'ed CAN frame buffer */ |
317 | skb = alloc_can_skb(dev, &cf); | ||
300 | if (skb == NULL) | 318 | if (skb == NULL) |
301 | return; | 319 | return; |
302 | skb->dev = dev; | ||
303 | skb->protocol = htons(ETH_P_CAN); | ||
304 | 320 | ||
305 | fi = priv->read_reg(priv, REG_FI); | 321 | fi = priv->read_reg(priv, REG_FI); |
306 | dlc = fi & 0x0F; | ||
307 | 322 | ||
308 | if (fi & FI_FF) { | 323 | if (fi & FI_FF) { |
309 | /* extended frame format (EFF) */ | 324 | /* extended frame format (EFF) */ |
@@ -320,18 +335,15 @@ static void sja1000_rx(struct net_device *dev) | |||
320 | | (priv->read_reg(priv, REG_ID2) >> 5); | 335 | | (priv->read_reg(priv, REG_ID2) >> 5); |
321 | } | 336 | } |
322 | 337 | ||
323 | if (fi & FI_RTR) | 338 | if (fi & FI_RTR) { |
324 | id |= CAN_RTR_FLAG; | 339 | id |= CAN_RTR_FLAG; |
340 | } else { | ||
341 | cf->can_dlc = get_can_dlc(fi & 0x0F); | ||
342 | for (i = 0; i < cf->can_dlc; i++) | ||
343 | cf->data[i] = priv->read_reg(priv, dreg++); | ||
344 | } | ||
325 | 345 | ||
326 | cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); | ||
327 | memset(cf, 0, sizeof(struct can_frame)); | ||
328 | cf->can_id = id; | 346 | cf->can_id = id; |
329 | cf->can_dlc = dlc; | ||
330 | for (i = 0; i < dlc; i++) | ||
331 | cf->data[i] = priv->read_reg(priv, dreg++); | ||
332 | |||
333 | while (i < 8) | ||
334 | cf->data[i++] = 0; | ||
335 | 347 | ||
336 | /* release receive buffer */ | 348 | /* release receive buffer */ |
337 | priv->write_reg(priv, REG_CMR, CMD_RRB); | 349 | priv->write_reg(priv, REG_CMR, CMD_RRB); |
@@ -339,7 +351,7 @@ static void sja1000_rx(struct net_device *dev) | |||
339 | netif_rx(skb); | 351 | netif_rx(skb); |
340 | 352 | ||
341 | stats->rx_packets++; | 353 | stats->rx_packets++; |
342 | stats->rx_bytes += dlc; | 354 | stats->rx_bytes += cf->can_dlc; |
343 | } | 355 | } |
344 | 356 | ||
345 | static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | 357 | static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) |
@@ -351,15 +363,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
351 | enum can_state state = priv->can.state; | 363 | enum can_state state = priv->can.state; |
352 | uint8_t ecc, alc; | 364 | uint8_t ecc, alc; |
353 | 365 | ||
354 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 366 | skb = alloc_can_err_skb(dev, &cf); |
355 | if (skb == NULL) | 367 | if (skb == NULL) |
356 | return -ENOMEM; | 368 | return -ENOMEM; |
357 | skb->dev = dev; | ||
358 | skb->protocol = htons(ETH_P_CAN); | ||
359 | cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); | ||
360 | memset(cf, 0, sizeof(struct can_frame)); | ||
361 | cf->can_id = CAN_ERR_FLAG; | ||
362 | cf->can_dlc = CAN_ERR_DLC; | ||
363 | 369 | ||
364 | if (isrc & IRQ_DOI) { | 370 | if (isrc & IRQ_DOI) { |
365 | /* data overrun interrupt */ | 371 | /* data overrun interrupt */ |
@@ -446,6 +452,8 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
446 | CAN_ERR_CRTL_TX_PASSIVE : | 452 | CAN_ERR_CRTL_TX_PASSIVE : |
447 | CAN_ERR_CRTL_RX_PASSIVE; | 453 | CAN_ERR_CRTL_RX_PASSIVE; |
448 | } | 454 | } |
455 | cf->data[6] = txerr; | ||
456 | cf->data[7] = rxerr; | ||
449 | } | 457 | } |
450 | 458 | ||
451 | priv->can.state = state; | 459 | priv->can.state = state; |
@@ -526,7 +534,7 @@ static int sja1000_open(struct net_device *dev) | |||
526 | 534 | ||
527 | /* register interrupt handler, if not done by the device driver */ | 535 | /* register interrupt handler, if not done by the device driver */ |
528 | if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) { | 536 | if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) { |
529 | err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags, | 537 | err = request_irq(dev->irq, sja1000_interrupt, priv->irq_flags, |
530 | dev->name, (void *)dev); | 538 | dev->name, (void *)dev); |
531 | if (err) { | 539 | if (err) { |
532 | close_candev(dev); | 540 | close_candev(dev); |
@@ -565,7 +573,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv) | |||
565 | struct net_device *dev; | 573 | struct net_device *dev; |
566 | struct sja1000_priv *priv; | 574 | struct sja1000_priv *priv; |
567 | 575 | ||
568 | dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv); | 576 | dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv, |
577 | SJA1000_ECHO_SKB_MAX); | ||
569 | if (!dev) | 578 | if (!dev) |
570 | return NULL; | 579 | return NULL; |
571 | 580 | ||
@@ -575,6 +584,9 @@ struct net_device *alloc_sja1000dev(int sizeof_priv) | |||
575 | priv->can.bittiming_const = &sja1000_bittiming_const; | 584 | priv->can.bittiming_const = &sja1000_bittiming_const; |
576 | priv->can.do_set_bittiming = sja1000_set_bittiming; | 585 | priv->can.do_set_bittiming = sja1000_set_bittiming; |
577 | priv->can.do_set_mode = sja1000_set_mode; | 586 | priv->can.do_set_mode = sja1000_set_mode; |
587 | priv->can.do_get_berr_counter = sja1000_get_berr_counter; | ||
588 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | | ||
589 | CAN_CTRLMODE_BERR_REPORTING; | ||
578 | 590 | ||
579 | if (sizeof_priv) | 591 | if (sizeof_priv) |
580 | priv->priv = (void *)priv + sizeof(struct sja1000_priv); | 592 | priv->priv = (void *)priv + sizeof(struct sja1000_priv); |