net: Add DEVTYPE support for Ethernet based devices
[pandora-kernel.git] / drivers / net / usb / hso.c
index 837135f..fa4e581 100644 (file)
@@ -771,7 +771,8 @@ static void write_bulk_callback(struct urb *urb)
 }
 
 /* called by kernel when we need to transmit a packet */
-static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
+                                           struct net_device *net)
 {
        struct hso_net *odev = netdev_priv(net);
        int result;
@@ -780,7 +781,7 @@ static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
        netif_stop_queue(net);
        if (hso_get_activity(odev->parent) == -EAGAIN) {
                odev->skb_tx_buf = skb;
-               return 0;
+               return NETDEV_TX_OK;
        }
 
        /* log if asked */
@@ -816,7 +817,7 @@ static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
        }
        dev_kfree_skb(skb);
        /* we're done */
-       return result;
+       return NETDEV_TX_OK;
 }
 
 static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
@@ -828,7 +829,7 @@ static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info
        usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
        .get_drvinfo = hso_get_drvinfo,
        .get_link = ethtool_op_get_link
 };
@@ -899,15 +900,14 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
                                        continue;
                                }
                                /* Allocate an sk_buff */
-                               odev->skb_rx_buf = dev_alloc_skb(frame_len);
+                               odev->skb_rx_buf = netdev_alloc_skb(odev->net,
+                                                                   frame_len);
                                if (!odev->skb_rx_buf) {
                                        /* We got no receive buffer. */
                                        D1("could not allocate memory");
                                        odev->rx_parse_state = WAIT_SYNC;
                                        return;
                                }
-                               /* Here's where it came from */
-                               odev->skb_rx_buf->dev = odev->net;
 
                                /* Copy what we got so far. make room for iphdr
                                 * after tail. */
@@ -2481,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev)
        return 0;
 }
 
-static int hso_radio_toggle(void *data, enum rfkill_state state)
+static int hso_rfkill_set_block(void *data, bool blocked)
 {
        struct hso_device *hso_dev = data;
-       int enabled = (state == RFKILL_STATE_UNBLOCKED);
+       int enabled = !blocked;
        int rv;
 
        mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2498,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
        return rv;
 }
 
+static const struct rfkill_ops hso_rfkill_ops = {
+       .set_block = hso_rfkill_set_block,
+};
+
 /* Creates and sets up everything for rfkill */
 static void hso_create_rfkill(struct hso_device *hso_dev,
                             struct usb_interface *interface)
@@ -2506,35 +2510,35 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
        struct device *dev = &hso_net->net->dev;
        char *rfkn;
 
-       hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
-                                RFKILL_TYPE_WWAN);
-       if (!hso_net->rfkill) {
-               dev_err(dev, "%s - Out of memory\n", __func__);
-               return;
-       }
        rfkn = kzalloc(20, GFP_KERNEL);
-       if (!rfkn) {
-               rfkill_free(hso_net->rfkill);
-               hso_net->rfkill = NULL;
+       if (!rfkn)
                dev_err(dev, "%s - Out of memory\n", __func__);
-               return;
-       }
+
        snprintf(rfkn, 20, "hso-%d",
                 interface->altsetting->desc.bInterfaceNumber);
-       hso_net->rfkill->name = rfkn;
-       hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED;
-       hso_net->rfkill->data = hso_dev;
-       hso_net->rfkill->toggle_radio = hso_radio_toggle;
+
+       hso_net->rfkill = rfkill_alloc(rfkn,
+                                      &interface_to_usbdev(interface)->dev,
+                                      RFKILL_TYPE_WWAN,
+                                      &hso_rfkill_ops, hso_dev);
+       if (!hso_net->rfkill) {
+               dev_err(dev, "%s - Out of memory\n", __func__);
+               kfree(rfkn);
+               return;
+       }
        if (rfkill_register(hso_net->rfkill) < 0) {
+               rfkill_destroy(hso_net->rfkill);
                kfree(rfkn);
-               hso_net->rfkill->name = NULL;
-               rfkill_free(hso_net->rfkill);
                hso_net->rfkill = NULL;
                dev_err(dev, "%s - Failed to register rfkill\n", __func__);
                return;
        }
 }
 
+static struct device_type hso_type = {
+       .name   = "wwan",
+};
+
 /* Creates our network device */
 static struct hso_device *hso_create_net_device(struct usb_interface *interface,
                                                int port_spec)
@@ -2575,6 +2579,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
                goto exit;
        }
        SET_NETDEV_DEV(net, &interface->dev);
+       SET_NETDEV_DEVTYPE(net, &hso_type);
 
        /* registering our net device */
        result = register_netdev(net);
@@ -3165,8 +3170,10 @@ static void hso_free_interface(struct usb_interface *interface)
                        hso_stop_net_device(network_table[i]);
                        cancel_work_sync(&network_table[i]->async_put_intf);
                        cancel_work_sync(&network_table[i]->async_get_intf);
-                       if (rfk)
+                       if (rfk) {
                                rfkill_unregister(rfk);
+                               rfkill_destroy(rfk);
+                       }
                        hso_free_net_device(network_table[i]);
                }
        }