This source file includes following definitions.
- i1480_mpi_write
- i1480_mpi_read
- i1480_phy_fw_upload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <linux/delay.h>
16 #include <linux/device.h>
17 #include <linux/firmware.h>
18 #include "../../../wusbcore/include/wusb.h"
19 #include "i1480-dfu.h"
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 static
38 int i1480_mpi_write(struct i1480 *i1480, const void *data, size_t size)
39 {
40 int result;
41 struct i1480_cmd_mpi_write *cmd = i1480->cmd_buf;
42 struct i1480_evt_confirm *reply = i1480->evt_buf;
43
44 BUG_ON(size > 480);
45 result = -ENOMEM;
46 cmd->rccb.bCommandType = i1480_CET_VS1;
47 cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_WRITE);
48 cmd->size = cpu_to_le16(size);
49 memcpy(cmd->data, data, size);
50 reply->rceb.bEventType = i1480_CET_VS1;
51 reply->rceb.wEvent = i1480_CMD_MPI_WRITE;
52 result = i1480_cmd(i1480, "MPI-WRITE", sizeof(*cmd) + size, sizeof(*reply));
53 if (result < 0)
54 goto out;
55 if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
56 dev_err(i1480->dev, "MPI-WRITE: command execution failed: %d\n",
57 reply->bResultCode);
58 result = -EIO;
59 }
60 out:
61 return result;
62 }
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 static
86 int i1480_mpi_read(struct i1480 *i1480, u8 *data, u16 srcaddr, size_t size)
87 {
88 int result;
89 struct i1480_cmd_mpi_read *cmd = i1480->cmd_buf;
90 struct i1480_evt_mpi_read *reply = i1480->evt_buf;
91 unsigned cnt;
92
93 memset(i1480->cmd_buf, 0x69, 512);
94 memset(i1480->evt_buf, 0x69, 512);
95
96 BUG_ON(size > (i1480->buf_size - sizeof(*reply)) / 3);
97 result = -ENOMEM;
98 cmd->rccb.bCommandType = i1480_CET_VS1;
99 cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_READ);
100 cmd->size = cpu_to_le16(3*size);
101 for (cnt = 0; cnt < size; cnt++) {
102 cmd->data[cnt].page = (srcaddr + cnt) >> 8;
103 cmd->data[cnt].offset = (srcaddr + cnt) & 0xff;
104 }
105 reply->rceb.bEventType = i1480_CET_VS1;
106 reply->rceb.wEvent = i1480_CMD_MPI_READ;
107 result = i1480_cmd(i1480, "MPI-READ", sizeof(*cmd) + 2*size,
108 sizeof(*reply) + 3*size);
109 if (result < 0)
110 goto out;
111 if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
112 dev_err(i1480->dev, "MPI-READ: command execution failed: %d\n",
113 reply->bResultCode);
114 result = -EIO;
115 goto out;
116 }
117 for (cnt = 0; cnt < size; cnt++) {
118 if (reply->data[cnt].page != (srcaddr + cnt) >> 8)
119 dev_err(i1480->dev, "MPI-READ: page inconsistency at "
120 "index %u: expected 0x%02x, got 0x%02x\n", cnt,
121 (srcaddr + cnt) >> 8, reply->data[cnt].page);
122 if (reply->data[cnt].offset != ((srcaddr + cnt) & 0x00ff))
123 dev_err(i1480->dev, "MPI-READ: offset inconsistency at "
124 "index %u: expected 0x%02x, got 0x%02x\n", cnt,
125 (srcaddr + cnt) & 0x00ff,
126 reply->data[cnt].offset);
127 data[cnt] = reply->data[cnt].value;
128 }
129 result = 0;
130 out:
131 return result;
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 int i1480_phy_fw_upload(struct i1480 *i1480)
150 {
151 int result;
152 const struct firmware *fw;
153 const char *data_itr, *data_top;
154 const size_t MAX_BLK_SIZE = 480;
155 size_t data_size;
156 u8 phy_stat;
157
158 result = request_firmware(&fw, i1480->phy_fw_name, i1480->dev);
159 if (result < 0)
160 goto out;
161
162 for (data_itr = fw->data, data_top = data_itr + fw->size;
163 data_itr < data_top; data_itr += MAX_BLK_SIZE) {
164 data_size = min(MAX_BLK_SIZE, (size_t) (data_top - data_itr));
165 result = i1480_mpi_write(i1480, data_itr, data_size);
166 if (result < 0)
167 goto error_mpi_write;
168 }
169
170 result = i1480_mpi_read(i1480, &phy_stat, 0x0006, 1);
171 if (result < 0) {
172 dev_err(i1480->dev, "PHY: can't get status: %d\n", result);
173 goto error_mpi_status;
174 }
175 if (phy_stat != 0) {
176 result = -ENODEV;
177 dev_info(i1480->dev, "error, PHY not ready: %u\n", phy_stat);
178 goto error_phy_status;
179 }
180 dev_info(i1480->dev, "PHY fw '%s': uploaded\n", i1480->phy_fw_name);
181 error_phy_status:
182 error_mpi_status:
183 error_mpi_write:
184 release_firmware(fw);
185 if (result < 0)
186 dev_err(i1480->dev, "PHY fw '%s': failed to upload (%d), "
187 "power cycle device\n", i1480->phy_fw_name, result);
188 out:
189 return result;
190 }