5 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include <linux/module.h>
10 #include <linux/netdevice.h>
11 #include <linux/slab.h>
19 #define DRV_NAME "usb8xxx"
29 #define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
31 #define MESSAGE_HEADER_LEN 4
57 { USB_DEVICE(0x1286, 0x2001), .driver_info =
MODEL_8388 },
58 { USB_DEVICE(0x05a3, 0x8388), .driver_info =
MODEL_8388 },
64 static void if_usb_receive(
struct urb *
urb);
65 static void if_usb_receive_fwload(
struct urb *
urb);
74 static int if_usb_submit_rx_urb(
struct if_usb_card *cardp);
75 static int if_usb_reset_device(
struct if_usb_card *cardp);
83 static void if_usb_write_bulk_callback(
struct urb *
urb)
89 if (urb->status == 0) {
92 lbs_deb_usb2(&urb->dev->dev,
"URB status is successful\n");
93 lbs_deb_usb2(&urb->dev->dev,
"Actual length transmitted %d\n",
103 pr_info(
"URB in failure status: %d\n", urb->status);
150 wake_method.hdr.size =
cpu_to_le16(
sizeof(wake_method));
153 netdev_info(priv->
dev,
"Firmware does not seem to support PS mode\n");
157 lbs_deb_usb(
"Firmware seems to support PS with wake-via-command\n");
162 netdev_info(priv->
dev,
163 "Firmware doesn't wake via command interrupt; disabling PS mode\n");
168 static void if_usb_fw_timeo(
unsigned long priv)
173 lbs_deb_usb(
"Download complete, no event. Assuming success\n");
175 pr_err(
"Download timed out\n");
182 static void if_usb_reset_olpc_card(
struct lbs_private *priv)
198 struct usb_device *
udev;
199 struct usb_host_interface *iface_desc;
206 udev = interface_to_usbdev(intf);
217 iface_desc = intf->cur_altsetting;
219 lbs_deb_usbd(&udev->dev,
"bcdUSB = 0x%X bDeviceClass = 0x%X"
220 " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
222 udev->descriptor.bDeviceClass,
223 udev->descriptor.bDeviceSubClass,
224 udev->descriptor.bDeviceProtocol);
226 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++
i) {
227 endpoint = &iface_desc->endpoint[
i].desc;
228 if (usb_endpoint_is_bulk_in(endpoint)) {
230 cardp->
ep_in = usb_endpoint_num(endpoint);
235 }
else if (usb_endpoint_is_bulk_out(endpoint)) {
237 cardp->
ep_out = usb_endpoint_num(endpoint);
257 lbs_deb_usbd(&udev->dev,
"Could not allocate buffer\n");
271 if (machine_is_olpc())
278 usb_set_intfdata(intf, cardp);
281 fw_table, if_usb_prog_firmware);
290 if_usb_reset_device(cardp);
305 struct if_usb_card *cardp = usb_get_intfdata(intf);
320 usb_set_intfdata(intf,
NULL);
331 static int if_usb_send_fw_pkt(
struct if_usb_card *cardp)
365 usb_tx_block(cardp, cardp->
ep_out_buf,
sizeof(
struct fwdata) +
385 static int if_usb_reset_device(
struct if_usb_card *cardp)
405 if (ret && machine_is_olpc())
406 if_usb_reset_olpc_card(
NULL);
433 usb_sndbulkpipe(cardp->
udev,
435 payload, nb, if_usb_write_bulk_callback, cardp);
437 cardp->
tx_urb->transfer_flags |= URB_ZERO_PACKET;
450 static int __if_usb_submit_rx_urb(
struct if_usb_card *cardp,
451 void (*callbackfn)(
struct urb *urb))
465 usb_rcvbulkpipe(cardp->
udev, cardp->
ep_in),
470 cardp->
rx_urb->transfer_flags |= URB_ZERO_PACKET;
487 static int if_usb_submit_rx_urb_fwload(
struct if_usb_card *cardp)
489 return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
492 static int if_usb_submit_rx_urb(
struct if_usb_card *cardp)
494 return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
497 static void if_usb_receive_fwload(
struct urb *urb)
506 "URB status is failed during fw load\n");
516 pr_info(
"Firmware ready event received\n");
519 lbs_deb_usb(
"Waiting for confirmation; got %x %x\n",
521 if_usb_submit_rx_urb_fwload(cardp);
532 if_usb_submit_rx_urb_fwload(cardp);
535 "Received valid boot command response\n");
543 pr_info(
"Firmware already seems alive; resetting\n");
546 pr_info(
"boot cmd response wrong magic number (0x%x)\n",
552 pr_info(
"boot cmd response cmd_tag error (%d)\n",
555 pr_info(
"boot cmd response result error (%d)\n",
560 "Received valid boot command response\n");
563 if_usb_submit_rx_urb_fwload(cardp);
575 if (!syncfwheader->
cmd) {
595 if_usb_send_fw_pkt(cardp);
598 if_usb_submit_rx_urb_fwload(cardp);
603 #define MRVDRV_MIN_PKT_LEN 30
605 static inline void process_cmdtypedata(
int recvlength,
struct sk_buff *skb,
623 static inline void process_cmdrequest(
int recvlength,
uint8_t *recvbuff,
632 "The receive buffer is too large\n");
652 "Wake up main thread to handle cmd response\n");
662 static void if_usb_receive(
struct urb *urb)
667 int recvlength = urb->actual_length;
686 "Recv length = 0x%x, Recv type = 0x%X\n",
687 recvlength, recvtype);
688 }
else if (urb->status) {
695 process_cmdtypedata(recvlength, skb, cardp, priv);
699 process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
709 if (event & 0xffff0000) {
710 u32 trycount = (
event & 0xffff0000) >> 16;
725 if_usb_submit_rx_urb(cardp);
766 static int if_usb_issue_boot_command(
struct if_usb_card *cardp,
int ivalue)
772 bootcmd->
cmd = ivalue;
776 usb_tx_block(cardp, cardp->
ep_out_buf,
sizeof(*bootcmd));
799 struct fwheader *fwh = (
void *)data;
805 offset =
sizeof(
struct fwheader) + blksize;
822 pr_err(
"firmware file format check FAIL\n");
824 lbs_deb_fw(
"firmware file format check PASS\n");
829 static void if_usb_prog_firmware(
struct lbs_private *priv,
int ret,
830 const struct firmware *
fw,
831 const struct firmware *
unused)
835 static int reset_count = 10;
840 pr_err(
"failed to find firmware (%d)\n", ret);
845 if (check_fwfile_format(cardp->
fw->data, cardp->
fw->size)) {
861 if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
884 if (if_usb_submit_rx_urb(cardp) < 0)
888 if (--reset_count >= 0) {
889 if_usb_reset_device(cardp);
907 if_usb_send_fw_pkt(cardp);
916 pr_info(
"failed to load fw, resetting device!\n");
917 if (--reset_count >= 0) {
918 if_usb_reset_device(cardp);
922 pr_info(
"FW download failure, time = %d ms\n", i * 100);
927 cardp->
priv->fw_ready = 1;
928 if_usb_submit_rx_urb(cardp);
933 if_usb_setup_firmware(priv);
954 struct if_usb_card *cardp = usb_get_intfdata(intf);
966 if (machine_is_olpc()) {
989 struct if_usb_card *cardp = usb_get_intfdata(intf);
994 if_usb_submit_rx_urb(cardp);
1002 #define if_usb_suspend NULL
1003 #define if_usb_resume NULL
1006 static struct usb_driver if_usb_driver = {
1008 .probe = if_usb_probe,
1009 .disconnect = if_usb_disconnect,
1010 .id_table = if_usb_table,
1014 .disable_hub_initiated_lpm = 1,
1020 MODULE_AUTHOR(
"Marvell International Ltd. and Red Hat, Inc.");