]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/bcm/InterfaceDld.c
Staging: bcm: hostmibs: Added temporary variable to shorten lines
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / bcm / InterfaceDld.c
CommitLineData
f8942e07
SH
1#include "headers.h"
2
43664e14 3int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
f8942e07 4{
a5e4b81e 5 /* unsigned int reg = 0; */
43664e14 6 mm_segment_t oldfs = {0};
a5e4b81e 7 int errno = 0, len = 0; /* ,is_config_file = 0 */
43664e14 8 loff_t pos = 0;
f8942e07 9 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
a5e4b81e 10 /* PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; */
43664e14 11 char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
f8942e07 12
43664e14
MPS
13 if (!buff)
14 return -ENOMEM;
f8942e07 15
43664e14
MPS
16 while (1) {
17 oldfs = get_fs();
18 set_fs(get_ds());
19 len = vfs_read(flp, (void __force __user *)buff,
a5e4b81e 20 MAX_TRANSFER_CTRL_BYTE_USB, &pos);
43664e14
MPS
21 set_fs(oldfs);
22 if (len <= 0) {
23 if (len < 0) {
24 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
25 DBG_TYPE_INITEXIT, MP_INIT,
26 DBG_LVL_ALL, "len < 0");
27 errno = len;
28 } else {
29 errno = 0;
30 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
31 DBG_TYPE_INITEXIT, MP_INIT,
32 DBG_LVL_ALL,
33 "Got end of file!");
34 }
35 break;
36 }
37 /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
a5e4b81e
KM
38 * DBG_LVL_ALL, buff,
39 * MAX_TRANSFER_CTRL_BYTE_USB);
40 */
43664e14
MPS
41 errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
42 if (errno) {
43 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
44 DBG_TYPE_PRINTK, 0, 0,
45 "WRM Failed! status: %d", errno);
46 break;
f8942e07 47 }
43664e14
MPS
48 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
49 }
f8942e07 50
082e889b 51 kfree(buff);
43664e14 52 return errno;
f8942e07
SH
53}
54
a5e4b81e 55int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc)
f8942e07 56{
43664e14
MPS
57 char *buff, *buff_readback;
58 unsigned int reg = 0;
a5e4b81e
KM
59 mm_segment_t oldfs = {0};
60 int errno = 0, len = 0, is_config_file = 0;
61 loff_t pos = 0;
a8658182 62 static int fw_down;
a5e4b81e 63 INT Status = STATUS_SUCCESS;
f8942e07
SH
64 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
65
a5e4b81e
KM
66 buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
67 buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
68 if (!buff || !buff_readback) {
69 kfree(buff);
70 kfree(buff_readback);
f8942e07 71
a5e4b81e
KM
72 return -ENOMEM;
73 }
f8942e07 74
a5e4b81e 75 is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
f8942e07
SH
76
77 memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
78 memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
a5e4b81e
KM
79 while (1) {
80 oldfs = get_fs();
81 set_fs(get_ds());
82 len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
83 set_fs(oldfs);
84 fw_down++;
f8942e07 85
a5e4b81e
KM
86 if (len <= 0) {
87 if (len < 0) {
88 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
89 errno = len;
90 } else {
91 errno = 0;
92 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
93 }
94 break;
95 }
f8942e07
SH
96
97 Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
a5e4b81e
KM
98 if (Status) {
99 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
f8942e07
SH
100 goto exit;
101 }
102 reg++;
a5e4b81e
KM
103 if ((len-sizeof(unsigned int)) < 4) {
104 if (memcmp(buff_readback, buff, len)) {
105 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
106 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len);
f8942e07
SH
107 Status = -EIO;
108 goto exit;
a5e4b81e
KM
109 }
110 } else {
111 len -= 4;
112
113 while (len) {
114 if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) {
115 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
116 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]);
117 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
f8942e07
SH
118 Status = -EIO;
119 goto exit;
a5e4b81e
KM
120 }
121 len -= 4;
122 }
123 }
124 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
125 } /* End of while(1) */
126
f8942e07 127exit:
a5e4b81e
KM
128 kfree(buff);
129 kfree(buff_readback);
f8942e07
SH
130 return Status;
131}
132
a5e4b81e 133static int bcm_download_config_file(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
f8942e07
SH
134{
135 int retval = STATUS_SUCCESS;
136 B_UINT32 value = 0;
137
a5e4b81e 138 if (Adapter->pstargetparams == NULL) {
a8658182
KM
139 Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL);
140 if (Adapter->pstargetparams == NULL)
a5e4b81e 141 return -ENOMEM;
f8942e07 142 }
a5e4b81e
KM
143
144 if (psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS))
145 return -EIO;
146
147 retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
148 if (retval) {
082e889b 149 kfree(Adapter->pstargetparams);
f8942e07 150 Adapter->pstargetparams = NULL;
ef5d2056 151 return -EFAULT;
f8942e07 152 }
a5e4b81e 153
f8942e07
SH
154 /* Parse the structure and then Download the Firmware */
155 beceem_parse_target_struct(Adapter);
156
a5e4b81e 157 /* Initializing the NVM. */
f8942e07 158 BcmInitNVM(Adapter);
a5e4b81e 159 retval = InitLedSettings(Adapter);
f8942e07 160
a5e4b81e
KM
161 if (retval) {
162 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
f8942e07
SH
163 return retval;
164 }
165
a5e4b81e 166 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
f8942e07
SH
167 Adapter->LEDInfo.bLedInitDone = FALSE;
168 Adapter->DriverState = DRIVER_INIT;
169 wake_up(&Adapter->LEDInfo.notify_led_event);
170 }
171
a5e4b81e 172 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
f8942e07
SH
173 Adapter->DriverState = FW_DOWNLOAD;
174 wake_up(&Adapter->LEDInfo.notify_led_event);
175 }
176
177 /* Initialize the DDR Controller */
178 retval = ddr_init(Adapter);
a5e4b81e
KM
179 if (retval) {
180 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
f8942e07
SH
181 return retval;
182 }
183
184 value = 0;
185 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
186 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
187
a5e4b81e 188 if (Adapter->eNVMType == NVM_FLASH) {
f8942e07 189 retval = PropagateCalParamsFromFlashToMemory(Adapter);
a5e4b81e
KM
190 if (retval) {
191 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval);
f8942e07
SH
192 return retval;
193 }
194 }
195
a5e4b81e 196 retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(STARGETPARAMS), CONFIG_BEGIN_ADDR);
f8942e07 197
a5e4b81e
KM
198 if (retval)
199 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
f8942e07
SH
200 else
201 Adapter->bCfgDownloaded = TRUE;
202
f8942e07
SH
203 return retval;
204}
a5e4b81e
KM
205
206static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len)
f8942e07
SH
207{
208 int retval = STATUS_SUCCESS;
a5e4b81e
KM
209 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
210 if ((len-sizeof(unsigned int)) < 4) {
211 if (memcmp(readbackbuff , buff, len))
212 retval = -EINVAL;
213 } else {
214 len -= 4;
215
216 while (len) {
217 if (*(unsigned int *)&readbackbuff[len] != *(unsigned int *)&buff[len]) {
218 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper");
219 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]);
220 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
221 retval = -EINVAL;
f8942e07
SH
222 break;
223 }
a5e4b81e 224 len -= 4;
f8942e07
SH
225 }
226 }
227 return retval;
228}
a5e4b81e 229
f8942e07
SH
230int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
231{
232 int retval = STATUS_SUCCESS;
233 PUCHAR buff = NULL;
234
a5e4b81e
KM
235 /* Config File is needed for the Driver to download the Config file and
236 * Firmware. Check for the Config file to be first to be sent from the
237 * Application
238 */
239 atomic_set(&Adapter->uiMBupdate, FALSE);
240 if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
241 /* Can't Download Firmware. */
242 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n");
f8942e07
SH
243 return -EINVAL;
244 }
245
246 /* If Config File, Finish the DDR Settings and then Download CFG File */
a5e4b81e
KM
247 if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
248 retval = bcm_download_config_file(Adapter, psFwInfo);
249 } else {
250 buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
251 if (buff == NULL) {
252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory");
f8942e07
SH
253 return -ENOMEM;
254 }
a5e4b81e
KM
255
256 retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
257 if (retval != STATUS_SUCCESS) {
258 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
ef5d2056 259 retval = -EFAULT;
a5e4b81e 260 goto error;
f8942e07
SH
261 }
262
f8942e07
SH
263 retval = buffDnldVerify(Adapter,
264 buff,
265 psFwInfo->u32FirmwareLength,
266 psFwInfo->u32StartingAddress);
a5e4b81e
KM
267
268 if (retval != STATUS_SUCCESS) {
269 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval);
f8942e07
SH
270 goto error;
271 }
272 }
a5e4b81e 273
f8942e07 274error:
082e889b 275 kfree(buff);
f8942e07
SH
276 return retval;
277}
278
a5e4b81e 279static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
f8942e07 280{
a5e4b81e 281 unsigned int len = 0;
f8942e07
SH
282 int retval = STATUS_SUCCESS;
283 len = u32FirmwareLength;
284
a5e4b81e
KM
285 while (u32FirmwareLength) {
286 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
287 retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
288
289 if (retval) {
290 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
f8942e07
SH
291 break;
292 }
a5e4b81e
KM
293 u32StartingAddress += len;
294 u32FirmwareLength -= len;
295 mappedbuffer += len;
f8942e07
SH
296 }
297 return retval;
f8942e07
SH
298}
299
a5e4b81e 300static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
f8942e07 301{
f8942e07
SH
302 UINT len = u32FirmwareLength;
303 INT retval = STATUS_SUCCESS;
a5e4b81e 304 PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
f8942e07 305
a5e4b81e
KM
306 if (NULL == readbackbuff) {
307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
f8942e07
SH
308 return -ENOMEM;
309 }
f8942e07 310
a5e4b81e
KM
311 while (u32FirmwareLength && !retval) {
312 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
313 retval = rdm(Adapter, u32StartingAddress, readbackbuff, len);
f8942e07 314
a5e4b81e
KM
315 if (retval) {
316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval);
f8942e07
SH
317 break;
318 }
319
a8658182
KM
320 retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len);
321 if (STATUS_SUCCESS != retval)
f8942e07 322 break;
a5e4b81e
KM
323
324 u32StartingAddress += len;
325 u32FirmwareLength -= len;
326 mappedbuffer += len;
327
328 } /* end of while (u32FirmwareLength && !retval) */
082e889b 329 kfree(readbackbuff);
f8942e07
SH
330 return retval;
331}
332
a5e4b81e 333INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress)
f8942e07
SH
334{
335 INT status = STATUS_SUCCESS;
336
a5e4b81e
KM
337 status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
338 if (status != STATUS_SUCCESS) {
339 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed");
f8942e07
SH
340 goto error;
341 }
342
a5e4b81e
KM
343 status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
344 if (status != STATUS_SUCCESS) {
345 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed");
f8942e07
SH
346 goto error;
347 }
348error:
349 return status;
350}