b43legacy: use frame control helpers
[safe/jmp/linux-2.6] / drivers / net / iseries_veth.c
index 41b1d08..b8d0639 100644 (file)
@@ -73,7 +73,7 @@
 #include <asm/abs_addr.h>
 #include <asm/iseries/mf.h>
 #include <asm/uaccess.h>
-
+#include <asm/firmware.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
@@ -166,7 +166,7 @@ struct veth_msg {
 
 struct veth_lpar_connection {
        HvLpIndex remote_lp;
-       struct work_struct statemachine_wq;
+       struct delayed_work statemachine_wq;
        struct veth_msg *msgs;
        int num_events;
        struct veth_cap_data local_caps;
@@ -196,7 +196,6 @@ struct veth_lpar_connection {
 
 struct veth_port {
        struct device *dev;
-       struct net_device_stats stats;
        u64 mac_addr;
        HvLpIndexMap lpar_map;
 
@@ -309,7 +308,8 @@ static void veth_complete_allocation(void *parm, int number)
 
 static int veth_allocate_events(HvLpIndex rlp, int number)
 {
-       struct veth_allocation vc = { COMPLETION_INITIALIZER(vc.c), 0 };
+       struct veth_allocation vc =
+               { COMPLETION_INITIALIZER_ONSTACK(vc.c), 0 };
 
        mf_allocate_lp_events(rlp, HvLpEvent_Type_VirtualLan,
                            sizeof(struct veth_lpevent), number,
@@ -456,7 +456,7 @@ static struct kobj_type veth_port_ktype = {
 
 static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx)
 {
-       schedule_work(&cnx->statemachine_wq);
+       schedule_delayed_work(&cnx->statemachine_wq, 0);
 }
 
 static void veth_take_cap(struct veth_lpar_connection *cnx,
@@ -586,7 +586,7 @@ static void veth_handle_int(struct veth_lpevent *event)
        };
 }
 
-static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
+static void veth_handle_event(struct HvLpEvent *event)
 {
        struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
 
@@ -638,9 +638,11 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
 }
 
 /* FIXME: The gotos here are a bit dubious */
-static void veth_statemachine(void *p)
+static void veth_statemachine(struct work_struct *work)
 {
-       struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)p;
+       struct veth_lpar_connection *cnx =
+               container_of(work, struct veth_lpar_connection,
+                            statemachine_wq.work);
        int rlp = cnx->remote_lp;
        int rc;
 
@@ -814,20 +816,19 @@ static int veth_init_connection(u8 rlp)
 {
        struct veth_lpar_connection *cnx;
        struct veth_msg *msgs;
-       int i, rc;
+       int i;
 
        if ( (rlp == this_lp)
             || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) )
                return 0;
 
-       cnx = kmalloc(sizeof(*cnx), GFP_KERNEL);
+       cnx = kzalloc(sizeof(*cnx), GFP_KERNEL);
        if (! cnx)
                return -ENOMEM;
-       memset(cnx, 0, sizeof(*cnx));
 
        cnx->remote_lp = rlp;
        spin_lock_init(&cnx->lock);
-       INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx);
+       INIT_DELAYED_WORK(&cnx->statemachine_wq, veth_statemachine);
 
        init_timer(&cnx->ack_timer);
        cnx->ack_timer.function = veth_timed_ack;
@@ -844,20 +845,15 @@ static int veth_init_connection(u8 rlp)
 
        /* This gets us 1 reference, which is held on behalf of the driver
         * infrastructure. It's released at module unload. */
-       kobject_init(&cnx->kobject);
-       cnx->kobject.ktype = &veth_lpar_connection_ktype;
-       rc = kobject_set_name(&cnx->kobject, "cnx%.2d", rlp);
-       if (rc != 0)
-               return rc;
+       kobject_init(&cnx->kobject, &veth_lpar_connection_ktype);
 
-       msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL);
+       msgs = kcalloc(VETH_NUMBUFFERS, sizeof(struct veth_msg), GFP_KERNEL);
        if (! msgs) {
                veth_error("Can't allocate buffers for LPAR %d.\n", rlp);
                return -ENOMEM;
        }
 
        cnx->msgs = msgs;
-       memset(msgs, 0, VETH_NUMBUFFERS * sizeof(struct veth_msg));
 
        for (i = 0; i < VETH_NUMBUFFERS; i++) {
                msgs[i].token = i;
@@ -936,9 +932,6 @@ static void veth_release_connection(struct kobject *kobj)
 
 static int veth_open(struct net_device *dev)
 {
-       struct veth_port *port = (struct veth_port *) dev->priv;
-
-       memset(&port->stats, 0, sizeof (port->stats));
        netif_start_queue(dev);
        return 0;
 }
@@ -949,13 +942,6 @@ static int veth_close(struct net_device *dev)
        return 0;
 }
 
-static struct net_device_stats *veth_get_stats(struct net_device *dev)
-{
-       struct veth_port *port = (struct veth_port *) dev->priv;
-
-       return &port->stats;
-}
-
 static int veth_change_mtu(struct net_device *dev, int new_mtu)
 {
        if ((new_mtu < 68) || (new_mtu > VETH_MAX_MTU))
@@ -1035,7 +1021,7 @@ static const struct ethtool_ops ops = {
        .get_link = veth_get_link,
 };
 
-static struct net_device * __init veth_probe_one(int vlan,
+static struct net_device *veth_probe_one(int vlan,
                struct vio_dev *vio_dev)
 {
        struct net_device *dev;
@@ -1084,7 +1070,6 @@ static struct net_device * __init veth_probe_one(int vlan,
        dev->open = veth_open;
        dev->hard_start_xmit = veth_start_xmit;
        dev->stop = veth_close;
-       dev->get_stats = veth_get_stats;
        dev->change_mtu = veth_change_mtu;
        dev->set_mac_address = NULL;
        dev->set_multicast_list = veth_set_multicast_list;
@@ -1099,11 +1084,8 @@ static struct net_device * __init veth_probe_one(int vlan,
                return NULL;
        }
 
-       kobject_init(&port->kobject);
-       port->kobject.parent = &dev->class_dev.kobj;
-       port->kobject.ktype  = &veth_port_ktype;
-       kobject_set_name(&port->kobject, "veth_port");
-       if (0 != kobject_add(&port->kobject))
+       kobject_init(&port->kobject, &veth_port_ktype);
+       if (0 != kobject_add(&port->kobject, &dev->dev.kobj, "veth_port"))
                veth_error("Failed adding port for %s to sysfs.\n", dev->name);
 
        veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n",
@@ -1183,7 +1165,6 @@ static void veth_transmit_to_many(struct sk_buff *skb,
                                          HvLpIndexMap lpmask,
                                          struct net_device *dev)
 {
-       struct veth_port *port = (struct veth_port *) dev->priv;
        int i, success, error;
 
        success = error = 0;
@@ -1199,11 +1180,11 @@ static void veth_transmit_to_many(struct sk_buff *skb,
        }
 
        if (error)
-               port->stats.tx_errors++;
+               dev->stats.tx_errors++;
 
        if (success) {
-               port->stats.tx_packets++;
-               port->stats.tx_bytes += skb->len;
+               dev->stats.tx_packets++;
+               dev->stats.tx_bytes += skb->len;
        }
 }
 
@@ -1538,12 +1519,11 @@ static void veth_receive(struct veth_lpar_connection *cnx,
                }
 
                skb_put(skb, length);
-               skb->dev = dev;
                skb->protocol = eth_type_trans(skb, dev);
                skb->ip_summed = CHECKSUM_NONE;
                netif_rx(skb);  /* send it up */
-               port->stats.rx_packets++;
-               port->stats.rx_bytes += length;
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += length;
        } while (startchunk += nchunks, startchunk < VETH_MAX_FRAMES_PER_MSG);
 
        /* Ack it */
@@ -1666,7 +1646,7 @@ static struct vio_driver veth_driver = {
  * Module initialization/cleanup
  */
 
-void __exit veth_module_cleanup(void)
+static void __exit veth_module_cleanup(void)
 {
        int i;
        struct veth_lpar_connection *cnx;
@@ -1695,11 +1675,14 @@ void __exit veth_module_cleanup(void)
 }
 module_exit(veth_module_cleanup);
 
-int __init veth_module_init(void)
+static int __init veth_module_init(void)
 {
        int i;
        int rc;
 
+       if (!firmware_has_feature(FW_FEATURE_ISERIES))
+               return -ENODEV;
+
        this_lp = HvLpConfig_getLpIndex_outline();
 
        for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
@@ -1722,9 +1705,9 @@ int __init veth_module_init(void)
                        continue;
 
                kobj = &veth_cnx[i]->kobject;
-               kobj->parent = &veth_driver.driver.kobj;
                /* If the add failes, complain but otherwise continue */
-               if (0 != kobject_add(kobj))
+               if (0 != driver_add_kobj(&veth_driver.driver, kobj,
+                                       "cnx%.2d", veth_cnx[i]->remote_lp))
                        veth_error("cnx %d: Failed adding to sysfs.\n", i);
        }