/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#include "wifi.h"
#include "core.h"
#include "usb.h"
#include "base.h"
#include "ps.h"
#include "rtl8192c/fw_common.h"
#include <linux/export.h>
#include <linux/module.h>
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("USB basic driver for rtlwifi");
#define REALTEK_USB_VENQT_READ 0xC0
#define REALTEK_USB_VENQT_WRITE 0x40
#define REALTEK_USB_VENQT_CMD_REQ 0x05
#define REALTEK_USB_VENQT_CMD_IDX 0x00
#define MAX_USBCTRL_VENDORREQ_TIMES 10
static void usbctrl_async_callback(struct urb *urb)
{
if (urb) {
/* free dr */
kfree(urb->setup_packet);
/* free databuf */
kfree(urb->transfer_buffer);
}
}
static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
u16 value, u16 index, void *pdata,
u16 len)
{
int rc;
unsigned int pipe;
u8 reqtype;
struct usb_ctrlrequest *dr;
struct urb *urb;
const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
u8 *databuf;
if (WARN_ON_ONCE(len > databuf_maxlen))
len = databuf_maxlen;
pipe = usb_sndctrlpipe(udev, 0); /* write_out */
reqtype = REALTEK_USB_VENQT_WRITE;
dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
if (!dr)
return -ENOMEM;
databuf = kzalloc(databuf_maxlen, GFP_ATOMIC);
if (!databuf) {
kfree(dr);
return -ENOMEM;
}
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
kfree(databuf);
kfree(dr);
return -ENOMEM;
}
dr->bRequestType = reqtype;
dr->bRequest = request;
dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(len);
/* data are already in little-endian order */
memcpy(databuf, pdata, len);
usb_fill_control_urb(urb, udev, pipe,
(unsigned char *)dr, databuf, len,
usbctrl_async_callback, NULL);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
kfree(databuf);
kfree(dr);
}
usb_free_urb(urb);
return rc;
}
static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
u16 value, u16 index, void *pdata,
u16 len)
{
unsigned int pipe;
int status;
u8 reqtype;
int vendorreq_times = 0;
static int count;
pipe = usb_rcvctrlpipe(u