aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/usb.c
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2011-11-17 13:14:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-21 16:20:45 -0500
commitff6ff96b5ba5b39f7ab3d8ea0cf9ec414452ac92 (patch)
treead1c3294691a2860f9b8205ece269a1b36ac2f77 /drivers/net/wireless/rtlwifi/usb.c
parent040a72785cf19fd8032f24d584ee305158c87ac7 (diff)
rtlwifi: rtl8192cu: Change firmware upload to use block writes
Driver rtl8192cu writes the firmware with 32-bit asynchronous writes. This design is OK for USB 2.0 adapters, but the current implementation of xhcu-hcd has a limited ring size, which is exceeded. By converting to synchronous block writes, this error is avoided. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/usb.c')
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 209105c8e3dc..a461822c05b3 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -40,7 +40,6 @@
40#define REALTEK_USB_VENQT_CMD_REQ 0x05 40#define REALTEK_USB_VENQT_CMD_REQ 0x05
41#define REALTEK_USB_VENQT_CMD_IDX 0x00 41#define REALTEK_USB_VENQT_CMD_IDX 0x00
42 42
43#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254
44#define MAX_USBCTRL_VENDORREQ_TIMES 10 43#define MAX_USBCTRL_VENDORREQ_TIMES 10
45 44
46static void usbctrl_async_callback(struct urb *urb) 45static void usbctrl_async_callback(struct urb *urb)
@@ -203,6 +202,30 @@ static void _usb_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val)
203 _usb_write_async(to_usb_device(dev), addr, val, 4); 202 _usb_write_async(to_usb_device(dev), addr, val, 4);
204} 203}
205 204
205static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data,
206 u16 len)
207{
208 struct device *dev = rtlpriv->io.dev;
209 struct usb_device *udev = to_usb_device(dev);
210 u8 request = REALTEK_USB_VENQT_CMD_REQ;
211 u8 reqtype = REALTEK_USB_VENQT_WRITE;
212 u16 wvalue;
213 u16 index = REALTEK_USB_VENQT_CMD_IDX;
214 int pipe = usb_sndctrlpipe(udev, 0); /* write_out */
215 u8 *buffer;
216 dma_addr_t dma_addr;
217
218 wvalue = (u16)(addr&0x0000ffff);
219 buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr);
220 if (!buffer)
221 return;
222 memcpy(buffer, data, len);
223 usb_control_msg(udev, pipe, request, reqtype, wvalue,
224 index, buffer, len, 50);
225
226 usb_free_coherent(udev, (size_t)len, buffer, dma_addr);
227}
228
206static void _rtl_usb_io_handler_init(struct device *dev, 229static void _rtl_usb_io_handler_init(struct device *dev,
207 struct ieee80211_hw *hw) 230 struct ieee80211_hw *hw)
208{ 231{
@@ -216,6 +239,7 @@ static void _rtl_usb_io_handler_init(struct device *dev,
216 rtlpriv->io.read8_sync = _usb_read8_sync; 239 rtlpriv->io.read8_sync = _usb_read8_sync;
217 rtlpriv->io.read16_sync = _usb_read16_sync; 240 rtlpriv->io.read16_sync = _usb_read16_sync;
218 rtlpriv->io.read32_sync = _usb_read32_sync; 241 rtlpriv->io.read32_sync = _usb_read32_sync;
242 rtlpriv->io.writeN_sync = _usb_writeN_sync;
219} 243}
220 244
221static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw) 245static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw)