]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.27 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 27 Jul 2010 22:52:50 +0000 (15:52 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 27 Jul 2010 22:52:50 +0000 (15:52 -0700)
queue-2.6.27/cifs-fix-a-kernel-bug-with-remote-os-2-server-try-3.patch [new file with mode: 0644]
queue-2.6.27/cifs-remove-bogus-first_time-check-in-ntlmv2-session-setup-code.patch [new file with mode: 0644]
queue-2.6.27/cpmac-do-not-leak-struct-net_device-on-phy_connect-errors.patch [new file with mode: 0644]
queue-2.6.27/hostap-protect-against-initialization-interrupt.patch [new file with mode: 0644]
queue-2.6.27/hwmon-coretemp-properly-label-the-sensors.patch [new file with mode: 0644]
queue-2.6.27/hwmon-coretemp-skip-duplicate-cpu-entries.patch [new file with mode: 0644]
queue-2.6.27/math-emu-correct-test-for-downshifting-fraction-in-_fp_from_int.patch [new file with mode: 0644]
queue-2.6.27/series [new file with mode: 0644]
queue-2.6.27/sky2-enable-rx-tx-in-sky2_phy_reinit.patch [new file with mode: 0644]

diff --git a/queue-2.6.27/cifs-fix-a-kernel-bug-with-remote-os-2-server-try-3.patch b/queue-2.6.27/cifs-fix-a-kernel-bug-with-remote-os-2-server-try-3.patch
new file mode 100644 (file)
index 0000000..7d30bc5
--- /dev/null
@@ -0,0 +1,67 @@
+From 6513a81e9325d712f1bfb9a1d7b750134e49ff18 Mon Sep 17 00:00:00 2001
+From: Suresh Jayaraman <sjayaraman@suse.de>
+Date: Wed, 31 Mar 2010 12:00:03 +0530
+Subject: cifs: Fix a kernel BUG with remote OS/2 server (try #3)
+
+From: Suresh Jayaraman <sjayaraman@suse.de>
+
+commit 6513a81e9325d712f1bfb9a1d7b750134e49ff18 upstream.
+
+While chasing a bug report involving a OS/2 server, I noticed the server sets
+pSMBr->CountHigh to a incorrect value even in case of normal writes. This
+results in 'nbytes' being computed wrongly and triggers a kernel BUG at
+mm/filemap.c.
+
+void iov_iter_advance(struct iov_iter *i, size_t bytes)
+{
+        BUG_ON(i->count < bytes);    <--- BUG here
+
+Why the server is setting 'CountHigh' is not clear but only does so after
+writing 64k bytes. Though this looks like the server bug, the client side
+crash may not be acceptable.
+
+The workaround is to mask off high 16 bits if the number of bytes written as
+returned by the server is greater than the bytes requested by the client as
+suggested by Jeff Layton.
+
+Reviewed-by: Jeff Layton <jlayton@samba.org>
+Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/cifssmb.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -1594,6 +1594,14 @@ CIFSSMBWrite(const int xid, struct cifsT
+               *nbytes = le16_to_cpu(pSMBr->CountHigh);
+               *nbytes = (*nbytes) << 16;
+               *nbytes += le16_to_cpu(pSMBr->Count);
++
++              /*
++               * Mask off high 16 bits when bytes written as returned by the
++               * server is greater than bytes requested by the client. Some
++               * OS/2 servers are known to set incorrect CountHigh values.
++               */
++              if (*nbytes > count)
++                      *nbytes &= 0xFFFF;
+       }
+       cifs_buf_release(pSMB);
+@@ -1679,6 +1687,14 @@ CIFSSMBWrite2(const int xid, struct cifs
+               *nbytes = le16_to_cpu(pSMBr->CountHigh);
+               *nbytes = (*nbytes) << 16;
+               *nbytes += le16_to_cpu(pSMBr->Count);
++
++              /*
++               * Mask off high 16 bits when bytes written as returned by the
++               * server is greater than bytes requested by the client. OS/2
++               * servers are known to set incorrect CountHigh values.
++               */
++              if (*nbytes > count)
++                      *nbytes &= 0xFFFF;
+       }
+ /*    cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
diff --git a/queue-2.6.27/cifs-remove-bogus-first_time-check-in-ntlmv2-session-setup-code.patch b/queue-2.6.27/cifs-remove-bogus-first_time-check-in-ntlmv2-session-setup-code.patch
new file mode 100644 (file)
index 0000000..4144036
--- /dev/null
@@ -0,0 +1,46 @@
+From 8a224d489454b7457105848610cfebebdec5638d Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Wed, 16 Jun 2010 13:40:18 -0400
+Subject: cifs: remove bogus first_time check in NTLMv2 session setup code
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 8a224d489454b7457105848610cfebebdec5638d upstream.
+
+This bug appears to be the result of a cut-and-paste mistake from the
+NTLMv1 code. The function to generate the MAC key was commented out, but
+not the conditional above it. The conditional then ended up causing the
+session setup key not to be copied to the buffer unless this was the
+first session on the socket, and that made all but the first NTLMv2
+session setup fail.
+
+Fix this by removing the conditional and all of the commented clutter
+that made it difficult to see.
+
+Reported-by: Gunther Deschner <gdeschne@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/sess.c |   10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -482,15 +482,7 @@ CIFS_SessSetup(unsigned int xid, struct
+               /* calculate session key */
+               setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
+-              if (first_time) /* should this be moved into common code
+-                                 with similar ntlmv2 path? */
+-              /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
+-                              response BB FIXME, v2_sess_key); */
+-
+-              /* copy session key */
+-
+-      /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
+-              bcc_ptr += LM2_SESS_KEY_SIZE; */
++              /* FIXME: calculate MAC key */
+               memcpy(bcc_ptr, (char *)v2_sess_key,
+                      sizeof(struct ntlmv2_resp));
+               bcc_ptr += sizeof(struct ntlmv2_resp);
diff --git a/queue-2.6.27/cpmac-do-not-leak-struct-net_device-on-phy_connect-errors.patch b/queue-2.6.27/cpmac-do-not-leak-struct-net_device-on-phy_connect-errors.patch
new file mode 100644 (file)
index 0000000..a63eb17
--- /dev/null
@@ -0,0 +1,32 @@
+From ed770f01360b392564650bf1553ce723fa46afec Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <florian@openwrt.org>
+Date: Sun, 20 Jun 2010 22:07:48 +0000
+Subject: cpmac: do not leak struct net_device on phy_connect errors
+
+From: Florian Fainelli <florian@openwrt.org>
+
+commit ed770f01360b392564650bf1553ce723fa46afec upstream.
+
+If the call to phy_connect fails, we will return directly instead of freeing
+the previously allocated struct net_device.
+
+Signed-off-by: Florian Fainelli <florian@openwrt.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/cpmac.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/cpmac.c
++++ b/drivers/net/cpmac.c
+@@ -1174,7 +1174,8 @@ static int __devinit cpmac_probe(struct
+               if (netif_msg_drv(priv))
+                       printk(KERN_ERR "%s: Could not attach to PHY\n",
+                              dev->name);
+-              return PTR_ERR(priv->phy);
++              rc = PTR_ERR(priv->phy);
++              goto fail;
+       }
+       if ((rc = register_netdev(dev))) {
diff --git a/queue-2.6.27/hostap-protect-against-initialization-interrupt.patch b/queue-2.6.27/hostap-protect-against-initialization-interrupt.patch
new file mode 100644 (file)
index 0000000..793427e
--- /dev/null
@@ -0,0 +1,104 @@
+From d6a574ff6bfb842bdb98065da053881ff527be46 Mon Sep 17 00:00:00 2001
+From: Tim Gardner <tim.gardner@canonical.com>
+Date: Tue, 8 Jun 2010 11:33:02 -0600
+Subject: hostap: Protect against initialization interrupt
+
+From: Tim Gardner <tim.gardner@canonical.com>
+
+commit d6a574ff6bfb842bdb98065da053881ff527be46 upstream.
+
+Use an irq spinlock to hold off the IRQ handler until
+enough early card init is complete such that the handler
+can run without faulting.
+
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/net/wireless/hostap/hostap_cs.c   |   10 ++++++++++
+ drivers/net/wireless/hostap/hostap_hw.c   |   13 +++++++++++++
+ drivers/net/wireless/hostap/hostap_wlan.h |    2 +-
+ 3 files changed, 24 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/hostap/hostap_cs.c
++++ b/drivers/net/wireless/hostap/hostap_cs.c
+@@ -557,6 +557,7 @@ static int prism2_config(struct pcmcia_d
+       config_info_t conf;
+       cistpl_cftable_entry_t dflt = { 0 };
+       struct hostap_cs_priv *hw_priv;
++      unsigned long flags;
+       PDEBUG(DEBUG_FLOW, "prism2_config()\n");
+@@ -688,6 +689,12 @@ static int prism2_config(struct pcmcia_d
+       link->dev_node = &hw_priv->node;
+       /*
++       * Make sure the IRQ handler cannot proceed until at least
++       * dev->base_addr is initialized.
++       */
++      spin_lock_irqsave(&local->irq_init_lock, flags);
++
++      /*
+        * Allocate an interrupt line.  Note that this does not assign a
+        * handler to the interrupt, unless the 'Handler' member of the
+        * irq structure is initialized.
+@@ -712,6 +719,8 @@ static int prism2_config(struct pcmcia_d
+       dev->irq = link->irq.AssignedIRQ;
+       dev->base_addr = link->io.BasePort1;
++      spin_unlock_irqrestore(&local->irq_init_lock, flags);
++
+       /* Finally, report what we've done */
+       printk(KERN_INFO "%s: index 0x%02x: ",
+              dev_info, link->conf.ConfigIndex);
+@@ -742,6 +751,7 @@ static int prism2_config(struct pcmcia_d
+       return ret;
+  cs_failed:
++      spin_unlock_irqrestore(&local->irq_init_lock, flags);
+       cs_error(link, last_fn, last_ret);
+  failed:
+--- a/drivers/net/wireless/hostap/hostap_hw.c
++++ b/drivers/net/wireless/hostap/hostap_hw.c
+@@ -2631,6 +2631,18 @@ static irqreturn_t prism2_interrupt(int
+       iface = netdev_priv(dev);
+       local = iface->local;
++      /* Detect early interrupt before driver is fully configued */
++      spin_lock(&local->irq_init_lock);
++      if (!dev->base_addr) {
++              if (net_ratelimit()) {
++                      printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
++                             dev->name);
++              }
++              spin_unlock(&local->irq_init_lock);
++              return IRQ_HANDLED;
++      }
++      spin_unlock(&local->irq_init_lock);
++
+       prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
+       if (local->func->card_present && !local->func->card_present(local)) {
+@@ -3187,6 +3199,7 @@ prism2_init_local_data(struct prism2_hel
+       spin_lock_init(&local->cmdlock);
+       spin_lock_init(&local->baplock);
+       spin_lock_init(&local->lock);
++      spin_lock_init(&local->irq_init_lock);
+       mutex_init(&local->rid_bap_mtx);
+       if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
+--- a/drivers/net/wireless/hostap/hostap_wlan.h
++++ b/drivers/net/wireless/hostap/hostap_wlan.h
+@@ -653,7 +653,7 @@ struct local_info {
+       rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
+                             * when removing entries from the list.
+                             * TX and RX paths can use read lock. */
+-      spinlock_t cmdlock, baplock, lock;
++      spinlock_t cmdlock, baplock, lock, irq_init_lock;
+       struct mutex rid_bap_mtx;
+       u16 infofid; /* MAC buffer id for info frame */
+       /* txfid, intransmitfid, next_txtid, and next_alloc are protected by
diff --git a/queue-2.6.27/hwmon-coretemp-properly-label-the-sensors.patch b/queue-2.6.27/hwmon-coretemp-properly-label-the-sensors.patch
new file mode 100644 (file)
index 0000000..1e9d474
--- /dev/null
@@ -0,0 +1,50 @@
+From 3f4f09b4be35d38d6e2bf22c989443e65e70fc4c Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Fri, 9 Jul 2010 16:22:51 +0200
+Subject: hwmon: (coretemp) Properly label the sensors
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit 3f4f09b4be35d38d6e2bf22c989443e65e70fc4c upstream.
+
+Don't assume that CPU entry number and core ID always match. It
+worked in the simple cases (single CPU, no HT) but fails on
+multi-CPU systems.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Huaxu Wan <huaxu.wan@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/coretemp.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -52,6 +52,7 @@ struct coretemp_data {
+       struct mutex update_lock;
+       const char *name;
+       u32 id;
++      u16 core_id;
+       char valid;             /* zero until following fields are valid */
+       unsigned long last_updated;     /* in jiffies */
+       int temp;
+@@ -74,7 +75,7 @@ static ssize_t show_name(struct device *
+       if (attr->index == SHOW_NAME)
+               ret = sprintf(buf, "%s\n", data->name);
+       else    /* show label */
+-              ret = sprintf(buf, "Core %d\n", data->id);
++              ret = sprintf(buf, "Core %d\n", data->core_id);
+       return ret;
+ }
+@@ -216,6 +217,9 @@ static int __devinit coretemp_probe(stru
+       }
+       data->id = pdev->id;
++#ifdef CONFIG_SMP
++      data->core_id = c->cpu_core_id;
++#endif
+       data->name = "coretemp";
+       mutex_init(&data->update_lock);
diff --git a/queue-2.6.27/hwmon-coretemp-skip-duplicate-cpu-entries.patch b/queue-2.6.27/hwmon-coretemp-skip-duplicate-cpu-entries.patch
new file mode 100644 (file)
index 0000000..e820b94
--- /dev/null
@@ -0,0 +1,76 @@
+From d883b9f0977269d519469da72faec6a7f72cb489 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Fri, 9 Jul 2010 16:22:49 +0200
+Subject: hwmon: (coretemp) Skip duplicate CPU entries
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit d883b9f0977269d519469da72faec6a7f72cb489 upstream.
+
+On hyper-threaded CPUs, each core appears twice in the CPU list. Skip
+the second entry to avoid duplicate sensors.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Huaxu Wan <huaxu.wan@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/coretemp.c |   26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -317,6 +317,10 @@ struct pdev_entry {
+       struct list_head list;
+       struct platform_device *pdev;
+       unsigned int cpu;
++#ifdef CONFIG_SMP
++      u16 phys_proc_id;
++      u16 cpu_core_id;
++#endif
+ };
+ static LIST_HEAD(pdev_list);
+@@ -327,6 +331,22 @@ static int __cpuinit coretemp_device_add
+       int err;
+       struct platform_device *pdev;
+       struct pdev_entry *pdev_entry;
++#ifdef CONFIG_SMP
++      struct cpuinfo_x86 *c = &cpu_data(cpu);
++#endif
++
++      mutex_lock(&pdev_list_mutex);
++
++#ifdef CONFIG_SMP
++      /* Skip second HT entry of each core */
++      list_for_each_entry(pdev_entry, &pdev_list, list) {
++              if (c->phys_proc_id == pdev_entry->phys_proc_id &&
++                  c->cpu_core_id == pdev_entry->cpu_core_id) {
++                      err = 0;        /* Not an error */
++                      goto exit;
++              }
++      }
++#endif
+       pdev = platform_device_alloc(DRVNAME, cpu);
+       if (!pdev) {
+@@ -350,7 +370,10 @@ static int __cpuinit coretemp_device_add
+       pdev_entry->pdev = pdev;
+       pdev_entry->cpu = cpu;
+-      mutex_lock(&pdev_list_mutex);
++#ifdef CONFIG_SMP
++      pdev_entry->phys_proc_id = c->phys_proc_id;
++      pdev_entry->cpu_core_id = c->cpu_core_id;
++#endif
+       list_add_tail(&pdev_entry->list, &pdev_list);
+       mutex_unlock(&pdev_list_mutex);
+@@ -361,6 +384,7 @@ exit_device_free:
+ exit_device_put:
+       platform_device_put(pdev);
+ exit:
++      mutex_unlock(&pdev_list_mutex);
+       return err;
+ }
diff --git a/queue-2.6.27/math-emu-correct-test-for-downshifting-fraction-in-_fp_from_int.patch b/queue-2.6.27/math-emu-correct-test-for-downshifting-fraction-in-_fp_from_int.patch
new file mode 100644 (file)
index 0000000..c95eb2a
--- /dev/null
@@ -0,0 +1,56 @@
+From f8324e20f8289dffc646d64366332e05eaacab25 Mon Sep 17 00:00:00 2001
+From: Mikael Pettersson <mikpe@it.uu.se>
+Date: Tue, 20 Jul 2010 18:45:14 -0700
+Subject: math-emu: correct test for downshifting fraction in _FP_FROM_INT()
+
+From: Mikael Pettersson <mikpe@it.uu.se>
+
+commit f8324e20f8289dffc646d64366332e05eaacab25 upstream.
+
+The kernel's math-emu code contains a macro _FP_FROM_INT() which is
+used to convert an integer to a raw normalized floating-point value.
+It does this basically in three steps:
+
+1. Compute the exponent from the number of leading zero bits.
+2. Downshift large fractions to put the MSB in the right position
+   for normalized fractions.
+3. Upshift small fractions to put the MSB in the right position.
+
+There is an boundary error in step 2, causing a fraction with its
+MSB exactly one bit above the normalized MSB position to not be
+downshifted.  This results in a non-normalized raw float, which when
+packed becomes a massively inaccurate representation for that input.
+
+The impact of this depends on a number of arch-specific factors,
+but it is known to have broken emulation of FXTOD instructions
+on UltraSPARC III, which was originally reported as GCC bug 44631
+<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44631>.
+
+Any arch which uses math-emu to emulate conversions from integers to
+same-size floats may be affected.
+
+The fix is simple: the exponent comparison used to determine if the
+fraction should be downshifted must be "<=" not "<".
+
+I'm sending a kernel module to test this as a reply to this message.
+There are also SPARC user-space test cases in the GCC bug entry.
+
+Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/math-emu/op-common.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/math-emu/op-common.h
++++ b/include/math-emu/op-common.h
+@@ -793,7 +793,7 @@ do {                                                                       \
+               X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
+       X##_e = rsize - X##_e - 1;                                      \
+                                                                       \
+-      if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)    \
++      if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e)   \
+         __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
+       _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);                       \
+       if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)                       \
diff --git a/queue-2.6.27/series b/queue-2.6.27/series
new file mode 100644 (file)
index 0000000..9c36795
--- /dev/null
@@ -0,0 +1,8 @@
+hwmon-coretemp-properly-label-the-sensors.patch
+hwmon-coretemp-skip-duplicate-cpu-entries.patch
+cifs-remove-bogus-first_time-check-in-ntlmv2-session-setup-code.patch
+cifs-fix-a-kernel-bug-with-remote-os-2-server-try-3.patch
+cpmac-do-not-leak-struct-net_device-on-phy_connect-errors.patch
+sky2-enable-rx-tx-in-sky2_phy_reinit.patch
+math-emu-correct-test-for-downshifting-fraction-in-_fp_from_int.patch
+hostap-protect-against-initialization-interrupt.patch
diff --git a/queue-2.6.27/sky2-enable-rx-tx-in-sky2_phy_reinit.patch b/queue-2.6.27/sky2-enable-rx-tx-in-sky2_phy_reinit.patch
new file mode 100644 (file)
index 0000000..ae69ec5
--- /dev/null
@@ -0,0 +1,80 @@
+From 38000a94a902e94ca8b5498f7871c6316de8957a Mon Sep 17 00:00:00 2001
+From: Brandon Philips <brandon@ifup.org>
+Date: Wed, 16 Jun 2010 16:21:58 +0000
+Subject: sky2: enable rx/tx in sky2_phy_reinit()
+
+From: Brandon Philips <brandon@ifup.org>
+
+commit 38000a94a902e94ca8b5498f7871c6316de8957a upstream.
+
+sky2_phy_reinit is called by the ethtool helpers sky2_set_settings,
+sky2_nway_reset and sky2_set_pauseparam when netif_running.
+
+However, at the end of sky2_phy_init GM_GP_CTRL has GM_GPCR_RX_ENA and
+GM_GPCR_TX_ENA cleared. So, doing these commands causes the device to
+stop working:
+
+$ ethtool -r eth0
+$ ethtool -A eth0 autoneg off
+
+Fix this issue by enabling Rx/Tx after running sky2_phy_init in
+sky2_phy_reinit.
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+Tested-by: Brandon Philips <bphilips@suse.de>
+Cc: stable@kernel.org
+Tested-by: Mike McCormack <mikem@ring3k.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/sky2.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -688,11 +688,24 @@ static void sky2_phy_power_down(struct s
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+ }
++/* Enable Rx/Tx */
++static void sky2_enable_rx_tx(struct sky2_port *sky2)
++{
++      struct sky2_hw *hw = sky2->hw;
++      unsigned port = sky2->port;
++      u16 reg;
++
++      reg = gma_read16(hw, port, GM_GP_CTRL);
++      reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
++      gma_write16(hw, port, GM_GP_CTRL, reg);
++}
++
+ /* Force a renegotiation */
+ static void sky2_phy_reinit(struct sky2_port *sky2)
+ {
+       spin_lock_bh(&sky2->phy_lock);
+       sky2_phy_init(sky2->hw, sky2->port);
++      sky2_enable_rx_tx(sky2);
+       spin_unlock_bh(&sky2->phy_lock);
+ }
+@@ -1862,7 +1875,6 @@ static void sky2_link_up(struct sky2_por
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+-      u16 reg;
+       static const char *fc_name[] = {
+               [FC_NONE]       = "none",
+               [FC_TX]         = "tx",
+@@ -1870,10 +1882,7 @@ static void sky2_link_up(struct sky2_por
+               [FC_BOTH]       = "both",
+       };
+-      /* enable Rx/Tx */
+-      reg = gma_read16(hw, port, GM_GP_CTRL);
+-      reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+-      gma_write16(hw, port, GM_GP_CTRL, reg);
++      sky2_enable_rx_tx(sky2);
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);