Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 1 | /* |
| 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 Cabessa | f2ca407 | 2014-03-26 17:49:01 +0100 | [diff] [blame] | 34 | #include <linux/compiler.h> |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 35 | #include "firmware.h" |
Malcolm Priestley | 62c8526 | 2014-05-26 13:59:07 +0100 | [diff] [blame] | 36 | #include "usbpipe.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 37 | |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 38 | #define FIRMWARE_VERSION 0x133 /* version 1.51 */ |
| 39 | #define FIRMWARE_NAME "vntwusb.fw" |
| 40 | |
| 41 | #define FIRMWARE_CHUNK_SIZE 0x400 |
| 42 | |
Malcolm Priestley | 6a86b77 | 2014-06-04 18:25:31 +0100 | [diff] [blame] | 43 | int vnt_download_firmware(struct vnt_private *priv) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 44 | { |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 45 | struct device *dev = &priv->usb->dev; |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 46 | const struct firmware *fw; |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 47 | int status; |
| 48 | void *buffer = NULL; |
Andres More | e269fc2 | 2013-02-12 20:36:29 -0500 | [diff] [blame] | 49 | bool result = false; |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 50 | u16 length; |
Malcolm Priestley | f20fbdf8 | 2012-10-07 11:41:31 +0100 | [diff] [blame] | 51 | int ii, rc; |
| 52 | |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 53 | dev_dbg(dev, "---->Download firmware\n"); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 54 | |
Malcolm Priestley | f20fbdf8 | 2012-10-07 11:41:31 +0100 | [diff] [blame] | 55 | 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 Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 59 | goto out; |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 60 | } |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 61 | |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 62 | buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); |
| 63 | if (!buffer) |
Christian Engelmayer | d34add0 | 2015-02-11 20:33:15 +0100 | [diff] [blame] | 64 | goto free_fw; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 65 | |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 66 | for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 67 | length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); |
| 68 | memcpy(buffer, fw->data + ii, length); |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 69 | |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 70 | status = vnt_control_out(priv, |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 71 | 0, |
| 72 | 0x1200+ii, |
| 73 | 0x0000, |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 74 | length, |
| 75 | buffer); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 76 | |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 77 | dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size); |
| 78 | |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 79 | if (status != STATUS_SUCCESS) |
Malcolm Priestley | f20fbdf8 | 2012-10-07 11:41:31 +0100 | [diff] [blame] | 80 | goto free_fw; |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 81 | } |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 82 | |
Andres More | 4e9b5e2 | 2013-02-12 20:36:30 -0500 | [diff] [blame] | 83 | result = true; |
Malcolm Priestley | f20fbdf8 | 2012-10-07 11:41:31 +0100 | [diff] [blame] | 84 | free_fw: |
| 85 | release_firmware(fw); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 86 | |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 87 | out: |
Malcolm Priestley | da47d98 | 2014-06-04 18:25:27 +0100 | [diff] [blame] | 88 | kfree(buffer); |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 89 | |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 90 | return result; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 91 | } |
Ben Hutchings | 31d5bbf | 2011-01-09 04:16:48 +0000 | [diff] [blame] | 92 | MODULE_FIRMWARE(FIRMWARE_NAME); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 93 | |
Malcolm Priestley | 1432146 | 2014-06-04 18:25:32 +0100 | [diff] [blame] | 94 | int vnt_firmware_branch_to_sram(struct vnt_private *priv) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 95 | { |
Malcolm Priestley | e21a53c | 2014-06-04 18:25:28 +0100 | [diff] [blame] | 96 | int status; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 97 | |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 98 | dev_dbg(&priv->usb->dev, "---->Branch to Sram\n"); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 99 | |
Malcolm Priestley | e21a53c | 2014-06-04 18:25:28 +0100 | [diff] [blame] | 100 | status = vnt_control_out(priv, |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 101 | 1, |
| 102 | 0x1200, |
| 103 | 0x0000, |
| 104 | 0, |
| 105 | NULL); |
Tapasweni Pathak | f0cffbf | 2014-09-28 18:11:54 +0530 | [diff] [blame] | 106 | return status == STATUS_SUCCESS; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 107 | } |
| 108 | |
Malcolm Priestley | 45d63f8 | 2014-06-04 18:25:33 +0100 | [diff] [blame] | 109 | int vnt_check_firmware_version(struct vnt_private *priv) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 110 | { |
Malcolm Priestley | 0fe8b95 | 2014-06-04 18:25:29 +0100 | [diff] [blame] | 111 | int status; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 112 | |
Malcolm Priestley | 0fe8b95 | 2014-06-04 18:25:29 +0100 | [diff] [blame] | 113 | status = vnt_control_in(priv, |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 114 | MESSAGE_TYPE_READ, |
| 115 | 0, |
| 116 | MESSAGE_REQUEST_VERSION, |
| 117 | 2, |
Malcolm Priestley | 8a73f9d | 2014-07-19 12:30:05 +0100 | [diff] [blame] | 118 | (u8 *)&priv->firmware_version); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 119 | |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 120 | dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", |
Malcolm Priestley | 8a73f9d | 2014-07-19 12:30:05 +0100 | [diff] [blame] | 121 | priv->firmware_version); |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 122 | |
Malcolm Priestley | 0fe8b95 | 2014-06-04 18:25:29 +0100 | [diff] [blame] | 123 | if (status != STATUS_SUCCESS) { |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 124 | dev_dbg(&priv->usb->dev, "Firmware Invalid.\n"); |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 125 | return false; |
| 126 | } |
Malcolm Priestley | 8a73f9d | 2014-07-19 12:30:05 +0100 | [diff] [blame] | 127 | if (priv->firmware_version == 0xFFFF) { |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 128 | dev_dbg(&priv->usb->dev, "In Loader.\n"); |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 129 | return false; |
| 130 | } |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 131 | |
| 132 | dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", |
Malcolm Priestley | 8a73f9d | 2014-07-19 12:30:05 +0100 | [diff] [blame] | 133 | priv->firmware_version); |
Malcolm Priestley | 9197f35 | 2014-06-04 18:25:30 +0100 | [diff] [blame] | 134 | |
Malcolm Priestley | 8a73f9d | 2014-07-19 12:30:05 +0100 | [diff] [blame] | 135 | if (priv->firmware_version < FIRMWARE_VERSION) { |
Nandini Hanumanthagowda | efbe518 | 2013-10-18 00:22:26 +0530 | [diff] [blame] | 136 | /* branch to loader for download new firmware */ |
Malcolm Priestley | 1432146 | 2014-06-04 18:25:32 +0100 | [diff] [blame] | 137 | vnt_firmware_branch_to_sram(priv); |
Nandini Hanumanthagowda | 1266ed7 | 2013-10-18 00:22:23 +0530 | [diff] [blame] | 138 | return false; |
| 139 | } |
| 140 | return true; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 141 | } |