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