blob: d440f284bf1891c8bec4c1afc95996a8241debea [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *
20 * File: baseband.c
21 *
22 * Purpose: Implement functions to access baseband
23 *
24 * Author: Yiching Chen
25 *
26 * Date: May 20, 2004
27 *
28 * Functions:
29 *
30 * Revision History:
31 *
32 */
33
Cédric Cabessaf2ca4072014-03-26 17:49:01 +010034#include <linux/compiler.h>
Forest Bond92b96792009-06-13 07:38:31 -040035#include "firmware.h"
Malcolm Priestley62c85262014-05-26 13:59:07 +010036#include "usbpipe.h"
Forest Bond92b96792009-06-13 07:38:31 -040037
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000038#define FIRMWARE_VERSION 0x133 /* version 1.51 */
39#define FIRMWARE_NAME "vntwusb.fw"
40
41#define FIRMWARE_CHUNK_SIZE 0x400
42
Malcolm Priestley6a86b772014-06-04 18:25:31 +010043int vnt_download_firmware(struct vnt_private *priv)
Forest Bond92b96792009-06-13 07:38:31 -040044{
Malcolm Priestleyda47d982014-06-04 18:25:27 +010045 struct device *dev = &priv->usb->dev;
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000046 const struct firmware *fw;
Malcolm Priestleyda47d982014-06-04 18:25:27 +010047 int status;
48 void *buffer = NULL;
Andres Moree269fc22013-02-12 20:36:29 -050049 bool result = false;
Malcolm Priestleyda47d982014-06-04 18:25:27 +010050 u16 length;
Malcolm Priestleyf20fbdf82012-10-07 11:41:31 +010051 int ii, rc;
52
Malcolm Priestley9197f352014-06-04 18:25:30 +010053 dev_dbg(dev, "---->Download firmware\n");
Forest Bond92b96792009-06-13 07:38:31 -040054
Malcolm Priestleyf20fbdf82012-10-07 11:41:31 +010055 rc = request_firmware(&fw, FIRMWARE_NAME, dev);
56 if (rc) {
57 dev_err(dev, "firmware file %s request failed (%d)\n",
58 FIRMWARE_NAME, rc);
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000059 goto out;
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000060 }
Forest Bond92b96792009-06-13 07:38:31 -040061
Malcolm Priestleyda47d982014-06-04 18:25:27 +010062 buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
63 if (!buffer)
Christian Engelmayerd34add02015-02-11 20:33:15 +010064 goto free_fw;
Forest Bond92b96792009-06-13 07:38:31 -040065
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000066 for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
Malcolm Priestleyda47d982014-06-04 18:25:27 +010067 length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
68 memcpy(buffer, fw->data + ii, length);
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000069
Malcolm Priestleyda47d982014-06-04 18:25:27 +010070 status = vnt_control_out(priv,
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +053071 0,
72 0x1200+ii,
73 0x0000,
Malcolm Priestleyda47d982014-06-04 18:25:27 +010074 length,
75 buffer);
Forest Bond92b96792009-06-13 07:38:31 -040076
Malcolm Priestley9197f352014-06-04 18:25:30 +010077 dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
78
Malcolm Priestleyda47d982014-06-04 18:25:27 +010079 if (status != STATUS_SUCCESS)
Malcolm Priestleyf20fbdf82012-10-07 11:41:31 +010080 goto free_fw;
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +053081 }
Forest Bond92b96792009-06-13 07:38:31 -040082
Andres More4e9b5e22013-02-12 20:36:30 -050083 result = true;
Malcolm Priestleyf20fbdf82012-10-07 11:41:31 +010084free_fw:
85 release_firmware(fw);
Forest Bond92b96792009-06-13 07:38:31 -040086
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000087out:
Malcolm Priestleyda47d982014-06-04 18:25:27 +010088 kfree(buffer);
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000089
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000090 return result;
Forest Bond92b96792009-06-13 07:38:31 -040091}
Ben Hutchings31d5bbf2011-01-09 04:16:48 +000092MODULE_FIRMWARE(FIRMWARE_NAME);
Forest Bond92b96792009-06-13 07:38:31 -040093
Malcolm Priestley14321462014-06-04 18:25:32 +010094int vnt_firmware_branch_to_sram(struct vnt_private *priv)
Forest Bond92b96792009-06-13 07:38:31 -040095{
Malcolm Priestleye21a53c2014-06-04 18:25:28 +010096 int status;
Forest Bond92b96792009-06-13 07:38:31 -040097
Malcolm Priestley9197f352014-06-04 18:25:30 +010098 dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
Forest Bond92b96792009-06-13 07:38:31 -040099
Malcolm Priestleye21a53c2014-06-04 18:25:28 +0100100 status = vnt_control_out(priv,
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +0530101 1,
102 0x1200,
103 0x0000,
104 0,
105 NULL);
Tapasweni Pathakf0cffbf2014-09-28 18:11:54 +0530106 return status == STATUS_SUCCESS;
Forest Bond92b96792009-06-13 07:38:31 -0400107}
108
Malcolm Priestley45d63f82014-06-04 18:25:33 +0100109int vnt_check_firmware_version(struct vnt_private *priv)
Forest Bond92b96792009-06-13 07:38:31 -0400110{
Malcolm Priestley0fe8b952014-06-04 18:25:29 +0100111 int status;
Forest Bond92b96792009-06-13 07:38:31 -0400112
Malcolm Priestley0fe8b952014-06-04 18:25:29 +0100113 status = vnt_control_in(priv,
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +0530114 MESSAGE_TYPE_READ,
115 0,
116 MESSAGE_REQUEST_VERSION,
117 2,
Malcolm Priestley8a73f9d2014-07-19 12:30:05 +0100118 (u8 *)&priv->firmware_version);
Forest Bond92b96792009-06-13 07:38:31 -0400119
Malcolm Priestley9197f352014-06-04 18:25:30 +0100120 dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
Malcolm Priestley8a73f9d2014-07-19 12:30:05 +0100121 priv->firmware_version);
Malcolm Priestley9197f352014-06-04 18:25:30 +0100122
Malcolm Priestley0fe8b952014-06-04 18:25:29 +0100123 if (status != STATUS_SUCCESS) {
Malcolm Priestley9197f352014-06-04 18:25:30 +0100124 dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +0530125 return false;
126 }
Malcolm Priestley8a73f9d2014-07-19 12:30:05 +0100127 if (priv->firmware_version == 0xFFFF) {
Malcolm Priestley9197f352014-06-04 18:25:30 +0100128 dev_dbg(&priv->usb->dev, "In Loader.\n");
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +0530129 return false;
130 }
Malcolm Priestley9197f352014-06-04 18:25:30 +0100131
132 dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
Malcolm Priestley8a73f9d2014-07-19 12:30:05 +0100133 priv->firmware_version);
Malcolm Priestley9197f352014-06-04 18:25:30 +0100134
Malcolm Priestley8a73f9d2014-07-19 12:30:05 +0100135 if (priv->firmware_version < FIRMWARE_VERSION) {
Nandini Hanumanthagowdaefbe5182013-10-18 00:22:26 +0530136 /* branch to loader for download new firmware */
Malcolm Priestley14321462014-06-04 18:25:32 +0100137 vnt_firmware_branch_to_sram(priv);
Nandini Hanumanthagowda1266ed72013-10-18 00:22:23 +0530138 return false;
139 }
140 return true;
Forest Bond92b96792009-06-13 07:38:31 -0400141}