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