• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * File: baseband.c
7  *
8  * Purpose: Implement functions to access baseband
9  *
10  * Author: Yiching Chen
11  *
12  * Date: May 20, 2004
13  *
14  * Functions:
15  *
16  * Revision History:
17  *
18  */
19 
20 #include <linux/compiler.h>
21 #include "firmware.h"
22 #include "usbpipe.h"
23 
24 #define FIRMWARE_VERSION	0x133		/* version 1.51 */
25 #define FIRMWARE_NAME		"vntwusb.fw"
26 
27 #define FIRMWARE_CHUNK_SIZE	0x400
28 
vnt_download_firmware(struct vnt_private * priv)29 int vnt_download_firmware(struct vnt_private *priv)
30 {
31 	struct device *dev = &priv->usb->dev;
32 	const struct firmware *fw;
33 	void *buffer = NULL;
34 	u16 length;
35 	int ii;
36 	int ret = 0;
37 
38 	dev_dbg(dev, "---->Download firmware\n");
39 
40 	ret = request_firmware(&fw, FIRMWARE_NAME, dev);
41 	if (ret) {
42 		dev_err(dev, "firmware file %s request failed (%d)\n",
43 			FIRMWARE_NAME, ret);
44 		goto end;
45 	}
46 
47 	buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
48 	if (!buffer) {
49 		ret = -ENOMEM;
50 		goto free_fw;
51 	}
52 
53 	for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
54 		length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
55 		memcpy(buffer, fw->data + ii, length);
56 
57 		ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length,
58 				      buffer);
59 		if (ret)
60 			goto free_buffer;
61 
62 		dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
63 	}
64 
65 free_buffer:
66 	kfree(buffer);
67 free_fw:
68 	release_firmware(fw);
69 end:
70 	return ret;
71 }
72 MODULE_FIRMWARE(FIRMWARE_NAME);
73 
vnt_firmware_branch_to_sram(struct vnt_private * priv)74 int vnt_firmware_branch_to_sram(struct vnt_private *priv)
75 {
76 	dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
77 
78 	return vnt_control_out(priv, 1, 0x1200, 0x0000, 0, NULL);
79 }
80 
vnt_check_firmware_version(struct vnt_private * priv)81 int vnt_check_firmware_version(struct vnt_private *priv)
82 {
83 	int ret = 0;
84 
85 	ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0,
86 			     MESSAGE_REQUEST_VERSION, 2,
87 			     (u8 *)&priv->firmware_version);
88 	if (ret) {
89 		dev_dbg(&priv->usb->dev,
90 			"Could not get firmware version: %d.\n", ret);
91 		goto end;
92 	}
93 
94 	dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
95 		priv->firmware_version);
96 
97 	if (priv->firmware_version == 0xFFFF) {
98 		dev_dbg(&priv->usb->dev, "In Loader.\n");
99 		ret = -EINVAL;
100 		goto end;
101 	}
102 
103 	if (priv->firmware_version < FIRMWARE_VERSION) {
104 		/* branch to loader for download new firmware */
105 		ret = vnt_firmware_branch_to_sram(priv);
106 		if (ret) {
107 			dev_dbg(&priv->usb->dev,
108 				"Could not branch to SRAM: %d.\n", ret);
109 		} else {
110 			ret = -EINVAL;
111 		}
112 	}
113 
114 end:
115 	return ret;
116 }
117