aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/rionet.c103
1 files changed, 78 insertions, 25 deletions
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index f433b594388e..6d1f6ed3113f 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -208,6 +208,17 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
208 if (nets[rnet->mport->id].active[destid]) 208 if (nets[rnet->mport->id].active[destid])
209 rionet_queue_tx_msg(skb, ndev, 209 rionet_queue_tx_msg(skb, ndev,
210 nets[rnet->mport->id].active[destid]); 210 nets[rnet->mport->id].active[destid]);
211 else {
212 /*
213 * If the target device was removed from the list of
214 * active peers but we still have TX packets targeting
215 * it just report sending a packet to the target
216 * (without actual packet transfer).
217 */
218 dev_kfree_skb_any(skb);
219 ndev->stats.tx_packets++;
220 ndev->stats.tx_bytes += skb->len;
221 }
211 } 222 }
212 223
213 spin_unlock_irqrestore(&rnet->tx_lock, flags); 224 spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -385,24 +396,28 @@ static int rionet_close(struct net_device *ndev)
385 return 0; 396 return 0;
386} 397}
387 398
388static void rionet_remove(struct rio_dev *rdev) 399static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
389{ 400{
390 struct net_device *ndev = rio_get_drvdata(rdev); 401 struct rio_dev *rdev = to_rio_dev(dev);
391 unsigned char netid = rdev->net->hport->id; 402 unsigned char netid = rdev->net->hport->id;
392 struct rionet_peer *peer, *tmp; 403 struct rionet_peer *peer, *tmp;
393 404
394 unregister_netdev(ndev); 405 if (dev_rionet_capable(rdev)) {
395 406 list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
396 free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) * 407 if (peer->rdev == rdev) {
397 RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size))); 408 if (nets[netid].active[rdev->destid]) {
398 nets[netid].active = NULL; 409 nets[netid].active[rdev->destid] = NULL;
410 nets[netid].nact--;
411 }
399 412
400 list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) { 413 list_del(&peer->node);
401 list_del(&peer->node); 414 kfree(peer);
402 kfree(peer); 415 break;
416 }
417 }
403 } 418 }
404 419
405 free_netdev(ndev); 420 return 0;
406} 421}
407 422
408static void rionet_get_drvinfo(struct net_device *ndev, 423static void rionet_get_drvinfo(struct net_device *ndev,
@@ -503,12 +518,13 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
503 518
504static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1]; 519static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
505 520
506static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) 521static int rionet_add_dev(struct device *dev, struct subsys_interface *sif)
507{ 522{
508 int rc = -ENODEV; 523 int rc = -ENODEV;
509 u32 lsrc_ops, ldst_ops; 524 u32 lsrc_ops, ldst_ops;
510 struct rionet_peer *peer; 525 struct rionet_peer *peer;
511 struct net_device *ndev = NULL; 526 struct net_device *ndev = NULL;
527 struct rio_dev *rdev = to_rio_dev(dev);
512 unsigned char netid = rdev->net->hport->id; 528 unsigned char netid = rdev->net->hport->id;
513 int oldnet; 529 int oldnet;
514 530
@@ -518,8 +534,9 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
518 oldnet = test_and_set_bit(netid, net_table); 534 oldnet = test_and_set_bit(netid, net_table);
519 535
520 /* 536 /*
521 * First time through, make sure local device is rionet 537 * If first time through this net, make sure local device is rionet
522 * capable, setup netdev (will be skipped on later probes) 538 * capable and setup netdev (this step will be skipped in later probes
539 * on the same net).
523 */ 540 */
524 if (!oldnet) { 541 if (!oldnet) {
525 rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, 542 rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
@@ -541,6 +558,12 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
541 } 558 }
542 nets[netid].ndev = ndev; 559 nets[netid].ndev = ndev;
543 rc = rionet_setup_netdev(rdev->net->hport, ndev); 560 rc = rionet_setup_netdev(rdev->net->hport, ndev);
561 if (rc) {
562 printk(KERN_ERR "%s: failed to setup netdev (rc=%d)\n",
563 DRV_NAME, rc);
564 goto out;
565 }
566
544 INIT_LIST_HEAD(&nets[netid].peers); 567 INIT_LIST_HEAD(&nets[netid].peers);
545 nets[netid].nact = 0; 568 nets[netid].nact = 0;
546 } else if (nets[netid].ndev == NULL) 569 } else if (nets[netid].ndev == NULL)
@@ -559,31 +582,61 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
559 list_add_tail(&peer->node, &nets[netid].peers); 582 list_add_tail(&peer->node, &nets[netid].peers);
560 } 583 }
561 584
562 rio_set_drvdata(rdev, nets[netid].ndev); 585 return 0;
563 586out:
564 out:
565 return rc; 587 return rc;
566} 588}
567 589
590#ifdef MODULE
568static struct rio_device_id rionet_id_table[] = { 591static struct rio_device_id rionet_id_table[] = {
569 {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)} 592 {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)},
593 { 0, } /* terminate list */
570}; 594};
571 595
572static struct rio_driver rionet_driver = { 596MODULE_DEVICE_TABLE(rapidio, rionet_id_table);
573 .name = "rionet", 597#endif
574 .id_table = rionet_id_table, 598
575 .probe = rionet_probe, 599static struct subsys_interface rionet_interface = {
576 .remove = rionet_remove, 600 .name = "rionet",
601 .subsys = &rio_bus_type,
602 .add_dev = rionet_add_dev,
603 .remove_dev = rionet_remove_dev,
577}; 604};
578 605
579static int __init rionet_init(void) 606static int __init rionet_init(void)
580{ 607{
581 return rio_register_driver(&rionet_driver); 608 return subsys_interface_register(&rionet_interface);
582} 609}
583 610
584static void __exit rionet_exit(void) 611static void __exit rionet_exit(void)
585{ 612{
586 rio_unregister_driver(&rionet_driver); 613 struct rionet_private *rnet;
614 struct net_device *ndev;
615 struct rionet_peer *peer, *tmp;
616 int i;
617
618 for (i = 0; i < RIONET_MAX_NETS; i++) {
619 if (nets[i].ndev != NULL) {
620 ndev = nets[i].ndev;
621 rnet = netdev_priv(ndev);
622 unregister_netdev(ndev);
623
624 list_for_each_entry_safe(peer,
625 tmp, &nets[i].peers, node) {
626 list_del(&peer->node);
627 kfree(peer);
628 }
629
630 free_pages((unsigned long)nets[i].active,
631 get_order(sizeof(void *) *
632 RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size)));
633 nets[i].active = NULL;
634
635 free_netdev(ndev);
636 }
637 }
638
639 subsys_interface_unregister(&rionet_interface);
587} 640}
588 641
589late_initcall(rionet_init); 642late_initcall(rionet_init);