]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:23:43 +0000 (10:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:23:43 +0000 (10:23 -0700)
Pull networking update from David Miller:

 1) Propagate return error values properly in irda, spider_net, sfc, and
    bfin_mac.  From Wei Yongjun.

 2) Fix fec driver OOPS on rapid link up/down, from Frank Li.

 3) FIX VF resource allocation and chip message payload length errors in
    be2net driver, from Sathya Perla.

 4) Fix inner protocol inspection during GSO from Pravin B Shelar.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  if_cablemodem.h: Add parenthesis around ioctl macros
  gso: Handle Trans-Ether-Bridging protocol in skb_network_protocol()
  net: fec: fix kernel oops when plug/unplug cable many times
  bfin_mac: fix error return code in bfin_mac_probe()
  sfc: fix return value check in efx_ptp_probe_channel()
  net/spider_net: fix error return code in spider_net_open()
  net/irda: fix error return code in bfin_sir_open()
  net: of_mdio: fix behavior on missing phy device
  sierra_net: keep status interrupt URB active
  usbnet: allow status interrupt URB to always be active
  qmi_wwan/cdc_ether: add device IDs for Dell 5804 (Novatel E371) WWAN card
  be2net: disable TX in be_close()
  be2net: fix EQ from getting full while cleaning RX CQ
  be2net: fix payload_len value for GET_MAC_LIST cmd req
  be2net: provision VF resources before enabling SR-IOV

18 files changed:
drivers/net/ethernet/adi/bfin_mac.c
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/sfc/ptp.c
drivers/net/ethernet/toshiba/spider_net.c
drivers/net/irda/bfin_sir.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/sierra_net.c
drivers/net/usb/usbnet.c
drivers/of/of_mdio.c
include/linux/usb/usbnet.h
include/uapi/linux/if_cablemodem.h
net/core/dev.c
net/ipv4/gre.c
net/ipv4/udp.c

index ee705771bd2cb43658fd55edffa5811a179b6c80..dada66bfe0d6e018778ba24939f15b82e9468b0d 100644 (file)
@@ -1700,7 +1700,8 @@ static int bfin_mac_probe(struct platform_device *pdev)
        }
 
        bfin_mac_hwtstamp_init(ndev);
-       if (bfin_phc_init(ndev, &pdev->dev)) {
+       rc = bfin_phc_init(ndev, &pdev->dev);
+       if (rc) {
                dev_err(&pdev->dev, "Cannot register PHC device!\n");
                goto out_err_phc;
        }
index e1e5bb9d90545d6a625d5476c873b942a2a37a04..fd7b547698abd89f829008e717e34f2fc9d9e2f9 100644 (file)
@@ -2640,9 +2640,8 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
        req = get_mac_list_cmd.va;
 
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                               OPCODE_COMMON_GET_MAC_LIST, sizeof(*req),
-                               wrb, &get_mac_list_cmd);
-
+                              OPCODE_COMMON_GET_MAC_LIST,
+                              get_mac_list_cmd.size, wrb, &get_mac_list_cmd);
        req->hdr.domain = domain;
        req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
        req->perm_override = 1;
index 6c52a60dcdb769b9fb52ea3ba8050dd413432102..a444110b060fd74361759be2f9f3a25a4f0fe095 100644 (file)
@@ -1827,7 +1827,7 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
                        mdelay(1);
                } else {
                        be_rx_compl_discard(rxo, rxcp);
-                       be_cq_notify(adapter, rx_cq->id, true, 1);
+                       be_cq_notify(adapter, rx_cq->id, false, 1);
                        if (rxcp->num_rcvd == 0)
                                break;
                }
@@ -2533,11 +2533,6 @@ static void be_rx_qs_destroy(struct be_adapter *adapter)
                q = &rxo->q;
                if (q->created) {
                        be_cmd_rxq_destroy(adapter, q);
-                       /* After the rxq is invalidated, wait for a grace time
-                        * of 1ms for all dma to end and the flush compl to
-                        * arrive
-                        */
-                       mdelay(1);
                        be_rx_cq_clean(rxo);
                }
                be_queue_free(adapter, q);
@@ -2564,6 +2559,7 @@ static int be_close(struct net_device *netdev)
         * all tx skbs are freed.
         */
        be_tx_compl_clean(adapter);
+       netif_tx_disable(netdev);
 
        be_rx_qs_destroy(adapter);
 
@@ -2672,6 +2668,7 @@ static int be_open(struct net_device *netdev)
        if (!status)
                be_link_status_update(adapter, link_status);
 
+       netif_tx_start_all_queues(netdev);
        be_roce_dev_open(adapter);
        return 0;
 err:
@@ -2783,6 +2780,8 @@ static void be_vf_clear(struct be_adapter *adapter)
                goto done;
        }
 
+       pci_disable_sriov(adapter->pdev);
+
        for_all_vfs(adapter, vf_cfg, vf) {
                if (lancer_chip(adapter))
                        be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
@@ -2792,7 +2791,6 @@ static void be_vf_clear(struct be_adapter *adapter)
 
                be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
        }
-       pci_disable_sriov(adapter->pdev);
 done:
        kfree(adapter->vf_cfg);
        adapter->num_vfs = 0;
@@ -2889,13 +2887,8 @@ static int be_vf_setup(struct be_adapter *adapter)
                        dev_info(dev, "Device supports %d VFs and not %d\n",
                                 adapter->dev_num_vfs, num_vfs);
                adapter->num_vfs = min_t(u16, num_vfs, adapter->dev_num_vfs);
-
-               status = pci_enable_sriov(adapter->pdev, num_vfs);
-               if (status) {
-                       dev_err(dev, "SRIOV enable failed\n");
-                       adapter->num_vfs = 0;
+               if (!adapter->num_vfs)
                        return 0;
-               }
        }
 
        status = be_vf_setup_init(adapter);
@@ -2944,6 +2937,15 @@ static int be_vf_setup(struct be_adapter *adapter)
 
                be_cmd_enable_vf(adapter, vf + 1);
        }
+
+       if (!old_vfs) {
+               status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
+               if (status) {
+                       dev_err(dev, "SRIOV enable failed\n");
+                       adapter->num_vfs = 0;
+                       goto err;
+               }
+       }
        return 0;
 err:
        dev_err(dev, "VF setup failed\n");
@@ -3198,7 +3200,7 @@ static int be_setup(struct be_adapter *adapter)
                be_cmd_set_flow_control(adapter, adapter->tx_fc,
                                        adapter->rx_fc);
 
-       if (be_physfn(adapter) && num_vfs) {
+       if (be_physfn(adapter)) {
                if (adapter->dev_num_vfs)
                        be_vf_setup(adapter);
                else
index ceb4d43c132db30f4b82c09a2f100e1f6c98652b..9ce5b7185fda196f521d439a143b3021b56ff5c3 100644 (file)
@@ -198,6 +198,11 @@ struct bufdesc_ex {
 #define FLAG_RX_CSUM_ENABLED   (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
 #define FLAG_RX_CSUM_ERROR     (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
 
+struct fec_enet_delayed_work {
+       struct delayed_work delay_work;
+       bool timeout;
+};
+
 /* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
  * tx_bd_base always point to the base of the buffer descriptors.  The
  * cur_rx and cur_tx point to the currently available buffer.
@@ -232,9 +237,6 @@ struct fec_enet_private {
        /* The ring entries to be free()ed */
        struct bufdesc  *dirty_tx;
 
-       /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
-       spinlock_t hw_lock;
-
        struct  platform_device *pdev;
 
        int     opened;
@@ -269,7 +271,7 @@ struct fec_enet_private {
        int hwts_rx_en;
        int hwts_tx_en;
        struct timer_list time_keep;
-
+       struct fec_enet_delayed_work delay_work;
 };
 
 void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev);
index e25bf832e6b3e1f5695f7075537cef6d711c3706..aff0310a778bf7afb545c4b53f995770f7f03ec2 100644 (file)
@@ -445,6 +445,13 @@ fec_restart(struct net_device *ndev, int duplex)
        u32 rcntl = OPT_FRAME_SIZE | 0x04;
        u32 ecntl = 0x2; /* ETHEREN */
 
+       if (netif_running(ndev)) {
+               netif_device_detach(ndev);
+               napi_disable(&fep->napi);
+               netif_stop_queue(ndev);
+               netif_tx_lock(ndev);
+       }
+
        /* Whack a reset.  We should wait for this. */
        writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
@@ -605,6 +612,13 @@ fec_restart(struct net_device *ndev, int duplex)
 
        /* Enable interrupts we wish to service */
        writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+
+       if (netif_running(ndev)) {
+               netif_device_attach(ndev);
+               napi_enable(&fep->napi);
+               netif_wake_queue(ndev);
+               netif_tx_unlock(ndev);
+       }
 }
 
 static void
@@ -644,8 +658,22 @@ fec_timeout(struct net_device *ndev)
 
        ndev->stats.tx_errors++;
 
-       fec_restart(ndev, fep->full_duplex);
-       netif_wake_queue(ndev);
+       fep->delay_work.timeout = true;
+       schedule_delayed_work(&(fep->delay_work.delay_work), 0);
+}
+
+static void fec_enet_work(struct work_struct *work)
+{
+       struct fec_enet_private *fep =
+               container_of(work,
+                            struct fec_enet_private,
+                            delay_work.delay_work.work);
+
+       if (fep->delay_work.timeout) {
+               fep->delay_work.timeout = false;
+               fec_restart(fep->netdev, fep->full_duplex);
+               netif_wake_queue(fep->netdev);
+       }
 }
 
 static void
@@ -1024,16 +1052,12 @@ static void fec_enet_adjust_link(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
        struct phy_device *phy_dev = fep->phy_dev;
-       unsigned long flags;
-
        int status_change = 0;
 
-       spin_lock_irqsave(&fep->hw_lock, flags);
-
        /* Prevent a state halted on mii error */
        if (fep->mii_timeout && phy_dev->state == PHY_HALTED) {
                phy_dev->state = PHY_RESUMING;
-               goto spin_unlock;
+               return;
        }
 
        if (phy_dev->link) {
@@ -1061,9 +1085,6 @@ static void fec_enet_adjust_link(struct net_device *ndev)
                }
        }
 
-spin_unlock:
-       spin_unlock_irqrestore(&fep->hw_lock, flags);
-
        if (status_change)
                phy_print_status(phy_dev);
 }
@@ -1732,7 +1753,6 @@ static int fec_enet_init(struct net_device *ndev)
                return -ENOMEM;
 
        memset(cbd_base, 0, PAGE_SIZE);
-       spin_lock_init(&fep->hw_lock);
 
        fep->netdev = ndev;
 
@@ -1952,6 +1972,7 @@ fec_probe(struct platform_device *pdev)
        if (fep->bufdesc_ex && fep->ptp_clock)
                netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);
 
+       INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
        return 0;
 
 failed_register:
@@ -1984,6 +2005,7 @@ fec_drv_remove(struct platform_device *pdev)
        struct fec_enet_private *fep = netdev_priv(ndev);
        int i;
 
+       cancel_delayed_work_sync(&(fep->delay_work.delay_work));
        unregister_netdev(ndev);
        fec_enet_mii_remove(fep);
        del_timer_sync(&fep->time_keep);
index 07f6baa15c0cd4cc075130d45130729eb77c7d1b..9a95abf2dedfad3dce17f6739eaba93a23e4c105 100644 (file)
@@ -912,8 +912,10 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
 
        ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info,
                                            &efx->pci_dev->dev);
-       if (!ptp->phc_clock)
+       if (IS_ERR(ptp->phc_clock)) {
+               rc = PTR_ERR(ptp->phc_clock);
                goto fail3;
+       }
 
        INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker);
        ptp->pps_workwq = create_singlethread_workqueue("sfc_pps");
index c655fe60121ee3694297f289ef3d4529d3081a9d..5734480c1ecfa5f91a134720fe478bb68826fc50 100644 (file)
@@ -1990,7 +1990,8 @@ spider_net_open(struct net_device *netdev)
                goto alloc_rx_failed;
 
        /* Allocate rx skbs */
-       if (spider_net_alloc_rx_skbs(card))
+       result = spider_net_alloc_rx_skbs(card);
+       if (result)
                goto alloc_skbs_failed;
 
        spider_net_set_multi(netdev);
index a06fca61c9a08f308cb0ef82f1d086cf59d0ad33..22b4527321b1cf6a99140f8845ba40137f8cf451 100644 (file)
@@ -609,7 +609,7 @@ static int bfin_sir_open(struct net_device *dev)
 {
        struct bfin_sir_self *self = netdev_priv(dev);
        struct bfin_sir_port *port = self->sir_port;
-       int err = -ENOMEM;
+       int err;
 
        self->newspeed = 0;
        self->speed = 9600;
@@ -623,8 +623,10 @@ static int bfin_sir_open(struct net_device *dev)
        bfin_sir_set_speed(port, 9600);
 
        self->irlap = irlap_open(dev, &self->qos, DRIVER_NAME);
-       if (!self->irlap)
+       if (!self->irlap) {
+               err = -ENOMEM;
                goto err_irlap;
+       }
 
        INIT_WORK(&self->work, bfin_sir_send_work);
 
index 24fbec27a22a93c144f255cfdb72e5ab7a7dad63..078795fe6e312f22348d381e03b07c4274e07f87 100644 (file)
@@ -613,6 +613,13 @@ static const struct usb_device_id  products [] = {
        .driver_info = 0,
 },
 
+/* Dell Wireless 5804 (Novatel E371) - handled by qmi_wwan */
+{
+       USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x819b, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = 0,
+},
+
 /* AnyDATA ADU960S - handled by qmi_wwan */
 {
        USB_DEVICE_AND_INTERFACE_INFO(0x16d5, 0x650a, USB_CLASS_COMM,
index 834e405fb57abebb9b2c6c6373c5ca09f4da46bf..cf887c2384e95004547bf56ef7dc8ea0a67e66e5 100644 (file)
@@ -501,6 +501,13 @@ static const struct usb_device_id products[] = {
                                              USB_CDC_PROTO_NONE),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
+       {       /* Dell Wireless 5804 (Novatel E371) */
+               USB_DEVICE_AND_INTERFACE_INFO(0x413C, 0x819b,
+                                             USB_CLASS_COMM,
+                                             USB_CDC_SUBCLASS_ETHERNET,
+                                             USB_CDC_PROTO_NONE),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
        {       /* ADU960S */
                USB_DEVICE_AND_INTERFACE_INFO(0x16d5, 0x650a,
                                              USB_CLASS_COMM,
index a923d61c6fc54ab676ade398e8704f7c24a66a0d..a79e9d3349284ac7c8371ae495d03110f87a3d42 100644 (file)
@@ -426,6 +426,13 @@ static void sierra_net_dosync(struct usbnet *dev)
 
        dev_dbg(&dev->udev->dev, "%s", __func__);
 
+       /* The SIERRA_NET_HIP_MSYNC_ID command appears to request that the
+        * firmware restart itself.  After restarting, the modem will respond
+        * with the SIERRA_NET_HIP_RESTART_ID indication.  The driver continues
+        * sending MSYNC commands every few seconds until it receives the
+        * RESTART event from the firmware
+        */
+
        /* tell modem we are ready */
        status = sierra_net_send_sync(dev);
        if (status < 0)
@@ -704,6 +711,9 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
        /* set context index initially to 0 - prepares tx hdr template */
        sierra_net_set_ctx_index(priv, 0);
 
+       /* prepare sync message template */
+       memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
        /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
        dev->rx_urb_size  = SIERRA_NET_RX_URB_SIZE;
        if (dev->udev->speed != USB_SPEED_HIGH)
@@ -739,11 +749,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
                kfree(priv);
                return -ENODEV;
        }
-       /* prepare sync message from template */
-       memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
-
-       /* initiate the sync sequence */
-       sierra_net_dosync(dev);
 
        return 0;
 }
@@ -766,8 +771,9 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
                netdev_err(dev->net,
                        "usb_control_msg failed, status %d\n", status);
 
-       sierra_net_set_private(dev, NULL);
+       usbnet_status_stop(dev);
 
+       sierra_net_set_private(dev, NULL);
        kfree(priv);
 }
 
@@ -908,6 +914,24 @@ static const struct driver_info sierra_net_info_direct_ip = {
        .tx_fixup = sierra_net_tx_fixup,
 };
 
+static int
+sierra_net_probe(struct usb_interface *udev, const struct usb_device_id *prod)
+{
+       int ret;
+
+       ret = usbnet_probe(udev, prod);
+       if (ret == 0) {
+               struct usbnet *dev = usb_get_intfdata(udev);
+
+               ret = usbnet_status_start(dev, GFP_KERNEL);
+               if (ret == 0) {
+                       /* Interrupt URB now set up; initiate sync sequence */
+                       sierra_net_dosync(dev);
+               }
+       }
+       return ret;
+}
+
 #define DIRECT_IP_DEVICE(vend, prod) \
        {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \
        .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
@@ -930,7 +954,7 @@ MODULE_DEVICE_TABLE(usb, products);
 static struct usb_driver sierra_net_driver = {
        .name = "sierra_net",
        .id_table = products,
-       .probe = usbnet_probe,
+       .probe = sierra_net_probe,
        .disconnect = usbnet_disconnect,
        .suspend = usbnet_suspend,
        .resume = usbnet_resume,
index 1e5a9b72650e9946e23040f1169421bf87d18317..f95cb032394bb03f05b7ae2605b7b9585e8e3c67 100644 (file)
@@ -252,6 +252,70 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
        return 0;
 }
 
+/* Submit the interrupt URB if not previously submitted, increasing refcount */
+int usbnet_status_start(struct usbnet *dev, gfp_t mem_flags)
+{
+       int ret = 0;
+
+       WARN_ON_ONCE(dev->interrupt == NULL);
+       if (dev->interrupt) {
+               mutex_lock(&dev->interrupt_mutex);
+
+               if (++dev->interrupt_count == 1)
+                       ret = usb_submit_urb(dev->interrupt, mem_flags);
+
+               dev_dbg(&dev->udev->dev, "incremented interrupt URB count to %d\n",
+                       dev->interrupt_count);
+               mutex_unlock(&dev->interrupt_mutex);
+       }
+       return ret;
+}
+EXPORT_SYMBOL_GPL(usbnet_status_start);
+
+/* For resume; submit interrupt URB if previously submitted */
+static int __usbnet_status_start_force(struct usbnet *dev, gfp_t mem_flags)
+{
+       int ret = 0;
+
+       mutex_lock(&dev->interrupt_mutex);
+       if (dev->interrupt_count) {
+               ret = usb_submit_urb(dev->interrupt, mem_flags);
+               dev_dbg(&dev->udev->dev,
+                       "submitted interrupt URB for resume\n");
+       }
+       mutex_unlock(&dev->interrupt_mutex);
+       return ret;
+}
+
+/* Kill the interrupt URB if all submitters want it killed */
+void usbnet_status_stop(struct usbnet *dev)
+{
+       if (dev->interrupt) {
+               mutex_lock(&dev->interrupt_mutex);
+               WARN_ON(dev->interrupt_count == 0);
+
+               if (dev->interrupt_count && --dev->interrupt_count == 0)
+                       usb_kill_urb(dev->interrupt);
+
+               dev_dbg(&dev->udev->dev,
+                       "decremented interrupt URB count to %d\n",
+                       dev->interrupt_count);
+               mutex_unlock(&dev->interrupt_mutex);
+       }
+}
+EXPORT_SYMBOL_GPL(usbnet_status_stop);
+
+/* For suspend; always kill interrupt URB */
+static void __usbnet_status_stop_force(struct usbnet *dev)
+{
+       if (dev->interrupt) {
+               mutex_lock(&dev->interrupt_mutex);
+               usb_kill_urb(dev->interrupt);
+               dev_dbg(&dev->udev->dev, "killed interrupt URB for suspend\n");
+               mutex_unlock(&dev->interrupt_mutex);
+       }
+}
+
 /* Passes this packet up the stack, updating its accounting.
  * Some link protocols batch packets, so their rx_fixup paths
  * can return clones as well as just modify the original skb.
@@ -725,7 +789,7 @@ int usbnet_stop (struct net_device *net)
        if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
                usbnet_terminate_urbs(dev);
 
-       usb_kill_urb(dev->interrupt);
+       usbnet_status_stop(dev);
 
        usbnet_purge_paused_rxq(dev);
 
@@ -787,7 +851,7 @@ int usbnet_open (struct net_device *net)
 
        /* start any status interrupt transfer */
        if (dev->interrupt) {
-               retval = usb_submit_urb (dev->interrupt, GFP_KERNEL);
+               retval = usbnet_status_start(dev, GFP_KERNEL);
                if (retval < 0) {
                        netif_err(dev, ifup, dev->net,
                                  "intr submit %d\n", retval);
@@ -1458,6 +1522,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        dev->delay.data = (unsigned long) dev;
        init_timer (&dev->delay);
        mutex_init (&dev->phy_mutex);
+       mutex_init(&dev->interrupt_mutex);
+       dev->interrupt_count = 0;
 
        dev->net = net;
        strcpy (net->name, "usb%d");
@@ -1593,7 +1659,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
                 */
                netif_device_detach (dev->net);
                usbnet_terminate_urbs(dev);
-               usb_kill_urb(dev->interrupt);
+               __usbnet_status_stop_force(dev);
 
                /*
                 * reattach so runtime management can use and
@@ -1613,9 +1679,8 @@ int usbnet_resume (struct usb_interface *intf)
        int                     retval;
 
        if (!--dev->suspend_count) {
-               /* resume interrupt URBs */
-               if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags))
-                       usb_submit_urb(dev->interrupt, GFP_NOIO);
+               /* resume interrupt URB if it was previously submitted */
+               __usbnet_status_start_force(dev, GFP_NOIO);
 
                spin_lock_irq(&dev->txq.lock);
                while ((res = usb_get_from_anchor(&dev->deferred))) {
index 23049aeca662c7a1944daa127a2fc77c3dcd4410..d5a57a9e329c85de3e48722e8b9576f56dcea577 100644 (file)
@@ -84,13 +84,10 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
                phy = get_phy_device(mdio, addr, is_c45);
 
                if (!phy || IS_ERR(phy)) {
-                       phy = phy_device_create(mdio, addr, 0, false, NULL);
-                       if (!phy || IS_ERR(phy)) {
-                               dev_err(&mdio->dev,
-                                       "error creating PHY at address %i\n",
-                                       addr);
-                               continue;
-                       }
+                       dev_err(&mdio->dev,
+                               "cannot get PHY at address %i\n",
+                               addr);
+                       continue;
                }
 
                /* Associate the OF node with the device structure so it
index da46327fca173044b186943f8c7a044378d186cd..f18d64129f99982f966f3c2fe733cd85260dc625 100644 (file)
@@ -56,6 +56,8 @@ struct usbnet {
        struct sk_buff_head     done;
        struct sk_buff_head     rxq_pause;
        struct urb              *interrupt;
+       unsigned                interrupt_count;
+       struct mutex            interrupt_mutex;
        struct usb_anchor       deferred;
        struct tasklet_struct   bh;
 
@@ -248,4 +250,7 @@ extern int usbnet_nway_reset(struct net_device *net);
 extern int usbnet_manage_power(struct usbnet *, int);
 extern void usbnet_link_change(struct usbnet *, bool, bool);
 
+extern int usbnet_status_start(struct usbnet *dev, gfp_t mem_flags);
+extern void usbnet_status_stop(struct usbnet *dev);
+
 #endif /* __LINUX_USB_USBNET_H */
index 9ca1007edd930632e5942d2626caba02943d032a..ee6b3c442baf008cbee2037720bbbca8e1e411d5 100644 (file)
  */
 
 /* some useful defines for sb1000.c e cmconfig.c - fv */
-#define SIOCGCMSTATS           SIOCDEVPRIVATE+0        /* get cable modem stats */
-#define SIOCGCMFIRMWARE                SIOCDEVPRIVATE+1        /* get cm firmware version */
-#define SIOCGCMFREQUENCY       SIOCDEVPRIVATE+2        /* get cable modem frequency */
-#define SIOCSCMFREQUENCY       SIOCDEVPRIVATE+3        /* set cable modem frequency */
-#define SIOCGCMPIDS                    SIOCDEVPRIVATE+4        /* get cable modem PIDs */
-#define SIOCSCMPIDS                    SIOCDEVPRIVATE+5        /* set cable modem PIDs */
+#define SIOCGCMSTATS           (SIOCDEVPRIVATE+0)      /* get cable modem stats */
+#define SIOCGCMFIRMWARE                (SIOCDEVPRIVATE+1)      /* get cm firmware version */
+#define SIOCGCMFREQUENCY       (SIOCDEVPRIVATE+2)      /* get cable modem frequency */
+#define SIOCSCMFREQUENCY       (SIOCDEVPRIVATE+3)      /* set cable modem frequency */
+#define SIOCGCMPIDS                    (SIOCDEVPRIVATE+4)      /* get cable modem PIDs */
+#define SIOCSCMPIDS                    (SIOCDEVPRIVATE+5)      /* set cable modem PIDs */
 
 #endif
index 40b1fadaf637cafb12a8aece038882f8ba045274..fc1e289397f5895f3d2191ee78c9b450cc33e5cf 100644 (file)
@@ -2213,6 +2213,17 @@ __be16 skb_network_protocol(struct sk_buff *skb)
        __be16 type = skb->protocol;
        int vlan_depth = ETH_HLEN;
 
+       /* Tunnel gso handlers can set protocol to ethernet. */
+       if (type == htons(ETH_P_TEB)) {
+               struct ethhdr *eth;
+
+               if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
+                       return 0;
+
+               eth = (struct ethhdr *)skb_mac_header(skb);
+               type = eth->h_proto;
+       }
+
        while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
                struct vlan_hdr *vh;
 
index cc22363965d2a9a66d08e9368cc4e62e2ccea08a..b2e805af9b87a03675d7bac1a7e210124757e566 100644 (file)
@@ -150,13 +150,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
                csum = false;
 
        /* setup inner skb. */
-       if (greh->protocol == htons(ETH_P_TEB)) {
-               struct ethhdr *eth = (struct ethhdr *)skb_inner_mac_header(skb);
-               skb->protocol = eth->h_proto;
-       } else {
-               skb->protocol = greh->protocol;
-       }
-
+       skb->protocol = greh->protocol;
        skb->encapsulation = 0;
 
        if (unlikely(!pskb_may_pull(skb, ghl)))
index 0ae038a4c7a80929e2083911d3fc17aa5432be3f..0bf5d399a03c1c0eaedeedd4a6a9db4ee2af68e6 100644 (file)
@@ -2311,7 +2311,6 @@ static struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        int mac_len = skb->mac_len;
        int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
-       struct ethhdr *inner_eth = (struct ethhdr *)skb_inner_mac_header(skb);
        __be16 protocol = skb->protocol;
        netdev_features_t enc_features;
        int outer_hlen;
@@ -2324,8 +2323,7 @@ static struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
        skb_reset_mac_header(skb);
        skb_set_network_header(skb, skb_inner_network_offset(skb));
        skb->mac_len = skb_inner_network_offset(skb);
-       inner_eth = (struct ethhdr *)skb_mac_header(skb);
-       skb->protocol = inner_eth->h_proto;
+       skb->protocol = htons(ETH_P_TEB);
 
        /* segment inner packet. */
        enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);