/**
* This file contains functions used in USB interface module.
*/
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/usb.h>
#ifdef CONFIG_OLPC
#include <asm/olpc.h>
#endif
#define DRV_NAME "usb8xxx"
#include "host.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
#include "cmd.h"
#include "if_usb.h"
#define INSANEDEBUG 0
#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
#define MESSAGE_HEADER_LEN 4
static char *lbs_fw_name = "usb8388.bin";
module_param_named(fw_name, lbs_fw_name, charp, 0644);
static struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
{ USB_DEVICE(0x1286, 0x2001) },
{ USB_DEVICE(0x05a3, 0x8388) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, if_usb_table);
static void if_usb_receive(struct urb *urb);
static void if_usb_receive_fwload(struct urb *urb);
static int __if_usb_prog_firmware(struct if_usb_card *cardp,
const char *fwname, int cmd);
static int if_usb_prog_firmware(struct if_usb_card *cardp,
const char *fwname, int cmd);
static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
uint8_t *payload, uint16_t nb);
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
uint16_t nb);
static void if_usb_free(struct if_usb_card *cardp);
static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
static int if_usb_reset_device(struct if_usb_card *cardp);
/* sysfs hooks */
/**
* Set function to write firmware to device's persistent memory
*/
static ssize_t if_usb_firmware_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
int ret;
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
if (ret == 0)
return count;
return ret;
}
/**
* lbs_flash_fw attribute to be exported per ethX interface through sysfs
* (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to
* the device's persistent memory:
* echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_fw
*/
static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
/**
* Set function to write firmware to device's persistent memory
*/
static ssize_t if_usb_boot2_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
int ret;
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
if (ret == 0)
return count;
return ret;
}
/**
* lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
* (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware
* to the device's persistent memory:
* echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_boot2
*/
static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
/**
* @brief call back function to handle the status of the URB
* @param urb pointer to urb structure
* @return N/A
*/
static void if_usb_write_bulk_callback(struct urb *urb)
{
struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
/* handle the transmission complete validations */
if (urb->status == 0) {
struct lbs_private *priv = cardp->priv;
lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
lbs_deb_usb2(&urb