GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / staging / vt6656 / firmware.c
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           "/*(DEBLOBBED)*/"
26
27 #define FIRMWARE_CHUNK_SIZE     0x400
28
29 int 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 = reject_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;
70 free_fw:
71         release_firmware(fw);
72
73 out:
74         kfree(buffer);
75
76         return result;
77 }
78 /*(DEBLOBBED)*/
79
80 int 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
95 int 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                 /* branch to loader for download new firmware */
123                 vnt_firmware_branch_to_sram(priv);
124                 return false;
125         }
126         return true;
127 }