• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *
16  * File: baseband.c
17  *
18  * Purpose: Implement functions to access baseband
19  *
20  * Author: Yiching Chen
21  *
22  * Date: May 20, 2004
23  *
24  * Functions:
25  *
26  * Revision History:
27  *
28  */
29 
30 #include <linux/compiler.h>
31 #include "firmware.h"
32 #include "usbpipe.h"
33 
34 #define FIRMWARE_VERSION	0x133		/* version 1.51 */
35 #define FIRMWARE_NAME		"vntwusb.fw"
36 
37 #define FIRMWARE_CHUNK_SIZE	0x400
38 
vnt_download_firmware(struct vnt_private * priv)39 int vnt_download_firmware(struct vnt_private *priv)
40 {
41 	struct device *dev = &priv->usb->dev;
42 	const struct firmware *fw;
43 	int status;
44 	void *buffer = NULL;
45 	bool result = false;
46 	u16 length;
47 	int ii, rc;
48 
49 	dev_dbg(dev, "---->Download firmware\n");
50 
51 	rc = request_firmware(&fw, FIRMWARE_NAME, dev);
52 	if (rc) {
53 		dev_err(dev, "firmware file %s request failed (%d)\n",
54 			FIRMWARE_NAME, rc);
55 			goto out;
56 	}
57 
58 	buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
59 	if (!buffer)
60 		goto free_fw;
61 
62 	for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
63 		length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
64 		memcpy(buffer, fw->data + ii, length);
65 
66 		status = vnt_control_out(priv,
67 					 0,
68 					 0x1200 + ii,
69 					 0x0000,
70 					 length,
71 					 buffer);
72 
73 		dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
74 
75 		if (status != STATUS_SUCCESS)
76 			goto free_fw;
77 	}
78 
79 	result = true;
80 free_fw:
81 	release_firmware(fw);
82 
83 out:
84 	kfree(buffer);
85 
86 	return result;
87 }
88 MODULE_FIRMWARE(FIRMWARE_NAME);
89 
vnt_firmware_branch_to_sram(struct vnt_private * priv)90 int vnt_firmware_branch_to_sram(struct vnt_private *priv)
91 {
92 	int status;
93 
94 	dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
95 
96 	status = vnt_control_out(priv,
97 				 1,
98 				 0x1200,
99 				 0x0000,
100 				 0,
101 				 NULL);
102 	return status == STATUS_SUCCESS;
103 }
104 
vnt_check_firmware_version(struct vnt_private * priv)105 int vnt_check_firmware_version(struct vnt_private *priv)
106 {
107 	int status;
108 
109 	status = vnt_control_in(priv,
110 				MESSAGE_TYPE_READ,
111 				0,
112 				MESSAGE_REQUEST_VERSION,
113 				2,
114 				(u8 *)&priv->firmware_version);
115 
116 	dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
117 		priv->firmware_version);
118 
119 	if (status != STATUS_SUCCESS) {
120 		dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
121 		return false;
122 	}
123 	if (priv->firmware_version == 0xFFFF) {
124 		dev_dbg(&priv->usb->dev, "In Loader.\n");
125 		return false;
126 	}
127 
128 	dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
129 		priv->firmware_version);
130 
131 	if (priv->firmware_version < FIRMWARE_VERSION) {
132 		/* branch to loader for download new firmware */
133 		vnt_firmware_branch_to_sram(priv);
134 		return false;
135 	}
136 	return true;
137 }
138