~ubuntu-branches/ubuntu/saucy/linux-ti-omap4/saucy-proposed

« back to all changes in this revision

Viewing changes to drivers/net/wireless/libertas/if_usb.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati, Stefan Bader, Upstream Kernel Changes
  • Date: 2012-08-15 17:17:43 UTC
  • Revision ID: package-import@ubuntu.com-20120815171743-h5wnuf51xe7pvdid
Tags: 3.5.0-207.13
[ Paolo Pisati ]

* Start new release

[ Stefan Bader ]

* (config) Enable getabis to use local package copies

[ Upstream Kernel Changes ]

* fixup: gargabe collect iva_seq[0|1] init
* [Config] enable all SND_OMAP_SOC_*s
* fixup: cm2xxx_3xxx.o is needed for omap2_cm_read|write_reg
* fixup: add some snd_soc_dai* helper functions
* fixup: s/snd_soc_dpcm_params/snd_soc_dpcm/g
* fixup: typo, no_host_mode and useless SDP4430 init
* fixup: enable again aess hwmod

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
#define MESSAGE_HEADER_LEN      4
31
31
 
32
 
static char *lbs_fw_name = NULL;
33
 
module_param_named(fw_name, lbs_fw_name, charp, 0644);
34
 
 
35
32
MODULE_FIRMWARE("libertas/usb8388_v9.bin");
36
33
MODULE_FIRMWARE("libertas/usb8388_v5.bin");
37
34
MODULE_FIRMWARE("libertas/usb8388.bin");
44
41
        MODEL_8682 = 0x2
45
42
};
46
43
 
 
44
/* table of firmware file names */
 
45
static const struct lbs_fw_table fw_table[] = {
 
46
        { MODEL_8388, "libertas/usb8388_olpc.bin", NULL },
 
47
        { MODEL_8388, "libertas/usb8388_v9.bin", NULL },
 
48
        { MODEL_8388, "libertas/usb8388_v5.bin", NULL },
 
49
        { MODEL_8388, "libertas/usb8388.bin", NULL },
 
50
        { MODEL_8388, "usb8388.bin", NULL },
 
51
        { MODEL_8682, "libertas/usb8682.bin", NULL }
 
52
};
 
53
 
47
54
static struct usb_device_id if_usb_table[] = {
48
55
        /* Enter the device signature inside */
49
56
        { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
55
62
 
56
63
static void if_usb_receive(struct urb *urb);
57
64
static void if_usb_receive_fwload(struct urb *urb);
58
 
static int __if_usb_prog_firmware(struct if_usb_card *cardp,
59
 
                                        const char *fwname, int cmd);
60
 
static int if_usb_prog_firmware(struct if_usb_card *cardp,
61
 
                                        const char *fwname, int cmd);
 
65
static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
 
66
                                 const struct firmware *fw,
 
67
                                 const struct firmware *unused);
62
68
static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
63
69
                               uint8_t *payload, uint16_t nb);
64
70
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
67
73
static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
68
74
static int if_usb_reset_device(struct if_usb_card *cardp);
69
75
 
70
 
/* sysfs hooks */
71
 
 
72
 
/*
73
 
 *  Set function to write firmware to device's persistent memory
74
 
 */
75
 
static ssize_t if_usb_firmware_set(struct device *dev,
76
 
                struct device_attribute *attr, const char *buf, size_t count)
77
 
{
78
 
        struct lbs_private *priv = to_net_dev(dev)->ml_priv;
79
 
        struct if_usb_card *cardp = priv->card;
80
 
        int ret;
81
 
 
82
 
        BUG_ON(buf == NULL);
83
 
 
84
 
        ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
85
 
        if (ret == 0)
86
 
                return count;
87
 
 
88
 
        return ret;
89
 
}
90
 
 
91
 
/*
92
 
 * lbs_flash_fw attribute to be exported per ethX interface through sysfs
93
 
 * (/sys/class/net/ethX/lbs_flash_fw).  Use this like so to write firmware to
94
 
 * the device's persistent memory:
95
 
 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_fw
96
 
 */
97
 
static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
98
 
 
99
 
/**
100
 
 * if_usb_boot2_set - write firmware to device's persistent memory
101
 
 *
102
 
 * @dev: target device
103
 
 * @attr: device attributes
104
 
 * @buf: firmware buffer to write
105
 
 * @count: number of bytes to write
106
 
 *
107
 
 * returns: number of bytes written or negative error code
108
 
 */
109
 
static ssize_t if_usb_boot2_set(struct device *dev,
110
 
                struct device_attribute *attr, const char *buf, size_t count)
111
 
{
112
 
        struct lbs_private *priv = to_net_dev(dev)->ml_priv;
113
 
        struct if_usb_card *cardp = priv->card;
114
 
        int ret;
115
 
 
116
 
        BUG_ON(buf == NULL);
117
 
 
118
 
        ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
119
 
        if (ret == 0)
120
 
                return count;
121
 
 
122
 
        return ret;
123
 
}
124
 
 
125
 
/*
126
 
 * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
127
 
 * (/sys/class/net/ethX/lbs_flash_boot2).  Use this like so to write firmware
128
 
 * to the device's persistent memory:
129
 
 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_boot2
130
 
 */
131
 
static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
132
 
 
133
76
/**
134
77
 * if_usb_write_bulk_callback - callback function to handle the status
135
78
 * of the URB
256
199
        struct usb_endpoint_descriptor *endpoint;
257
200
        struct lbs_private *priv;
258
201
        struct if_usb_card *cardp;
 
202
        int r = -ENOMEM;
259
203
        int i;
260
204
 
261
205
        udev = interface_to_usbdev(intf);
313
257
                goto dealloc;
314
258
        }
315
259
 
316
 
        /* Upload firmware */
317
 
        kparam_block_sysfs_write(fw_name);
318
 
        if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
319
 
                kparam_unblock_sysfs_write(fw_name);
320
 
                lbs_deb_usbd(&udev->dev, "FW upload failed\n");
321
 
                goto err_prog_firmware;
322
 
        }
323
 
        kparam_unblock_sysfs_write(fw_name);
324
 
 
325
260
        if (!(priv = lbs_add_card(cardp, &intf->dev)))
326
 
                goto err_prog_firmware;
 
261
                goto err_add_card;
327
262
 
328
263
        cardp->priv = priv;
329
 
        cardp->priv->fw_ready = 1;
330
264
 
331
265
        priv->hw_host_to_card = if_usb_host_to_card;
332
266
        priv->enter_deep_sleep = NULL;
339
273
 
340
274
        cardp->boot2_version = udev->descriptor.bcdDevice;
341
275
 
342
 
        if_usb_submit_rx_urb(cardp);
343
 
 
344
 
        if (lbs_start_card(priv))
345
 
                goto err_start_card;
346
 
 
347
 
        if_usb_setup_firmware(priv);
348
 
 
349
276
        usb_get_dev(udev);
350
277
        usb_set_intfdata(intf, cardp);
351
278
 
352
 
        if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
353
 
                netdev_err(priv->dev,
354
 
                           "cannot register lbs_flash_fw attribute\n");
355
 
 
356
 
        if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
357
 
                netdev_err(priv->dev,
358
 
                           "cannot register lbs_flash_boot2 attribute\n");
359
 
 
360
 
        /*
361
 
         * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
362
 
         */
363
 
        priv->wol_criteria = EHS_REMOVE_WAKEUP;
364
 
        if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
365
 
                priv->ehs_remove_supported = false;
 
279
        r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
 
280
                                   fw_table, if_usb_prog_firmware);
 
281
        if (r)
 
282
                goto err_get_fw;
366
283
 
367
284
        return 0;
368
285
 
369
 
err_start_card:
 
286
err_get_fw:
370
287
        lbs_remove_card(priv);
371
 
err_prog_firmware:
 
288
err_add_card:
372
289
        if_usb_reset_device(cardp);
373
290
dealloc:
374
291
        if_usb_free(cardp);
375
292
 
376
293
error:
377
 
        return -ENOMEM;
 
294
        return r;
378
295
}
379
296
 
380
297
/**
389
306
 
390
307
        lbs_deb_enter(LBS_DEB_MAIN);
391
308
 
392
 
        device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2);
393
 
        device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_fw);
394
 
 
395
309
        cardp->surprise_removed = 1;
396
310
 
397
311
        if (priv) {
912
826
        return ret;
913
827
}
914
828
 
915
 
 
916
 
/**
917
 
*  if_usb_prog_firmware - programs the firmware subject to cmd
918
 
*
919
 
*  @cardp:      the if_usb_card descriptor
920
 
*  @fwname:     firmware or boot2 image file name
921
 
*  @cmd:        either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
922
 
*               or BOOT_CMD_UPDATE_BOOT2.
923
 
*  returns:     0 or error code
924
 
*/
925
 
static int if_usb_prog_firmware(struct if_usb_card *cardp,
926
 
                                const char *fwname, int cmd)
927
 
{
928
 
        struct lbs_private *priv = cardp->priv;
929
 
        unsigned long flags, caps;
930
 
        int ret;
931
 
 
932
 
        caps = priv->fwcapinfo;
933
 
        if (((cmd == BOOT_CMD_UPDATE_FW) && !(caps & FW_CAPINFO_FIRMWARE_UPGRADE)) ||
934
 
            ((cmd == BOOT_CMD_UPDATE_BOOT2) && !(caps & FW_CAPINFO_BOOT2_UPGRADE)))
935
 
                return -EOPNOTSUPP;
936
 
 
937
 
        /* Ensure main thread is idle. */
938
 
        spin_lock_irqsave(&priv->driver_lock, flags);
939
 
        while (priv->cur_cmd != NULL || priv->dnld_sent != DNLD_RES_RECEIVED) {
940
 
                spin_unlock_irqrestore(&priv->driver_lock, flags);
941
 
                if (wait_event_interruptible(priv->waitq,
942
 
                                (priv->cur_cmd == NULL &&
943
 
                                priv->dnld_sent == DNLD_RES_RECEIVED))) {
944
 
                        return -ERESTARTSYS;
945
 
                }
946
 
                spin_lock_irqsave(&priv->driver_lock, flags);
947
 
        }
948
 
        priv->dnld_sent = DNLD_BOOTCMD_SENT;
949
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
950
 
 
951
 
        ret = __if_usb_prog_firmware(cardp, fwname, cmd);
952
 
 
953
 
        spin_lock_irqsave(&priv->driver_lock, flags);
954
 
        priv->dnld_sent = DNLD_RES_RECEIVED;
955
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
956
 
 
957
 
        wake_up(&priv->waitq);
958
 
 
959
 
        return ret;
960
 
}
961
 
 
962
 
/* table of firmware file names */
963
 
static const struct {
964
 
        u32 model;
965
 
        const char *fwname;
966
 
} fw_table[] = {
967
 
        { MODEL_8388, "libertas/usb8388_v9.bin" },
968
 
        { MODEL_8388, "libertas/usb8388_v5.bin" },
969
 
        { MODEL_8388, "libertas/usb8388.bin" },
970
 
        { MODEL_8388, "usb8388.bin" },
971
 
        { MODEL_8682, "libertas/usb8682.bin" }
972
 
};
973
 
 
974
 
#ifdef CONFIG_OLPC
975
 
 
976
 
static int try_olpc_fw(struct if_usb_card *cardp)
977
 
{
978
 
        int retval = -ENOENT;
979
 
 
980
 
        /* try the OLPC firmware first; fall back to fw_table list */
981
 
        if (machine_is_olpc() && cardp->model == MODEL_8388)
982
 
                retval = request_firmware(&cardp->fw,
983
 
                                "libertas/usb8388_olpc.bin", &cardp->udev->dev);
984
 
        return retval;
985
 
}
986
 
 
987
 
#else
988
 
static int try_olpc_fw(struct if_usb_card *cardp) { return -ENOENT; }
989
 
#endif /* !CONFIG_OLPC */
990
 
 
991
 
static int get_fw(struct if_usb_card *cardp, const char *fwname)
992
 
{
993
 
        int i;
994
 
 
995
 
        /* Try user-specified firmware first */
996
 
        if (fwname)
997
 
                return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
998
 
 
999
 
        /* Handle OLPC firmware */
1000
 
        if (try_olpc_fw(cardp) == 0)
1001
 
                return 0;
1002
 
 
1003
 
        /* Otherwise search for firmware to use */
1004
 
        for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
1005
 
                if (fw_table[i].model != cardp->model)
1006
 
                        continue;
1007
 
                if (request_firmware(&cardp->fw, fw_table[i].fwname,
1008
 
                                        &cardp->udev->dev) == 0)
1009
 
                        return 0;
1010
 
        }
1011
 
 
1012
 
        return -ENOENT;
1013
 
}
1014
 
 
1015
 
static int __if_usb_prog_firmware(struct if_usb_card *cardp,
1016
 
                                        const char *fwname, int cmd)
1017
 
{
 
829
static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
 
830
                                 const struct firmware *fw,
 
831
                                 const struct firmware *unused)
 
832
{
 
833
        struct if_usb_card *cardp = priv->card;
1018
834
        int i = 0;
1019
835
        static int reset_count = 10;
1020
 
        int ret = 0;
1021
836
 
1022
837
        lbs_deb_enter(LBS_DEB_USB);
1023
838
 
1024
 
        ret = get_fw(cardp, fwname);
1025
839
        if (ret) {
1026
840
                pr_err("failed to find firmware (%d)\n", ret);
1027
841
                goto done;
1028
842
        }
1029
843
 
 
844
        cardp->fw = fw;
1030
845
        if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
1031
846
                ret = -EINVAL;
1032
847
                goto release_fw;
1053
868
        do {
1054
869
                int j = 0;
1055
870
                i++;
1056
 
                if_usb_issue_boot_command(cardp, cmd);
 
871
                if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
1057
872
                /* wait for command response */
1058
873
                do {
1059
874
                        j++;
1109
924
                goto release_fw;
1110
925
        }
1111
926
 
 
927
        cardp->priv->fw_ready = 1;
 
928
        if_usb_submit_rx_urb(cardp);
 
929
 
 
930
        if (lbs_start_card(priv))
 
931
                goto release_fw;
 
932
 
 
933
        if_usb_setup_firmware(priv);
 
934
 
 
935
        /*
 
936
         * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
 
937
         */
 
938
        priv->wol_criteria = EHS_REMOVE_WAKEUP;
 
939
        if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
 
940
                priv->ehs_remove_supported = false;
 
941
 
1112
942
 release_fw:
1113
943
        release_firmware(cardp->fw);
1114
944
        cardp->fw = NULL;
1115
945
 
1116
946
 done:
1117
 
        lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
1118
 
        return ret;
 
947
        lbs_deb_leave(LBS_DEB_USB);
1119
948
}
1120
949
 
1121
950
 
1128
957
 
1129
958
        lbs_deb_enter(LBS_DEB_USB);
1130
959
 
1131
 
        if (priv->psstate != PS_STATE_FULL_POWER)
1132
 
                return -1;
 
960
        if (priv->psstate != PS_STATE_FULL_POWER) {
 
961
                ret = -1;
 
962
                goto out;
 
963
        }
1133
964
 
1134
965
#ifdef CONFIG_OLPC
1135
966
        if (machine_is_olpc()) {
1180
1011
        .suspend = if_usb_suspend,
1181
1012
        .resume = if_usb_resume,
1182
1013
        .reset_resume = if_usb_resume,
 
1014
        .disable_hub_initiated_lpm = 1,
1183
1015
};
1184
1016
 
1185
1017
module_usb_driver(if_usb_driver);