109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f988d640SKalle Valo /*
3f988d640SKalle Valo * This file contains functions used in USB interface module.
4f988d640SKalle Valo */
5f988d640SKalle Valo
6f988d640SKalle Valo #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7f988d640SKalle Valo
8f988d640SKalle Valo #include <linux/delay.h>
9f988d640SKalle Valo #include <linux/module.h>
10f988d640SKalle Valo #include <linux/firmware.h>
11f988d640SKalle Valo #include <linux/netdevice.h>
12f988d640SKalle Valo #include <linux/slab.h>
13f988d640SKalle Valo #include <linux/usb.h>
14f988d640SKalle Valo #include <linux/olpc-ec.h>
15f988d640SKalle Valo
16f988d640SKalle Valo #ifdef CONFIG_OLPC
17f988d640SKalle Valo #include <asm/olpc.h>
18f988d640SKalle Valo #endif
19f988d640SKalle Valo
20f988d640SKalle Valo #define DRV_NAME "usb8xxx"
21f988d640SKalle Valo
22f988d640SKalle Valo #include "host.h"
23f988d640SKalle Valo #include "decl.h"
24f988d640SKalle Valo #include "defs.h"
25f988d640SKalle Valo #include "dev.h"
26f988d640SKalle Valo #include "cmd.h"
27f988d640SKalle Valo #include "if_usb.h"
28f988d640SKalle Valo
29f988d640SKalle Valo #define INSANEDEBUG 0
30f988d640SKalle Valo #define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
31f988d640SKalle Valo
32f988d640SKalle Valo #define MESSAGE_HEADER_LEN 4
33f988d640SKalle Valo
34f988d640SKalle Valo MODULE_FIRMWARE("libertas/usb8388_v9.bin");
35f988d640SKalle Valo MODULE_FIRMWARE("libertas/usb8388_v5.bin");
36f988d640SKalle Valo MODULE_FIRMWARE("libertas/usb8388.bin");
37f988d640SKalle Valo MODULE_FIRMWARE("libertas/usb8682.bin");
38f988d640SKalle Valo MODULE_FIRMWARE("usb8388.bin");
39f988d640SKalle Valo
40f988d640SKalle Valo enum {
41f988d640SKalle Valo MODEL_UNKNOWN = 0x0,
42f988d640SKalle Valo MODEL_8388 = 0x1,
43f988d640SKalle Valo MODEL_8682 = 0x2
44f988d640SKalle Valo };
45f988d640SKalle Valo
46f988d640SKalle Valo /* table of firmware file names */
47f988d640SKalle Valo static const struct lbs_fw_table fw_table[] = {
48f988d640SKalle Valo { MODEL_8388, "libertas/usb8388_olpc.bin", NULL },
49f988d640SKalle Valo { MODEL_8388, "libertas/usb8388_v9.bin", NULL },
50f988d640SKalle Valo { MODEL_8388, "libertas/usb8388_v5.bin", NULL },
51f988d640SKalle Valo { MODEL_8388, "libertas/usb8388.bin", NULL },
52f988d640SKalle Valo { MODEL_8388, "usb8388.bin", NULL },
53764f3f1eSKevin Easton { MODEL_8682, "libertas/usb8682.bin", NULL },
54764f3f1eSKevin Easton { 0, NULL, NULL }
55f988d640SKalle Valo };
56f988d640SKalle Valo
573673c417SArvind Yadav static const struct usb_device_id if_usb_table[] = {
58f988d640SKalle Valo /* Enter the device signature inside */
59f988d640SKalle Valo { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
60f988d640SKalle Valo { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
61f988d640SKalle Valo {} /* Terminating entry */
62f988d640SKalle Valo };
63f988d640SKalle Valo
64f988d640SKalle Valo MODULE_DEVICE_TABLE(usb, if_usb_table);
65f988d640SKalle Valo
66f988d640SKalle Valo static void if_usb_receive(struct urb *urb);
67f988d640SKalle Valo static void if_usb_receive_fwload(struct urb *urb);
68f988d640SKalle Valo static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
69f988d640SKalle Valo const struct firmware *fw,
70f988d640SKalle Valo const struct firmware *unused);
71f988d640SKalle Valo static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
72f988d640SKalle Valo uint8_t *payload, uint16_t nb);
73f988d640SKalle Valo static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
74f988d640SKalle Valo uint16_t nb);
75f988d640SKalle Valo static void if_usb_free(struct if_usb_card *cardp);
76f988d640SKalle Valo static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
77f988d640SKalle Valo static int if_usb_reset_device(struct if_usb_card *cardp);
78f988d640SKalle Valo
79f988d640SKalle Valo /**
80f988d640SKalle Valo * if_usb_write_bulk_callback - callback function to handle the status
81f988d640SKalle Valo * of the URB
82f988d640SKalle Valo * @urb: pointer to &urb structure
83f988d640SKalle Valo * returns: N/A
84f988d640SKalle Valo */
if_usb_write_bulk_callback(struct urb * urb)85f988d640SKalle Valo static void if_usb_write_bulk_callback(struct urb *urb)
86f988d640SKalle Valo {
87f988d640SKalle Valo struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
88f988d640SKalle Valo
89f988d640SKalle Valo /* handle the transmission complete validations */
90f988d640SKalle Valo
91f988d640SKalle Valo if (urb->status == 0) {
92f988d640SKalle Valo struct lbs_private *priv = cardp->priv;
93f988d640SKalle Valo
94f988d640SKalle Valo lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
95f988d640SKalle Valo lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
96f988d640SKalle Valo urb->actual_length);
97f988d640SKalle Valo
98f988d640SKalle Valo /* Boot commands such as UPDATE_FW and UPDATE_BOOT2 are not
99f988d640SKalle Valo * passed up to the lbs level.
100f988d640SKalle Valo */
101f988d640SKalle Valo if (priv && priv->dnld_sent != DNLD_BOOTCMD_SENT)
102f988d640SKalle Valo lbs_host_to_card_done(priv);
103f988d640SKalle Valo } else {
104f988d640SKalle Valo /* print the failure status number for debug */
105f988d640SKalle Valo pr_info("URB in failure status: %d\n", urb->status);
106f988d640SKalle Valo }
107f988d640SKalle Valo }
108f988d640SKalle Valo
109f988d640SKalle Valo /**
110f988d640SKalle Valo * if_usb_free - free tx/rx urb, skb and rx buffer
111f988d640SKalle Valo * @cardp: pointer to &if_usb_card
112f988d640SKalle Valo * returns: N/A
113f988d640SKalle Valo */
if_usb_free(struct if_usb_card * cardp)114f988d640SKalle Valo static void if_usb_free(struct if_usb_card *cardp)
115f988d640SKalle Valo {
116f988d640SKalle Valo /* Unlink tx & rx urb */
117f988d640SKalle Valo usb_kill_urb(cardp->tx_urb);
118f988d640SKalle Valo usb_kill_urb(cardp->rx_urb);
119f988d640SKalle Valo
120f988d640SKalle Valo usb_free_urb(cardp->tx_urb);
121f988d640SKalle Valo cardp->tx_urb = NULL;
122f988d640SKalle Valo
123f988d640SKalle Valo usb_free_urb(cardp->rx_urb);
124f988d640SKalle Valo cardp->rx_urb = NULL;
125f988d640SKalle Valo
126f988d640SKalle Valo kfree(cardp->ep_out_buf);
127f988d640SKalle Valo cardp->ep_out_buf = NULL;
128f988d640SKalle Valo }
129f988d640SKalle Valo
if_usb_setup_firmware(struct lbs_private * priv)130f988d640SKalle Valo static void if_usb_setup_firmware(struct lbs_private *priv)
131f988d640SKalle Valo {
132f988d640SKalle Valo struct if_usb_card *cardp = priv->card;
133f988d640SKalle Valo struct cmd_ds_set_boot2_ver b2_cmd;
134f988d640SKalle Valo struct cmd_ds_802_11_fw_wake_method wake_method;
135f988d640SKalle Valo
136f988d640SKalle Valo b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
137f988d640SKalle Valo b2_cmd.action = 0;
138f988d640SKalle Valo b2_cmd.version = cardp->boot2_version;
139f988d640SKalle Valo
140f988d640SKalle Valo if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
141f988d640SKalle Valo lbs_deb_usb("Setting boot2 version failed\n");
142f988d640SKalle Valo
143f988d640SKalle Valo priv->wol_gpio = 2; /* Wake via GPIO2... */
144f988d640SKalle Valo priv->wol_gap = 20; /* ... after 20ms */
145f988d640SKalle Valo lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
146f988d640SKalle Valo (struct wol_config *) NULL);
147f988d640SKalle Valo
148f988d640SKalle Valo wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
149f988d640SKalle Valo wake_method.action = cpu_to_le16(CMD_ACT_GET);
150f988d640SKalle Valo if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
151f988d640SKalle Valo netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
152f988d640SKalle Valo priv->fwcapinfo &= ~FW_CAPINFO_PS;
153f988d640SKalle Valo } else {
154f988d640SKalle Valo if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
155f988d640SKalle Valo lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
156f988d640SKalle Valo } else {
157f988d640SKalle Valo /* The versions which boot up this way don't seem to
158f988d640SKalle Valo work even if we set it to the command interrupt */
159f988d640SKalle Valo priv->fwcapinfo &= ~FW_CAPINFO_PS;
160f988d640SKalle Valo netdev_info(priv->dev,
161f988d640SKalle Valo "Firmware doesn't wake via command interrupt; disabling PS mode\n");
162f988d640SKalle Valo }
163f988d640SKalle Valo }
164f988d640SKalle Valo }
165f988d640SKalle Valo
if_usb_fw_timeo(struct timer_list * t)16678ce6a90SKees Cook static void if_usb_fw_timeo(struct timer_list *t)
167f988d640SKalle Valo {
16878ce6a90SKees Cook struct if_usb_card *cardp = from_timer(cardp, t, fw_timeout);
169f988d640SKalle Valo
170f988d640SKalle Valo if (cardp->fwdnldover) {
171f988d640SKalle Valo lbs_deb_usb("Download complete, no event. Assuming success\n");
172f988d640SKalle Valo } else {
173f988d640SKalle Valo pr_err("Download timed out\n");
174f988d640SKalle Valo cardp->surprise_removed = 1;
175f988d640SKalle Valo }
176f988d640SKalle Valo wake_up(&cardp->fw_wq);
177f988d640SKalle Valo }
178f988d640SKalle Valo
179f988d640SKalle Valo #ifdef CONFIG_OLPC
if_usb_reset_olpc_card(struct lbs_private * priv)180f988d640SKalle Valo static void if_usb_reset_olpc_card(struct lbs_private *priv)
181f988d640SKalle Valo {
182f988d640SKalle Valo printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
183f988d640SKalle Valo olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
184f988d640SKalle Valo }
185f988d640SKalle Valo #endif
186f988d640SKalle Valo
187f988d640SKalle Valo /**
188f988d640SKalle Valo * if_usb_probe - sets the configuration values
189f988d640SKalle Valo * @intf: &usb_interface pointer
190f988d640SKalle Valo * @id: pointer to usb_device_id
191f988d640SKalle Valo * returns: 0 on success, error code on failure
192f988d640SKalle Valo */
if_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)193f988d640SKalle Valo static int if_usb_probe(struct usb_interface *intf,
194f988d640SKalle Valo const struct usb_device_id *id)
195f988d640SKalle Valo {
196f988d640SKalle Valo struct usb_device *udev;
197f988d640SKalle Valo struct usb_host_interface *iface_desc;
198f988d640SKalle Valo struct usb_endpoint_descriptor *endpoint;
199f988d640SKalle Valo struct lbs_private *priv;
200f988d640SKalle Valo struct if_usb_card *cardp;
201f988d640SKalle Valo int r = -ENOMEM;
202f988d640SKalle Valo int i;
203f988d640SKalle Valo
204f988d640SKalle Valo udev = interface_to_usbdev(intf);
205f988d640SKalle Valo
206f988d640SKalle Valo cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
207f988d640SKalle Valo if (!cardp)
208f988d640SKalle Valo goto error;
209f988d640SKalle Valo
21078ce6a90SKees Cook timer_setup(&cardp->fw_timeout, if_usb_fw_timeo, 0);
211f988d640SKalle Valo init_waitqueue_head(&cardp->fw_wq);
212f988d640SKalle Valo
213f988d640SKalle Valo cardp->udev = udev;
214f988d640SKalle Valo cardp->model = (uint32_t) id->driver_info;
215f988d640SKalle Valo iface_desc = intf->cur_altsetting;
216f988d640SKalle Valo
217f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
218f988d640SKalle Valo " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
219f988d640SKalle Valo le16_to_cpu(udev->descriptor.bcdUSB),
220f988d640SKalle Valo udev->descriptor.bDeviceClass,
221f988d640SKalle Valo udev->descriptor.bDeviceSubClass,
222f988d640SKalle Valo udev->descriptor.bDeviceProtocol);
223f988d640SKalle Valo
224f988d640SKalle Valo for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
225f988d640SKalle Valo endpoint = &iface_desc->endpoint[i].desc;
226f988d640SKalle Valo if (usb_endpoint_is_bulk_in(endpoint)) {
227f988d640SKalle Valo cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
228f988d640SKalle Valo cardp->ep_in = usb_endpoint_num(endpoint);
229f988d640SKalle Valo
230f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
231f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
232f988d640SKalle Valo
233f988d640SKalle Valo } else if (usb_endpoint_is_bulk_out(endpoint)) {
234f988d640SKalle Valo cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
235f988d640SKalle Valo cardp->ep_out = usb_endpoint_num(endpoint);
236f988d640SKalle Valo
237f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
238f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
239f988d640SKalle Valo }
240f988d640SKalle Valo }
241f988d640SKalle Valo if (!cardp->ep_out_size || !cardp->ep_in_size) {
242f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
243f988d640SKalle Valo goto dealloc;
244f988d640SKalle Valo }
245f988d640SKalle Valo if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
246f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
247f988d640SKalle Valo goto dealloc;
248f988d640SKalle Valo }
249f988d640SKalle Valo if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
250f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
251f988d640SKalle Valo goto dealloc;
252f988d640SKalle Valo }
253f988d640SKalle Valo cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
254f988d640SKalle Valo if (!cardp->ep_out_buf) {
255f988d640SKalle Valo lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
256f988d640SKalle Valo goto dealloc;
257f988d640SKalle Valo }
258f988d640SKalle Valo
259bbc2a101SLubomir Rintel priv = lbs_add_card(cardp, &intf->dev);
260bbc2a101SLubomir Rintel if (IS_ERR(priv)) {
261bbc2a101SLubomir Rintel r = PTR_ERR(priv);
262f988d640SKalle Valo goto err_add_card;
263bbc2a101SLubomir Rintel }
264f988d640SKalle Valo
265f988d640SKalle Valo cardp->priv = priv;
266f988d640SKalle Valo
267f988d640SKalle Valo priv->hw_host_to_card = if_usb_host_to_card;
268f988d640SKalle Valo priv->enter_deep_sleep = NULL;
269f988d640SKalle Valo priv->exit_deep_sleep = NULL;
270f988d640SKalle Valo priv->reset_deep_sleep_wakeup = NULL;
271fae4f9f7SAndreas Kemnade priv->is_polling = false;
272f988d640SKalle Valo #ifdef CONFIG_OLPC
273f988d640SKalle Valo if (machine_is_olpc())
274f988d640SKalle Valo priv->reset_card = if_usb_reset_olpc_card;
275f988d640SKalle Valo #endif
276f988d640SKalle Valo
277f988d640SKalle Valo cardp->boot2_version = udev->descriptor.bcdDevice;
278f988d640SKalle Valo
279f988d640SKalle Valo usb_get_dev(udev);
280f988d640SKalle Valo usb_set_intfdata(intf, cardp);
281f988d640SKalle Valo
282f988d640SKalle Valo r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
283f988d640SKalle Valo fw_table, if_usb_prog_firmware);
284f988d640SKalle Valo if (r)
285f988d640SKalle Valo goto err_get_fw;
286f988d640SKalle Valo
287f988d640SKalle Valo return 0;
288f988d640SKalle Valo
289f988d640SKalle Valo err_get_fw:
2906fd57e1dSHangyu Hua usb_put_dev(udev);
291f988d640SKalle Valo lbs_remove_card(priv);
292f988d640SKalle Valo err_add_card:
293f988d640SKalle Valo if_usb_reset_device(cardp);
294f988d640SKalle Valo dealloc:
295f988d640SKalle Valo if_usb_free(cardp);
2969692151eSWang Hai kfree(cardp);
297f988d640SKalle Valo
298f988d640SKalle Valo error:
299f988d640SKalle Valo return r;
300f988d640SKalle Valo }
301f988d640SKalle Valo
302f988d640SKalle Valo /**
303f988d640SKalle Valo * if_usb_disconnect - free resource and cleanup
304f988d640SKalle Valo * @intf: USB interface structure
305f988d640SKalle Valo * returns: N/A
306f988d640SKalle Valo */
if_usb_disconnect(struct usb_interface * intf)307f988d640SKalle Valo static void if_usb_disconnect(struct usb_interface *intf)
308f988d640SKalle Valo {
309f988d640SKalle Valo struct if_usb_card *cardp = usb_get_intfdata(intf);
310f988d640SKalle Valo struct lbs_private *priv = cardp->priv;
311f988d640SKalle Valo
312f988d640SKalle Valo cardp->surprise_removed = 1;
313f988d640SKalle Valo
314f988d640SKalle Valo if (priv) {
315f988d640SKalle Valo lbs_stop_card(priv);
316f988d640SKalle Valo lbs_remove_card(priv);
317f988d640SKalle Valo }
318f988d640SKalle Valo
319f988d640SKalle Valo /* Unlink and free urb */
320f988d640SKalle Valo if_usb_free(cardp);
3219692151eSWang Hai kfree(cardp);
322f988d640SKalle Valo
323f988d640SKalle Valo usb_set_intfdata(intf, NULL);
324f988d640SKalle Valo usb_put_dev(interface_to_usbdev(intf));
325f988d640SKalle Valo }
326f988d640SKalle Valo
327f988d640SKalle Valo /**
328f988d640SKalle Valo * if_usb_send_fw_pkt - download FW
329f988d640SKalle Valo * @cardp: pointer to &struct if_usb_card
330f988d640SKalle Valo * returns: 0
331f988d640SKalle Valo */
if_usb_send_fw_pkt(struct if_usb_card * cardp)332f988d640SKalle Valo static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
333f988d640SKalle Valo {
334f988d640SKalle Valo struct fwdata *fwdata = cardp->ep_out_buf;
335f988d640SKalle Valo const uint8_t *firmware = cardp->fw->data;
336f988d640SKalle Valo
337f988d640SKalle Valo /* If we got a CRC failure on the last block, back
338f988d640SKalle Valo up and retry it */
339f988d640SKalle Valo if (!cardp->CRC_OK) {
340f988d640SKalle Valo cardp->totalbytes = cardp->fwlastblksent;
341f988d640SKalle Valo cardp->fwseqnum--;
342f988d640SKalle Valo }
343f988d640SKalle Valo
344f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
345f988d640SKalle Valo cardp->totalbytes);
346f988d640SKalle Valo
347f988d640SKalle Valo /* struct fwdata (which we sent to the card) has an
348f988d640SKalle Valo extra __le32 field in between the header and the data,
349f988d640SKalle Valo which is not in the struct fwheader in the actual
350f988d640SKalle Valo firmware binary. Insert the seqnum in the middle... */
351f988d640SKalle Valo memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
352f988d640SKalle Valo sizeof(struct fwheader));
353f988d640SKalle Valo
354f988d640SKalle Valo cardp->fwlastblksent = cardp->totalbytes;
355f988d640SKalle Valo cardp->totalbytes += sizeof(struct fwheader);
356f988d640SKalle Valo
357f988d640SKalle Valo memcpy(fwdata->data, &firmware[cardp->totalbytes],
358f988d640SKalle Valo le32_to_cpu(fwdata->hdr.datalength));
359f988d640SKalle Valo
360f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
361f988d640SKalle Valo le32_to_cpu(fwdata->hdr.datalength));
362f988d640SKalle Valo
363f988d640SKalle Valo fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
364f988d640SKalle Valo cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
365f988d640SKalle Valo
366f988d640SKalle Valo usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
367f988d640SKalle Valo le32_to_cpu(fwdata->hdr.datalength));
368f988d640SKalle Valo
369f988d640SKalle Valo if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
370f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
371f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
372f988d640SKalle Valo cardp->fwseqnum, cardp->totalbytes);
373f988d640SKalle Valo } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
374f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
375aeffda6bSColin Ian King lbs_deb_usb2(&cardp->udev->dev, "Downloading FW JUMP BLOCK\n");
376f988d640SKalle Valo
377f988d640SKalle Valo cardp->fwfinalblk = 1;
378f988d640SKalle Valo }
379f988d640SKalle Valo
380f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
381f988d640SKalle Valo cardp->totalbytes);
382f988d640SKalle Valo
383f988d640SKalle Valo return 0;
384f988d640SKalle Valo }
385f988d640SKalle Valo
if_usb_reset_device(struct if_usb_card * cardp)386f988d640SKalle Valo static int if_usb_reset_device(struct if_usb_card *cardp)
387f988d640SKalle Valo {
388f988d640SKalle Valo struct cmd_header *cmd = cardp->ep_out_buf + 4;
389f988d640SKalle Valo int ret;
390f988d640SKalle Valo
391f988d640SKalle Valo *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
392f988d640SKalle Valo
393f988d640SKalle Valo cmd->command = cpu_to_le16(CMD_802_11_RESET);
394f988d640SKalle Valo cmd->size = cpu_to_le16(sizeof(cmd));
395f988d640SKalle Valo cmd->result = cpu_to_le16(0);
396f988d640SKalle Valo cmd->seqnum = cpu_to_le16(0x5a5a);
397f988d640SKalle Valo usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));
398f988d640SKalle Valo
399f988d640SKalle Valo msleep(100);
400f988d640SKalle Valo ret = usb_reset_device(cardp->udev);
401f988d640SKalle Valo msleep(100);
402f988d640SKalle Valo
403f988d640SKalle Valo #ifdef CONFIG_OLPC
404f988d640SKalle Valo if (ret && machine_is_olpc())
405f988d640SKalle Valo if_usb_reset_olpc_card(NULL);
406f988d640SKalle Valo #endif
407f988d640SKalle Valo
408f988d640SKalle Valo return ret;
409f988d640SKalle Valo }
410f988d640SKalle Valo
411f988d640SKalle Valo /**
412f988d640SKalle Valo * usb_tx_block - transfer the data to the device
413f988d640SKalle Valo * @cardp: pointer to &struct if_usb_card
414f988d640SKalle Valo * @payload: pointer to payload data
415f988d640SKalle Valo * @nb: data length
416f988d640SKalle Valo * returns: 0 for success or negative error code
417f988d640SKalle Valo */
usb_tx_block(struct if_usb_card * cardp,uint8_t * payload,uint16_t nb)418f988d640SKalle Valo static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
419f988d640SKalle Valo {
420f988d640SKalle Valo int ret;
421f988d640SKalle Valo
422f988d640SKalle Valo /* check if device is removed */
423f988d640SKalle Valo if (cardp->surprise_removed) {
424f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
425f988d640SKalle Valo ret = -ENODEV;
426f988d640SKalle Valo goto tx_ret;
427f988d640SKalle Valo }
428f988d640SKalle Valo
429f988d640SKalle Valo usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
430f988d640SKalle Valo usb_sndbulkpipe(cardp->udev,
431f988d640SKalle Valo cardp->ep_out),
432f988d640SKalle Valo payload, nb, if_usb_write_bulk_callback, cardp);
433f988d640SKalle Valo
434f988d640SKalle Valo cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
435f988d640SKalle Valo
436f988d640SKalle Valo if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
437f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
438f988d640SKalle Valo } else {
439f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
440f988d640SKalle Valo ret = 0;
441f988d640SKalle Valo }
442f988d640SKalle Valo
443f988d640SKalle Valo tx_ret:
444f988d640SKalle Valo return ret;
445f988d640SKalle Valo }
446f988d640SKalle Valo
__if_usb_submit_rx_urb(struct if_usb_card * cardp,void (* callbackfn)(struct urb * urb))447f988d640SKalle Valo static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
448f988d640SKalle Valo void (*callbackfn)(struct urb *urb))
449f988d640SKalle Valo {
450f988d640SKalle Valo struct sk_buff *skb;
451f988d640SKalle Valo int ret = -1;
452f988d640SKalle Valo
453f988d640SKalle Valo if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
454f988d640SKalle Valo pr_err("No free skb\n");
455f988d640SKalle Valo goto rx_ret;
456f988d640SKalle Valo }
457f988d640SKalle Valo
458f988d640SKalle Valo cardp->rx_skb = skb;
459f988d640SKalle Valo
460f988d640SKalle Valo /* Fill the receive configuration URB and initialise the Rx call back */
461f988d640SKalle Valo usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
462f988d640SKalle Valo usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
463f988d640SKalle Valo skb->data + IPFIELD_ALIGN_OFFSET,
464f988d640SKalle Valo MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
465f988d640SKalle Valo cardp);
466f988d640SKalle Valo
467f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
468f988d640SKalle Valo if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
469f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
470f988d640SKalle Valo kfree_skb(skb);
471f988d640SKalle Valo cardp->rx_skb = NULL;
472f988d640SKalle Valo ret = -1;
473f988d640SKalle Valo } else {
474f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
475f988d640SKalle Valo ret = 0;
476f988d640SKalle Valo }
477f988d640SKalle Valo
478f988d640SKalle Valo rx_ret:
479f988d640SKalle Valo return ret;
480f988d640SKalle Valo }
481f988d640SKalle Valo
if_usb_submit_rx_urb_fwload(struct if_usb_card * cardp)482f988d640SKalle Valo static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
483f988d640SKalle Valo {
484f988d640SKalle Valo return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
485f988d640SKalle Valo }
486f988d640SKalle Valo
if_usb_submit_rx_urb(struct if_usb_card * cardp)487f988d640SKalle Valo static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
488f988d640SKalle Valo {
489f988d640SKalle Valo return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
490f988d640SKalle Valo }
491f988d640SKalle Valo
if_usb_receive_fwload(struct urb * urb)492f988d640SKalle Valo static void if_usb_receive_fwload(struct urb *urb)
493f988d640SKalle Valo {
494f988d640SKalle Valo struct if_usb_card *cardp = urb->context;
495f988d640SKalle Valo struct sk_buff *skb = cardp->rx_skb;
496f988d640SKalle Valo struct fwsyncheader *syncfwheader;
497f988d640SKalle Valo struct bootcmdresp bootcmdresp;
498f988d640SKalle Valo
499f988d640SKalle Valo if (urb->status) {
500f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
501f988d640SKalle Valo "URB status is failed during fw load\n");
502f988d640SKalle Valo kfree_skb(skb);
503f988d640SKalle Valo return;
504f988d640SKalle Valo }
505f988d640SKalle Valo
506f988d640SKalle Valo if (cardp->fwdnldover) {
507f988d640SKalle Valo __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
508f988d640SKalle Valo
509f988d640SKalle Valo if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
510f988d640SKalle Valo tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
511f988d640SKalle Valo pr_info("Firmware ready event received\n");
512f988d640SKalle Valo wake_up(&cardp->fw_wq);
513f988d640SKalle Valo } else {
514f988d640SKalle Valo lbs_deb_usb("Waiting for confirmation; got %x %x\n",
515f988d640SKalle Valo le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
516f988d640SKalle Valo if_usb_submit_rx_urb_fwload(cardp);
517f988d640SKalle Valo }
518f988d640SKalle Valo kfree_skb(skb);
519f988d640SKalle Valo return;
520f988d640SKalle Valo }
521f988d640SKalle Valo if (cardp->bootcmdresp <= 0) {
522f988d640SKalle Valo memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
523f988d640SKalle Valo sizeof(bootcmdresp));
524f988d640SKalle Valo
525f988d640SKalle Valo if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
526f988d640SKalle Valo kfree_skb(skb);
527f988d640SKalle Valo if_usb_submit_rx_urb_fwload(cardp);
528f988d640SKalle Valo cardp->bootcmdresp = BOOT_CMD_RESP_OK;
529f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
530f988d640SKalle Valo "Received valid boot command response\n");
531f988d640SKalle Valo return;
532f988d640SKalle Valo }
533f988d640SKalle Valo if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
534f988d640SKalle Valo if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
535f988d640SKalle Valo bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
536f988d640SKalle Valo bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
537f988d640SKalle Valo if (!cardp->bootcmdresp)
538f988d640SKalle Valo pr_info("Firmware already seems alive; resetting\n");
539f988d640SKalle Valo cardp->bootcmdresp = -1;
540f988d640SKalle Valo } else {
541f988d640SKalle Valo pr_info("boot cmd response wrong magic number (0x%x)\n",
542f988d640SKalle Valo le32_to_cpu(bootcmdresp.magic));
543f988d640SKalle Valo }
544f988d640SKalle Valo } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
545f988d640SKalle Valo (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
546f988d640SKalle Valo (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
547f988d640SKalle Valo pr_info("boot cmd response cmd_tag error (%d)\n",
548f988d640SKalle Valo bootcmdresp.cmd);
549f988d640SKalle Valo } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
550f988d640SKalle Valo pr_info("boot cmd response result error (%d)\n",
551f988d640SKalle Valo bootcmdresp.result);
552f988d640SKalle Valo } else {
553f988d640SKalle Valo cardp->bootcmdresp = 1;
554f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
555f988d640SKalle Valo "Received valid boot command response\n");
556f988d640SKalle Valo }
557f988d640SKalle Valo kfree_skb(skb);
558f988d640SKalle Valo if_usb_submit_rx_urb_fwload(cardp);
559f988d640SKalle Valo return;
560f988d640SKalle Valo }
561f988d640SKalle Valo
562f988d640SKalle Valo syncfwheader = kmemdup(skb->data + IPFIELD_ALIGN_OFFSET,
563f988d640SKalle Valo sizeof(struct fwsyncheader), GFP_ATOMIC);
564f988d640SKalle Valo if (!syncfwheader) {
565f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
566f988d640SKalle Valo kfree_skb(skb);
567f988d640SKalle Valo return;
568f988d640SKalle Valo }
569f988d640SKalle Valo
570f988d640SKalle Valo if (!syncfwheader->cmd) {
571f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
572f988d640SKalle Valo lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
573f988d640SKalle Valo le32_to_cpu(syncfwheader->seqnum));
574f988d640SKalle Valo cardp->CRC_OK = 1;
575f988d640SKalle Valo } else {
576f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
577f988d640SKalle Valo cardp->CRC_OK = 0;
578f988d640SKalle Valo }
579f988d640SKalle Valo
580f988d640SKalle Valo kfree_skb(skb);
581f988d640SKalle Valo
582f988d640SKalle Valo /* Give device 5s to either write firmware to its RAM or eeprom */
583f988d640SKalle Valo mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
584f988d640SKalle Valo
585f988d640SKalle Valo if (cardp->fwfinalblk) {
586f988d640SKalle Valo cardp->fwdnldover = 1;
587f988d640SKalle Valo goto exit;
588f988d640SKalle Valo }
589f988d640SKalle Valo
590f988d640SKalle Valo if_usb_send_fw_pkt(cardp);
591f988d640SKalle Valo
592f988d640SKalle Valo exit:
593f988d640SKalle Valo if_usb_submit_rx_urb_fwload(cardp);
594f988d640SKalle Valo
595f988d640SKalle Valo kfree(syncfwheader);
596f988d640SKalle Valo }
597f988d640SKalle Valo
598f988d640SKalle Valo #define MRVDRV_MIN_PKT_LEN 30
599f988d640SKalle Valo
process_cmdtypedata(int recvlength,struct sk_buff * skb,struct if_usb_card * cardp,struct lbs_private * priv)600f988d640SKalle Valo static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
601f988d640SKalle Valo struct if_usb_card *cardp,
602f988d640SKalle Valo struct lbs_private *priv)
603f988d640SKalle Valo {
604f988d640SKalle Valo if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
605f988d640SKalle Valo || recvlength < MRVDRV_MIN_PKT_LEN) {
606f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
607f988d640SKalle Valo kfree_skb(skb);
608f988d640SKalle Valo return;
609f988d640SKalle Valo }
610f988d640SKalle Valo
611f988d640SKalle Valo skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
612f988d640SKalle Valo skb_put(skb, recvlength);
613f988d640SKalle Valo skb_pull(skb, MESSAGE_HEADER_LEN);
614f988d640SKalle Valo
615f988d640SKalle Valo lbs_process_rxed_packet(priv, skb);
616f988d640SKalle Valo }
617f988d640SKalle Valo
process_cmdrequest(int recvlength,uint8_t * recvbuff,struct sk_buff * skb,struct if_usb_card * cardp,struct lbs_private * priv)618f988d640SKalle Valo static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
619f988d640SKalle Valo struct sk_buff *skb,
620f988d640SKalle Valo struct if_usb_card *cardp,
621f988d640SKalle Valo struct lbs_private *priv)
622f988d640SKalle Valo {
623a3128feeSSebastian Andrzej Siewior unsigned long flags;
624f988d640SKalle Valo u8 i;
625f988d640SKalle Valo
626f988d640SKalle Valo if (recvlength > LBS_CMD_BUFFER_SIZE) {
627f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
628f988d640SKalle Valo "The receive buffer is too large\n");
629f988d640SKalle Valo kfree_skb(skb);
630f988d640SKalle Valo return;
631f988d640SKalle Valo }
632f988d640SKalle Valo
633a3128feeSSebastian Andrzej Siewior spin_lock_irqsave(&priv->driver_lock, flags);
634f988d640SKalle Valo
635f988d640SKalle Valo i = (priv->resp_idx == 0) ? 1 : 0;
636f988d640SKalle Valo BUG_ON(priv->resp_len[i]);
637f988d640SKalle Valo priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
638f988d640SKalle Valo memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
639f988d640SKalle Valo priv->resp_len[i]);
640*3968e81bSYang Yingliang dev_kfree_skb_irq(skb);
641f988d640SKalle Valo lbs_notify_command_response(priv, i);
642f988d640SKalle Valo
643a3128feeSSebastian Andrzej Siewior spin_unlock_irqrestore(&priv->driver_lock, flags);
644f988d640SKalle Valo
645f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
646f988d640SKalle Valo "Wake up main thread to handle cmd response\n");
647f988d640SKalle Valo }
648f988d640SKalle Valo
649f988d640SKalle Valo /**
650f988d640SKalle Valo * if_usb_receive - read the packet into the upload buffer,
651f988d640SKalle Valo * wake up the main thread and initialise the Rx callack
652f988d640SKalle Valo *
653f988d640SKalle Valo * @urb: pointer to &struct urb
654f988d640SKalle Valo * returns: N/A
655f988d640SKalle Valo */
if_usb_receive(struct urb * urb)656f988d640SKalle Valo static void if_usb_receive(struct urb *urb)
657f988d640SKalle Valo {
658f988d640SKalle Valo struct if_usb_card *cardp = urb->context;
659f988d640SKalle Valo struct sk_buff *skb = cardp->rx_skb;
660f988d640SKalle Valo struct lbs_private *priv = cardp->priv;
661f988d640SKalle Valo int recvlength = urb->actual_length;
662f988d640SKalle Valo uint8_t *recvbuff = NULL;
663f988d640SKalle Valo uint32_t recvtype = 0;
664f988d640SKalle Valo __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
665f988d640SKalle Valo uint32_t event;
666f988d640SKalle Valo
667f988d640SKalle Valo if (recvlength) {
668f988d640SKalle Valo if (urb->status) {
669f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
670f988d640SKalle Valo urb->status);
671f988d640SKalle Valo kfree_skb(skb);
672f988d640SKalle Valo goto setup_for_next;
673f988d640SKalle Valo }
674f988d640SKalle Valo
675f988d640SKalle Valo recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
676f988d640SKalle Valo recvtype = le32_to_cpu(pkt[0]);
677f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,
678f988d640SKalle Valo "Recv length = 0x%x, Recv type = 0x%X\n",
679f988d640SKalle Valo recvlength, recvtype);
680f988d640SKalle Valo } else if (urb->status) {
681f988d640SKalle Valo kfree_skb(skb);
6824bc606afSKees Cook return;
683f988d640SKalle Valo }
684f988d640SKalle Valo
685f988d640SKalle Valo switch (recvtype) {
686f988d640SKalle Valo case CMD_TYPE_DATA:
687f988d640SKalle Valo process_cmdtypedata(recvlength, skb, cardp, priv);
688f988d640SKalle Valo break;
689f988d640SKalle Valo
690f988d640SKalle Valo case CMD_TYPE_REQUEST:
691f988d640SKalle Valo process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
692f988d640SKalle Valo break;
693f988d640SKalle Valo
694f988d640SKalle Valo case CMD_TYPE_INDICATION:
695f988d640SKalle Valo /* Event handling */
696f988d640SKalle Valo event = le32_to_cpu(pkt[1]);
697f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event);
698f988d640SKalle Valo kfree_skb(skb);
699f988d640SKalle Valo
700f988d640SKalle Valo /* Icky undocumented magic special case */
701f988d640SKalle Valo if (event & 0xffff0000) {
702f988d640SKalle Valo u32 trycount = (event & 0xffff0000) >> 16;
703f988d640SKalle Valo
704f988d640SKalle Valo lbs_send_tx_feedback(priv, trycount);
705f988d640SKalle Valo } else
706f988d640SKalle Valo lbs_queue_event(priv, event & 0xFF);
707f988d640SKalle Valo break;
708f988d640SKalle Valo
709f988d640SKalle Valo default:
710f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
711f988d640SKalle Valo recvtype);
712f988d640SKalle Valo kfree_skb(skb);
713f988d640SKalle Valo break;
714f988d640SKalle Valo }
715f988d640SKalle Valo
716f988d640SKalle Valo setup_for_next:
717f988d640SKalle Valo if_usb_submit_rx_urb(cardp);
718f988d640SKalle Valo }
719f988d640SKalle Valo
720f988d640SKalle Valo /**
721f988d640SKalle Valo * if_usb_host_to_card - downloads data to FW
722f988d640SKalle Valo * @priv: pointer to &struct lbs_private structure
723f988d640SKalle Valo * @type: type of data
724f988d640SKalle Valo * @payload: pointer to data buffer
725f988d640SKalle Valo * @nb: number of bytes
726f988d640SKalle Valo * returns: 0 for success or negative error code
727f988d640SKalle Valo */
if_usb_host_to_card(struct lbs_private * priv,uint8_t type,uint8_t * payload,uint16_t nb)728f988d640SKalle Valo static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
729f988d640SKalle Valo uint8_t *payload, uint16_t nb)
730f988d640SKalle Valo {
731f988d640SKalle Valo struct if_usb_card *cardp = priv->card;
732f988d640SKalle Valo
733f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
734f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
735f988d640SKalle Valo
736f988d640SKalle Valo if (type == MVMS_CMD) {
737f988d640SKalle Valo *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
738f988d640SKalle Valo priv->dnld_sent = DNLD_CMD_SENT;
739f988d640SKalle Valo } else {
740f988d640SKalle Valo *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
741f988d640SKalle Valo priv->dnld_sent = DNLD_DATA_SENT;
742f988d640SKalle Valo }
743f988d640SKalle Valo
744f988d640SKalle Valo memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
745f988d640SKalle Valo
746f988d640SKalle Valo return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
747f988d640SKalle Valo }
748f988d640SKalle Valo
749f988d640SKalle Valo /**
750f988d640SKalle Valo * if_usb_issue_boot_command - issues Boot command to the Boot2 code
751f988d640SKalle Valo * @cardp: pointer to &if_usb_card
752f988d640SKalle Valo * @ivalue: 1:Boot from FW by USB-Download
753f988d640SKalle Valo * 2:Boot from FW in EEPROM
754f988d640SKalle Valo * returns: 0 for success or negative error code
755f988d640SKalle Valo */
if_usb_issue_boot_command(struct if_usb_card * cardp,int ivalue)756f988d640SKalle Valo static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
757f988d640SKalle Valo {
758f988d640SKalle Valo struct bootcmd *bootcmd = cardp->ep_out_buf;
759f988d640SKalle Valo
760f988d640SKalle Valo /* Prepare command */
761f988d640SKalle Valo bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
762f988d640SKalle Valo bootcmd->cmd = ivalue;
763f988d640SKalle Valo memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
764f988d640SKalle Valo
765f988d640SKalle Valo /* Issue command */
766f988d640SKalle Valo usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
767f988d640SKalle Valo
768f988d640SKalle Valo return 0;
769f988d640SKalle Valo }
770f988d640SKalle Valo
771f988d640SKalle Valo
772f988d640SKalle Valo /**
773f988d640SKalle Valo * check_fwfile_format - check the validity of Boot2/FW image
774f988d640SKalle Valo *
775f988d640SKalle Valo * @data: pointer to image
776f988d640SKalle Valo * @totlen: image length
777f988d640SKalle Valo * returns: 0 (good) or 1 (failure)
778f988d640SKalle Valo */
check_fwfile_format(const uint8_t * data,uint32_t totlen)779f988d640SKalle Valo static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
780f988d640SKalle Valo {
781f988d640SKalle Valo uint32_t bincmd, exit;
782f988d640SKalle Valo uint32_t blksize, offset, len;
783f988d640SKalle Valo int ret;
784f988d640SKalle Valo
785f988d640SKalle Valo ret = 1;
786f988d640SKalle Valo exit = len = 0;
787f988d640SKalle Valo
788f988d640SKalle Valo do {
789f988d640SKalle Valo struct fwheader *fwh = (void *)data;
790f988d640SKalle Valo
791f988d640SKalle Valo bincmd = le32_to_cpu(fwh->dnldcmd);
792f988d640SKalle Valo blksize = le32_to_cpu(fwh->datalength);
793f988d640SKalle Valo switch (bincmd) {
794f988d640SKalle Valo case FW_HAS_DATA_TO_RECV:
795f988d640SKalle Valo offset = sizeof(struct fwheader) + blksize;
796f988d640SKalle Valo data += offset;
797f988d640SKalle Valo len += offset;
798f988d640SKalle Valo if (len >= totlen)
799f988d640SKalle Valo exit = 1;
800f988d640SKalle Valo break;
801f988d640SKalle Valo case FW_HAS_LAST_BLOCK:
802f988d640SKalle Valo exit = 1;
803f988d640SKalle Valo ret = 0;
804f988d640SKalle Valo break;
805f988d640SKalle Valo default:
806f988d640SKalle Valo exit = 1;
807f988d640SKalle Valo break;
808f988d640SKalle Valo }
809f988d640SKalle Valo } while (!exit);
810f988d640SKalle Valo
811f988d640SKalle Valo if (ret)
812f988d640SKalle Valo pr_err("firmware file format check FAIL\n");
813f988d640SKalle Valo else
814f988d640SKalle Valo lbs_deb_fw("firmware file format check PASS\n");
815f988d640SKalle Valo
816f988d640SKalle Valo return ret;
817f988d640SKalle Valo }
818f988d640SKalle Valo
if_usb_prog_firmware(struct lbs_private * priv,int ret,const struct firmware * fw,const struct firmware * unused)819f988d640SKalle Valo static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
820f988d640SKalle Valo const struct firmware *fw,
821f988d640SKalle Valo const struct firmware *unused)
822f988d640SKalle Valo {
823f988d640SKalle Valo struct if_usb_card *cardp = priv->card;
824f988d640SKalle Valo int i = 0;
825f988d640SKalle Valo static int reset_count = 10;
826f988d640SKalle Valo
827f988d640SKalle Valo if (ret) {
828f988d640SKalle Valo pr_err("failed to find firmware (%d)\n", ret);
829f988d640SKalle Valo goto done;
830f988d640SKalle Valo }
831f988d640SKalle Valo
832f988d640SKalle Valo cardp->fw = fw;
833f988d640SKalle Valo if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
834f988d640SKalle Valo ret = -EINVAL;
835f988d640SKalle Valo goto done;
836f988d640SKalle Valo }
837f988d640SKalle Valo
838f988d640SKalle Valo /* Cancel any pending usb business */
839f988d640SKalle Valo usb_kill_urb(cardp->rx_urb);
840f988d640SKalle Valo usb_kill_urb(cardp->tx_urb);
841f988d640SKalle Valo
842f988d640SKalle Valo cardp->fwlastblksent = 0;
843f988d640SKalle Valo cardp->fwdnldover = 0;
844f988d640SKalle Valo cardp->totalbytes = 0;
845f988d640SKalle Valo cardp->fwfinalblk = 0;
846f988d640SKalle Valo cardp->bootcmdresp = 0;
847f988d640SKalle Valo
848f988d640SKalle Valo restart:
849f988d640SKalle Valo if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
850f988d640SKalle Valo lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
851f988d640SKalle Valo ret = -EIO;
852f988d640SKalle Valo goto done;
853f988d640SKalle Valo }
854f988d640SKalle Valo
855f988d640SKalle Valo cardp->bootcmdresp = 0;
856f988d640SKalle Valo do {
857f988d640SKalle Valo int j = 0;
858f988d640SKalle Valo i++;
859f988d640SKalle Valo if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
860f988d640SKalle Valo /* wait for command response */
861f988d640SKalle Valo do {
862f988d640SKalle Valo j++;
863f988d640SKalle Valo msleep_interruptible(100);
864f988d640SKalle Valo } while (cardp->bootcmdresp == 0 && j < 10);
865f988d640SKalle Valo } while (cardp->bootcmdresp == 0 && i < 5);
866f988d640SKalle Valo
867f988d640SKalle Valo if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) {
868f988d640SKalle Valo /* Return to normal operation */
869f988d640SKalle Valo ret = -EOPNOTSUPP;
870f988d640SKalle Valo usb_kill_urb(cardp->rx_urb);
871f988d640SKalle Valo usb_kill_urb(cardp->tx_urb);
872f988d640SKalle Valo if (if_usb_submit_rx_urb(cardp) < 0)
873f988d640SKalle Valo ret = -EIO;
874f988d640SKalle Valo goto done;
875f988d640SKalle Valo } else if (cardp->bootcmdresp <= 0) {
876f988d640SKalle Valo if (--reset_count >= 0) {
877f988d640SKalle Valo if_usb_reset_device(cardp);
878f988d640SKalle Valo goto restart;
879f988d640SKalle Valo }
880f988d640SKalle Valo ret = -EIO;
881f988d640SKalle Valo goto done;
882f988d640SKalle Valo }
883f988d640SKalle Valo
884f988d640SKalle Valo i = 0;
885f988d640SKalle Valo
886f988d640SKalle Valo cardp->totalbytes = 0;
887f988d640SKalle Valo cardp->fwlastblksent = 0;
888f988d640SKalle Valo cardp->CRC_OK = 1;
889f988d640SKalle Valo cardp->fwdnldover = 0;
890f988d640SKalle Valo cardp->fwseqnum = -1;
891f988d640SKalle Valo cardp->totalbytes = 0;
892f988d640SKalle Valo cardp->fwfinalblk = 0;
893f988d640SKalle Valo
894f988d640SKalle Valo /* Send the first firmware packet... */
895f988d640SKalle Valo if_usb_send_fw_pkt(cardp);
896f988d640SKalle Valo
897f988d640SKalle Valo /* ... and wait for the process to complete */
898f988d640SKalle Valo wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
899f988d640SKalle Valo
900f988d640SKalle Valo del_timer_sync(&cardp->fw_timeout);
901f988d640SKalle Valo usb_kill_urb(cardp->rx_urb);
902f988d640SKalle Valo
903f988d640SKalle Valo if (!cardp->fwdnldover) {
904f988d640SKalle Valo pr_info("failed to load fw, resetting device!\n");
905f988d640SKalle Valo if (--reset_count >= 0) {
906f988d640SKalle Valo if_usb_reset_device(cardp);
907f988d640SKalle Valo goto restart;
908f988d640SKalle Valo }
909f988d640SKalle Valo
910f988d640SKalle Valo pr_info("FW download failure, time = %d ms\n", i * 100);
911f988d640SKalle Valo ret = -EIO;
912f988d640SKalle Valo goto done;
913f988d640SKalle Valo }
914f988d640SKalle Valo
915f988d640SKalle Valo cardp->priv->fw_ready = 1;
916f988d640SKalle Valo if_usb_submit_rx_urb(cardp);
917f988d640SKalle Valo
918f988d640SKalle Valo if (lbs_start_card(priv))
919f988d640SKalle Valo goto done;
920f988d640SKalle Valo
921f988d640SKalle Valo if_usb_setup_firmware(priv);
922f988d640SKalle Valo
923f988d640SKalle Valo /*
924f988d640SKalle Valo * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
925f988d640SKalle Valo */
926f988d640SKalle Valo priv->wol_criteria = EHS_REMOVE_WAKEUP;
927f988d640SKalle Valo if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
928f988d640SKalle Valo priv->ehs_remove_supported = false;
929f988d640SKalle Valo
930f988d640SKalle Valo done:
931f988d640SKalle Valo cardp->fw = NULL;
932f988d640SKalle Valo }
933f988d640SKalle Valo
934f988d640SKalle Valo
935f988d640SKalle Valo #ifdef CONFIG_PM
if_usb_suspend(struct usb_interface * intf,pm_message_t message)936f988d640SKalle Valo static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
937f988d640SKalle Valo {
938f988d640SKalle Valo struct if_usb_card *cardp = usb_get_intfdata(intf);
939f988d640SKalle Valo struct lbs_private *priv = cardp->priv;
940f988d640SKalle Valo int ret;
941f988d640SKalle Valo
942f988d640SKalle Valo if (priv->psstate != PS_STATE_FULL_POWER) {
943f988d640SKalle Valo ret = -1;
944f988d640SKalle Valo goto out;
945f988d640SKalle Valo }
946f988d640SKalle Valo
947f988d640SKalle Valo #ifdef CONFIG_OLPC
948f988d640SKalle Valo if (machine_is_olpc()) {
949f988d640SKalle Valo if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
950f988d640SKalle Valo olpc_ec_wakeup_clear(EC_SCI_SRC_WLAN);
951f988d640SKalle Valo else
952f988d640SKalle Valo olpc_ec_wakeup_set(EC_SCI_SRC_WLAN);
953f988d640SKalle Valo }
954f988d640SKalle Valo #endif
955f988d640SKalle Valo
956f988d640SKalle Valo ret = lbs_suspend(priv);
957f988d640SKalle Valo if (ret)
958f988d640SKalle Valo goto out;
959f988d640SKalle Valo
960f988d640SKalle Valo /* Unlink tx & rx urb */
961f988d640SKalle Valo usb_kill_urb(cardp->tx_urb);
962f988d640SKalle Valo usb_kill_urb(cardp->rx_urb);
963f988d640SKalle Valo
964f988d640SKalle Valo out:
965f988d640SKalle Valo return ret;
966f988d640SKalle Valo }
967f988d640SKalle Valo
if_usb_resume(struct usb_interface * intf)968f988d640SKalle Valo static int if_usb_resume(struct usb_interface *intf)
969f988d640SKalle Valo {
970f988d640SKalle Valo struct if_usb_card *cardp = usb_get_intfdata(intf);
971f988d640SKalle Valo struct lbs_private *priv = cardp->priv;
972f988d640SKalle Valo
973f988d640SKalle Valo if_usb_submit_rx_urb(cardp);
974f988d640SKalle Valo
975f988d640SKalle Valo lbs_resume(priv);
976f988d640SKalle Valo
977f988d640SKalle Valo return 0;
978f988d640SKalle Valo }
979f988d640SKalle Valo #else
980f988d640SKalle Valo #define if_usb_suspend NULL
981f988d640SKalle Valo #define if_usb_resume NULL
982f988d640SKalle Valo #endif
983f988d640SKalle Valo
984f988d640SKalle Valo static struct usb_driver if_usb_driver = {
985f988d640SKalle Valo .name = DRV_NAME,
986f988d640SKalle Valo .probe = if_usb_probe,
987f988d640SKalle Valo .disconnect = if_usb_disconnect,
988f988d640SKalle Valo .id_table = if_usb_table,
989f988d640SKalle Valo .suspend = if_usb_suspend,
990f988d640SKalle Valo .resume = if_usb_resume,
991f988d640SKalle Valo .reset_resume = if_usb_resume,
992f988d640SKalle Valo .disable_hub_initiated_lpm = 1,
993f988d640SKalle Valo };
994f988d640SKalle Valo
995f988d640SKalle Valo module_usb_driver(if_usb_driver);
996f988d640SKalle Valo
997f988d640SKalle Valo MODULE_DESCRIPTION("8388 USB WLAN Driver");
998f988d640SKalle Valo MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
999f988d640SKalle Valo MODULE_LICENSE("GPL");
1000