net: usb: raw-ip: support more rmnet interfaces
[linux-2.6.git] / drivers / net / rionet.c
index bc98e7f..7145714 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
+#include <linux/slab.h>
 #include <linux/rio_ids.h>
 
 #include <linux/netdevice.h>
@@ -72,23 +73,23 @@ static int rionet_check = 0;
 static int rionet_capable = 1;
 
 /*
- * This is a fast lookup table for for translating TX
+ * This is a fast lookup table for translating TX
  * Ethernet packets into a destination RIO device. It
  * could be made into a hash table to save memory depending
  * on system trade-offs.
  */
 static struct rio_dev **rionet_active;
 
-#define is_rionet_capable(pef, src_ops, dst_ops)               \
-                       ((pef & RIO_PEF_INB_MBOX) &&            \
-                        (pef & RIO_PEF_INB_DOORBELL) &&        \
+#define is_rionet_capable(src_ops, dst_ops)                    \
+                       ((src_ops & RIO_SRC_OPS_DATA_MSG) &&    \
+                        (dst_ops & RIO_DST_OPS_DATA_MSG) &&    \
                         (src_ops & RIO_SRC_OPS_DOORBELL) &&    \
                         (dst_ops & RIO_DST_OPS_DOORBELL))
 #define dev_rionet_capable(dev) \
-       is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
+       is_rionet_capable(dev->src_ops, dev->dst_ops)
 
-#define RIONET_MAC_MATCH(x)    (*(u32 *)x == 0x00010001)
-#define RIONET_GET_DESTID(x)   (*(u16 *)(x + 4))
+#define RIONET_MAC_MATCH(x)    (!memcmp((x), "\00\01\00\01", 4))
+#define RIONET_GET_DESTID(x)   ((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
 
 static int rionet_rx_clean(struct net_device *ndev)
 {
@@ -161,8 +162,8 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
        rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
 
        if (netif_msg_tx_queued(rnet))
-               printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
-                      (u32) skb, skb->len);
+               printk(KERN_INFO "%s: queued skb len %8.8x\n", DRV_NAME,
+                      skb->len);
 
        return 0;
 }
@@ -189,7 +190,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                return NETDEV_TX_BUSY;
        }
 
-       if (eth->h_dest[0] & 0x01) {
+       if (is_multicast_ether_addr(eth->h_dest)) {
                for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
                                i++)
                        if (rionet_active[i])
@@ -281,7 +282,6 @@ static int rionet_open(struct net_device *ndev)
 {
        int i, rc = 0;
        struct rionet_peer *peer, *tmp;
-       u32 pwdcsr;
        struct rionet_private *rnet = netdev_priv(ndev);
 
        if (netif_msg_ifup(rnet))
@@ -331,13 +331,8 @@ static int rionet_open(struct net_device *ndev)
                        continue;
                }
 
-               /*
-                * If device has initialized inbound doorbells,
-                * send a join message
-                */
-               rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
-               if (pwdcsr & RIO_DOORBELL_AVAIL)
-                       rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
+               /* Send a join message */
+               rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
        }
 
       out:
@@ -377,13 +372,13 @@ static int rionet_close(struct net_device *ndev)
 
 static void rionet_remove(struct rio_dev *rdev)
 {
-       struct net_device *ndev = NULL;
+       struct net_device *ndev = rio_get_drvdata(rdev);
        struct rionet_peer *peer, *tmp;
 
        free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
-                                       __ilog2(sizeof(void *)) + 4 : 0);
+                                       __fls(sizeof(void *)) + 4 : 0);
        unregister_netdev(ndev);
-       kfree(ndev);
+       free_netdev(ndev);
 
        list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
                list_del(&peer->node);
@@ -432,24 +427,14 @@ static const struct net_device_ops rionet_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
 };
 
-static int rionet_setup_netdev(struct rio_mport *mport)
+static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
 {
        int rc = 0;
-       struct net_device *ndev = NULL;
        struct rionet_private *rnet;
        u16 device_id;
 
-       /* Allocate our net_device structure */
-       ndev = alloc_etherdev(sizeof(struct rionet_private));
-       if (ndev == NULL) {
-               printk(KERN_INFO "%s: could not allocate ethernet device.\n",
-                      DRV_NAME);
-               rc = -ENOMEM;
-               goto out;
-       }
-
        rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
-                       mport->sys_size ? __ilog2(sizeof(void *)) + 4 : 0);
+                       mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
        if (!rionet_active) {
                rc = -ENOMEM;
                goto out;
@@ -501,25 +486,34 @@ static int rionet_setup_netdev(struct rio_mport *mport)
 static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
        int rc = -ENODEV;
-       u32 lpef, lsrc_ops, ldst_ops;
+       u32 lsrc_ops, ldst_ops;
        struct rionet_peer *peer;
+       struct net_device *ndev = NULL;
 
        /* If local device is not rionet capable, give up quickly */
        if (!rionet_capable)
                goto out;
 
+       /* Allocate our net_device structure */
+       ndev = alloc_etherdev(sizeof(struct rionet_private));
+       if (ndev == NULL) {
+               printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+                      DRV_NAME);
+               rc = -ENOMEM;
+               goto out;
+       }
+
        /*
         * First time through, make sure local device is rionet
         * capable, setup netdev,  and set flags so this is skipped
         * on later probes
         */
        if (!rionet_check) {
-               rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
                rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
                                         &lsrc_ops);
                rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
                                         &ldst_ops);
-               if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
+               if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
                        printk(KERN_ERR
                               "%s: local device is not network capable\n",
                               DRV_NAME);
@@ -528,7 +522,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
                        goto out;
                }
 
-               rc = rionet_setup_netdev(rdev->net->hport);
+               rc = rionet_setup_netdev(rdev->net->hport, ndev);
                rionet_check = 1;
        }
 
@@ -545,6 +539,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
                list_add_tail(&peer->node, &rionet_peers);
        }
 
+       rio_set_drvdata(rdev, ndev);
+
       out:
        return rc;
 }
@@ -570,5 +566,5 @@ static void __exit rionet_exit(void)
        rio_unregister_driver(&rionet_driver);
 }
 
-module_init(rionet_init);
+late_initcall(rionet_init);
 module_exit(rionet_exit);