InterfaceDld.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "headers.h"
  2. int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
  3. {
  4. /* unsigned int reg = 0; */
  5. mm_segment_t oldfs = {0};
  6. int errno = 0, len = 0; /* ,is_config_file = 0 */
  7. loff_t pos = 0;
  8. struct bcm_interface_adapter *psIntfAdapter = arg;
  9. /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
  10. char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
  11. if (!buff)
  12. return -ENOMEM;
  13. while (1) {
  14. oldfs = get_fs();
  15. set_fs(get_ds());
  16. len = vfs_read(flp, (void __force __user *)buff,
  17. MAX_TRANSFER_CTRL_BYTE_USB, &pos);
  18. set_fs(oldfs);
  19. if (len <= 0) {
  20. if (len < 0)
  21. errno = len;
  22. else
  23. errno = 0;
  24. break;
  25. }
  26. /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
  27. * DBG_LVL_ALL, buff,
  28. * MAX_TRANSFER_CTRL_BYTE_USB);
  29. */
  30. errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
  31. if (errno)
  32. break;
  33. on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
  34. }
  35. kfree(buff);
  36. return errno;
  37. }
  38. int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp,
  39. unsigned int on_chip_loc)
  40. {
  41. char *buff, *buff_readback;
  42. unsigned int reg = 0;
  43. mm_segment_t oldfs = {0};
  44. int errno = 0, len = 0, is_config_file = 0;
  45. loff_t pos = 0;
  46. static int fw_down;
  47. INT Status = STATUS_SUCCESS;
  48. struct bcm_interface_adapter *psIntfAdapter = arg;
  49. int bytes;
  50. buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
  51. buff_readback = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
  52. if (!buff || !buff_readback) {
  53. kfree(buff);
  54. kfree(buff_readback);
  55. return -ENOMEM;
  56. }
  57. is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
  58. while (1) {
  59. oldfs = get_fs();
  60. set_fs(get_ds());
  61. len = vfs_read(flp, (void __force __user *)buff,
  62. MAX_TRANSFER_CTRL_BYTE_USB, &pos);
  63. set_fs(oldfs);
  64. fw_down++;
  65. if (len <= 0) {
  66. if (len < 0)
  67. errno = len;
  68. else
  69. errno = 0;
  70. break;
  71. }
  72. bytes = InterfaceRDM(psIntfAdapter, on_chip_loc,
  73. buff_readback, len);
  74. if (bytes < 0) {
  75. Status = bytes;
  76. goto exit;
  77. }
  78. reg++;
  79. if ((len-sizeof(unsigned int)) < 4) {
  80. if (memcmp(buff_readback, buff, len)) {
  81. Status = -EIO;
  82. goto exit;
  83. }
  84. } else {
  85. len -= 4;
  86. while (len) {
  87. if (*(unsigned int *)&buff_readback[len] !=
  88. *(unsigned int *)&buff[len]) {
  89. Status = -EIO;
  90. goto exit;
  91. }
  92. len -= 4;
  93. }
  94. }
  95. on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
  96. } /* End of while(1) */
  97. exit:
  98. kfree(buff);
  99. kfree(buff_readback);
  100. return Status;
  101. }
  102. static int bcm_download_config_file(struct bcm_mini_adapter *Adapter,
  103. struct bcm_firmware_info *psFwInfo)
  104. {
  105. int retval = STATUS_SUCCESS;
  106. B_UINT32 value = 0;
  107. if (Adapter->pstargetparams == NULL) {
  108. Adapter->pstargetparams =
  109. kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
  110. if (Adapter->pstargetparams == NULL)
  111. return -ENOMEM;
  112. }
  113. if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params))
  114. return -EIO;
  115. retval = copy_from_user(Adapter->pstargetparams,
  116. psFwInfo->pvMappedFirmwareAddress,
  117. psFwInfo->u32FirmwareLength);
  118. if (retval) {
  119. kfree(Adapter->pstargetparams);
  120. Adapter->pstargetparams = NULL;
  121. return -EFAULT;
  122. }
  123. /* Parse the structure and then Download the Firmware */
  124. beceem_parse_target_struct(Adapter);
  125. /* Initializing the NVM. */
  126. BcmInitNVM(Adapter);
  127. retval = InitLedSettings(Adapter);
  128. if (retval)
  129. return retval;
  130. if (Adapter->LEDInfo.led_thread_running &
  131. BCM_LED_THREAD_RUNNING_ACTIVELY) {
  132. Adapter->LEDInfo.bLedInitDone = false;
  133. Adapter->DriverState = DRIVER_INIT;
  134. wake_up(&Adapter->LEDInfo.notify_led_event);
  135. }
  136. if (Adapter->LEDInfo.led_thread_running &
  137. BCM_LED_THREAD_RUNNING_ACTIVELY) {
  138. Adapter->DriverState = FW_DOWNLOAD;
  139. wake_up(&Adapter->LEDInfo.notify_led_event);
  140. }
  141. /* Initialize the DDR Controller */
  142. retval = ddr_init(Adapter);
  143. if (retval)
  144. return retval;
  145. value = 0;
  146. wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4,
  147. &value, sizeof(value));
  148. wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8,
  149. &value, sizeof(value));
  150. if (Adapter->eNVMType == NVM_FLASH) {
  151. retval = PropagateCalParamsFromFlashToMemory(Adapter);
  152. if (retval)
  153. return retval;
  154. }
  155. retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams,
  156. sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR);
  157. if (retval)
  158. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT,
  159. MP_INIT, DBG_LVL_ALL,
  160. "configuration file not downloaded properly");
  161. else
  162. Adapter->bCfgDownloaded = TRUE;
  163. return retval;
  164. }
  165. int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter,
  166. struct bcm_firmware_info *psFwInfo)
  167. {
  168. int retval = STATUS_SUCCESS;
  169. PUCHAR buff = NULL;
  170. /* Config File is needed for the Driver to download the Config file and
  171. * Firmware. Check for the Config file to be first to be sent from the
  172. * Application
  173. */
  174. atomic_set(&Adapter->uiMBupdate, false);
  175. if (!Adapter->bCfgDownloaded &&
  176. psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
  177. /* Can't Download Firmware. */
  178. return -EINVAL;
  179. }
  180. /* If Config File, Finish the DDR Settings and then Download CFG File */
  181. if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
  182. retval = bcm_download_config_file(Adapter, psFwInfo);
  183. } else {
  184. buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
  185. if (buff == NULL)
  186. return -ENOMEM;
  187. retval = copy_from_user(buff,
  188. psFwInfo->pvMappedFirmwareAddress,
  189. psFwInfo->u32FirmwareLength);
  190. if (retval != STATUS_SUCCESS) {
  191. retval = -EFAULT;
  192. goto error;
  193. }
  194. retval = buffDnldVerify(Adapter,
  195. buff,
  196. psFwInfo->u32FirmwareLength,
  197. psFwInfo->u32StartingAddress);
  198. if (retval != STATUS_SUCCESS)
  199. goto error;
  200. }
  201. error:
  202. kfree(buff);
  203. return retval;
  204. }
  205. static INT buffDnld(struct bcm_mini_adapter *Adapter,
  206. PUCHAR mappedbuffer, UINT u32FirmwareLength,
  207. ULONG u32StartingAddress)
  208. {
  209. unsigned int len = 0;
  210. int retval = STATUS_SUCCESS;
  211. len = u32FirmwareLength;
  212. while (u32FirmwareLength) {
  213. len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
  214. retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
  215. if (retval)
  216. break;
  217. u32StartingAddress += len;
  218. u32FirmwareLength -= len;
  219. mappedbuffer += len;
  220. }
  221. return retval;
  222. }
  223. static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter,
  224. PUCHAR mappedbuffer, UINT u32FirmwareLength,
  225. ULONG u32StartingAddress)
  226. {
  227. UINT len = u32FirmwareLength;
  228. INT retval = STATUS_SUCCESS;
  229. PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
  230. int bytes;
  231. if (NULL == readbackbuff)
  232. return -ENOMEM;
  233. while (u32FirmwareLength && !retval) {
  234. len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
  235. bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);
  236. if (bytes < 0) {
  237. retval = bytes;
  238. break;
  239. }
  240. if (memcmp(readbackbuff, mappedbuffer, len) != 0) {
  241. pr_err("%s() failed. The firmware doesn't match what was written",
  242. __func__);
  243. retval = -EIO;
  244. }
  245. u32StartingAddress += len;
  246. u32FirmwareLength -= len;
  247. mappedbuffer += len;
  248. } /* end of while (u32FirmwareLength && !retval) */
  249. kfree(readbackbuff);
  250. return retval;
  251. }
  252. INT buffDnldVerify(struct bcm_mini_adapter *Adapter,
  253. unsigned char *mappedbuffer,
  254. unsigned int u32FirmwareLength,
  255. unsigned long u32StartingAddress)
  256. {
  257. INT status = STATUS_SUCCESS;
  258. status = buffDnld(Adapter, mappedbuffer,
  259. u32FirmwareLength, u32StartingAddress);
  260. if (status != STATUS_SUCCESS)
  261. goto error;
  262. status = buffRdbkVerify(Adapter, mappedbuffer,
  263. u32FirmwareLength, u32StartingAddress);
  264. if (status != STATUS_SUCCESS)
  265. goto error;
  266. error:
  267. return status;
  268. }