--- /dev/null
+From a5ffbe0a1993a27072742ef7db6cf9839956fce9 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sat, 2 Feb 2013 15:55:00 -0600
+Subject: rtlwifi: Fix scheduling while atomic bug
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit a5ffbe0a1993a27072742ef7db6cf9839956fce9 upstream.
+
+Kernel commits 41affd5 and 6539306 changed the locking in rtl_lps_leave()
+from a spinlock to a mutex by doing the calls indirectly from a work queue
+to reduce the time that interrupts were disabled. This change was fine for
+most systems; however a scheduling while atomic bug was reported in
+https://bugzilla.redhat.com/show_bug.cgi?id=903881. The backtrace indicates
+that routine rtl_is_special(), which calls rtl_lps_leave() in three places
+was entered in atomic context. These direct calls are replaced by putting a
+request on the appropriate work queue.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Reported-and-tested-by: Nathaniel Doherty <ntdoherty@gmail.com>
+Cc: Nathaniel Doherty <ntdoherty@gmail.com>
+Cc: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/base.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/base.c
++++ b/drivers/net/wireless/rtlwifi/base.c
+@@ -980,7 +980,8 @@ u8 rtl_is_special_data(struct ieee80211_
+ is_tx ? "Tx" : "Rx");
+
+ if (is_tx) {
+- rtl_lps_leave(hw);
++ schedule_work(&rtlpriv->
++ works.lps_leave_work);
+ ppsc->last_delaylps_stamp_jiffies =
+ jiffies;
+ }
+@@ -990,7 +991,7 @@ u8 rtl_is_special_data(struct ieee80211_
+ }
+ } else if (ETH_P_ARP == ether_type) {
+ if (is_tx) {
+- rtl_lps_leave(hw);
++ schedule_work(&rtlpriv->works.lps_leave_work);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
+@@ -1000,7 +1001,7 @@ u8 rtl_is_special_data(struct ieee80211_
+ "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
+
+ if (is_tx) {
+- rtl_lps_leave(hw);
++ schedule_work(&rtlpriv->works.lps_leave_work);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
--- /dev/null
+From 0a06ad8e3a1cb5311b7dbafde45410aa1bce9d40 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sun, 27 Jan 2013 16:24:25 -0600
+Subject: rtlwifi: Fix the usage of the wrong variable in usb.c
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 0a06ad8e3a1cb5311b7dbafde45410aa1bce9d40 upstream.
+
+In routine _rtl_rx_pre_process(), skb_dequeue() is called to get an skb;
+however, the wrong variable name is used in subsequent calls.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/usb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/usb.c
++++ b/drivers/net/wireless/rtlwifi/usb.c
+@@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct i
+ WARN_ON(skb_queue_empty(&rx_queue));
+ while (!skb_queue_empty(&rx_queue)) {
+ _skb = skb_dequeue(&rx_queue);
+- _rtl_usb_rx_process_agg(hw, skb);
+- ieee80211_rx_irqsafe(hw, skb);
++ _rtl_usb_rx_process_agg(hw, _skb);
++ ieee80211_rx_irqsafe(hw, _skb);
+ }
+ }
+