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