aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/rionet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/rionet.c')
-rw-r--r--drivers/net/rionet.c141
1 files changed, 81 insertions, 60 deletions
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 91d25888a1b9..d8b9b1e8ee02 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -26,7 +26,7 @@
26#include <linux/ethtool.h> 26#include <linux/ethtool.h>
27 27
28#define DRV_NAME "rionet" 28#define DRV_NAME "rionet"
29#define DRV_VERSION "0.2" 29#define DRV_VERSION "0.3"
30#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>" 30#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>"
31#define DRV_DESC "Ethernet over RapidIO" 31#define DRV_DESC "Ethernet over RapidIO"
32 32
@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL");
47 47
48#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE 48#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
49#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE 49#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
50 50#define RIONET_MAX_NETS 8
51static LIST_HEAD(rionet_peers);
52 51
53struct rionet_private { 52struct rionet_private {
54 struct rio_mport *mport; 53 struct rio_mport *mport;
@@ -69,16 +68,14 @@ struct rionet_peer {
69 struct resource *res; 68 struct resource *res;
70}; 69};
71 70
72static int rionet_check = 0; 71struct rionet_net {
73static int rionet_capable = 1; 72 struct net_device *ndev;
73 struct list_head peers;
74 struct rio_dev **active;
75 int nact; /* number of active peers */
76};
74 77
75/* 78static struct rionet_net nets[RIONET_MAX_NETS];
76 * This is a fast lookup table for translating TX
77 * Ethernet packets into a destination RIO device. It
78 * could be made into a hash table to save memory depending
79 * on system trade-offs.
80 */
81static struct rio_dev **rionet_active;
82 79
83#define is_rionet_capable(src_ops, dst_ops) \ 80#define is_rionet_capable(src_ops, dst_ops) \
84 ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ 81 ((src_ops & RIO_SRC_OPS_DATA_MSG) && \
@@ -175,6 +172,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
175 struct ethhdr *eth = (struct ethhdr *)skb->data; 172 struct ethhdr *eth = (struct ethhdr *)skb->data;
176 u16 destid; 173 u16 destid;
177 unsigned long flags; 174 unsigned long flags;
175 int add_num = 1;
178 176
179 local_irq_save(flags); 177 local_irq_save(flags);
180 if (!spin_trylock(&rnet->tx_lock)) { 178 if (!spin_trylock(&rnet->tx_lock)) {
@@ -182,7 +180,10 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
182 return NETDEV_TX_LOCKED; 180 return NETDEV_TX_LOCKED;
183 } 181 }
184 182
185 if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) { 183 if (is_multicast_ether_addr(eth->h_dest))
184 add_num = nets[rnet->mport->id].nact;
185
186 if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
186 netif_stop_queue(ndev); 187 netif_stop_queue(ndev);
187 spin_unlock_irqrestore(&rnet->tx_lock, flags); 188 spin_unlock_irqrestore(&rnet->tx_lock, flags);
188 printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n", 189 printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
@@ -191,15 +192,22 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
191 } 192 }
192 193
193 if (is_multicast_ether_addr(eth->h_dest)) { 194 if (is_multicast_ether_addr(eth->h_dest)) {
195 int count = 0;
196
194 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); 197 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
195 i++) 198 i++)
196 if (rionet_active[i]) 199 if (nets[rnet->mport->id].active[i]) {
197 rionet_queue_tx_msg(skb, ndev, 200 rionet_queue_tx_msg(skb, ndev,
198 rionet_active[i]); 201 nets[rnet->mport->id].active[i]);
202 if (count)
203 atomic_inc(&skb->users);
204 count++;
205 }
199 } else if (RIONET_MAC_MATCH(eth->h_dest)) { 206 } else if (RIONET_MAC_MATCH(eth->h_dest)) {
200 destid = RIONET_GET_DESTID(eth->h_dest); 207 destid = RIONET_GET_DESTID(eth->h_dest);
201 if (rionet_active[destid]) 208 if (nets[rnet->mport->id].active[destid])
202 rionet_queue_tx_msg(skb, ndev, rionet_active[destid]); 209 rionet_queue_tx_msg(skb, ndev,
210 nets[rnet->mport->id].active[destid]);
203 } 211 }
204 212
205 spin_unlock_irqrestore(&rnet->tx_lock, flags); 213 spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -218,16 +226,21 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
218 printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", 226 printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
219 DRV_NAME, sid, tid, info); 227 DRV_NAME, sid, tid, info);
220 if (info == RIONET_DOORBELL_JOIN) { 228 if (info == RIONET_DOORBELL_JOIN) {
221 if (!rionet_active[sid]) { 229 if (!nets[rnet->mport->id].active[sid]) {
222 list_for_each_entry(peer, &rionet_peers, node) { 230 list_for_each_entry(peer,
223 if (peer->rdev->destid == sid) 231 &nets[rnet->mport->id].peers, node) {
224 rionet_active[sid] = peer->rdev; 232 if (peer->rdev->destid == sid) {
233 nets[rnet->mport->id].active[sid] =
234 peer->rdev;
235 nets[rnet->mport->id].nact++;
236 }
225 } 237 }
226 rio_mport_send_doorbell(mport, sid, 238 rio_mport_send_doorbell(mport, sid,
227 RIONET_DOORBELL_JOIN); 239 RIONET_DOORBELL_JOIN);
228 } 240 }
229 } else if (info == RIONET_DOORBELL_LEAVE) { 241 } else if (info == RIONET_DOORBELL_LEAVE) {
230 rionet_active[sid] = NULL; 242 nets[rnet->mport->id].active[sid] = NULL;
243 nets[rnet->mport->id].nact--;
231 } else { 244 } else {
232 if (netif_msg_intr(rnet)) 245 if (netif_msg_intr(rnet))
233 printk(KERN_WARNING "%s: unhandled doorbell\n", 246 printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -321,7 +334,8 @@ static int rionet_open(struct net_device *ndev)
321 netif_carrier_on(ndev); 334 netif_carrier_on(ndev);
322 netif_start_queue(ndev); 335 netif_start_queue(ndev);
323 336
324 list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { 337 list_for_each_entry_safe(peer, tmp,
338 &nets[rnet->mport->id].peers, node) {
325 if (!(peer->res = rio_request_outb_dbell(peer->rdev, 339 if (!(peer->res = rio_request_outb_dbell(peer->rdev,
326 RIONET_DOORBELL_JOIN, 340 RIONET_DOORBELL_JOIN,
327 RIONET_DOORBELL_LEAVE))) 341 RIONET_DOORBELL_LEAVE)))
@@ -346,7 +360,7 @@ static int rionet_close(struct net_device *ndev)
346 int i; 360 int i;
347 361
348 if (netif_msg_ifup(rnet)) 362 if (netif_msg_ifup(rnet))
349 printk(KERN_INFO "%s: close\n", DRV_NAME); 363 printk(KERN_INFO "%s: close %s\n", DRV_NAME, ndev->name);
350 364
351 netif_stop_queue(ndev); 365 netif_stop_queue(ndev);
352 netif_carrier_off(ndev); 366 netif_carrier_off(ndev);
@@ -354,10 +368,11 @@ static int rionet_close(struct net_device *ndev)
354 for (i = 0; i < RIONET_RX_RING_SIZE; i++) 368 for (i = 0; i < RIONET_RX_RING_SIZE; i++)
355 kfree_skb(rnet->rx_skb[i]); 369 kfree_skb(rnet->rx_skb[i]);
356 370
357 list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { 371 list_for_each_entry_safe(peer, tmp,
358 if (rionet_active[peer->rdev->destid]) { 372 &nets[rnet->mport->id].peers, node) {
373 if (nets[rnet->mport->id].active[peer->rdev->destid]) {
359 rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); 374 rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
360 rionet_active[peer->rdev->destid] = NULL; 375 nets[rnet->mport->id].active[peer->rdev->destid] = NULL;
361 } 376 }
362 rio_release_outb_dbell(peer->rdev, peer->res); 377 rio_release_outb_dbell(peer->rdev, peer->res);
363 } 378 }
@@ -373,17 +388,21 @@ static int rionet_close(struct net_device *ndev)
373static void rionet_remove(struct rio_dev *rdev) 388static void rionet_remove(struct rio_dev *rdev)
374{ 389{
375 struct net_device *ndev = rio_get_drvdata(rdev); 390 struct net_device *ndev = rio_get_drvdata(rdev);
391 unsigned char netid = rdev->net->hport->id;
376 struct rionet_peer *peer, *tmp; 392 struct rionet_peer *peer, *tmp;
377 393
378 free_pages((unsigned long)rionet_active, get_order(sizeof(void *) *
379 RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
380 unregister_netdev(ndev); 394 unregister_netdev(ndev);
381 free_netdev(ndev);
382 395
383 list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { 396 free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) *
397 RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
398 nets[netid].active = NULL;
399
400 list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
384 list_del(&peer->node); 401 list_del(&peer->node);
385 kfree(peer); 402 kfree(peer);
386 } 403 }
404
405 free_netdev(ndev);
387} 406}
388 407
389static void rionet_get_drvinfo(struct net_device *ndev, 408static void rionet_get_drvinfo(struct net_device *ndev,
@@ -435,13 +454,13 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
435 const size_t rionet_active_bytes = sizeof(void *) * 454 const size_t rionet_active_bytes = sizeof(void *) *
436 RIO_MAX_ROUTE_ENTRIES(mport->sys_size); 455 RIO_MAX_ROUTE_ENTRIES(mport->sys_size);
437 456
438 rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, 457 nets[mport->id].active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
439 get_order(rionet_active_bytes)); 458 get_order(rionet_active_bytes));
440 if (!rionet_active) { 459 if (!nets[mport->id].active) {
441 rc = -ENOMEM; 460 rc = -ENOMEM;
442 goto out; 461 goto out;
443 } 462 }
444 memset((void *)rionet_active, 0, rionet_active_bytes); 463 memset((void *)nets[mport->id].active, 0, rionet_active_bytes);
445 464
446 /* Set up private area */ 465 /* Set up private area */
447 rnet = netdev_priv(ndev); 466 rnet = netdev_priv(ndev);
@@ -470,60 +489,62 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
470 if (rc != 0) 489 if (rc != 0)
471 goto out; 490 goto out;
472 491
473 printk("%s: %s %s Version %s, MAC %pM\n", 492 printk(KERN_INFO "%s: %s %s Version %s, MAC %pM, %s\n",
474 ndev->name, 493 ndev->name,
475 DRV_NAME, 494 DRV_NAME,
476 DRV_DESC, 495 DRV_DESC,
477 DRV_VERSION, 496 DRV_VERSION,
478 ndev->dev_addr); 497 ndev->dev_addr,
498 mport->name);
479 499
480 out: 500 out:
481 return rc; 501 return rc;
482} 502}
483 503
484/* 504static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
485 * XXX Make multi-net safe 505
486 */
487static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) 506static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
488{ 507{
489 int rc = -ENODEV; 508 int rc = -ENODEV;
490 u32 lsrc_ops, ldst_ops; 509 u32 lsrc_ops, ldst_ops;
491 struct rionet_peer *peer; 510 struct rionet_peer *peer;
492 struct net_device *ndev = NULL; 511 struct net_device *ndev = NULL;
512 unsigned char netid = rdev->net->hport->id;
513 int oldnet;
493 514
494 /* If local device is not rionet capable, give up quickly */ 515 if (netid >= RIONET_MAX_NETS)
495 if (!rionet_capable) 516 return rc;
496 goto out;
497 517
498 /* Allocate our net_device structure */ 518 oldnet = test_and_set_bit(netid, net_table);
499 ndev = alloc_etherdev(sizeof(struct rionet_private));
500 if (ndev == NULL) {
501 rc = -ENOMEM;
502 goto out;
503 }
504 519
505 /* 520 /*
506 * First time through, make sure local device is rionet 521 * First time through, make sure local device is rionet
507 * capable, setup netdev, and set flags so this is skipped 522 * capable, setup netdev (will be skipped on later probes)
508 * on later probes
509 */ 523 */
510 if (!rionet_check) { 524 if (!oldnet) {
511 rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, 525 rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
512 &lsrc_ops); 526 &lsrc_ops);
513 rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, 527 rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
514 &ldst_ops); 528 &ldst_ops);
515 if (!is_rionet_capable(lsrc_ops, ldst_ops)) { 529 if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
516 printk(KERN_ERR 530 printk(KERN_ERR
517 "%s: local device is not network capable\n", 531 "%s: local device %s is not network capable\n",
518 DRV_NAME); 532 DRV_NAME, rdev->net->hport->name);
519 rionet_check = 1;
520 rionet_capable = 0;
521 goto out; 533 goto out;
522 } 534 }
523 535
536 /* Allocate our net_device structure */
537 ndev = alloc_etherdev(sizeof(struct rionet_private));
538 if (ndev == NULL) {
539 rc = -ENOMEM;
540 goto out;
541 }
542 nets[netid].ndev = ndev;
524 rc = rionet_setup_netdev(rdev->net->hport, ndev); 543 rc = rionet_setup_netdev(rdev->net->hport, ndev);
525 rionet_check = 1; 544 INIT_LIST_HEAD(&nets[netid].peers);
526 } 545 nets[netid].nact = 0;
546 } else if (nets[netid].ndev == NULL)
547 goto out;
527 548
528 /* 549 /*
529 * If the remote device has mailbox/doorbell capabilities, 550 * If the remote device has mailbox/doorbell capabilities,
@@ -535,10 +556,10 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
535 goto out; 556 goto out;
536 } 557 }
537 peer->rdev = rdev; 558 peer->rdev = rdev;
538 list_add_tail(&peer->node, &rionet_peers); 559 list_add_tail(&peer->node, &nets[netid].peers);
539 } 560 }
540 561
541 rio_set_drvdata(rdev, ndev); 562 rio_set_drvdata(rdev, nets[netid].ndev);
542 563
543 out: 564 out:
544 return rc; 565 return rc;