]>
Commit | Line | Data |
---|---|---|
d16044cf AB |
1 | #include <linux/fs.h> |
2 | ||
f8942e07 SH |
3 | #include "headers.h" |
4 | /*************************************************************** | |
5 | * Function - bcm_char_open() | |
6 | * | |
7 | * Description - This is the "open" entry point for the character | |
8 | * driver. | |
9 | * | |
10 | * Parameters - inode: Pointer to the Inode structure of char device | |
11 | * filp : File pointer of the char device | |
12 | * | |
13 | * Returns - Zero(Success) | |
14 | ****************************************************************/ | |
15 | static struct class *bcm_class = NULL; | |
16 | static int bcm_char_open(struct inode *inode, struct file * filp) | |
17 | { | |
18 | PMINI_ADAPTER Adapter = NULL; | |
19 | PPER_TARANG_DATA pTarang = NULL; | |
20 | ||
21 | Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
22 | pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL); | |
23 | if (!pTarang) | |
24 | return -ENOMEM; | |
25 | ||
26 | memset (pTarang, 0, sizeof(PER_TARANG_DATA)); | |
27 | pTarang->Adapter = Adapter; | |
28 | pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB) ; | |
29 | ||
30 | down(&Adapter->RxAppControlQueuelock); | |
31 | pTarang->next = Adapter->pTarangs; | |
32 | Adapter->pTarangs = pTarang; | |
33 | up(&Adapter->RxAppControlQueuelock); | |
34 | ||
35 | /* Store the Adapter structure */ | |
36 | filp->private_data = pTarang; | |
37 | ||
38 | /*Start Queuing the control response Packets*/ | |
39 | atomic_inc(&Adapter->ApplicationRunning); | |
d16044cf AB |
40 | |
41 | nonseekable_open(inode, filp); | |
f8942e07 SH |
42 | return 0; |
43 | } | |
44 | static int bcm_char_release(struct inode *inode, struct file *filp) | |
45 | { | |
46 | PPER_TARANG_DATA pTarang, tmp, ptmp; | |
47 | PMINI_ADAPTER Adapter=NULL; | |
48 | struct sk_buff * pkt, * npkt; | |
49 | ||
50 | pTarang = (PPER_TARANG_DATA)filp->private_data; | |
51 | ||
52 | if(pTarang == NULL) | |
53 | { | |
54 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ptarang is null\n"); | |
55 | return 0; | |
56 | } | |
57 | ||
58 | Adapter = pTarang->Adapter; | |
59 | ||
60 | down( &Adapter->RxAppControlQueuelock); | |
61 | ||
62 | tmp = Adapter->pTarangs; | |
63 | for ( ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next ) | |
64 | { | |
65 | if ( tmp == pTarang ) | |
66 | break; | |
67 | } | |
68 | ||
69 | if ( tmp ) | |
70 | { | |
71 | if ( !ptmp ) | |
72 | Adapter->pTarangs = tmp->next; | |
73 | else | |
74 | ptmp->next = tmp->next; | |
75 | } | |
76 | ||
77 | else | |
78 | { | |
79 | up( &Adapter->RxAppControlQueuelock); | |
80 | return 0; | |
81 | } | |
82 | ||
83 | pkt = pTarang->RxAppControlHead; | |
84 | while ( pkt ) | |
85 | { | |
86 | npkt = pkt->next; | |
87 | kfree_skb(pkt); | |
88 | pkt = npkt; | |
89 | } | |
90 | ||
91 | up( &Adapter->RxAppControlQueuelock); | |
92 | ||
93 | /*Stop Queuing the control response Packets*/ | |
94 | atomic_dec(&Adapter->ApplicationRunning); | |
95 | ||
96 | bcm_kfree(pTarang); | |
97 | ||
98 | /* remove this filp from the asynchronously notified filp's */ | |
99 | filp->private_data = NULL; | |
100 | return 0; | |
101 | } | |
102 | ||
9f1c75ac | 103 | static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) |
f8942e07 SH |
104 | { |
105 | PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; | |
106 | PMINI_ADAPTER Adapter = pTarang->Adapter; | |
107 | struct sk_buff* Packet = NULL; | |
108 | UINT PktLen = 0; | |
109 | int wait_ret_val=0; | |
110 | ||
111 | wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, | |
112 | (pTarang->RxAppControlHead || Adapter->device_removed)); | |
113 | if((wait_ret_val == -ERESTARTSYS)) | |
114 | { | |
115 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Exiting as i've been asked to exit!!!\n"); | |
116 | return wait_ret_val; | |
117 | } | |
118 | ||
119 | if(Adapter->device_removed) | |
120 | { | |
121 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device Removed... Killing the Apps...\n"); | |
122 | return -ENODEV; | |
123 | } | |
124 | ||
125 | if(FALSE == Adapter->fw_download_done) | |
126 | return -EACCES; | |
127 | ||
128 | down( &Adapter->RxAppControlQueuelock); | |
129 | ||
130 | if(pTarang->RxAppControlHead) | |
131 | { | |
132 | Packet = pTarang->RxAppControlHead; | |
133 | DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail); | |
134 | pTarang->AppCtrlQueueLen--; | |
135 | } | |
136 | ||
137 | up(&Adapter->RxAppControlQueuelock); | |
138 | ||
139 | if(Packet) | |
140 | { | |
141 | PktLen = Packet->len; | |
142 | if(copy_to_user(buf, Packet->data, PktLen)) | |
143 | { | |
144 | bcm_kfree_skb(Packet); | |
145 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); | |
146 | return -EFAULT; | |
147 | } | |
148 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid); | |
149 | bcm_kfree_skb(Packet); | |
150 | } | |
151 | ||
152 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n"); | |
153 | return PktLen; | |
154 | } | |
155 | ||
9f1c75ac | 156 | static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) |
f8942e07 SH |
157 | { |
158 | PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; | |
44a17eff | 159 | void __user *argp = (void __user *)argp; |
f8942e07 SH |
160 | PMINI_ADAPTER Adapter = pTarang->Adapter; |
161 | INT Status = STATUS_FAILURE; | |
44a17eff | 162 | IOCTL_BUFFER IoBuffer={}; |
f8942e07 SH |
163 | #ifndef BCM_SHM_INTERFACE |
164 | int timeout = 0; | |
165 | #endif | |
166 | ||
167 | ||
168 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); | |
169 | ||
170 | if(_IOC_TYPE(cmd) != BCM_IOCTL) | |
171 | return -EFAULT; | |
172 | if(_IOC_DIR(cmd) & _IOC_READ) | |
44a17eff | 173 | Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); |
f8942e07 | 174 | else if (_IOC_DIR(cmd) & _IOC_WRITE) |
44a17eff | 175 | Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); |
f8942e07 SH |
176 | else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) |
177 | Status = STATUS_SUCCESS; | |
178 | ||
179 | if(Status) | |
180 | return -EFAULT; | |
181 | ||
182 | if(Adapter->device_removed) | |
183 | { | |
184 | return -EFAULT; | |
185 | } | |
186 | ||
187 | if(FALSE == Adapter->fw_download_done) | |
188 | { | |
189 | switch (cmd) | |
190 | { | |
191 | case IOCTL_MAC_ADDR_REQ: | |
192 | case IOCTL_LINK_REQ: | |
193 | case IOCTL_CM_REQUEST: | |
194 | case IOCTL_SS_INFO_REQ: | |
195 | case IOCTL_SEND_CONTROL_MESSAGE: | |
196 | case IOCTL_IDLE_REQ: | |
197 | case IOCTL_BCM_GPIO_SET_REQUEST: | |
198 | case IOCTL_BCM_GPIO_STATUS_REQUEST: | |
199 | return -EACCES; | |
200 | default: | |
201 | break; | |
202 | } | |
203 | } | |
204 | ||
205 | Status = vendorextnIoctl(Adapter, cmd, arg); | |
206 | if(Status != CONTINUE_COMMON_PATH ) | |
207 | { | |
208 | return Status; | |
209 | } | |
210 | ||
211 | switch(cmd){ | |
212 | // Rdms for Swin Idle... | |
213 | case IOCTL_BCM_REGISTER_READ_PRIVATE: | |
214 | { | |
215 | RDM_BUFFER sRdmBuffer = {0}; | |
216 | PCHAR temp_buff = NULL; | |
217 | UINT Bufflen = 0; | |
218 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 219 | if(copy_from_user((PCHAR)&IoBuffer, argp, |
f8942e07 SH |
220 | sizeof(IOCTL_BUFFER))) |
221 | { | |
222 | Status = -EFAULT; | |
223 | break; | |
224 | } | |
225 | ||
226 | Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; | |
227 | temp_buff = (PCHAR)kmalloc(Bufflen, GFP_KERNEL); | |
228 | if(!temp_buff) | |
229 | { | |
230 | return STATUS_FAILURE; | |
231 | } | |
232 | if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, | |
233 | IoBuffer.InputLength)) | |
234 | { | |
235 | Status = -EFAULT; | |
236 | break; | |
237 | } | |
238 | Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, | |
239 | (PUINT)temp_buff, Bufflen); | |
240 | if(Status != STATUS_SUCCESS) | |
241 | { | |
242 | bcm_kfree(temp_buff); | |
243 | return Status; | |
244 | } | |
44a17eff | 245 | if(copy_to_user(IoBuffer.OutputBuffer, |
f8942e07 SH |
246 | (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) |
247 | { | |
248 | Status = -EFAULT; | |
249 | } | |
250 | bcm_kfree(temp_buff); | |
251 | break; | |
252 | } | |
253 | case IOCTL_BCM_REGISTER_WRITE_PRIVATE: | |
254 | { | |
255 | WRM_BUFFER sWrmBuffer = {0}; | |
256 | UINT uiTempVar=0; | |
257 | /* Copy Ioctl Buffer structure */ | |
258 | ||
44a17eff | 259 | if(copy_from_user(&IoBuffer, argp, |
f8942e07 SH |
260 | sizeof(IOCTL_BUFFER))) |
261 | { | |
262 | Status = -EFAULT; | |
263 | break; | |
264 | } | |
265 | /* Get WrmBuffer structure */ | |
266 | if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, | |
267 | IoBuffer.InputLength)) | |
268 | { | |
269 | Status = -EFAULT; | |
270 | break; | |
271 | } | |
272 | uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
273 | if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
274 | ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
275 | (uiTempVar == EEPROM_REJECT_REG_2) || | |
276 | (uiTempVar == EEPROM_REJECT_REG_3) || | |
277 | (uiTempVar == EEPROM_REJECT_REG_4))) | |
278 | { | |
279 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
280 | Status = -EFAULT; | |
281 | break; | |
282 | } | |
283 | Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, | |
284 | (PUINT)sWrmBuffer.Data, sizeof(ULONG)); | |
285 | if(Status == STATUS_SUCCESS) | |
286 | { | |
287 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n"); | |
288 | } | |
289 | else | |
290 | { | |
291 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
292 | Status = -EFAULT; | |
293 | } | |
294 | break; | |
295 | } | |
296 | ||
297 | case IOCTL_BCM_REGISTER_READ: | |
298 | case IOCTL_BCM_EEPROM_REGISTER_READ: | |
299 | { | |
300 | RDM_BUFFER sRdmBuffer = {0}; | |
301 | PCHAR temp_buff = NULL; | |
302 | UINT uiTempVar = 0; | |
303 | if((Adapter->IdleMode == TRUE) || | |
304 | (Adapter->bShutStatus ==TRUE) || | |
305 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
306 | { | |
307 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); | |
308 | Status = -EACCES; | |
309 | break; | |
310 | } | |
311 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 312 | if(copy_from_user(&IoBuffer, argp, |
f8942e07 SH |
313 | sizeof(IOCTL_BUFFER))) |
314 | { | |
315 | Status = -EFAULT; | |
316 | break; | |
317 | } | |
318 | ||
319 | temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); | |
320 | if(!temp_buff) | |
321 | { | |
322 | return STATUS_FAILURE; | |
323 | } | |
324 | if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, | |
325 | IoBuffer.InputLength)) | |
326 | { | |
327 | Status = -EFAULT; | |
328 | break; | |
329 | } | |
330 | ||
331 | if( | |
332 | #if !defined(BCM_SHM_INTERFACE) | |
333 | (((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
334 | #endif | |
335 | ((ULONG)sRdmBuffer.Register & 0x3) | |
336 | ) | |
337 | { | |
338 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", | |
339 | (int)sRdmBuffer.Register); | |
340 | Status = -EINVAL; | |
341 | break; | |
342 | } | |
343 | ||
344 | uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; | |
345 | Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, | |
346 | (PUINT)temp_buff, IoBuffer.OutputLength); | |
347 | if(Status != STATUS_SUCCESS) | |
348 | { | |
349 | bcm_kfree(temp_buff); | |
350 | return Status; | |
351 | } | |
44a17eff | 352 | if(copy_to_user(IoBuffer.OutputBuffer, |
f8942e07 SH |
353 | (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) |
354 | { | |
355 | Status = -EFAULT; | |
356 | } | |
357 | bcm_kfree(temp_buff); | |
358 | break; | |
359 | } | |
360 | case IOCTL_BCM_REGISTER_WRITE: | |
361 | case IOCTL_BCM_EEPROM_REGISTER_WRITE: | |
362 | { | |
363 | WRM_BUFFER sWrmBuffer = {0}; | |
364 | UINT uiTempVar=0; | |
365 | if((Adapter->IdleMode == TRUE) || | |
366 | (Adapter->bShutStatus ==TRUE) || | |
367 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
368 | { | |
369 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); | |
370 | Status = -EACCES; | |
371 | break; | |
372 | } | |
373 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 374 | if(copy_from_user((PCHAR)&IoBuffer, argp, |
f8942e07 SH |
375 | sizeof(IOCTL_BUFFER))) |
376 | { | |
377 | Status = -EFAULT; | |
378 | break; | |
379 | } | |
380 | /* Get WrmBuffer structure */ | |
381 | if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, | |
382 | IoBuffer.InputLength)) | |
383 | { | |
384 | Status = -EFAULT; | |
385 | break; | |
386 | } | |
387 | if( | |
388 | #if !defined(BCM_SHM_INTERFACE) | |
389 | ||
390 | (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
391 | #endif | |
392 | ((ULONG)sWrmBuffer.Register & 0x3) | |
393 | ) | |
394 | { | |
395 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", | |
396 | (int)sWrmBuffer.Register); | |
397 | Status = -EINVAL; | |
398 | break; | |
399 | } | |
400 | uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
401 | if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
402 | ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
403 | (uiTempVar == EEPROM_REJECT_REG_2) || | |
404 | (uiTempVar == EEPROM_REJECT_REG_3) || | |
405 | (uiTempVar == EEPROM_REJECT_REG_4)) && | |
406 | (cmd == IOCTL_BCM_REGISTER_WRITE)) | |
407 | { | |
408 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
409 | Status = -EFAULT; | |
410 | break; | |
411 | } | |
412 | ||
413 | Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, | |
414 | (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); | |
415 | if(Status == STATUS_SUCCESS) | |
416 | { | |
417 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); | |
418 | } | |
419 | else | |
420 | { | |
421 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
422 | Status = -EFAULT; | |
423 | } | |
424 | break; | |
425 | } | |
426 | case IOCTL_BCM_GPIO_SET_REQUEST: | |
427 | { | |
428 | UCHAR ucResetValue[4]; | |
429 | UINT value =0; | |
430 | UINT uiBit = 0; | |
431 | UINT uiOperation = 0; | |
432 | ||
433 | GPIO_INFO gpio_info = {0}; | |
434 | if((Adapter->IdleMode == TRUE) || | |
435 | (Adapter->bShutStatus ==TRUE) || | |
436 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
437 | { | |
438 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); | |
439 | Status = -EACCES; | |
440 | break; | |
441 | } | |
44a17eff | 442 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
443 | { |
444 | Status = -EFAULT; | |
445 | break; | |
446 | } | |
447 | if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
448 | { | |
449 | Status = -EFAULT; | |
450 | break; | |
451 | } | |
452 | uiBit = gpio_info.uiGpioNumber; | |
453 | uiOperation = gpio_info.uiGpioValue; | |
454 | ||
455 | value= (1<<uiBit); | |
456 | ||
457 | if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE) | |
458 | { | |
459 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value); | |
460 | Status = -EINVAL; | |
461 | break; | |
462 | } | |
463 | ||
464 | ||
465 | if(uiOperation)//Set - setting 1 | |
466 | { | |
467 | //Set the gpio output register | |
468 | Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG , | |
469 | (PUINT)(&value), sizeof(UINT)); | |
470 | if(Status == STATUS_SUCCESS) | |
471 | { | |
472 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); | |
473 | } | |
474 | else | |
475 | { | |
476 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit); | |
477 | break; | |
478 | } | |
479 | } | |
480 | else//Unset - setting 0 | |
481 | { | |
482 | //Set the gpio output register | |
483 | Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG , | |
484 | (PUINT)(&value), sizeof(UINT)); | |
485 | if(Status == STATUS_SUCCESS) | |
486 | { | |
487 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n"); | |
488 | } | |
489 | else | |
490 | { | |
491 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit); | |
492 | break; | |
493 | } | |
494 | } | |
495 | ||
496 | Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, | |
497 | (PUINT)ucResetValue, sizeof(UINT)); | |
498 | if (STATUS_SUCCESS != Status) | |
499 | { | |
500 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed"); | |
501 | break; | |
502 | } | |
503 | //Set the gpio mode register to output | |
504 | *(UINT*)ucResetValue |= (1<<uiBit); | |
505 | Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER , | |
506 | (PUINT)ucResetValue, sizeof(UINT)); | |
507 | if(Status == STATUS_SUCCESS) | |
508 | { | |
509 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n"); | |
510 | } | |
511 | else | |
512 | { | |
513 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); | |
514 | break; | |
515 | } | |
516 | } | |
517 | break; | |
518 | case BCM_LED_THREAD_STATE_CHANGE_REQ: | |
519 | { | |
520 | ||
521 | USER_THREAD_REQ threadReq = {0}; | |
522 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive"); | |
523 | ||
524 | if((Adapter->IdleMode == TRUE) || | |
525 | (Adapter->bShutStatus ==TRUE) || | |
526 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
527 | { | |
528 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); | |
529 | Status = -EACCES; | |
530 | break; | |
531 | } | |
44a17eff | 532 | Status =copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
533 | if(Status) |
534 | { | |
535 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); | |
bf58bd66 | 536 | Status = -EFAULT; |
f8942e07 SH |
537 | break; |
538 | } | |
539 | ||
540 | Status= copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
541 | if(Status) | |
542 | { | |
543 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the InputBuffer from user space err:%d",Status); | |
bf58bd66 | 544 | Status = -EFAULT; |
f8942e07 SH |
545 | break; |
546 | } | |
547 | //if LED thread is running(Actively or Inactively) set it state to make inactive | |
548 | if(Adapter->LEDInfo.led_thread_running) | |
549 | { | |
550 | if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) | |
551 | { | |
552 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req"); | |
553 | Adapter->DriverState = LED_THREAD_ACTIVE; | |
554 | } | |
555 | else | |
556 | { | |
557 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req....."); | |
558 | Adapter->DriverState = LED_THREAD_INACTIVE; | |
559 | } | |
560 | ||
561 | //signal thread. | |
562 | wake_up(&Adapter->LEDInfo.notify_led_event); | |
563 | ||
564 | } | |
565 | } | |
566 | break; | |
567 | case IOCTL_BCM_GPIO_STATUS_REQUEST: | |
568 | { | |
569 | ULONG uiBit = 0; | |
570 | UCHAR ucRead[4]; | |
571 | GPIO_INFO gpio_info = {0}; | |
572 | if((Adapter->IdleMode == TRUE) || | |
573 | (Adapter->bShutStatus ==TRUE) || | |
574 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
575 | { | |
576 | Status = -EACCES; | |
577 | break; | |
578 | } | |
bf58bd66 DC |
579 | if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { |
580 | Status = -EFAULT; | |
581 | break; | |
582 | } | |
f8942e07 SH |
583 | if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) |
584 | { | |
585 | Status = -EFAULT; | |
586 | break; | |
587 | } | |
588 | uiBit = gpio_info.uiGpioNumber; | |
589 | //Set the gpio output register | |
590 | Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, | |
591 | (PUINT)ucRead, sizeof(UINT)); | |
592 | if(Status != STATUS_SUCCESS) | |
593 | { | |
594 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); | |
595 | return Status; | |
596 | } | |
597 | ||
598 | } | |
599 | break; | |
600 | case IOCTL_BCM_GPIO_MULTI_REQUEST: | |
601 | { | |
602 | UCHAR ucResetValue[4]; | |
603 | GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; | |
604 | PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; | |
605 | ||
606 | memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO)); | |
607 | ||
608 | if((Adapter->IdleMode == TRUE) || | |
609 | (Adapter->bShutStatus ==TRUE) || | |
610 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
611 | { | |
612 | Status = -EINVAL; | |
613 | break; | |
614 | } | |
44a17eff | 615 | Status = copy_from_user( (PCHAR)&IoBuffer, argp, sizeof( IOCTL_BUFFER)); |
f8942e07 SH |
616 | if(Status) |
617 | { | |
618 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); | |
bf58bd66 | 619 | Status = -EFAULT; |
f8942e07 SH |
620 | break; |
621 | } | |
622 | ||
623 | Status = copy_from_user( &gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
624 | if(Status) | |
625 | { | |
626 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); | |
bf58bd66 | 627 | Status = -EFAULT; |
f8942e07 SH |
628 | break; |
629 | } | |
630 | if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE) | |
631 | { | |
632 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); | |
633 | Status = -EINVAL; | |
634 | break; | |
635 | } | |
636 | ||
637 | /* Set the gpio output register */ | |
638 | ||
639 | if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & | |
640 | ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) | |
641 | { | |
642 | /* Set 1's in GPIO OUTPUT REGISTER */ | |
643 | *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
644 | pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
645 | pgpio_multi_info[WIMAX_IDX].uiGPIOValue; | |
646 | ||
647 | if( *(UINT*) ucResetValue) | |
648 | Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG)); | |
649 | ||
650 | if( Status != STATUS_SUCCESS) | |
651 | { | |
652 | BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); | |
653 | return Status; | |
654 | } | |
655 | ||
656 | /* Clear to 0's in GPIO OUTPUT REGISTER */ | |
657 | *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
658 | pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
659 | ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); | |
660 | ||
661 | if( *(UINT*) ucResetValue) | |
662 | Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG)); | |
663 | ||
664 | if( Status != STATUS_SUCCESS) | |
665 | { | |
666 | BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." ); | |
667 | return Status; | |
668 | } | |
669 | } | |
670 | ||
671 | if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) | |
672 | { | |
673 | Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); | |
674 | ||
675 | if(Status != STATUS_SUCCESS) | |
676 | { | |
677 | BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed."); | |
678 | return Status; | |
679 | } | |
680 | ||
681 | pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue & | |
682 | pgpio_multi_info[WIMAX_IDX].uiGPIOMask); | |
683 | } | |
684 | ||
44a17eff | 685 | Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); |
f8942e07 SH |
686 | if(Status) |
687 | { | |
688 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); | |
bf58bd66 | 689 | Status = -EFAULT; |
f8942e07 SH |
690 | break; |
691 | } | |
692 | } | |
693 | break; | |
694 | case IOCTL_BCM_GPIO_MODE_REQUEST: | |
695 | { | |
696 | UCHAR ucResetValue[4]; | |
697 | GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; | |
698 | PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode; | |
699 | ||
700 | if((Adapter->IdleMode == TRUE) || | |
701 | (Adapter->bShutStatus ==TRUE) || | |
702 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
703 | { | |
704 | Status = -EINVAL; | |
705 | break; | |
706 | } | |
44a17eff | 707 | Status = copy_from_user(&IoBuffer, argp, sizeof( IOCTL_BUFFER)); |
f8942e07 SH |
708 | if(Status) |
709 | { | |
710 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); | |
bf58bd66 | 711 | Status = -EFAULT; |
f8942e07 SH |
712 | break; |
713 | } | |
714 | ||
715 | Status = copy_from_user( &gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
716 | if(Status) | |
717 | { | |
718 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); | |
bf58bd66 | 719 | Status = -EFAULT; |
f8942e07 SH |
720 | break; |
721 | } | |
722 | ||
723 | Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT)); | |
724 | if( STATUS_SUCCESS != Status) | |
725 | { | |
726 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed"); | |
727 | return Status; | |
728 | } | |
729 | ||
730 | //Validating the request | |
731 | if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE) | |
732 | { | |
733 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); | |
734 | Status = -EINVAL; | |
735 | break; | |
736 | } | |
737 | ||
738 | if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) | |
739 | { | |
740 | /* write all OUT's (1's) */ | |
741 | *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & | |
742 | pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
743 | /* write all IN's (0's) */ | |
744 | *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & | |
745 | pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
746 | ||
747 | /* Currently implemented return the modes of all GPIO's | |
748 | * else needs to bit AND with mask | |
749 | * */ | |
750 | pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue; | |
751 | ||
752 | Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG)); | |
753 | if( Status == STATUS_SUCCESS) | |
754 | { | |
755 | BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done"); | |
756 | } | |
757 | else | |
758 | { | |
759 | BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed"); | |
760 | Status = -EFAULT; | |
761 | break; | |
762 | } | |
763 | } | |
764 | else /* if uiGPIOMask is 0 then return mode register configuration */ | |
765 | { | |
766 | pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue; | |
767 | } | |
44a17eff | 768 | Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); |
f8942e07 SH |
769 | if(Status) |
770 | { | |
771 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); | |
bf58bd66 | 772 | Status = -EFAULT; |
f8942e07 SH |
773 | break; |
774 | } | |
775 | } | |
776 | break; | |
777 | ||
778 | case IOCTL_MAC_ADDR_REQ: | |
779 | case IOCTL_LINK_REQ: | |
780 | case IOCTL_CM_REQUEST: | |
781 | case IOCTL_SS_INFO_REQ: | |
782 | case IOCTL_SEND_CONTROL_MESSAGE: | |
783 | case IOCTL_IDLE_REQ: | |
784 | { | |
785 | PVOID pvBuffer=NULL; | |
786 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 787 | if(copy_from_user(&IoBuffer, argp, |
f8942e07 SH |
788 | sizeof(IOCTL_BUFFER))) |
789 | { | |
790 | Status = -EFAULT; | |
791 | break; | |
792 | } | |
793 | pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
794 | if(!pvBuffer) | |
795 | { | |
796 | return -ENOMEM; | |
797 | } | |
798 | ||
799 | if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, | |
800 | IoBuffer.InputLength)) | |
801 | { | |
802 | Status = -EFAULT; | |
803 | bcm_kfree(pvBuffer); | |
804 | break; | |
805 | } | |
806 | ||
807 | down(&Adapter->LowPowerModeSync); | |
808 | Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, | |
809 | !Adapter->bPreparingForLowPowerMode, | |
810 | (1 * HZ)); | |
811 | if(Status == -ERESTARTSYS) | |
812 | goto cntrlEnd; | |
813 | ||
814 | if(Adapter->bPreparingForLowPowerMode) | |
815 | { | |
816 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n"); | |
817 | Status = STATUS_FAILURE ; | |
818 | goto cntrlEnd ; | |
819 | } | |
820 | Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); | |
821 | cntrlEnd: | |
822 | up(&Adapter->LowPowerModeSync); | |
823 | bcm_kfree(pvBuffer); | |
824 | break; | |
825 | } | |
826 | #ifndef BCM_SHM_INTERFACE | |
827 | case IOCTL_BCM_BUFFER_DOWNLOAD_START: | |
828 | { | |
829 | INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ; | |
830 | if(NVMAccess) | |
831 | { | |
832 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
833 | return -EACCES; | |
834 | } | |
835 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
836 | if(!down_trylock(&Adapter->fw_download_sema)) | |
837 | { | |
838 | Adapter->bBinDownloaded=FALSE; | |
839 | Adapter->fw_download_process_pid=current->pid; | |
840 | Adapter->bCfgDownloaded=FALSE; | |
841 | Adapter->fw_download_done=FALSE; | |
842 | netif_carrier_off(Adapter->dev); | |
843 | netif_stop_queue(Adapter->dev); | |
844 | Status = reset_card_proc(Adapter); | |
845 | if(Status) | |
846 | { | |
847 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "reset_card_proc Failed!\n"); | |
848 | up(&Adapter->fw_download_sema); | |
849 | up(&Adapter->NVMRdmWrmLock); | |
850 | break; | |
851 | } | |
852 | mdelay(10); | |
853 | } | |
854 | else | |
855 | { | |
856 | ||
857 | Status = -EBUSY; | |
858 | ||
859 | } | |
860 | up(&Adapter->NVMRdmWrmLock); | |
861 | break; | |
862 | } | |
863 | case IOCTL_BCM_BUFFER_DOWNLOAD: | |
864 | { | |
865 | FIRMWARE_INFO *psFwInfo=NULL; | |
866 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
867 | do{ | |
868 | if(!down_trylock(&Adapter->fw_download_sema)) | |
869 | { | |
870 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n"); | |
871 | Status=-EINVAL; | |
872 | break; | |
873 | } | |
874 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 875 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
876 | { |
877 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); | |
878 | Status = -EFAULT; | |
879 | break; | |
880 | } | |
881 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", | |
882 | IoBuffer.InputLength); | |
883 | psFwInfo=kmalloc(sizeof(*psFwInfo), GFP_KERNEL); | |
884 | if(!psFwInfo) | |
885 | { | |
886 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Failed to allocate buffer!!!!\n"); | |
887 | Status = -ENOMEM; | |
888 | break; | |
889 | } | |
890 | if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, | |
891 | IoBuffer.InputLength)) | |
892 | { | |
893 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from_user 2 failed\n"); | |
894 | Status = -EFAULT; | |
895 | break; | |
896 | } | |
897 | ||
898 | if(!psFwInfo->pvMappedFirmwareAddress || | |
899 | (psFwInfo->u32FirmwareLength == 0)) | |
900 | { | |
901 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", | |
902 | psFwInfo->u32FirmwareLength); | |
903 | Status = -EINVAL; | |
904 | break; | |
905 | } | |
906 | Status = bcm_ioctl_fw_download(Adapter, psFwInfo); | |
907 | if(Status != STATUS_SUCCESS) | |
908 | { | |
909 | if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR) | |
910 | { | |
911 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); | |
912 | } | |
913 | else | |
914 | { | |
915 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); | |
916 | } | |
917 | //up(&Adapter->fw_download_sema); | |
918 | ||
919 | if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
920 | { | |
921 | Adapter->DriverState = DRIVER_INIT; | |
922 | Adapter->LEDInfo.bLedInitDone = FALSE; | |
923 | wake_up(&Adapter->LEDInfo.notify_led_event); | |
924 | } | |
925 | } | |
926 | break ; | |
927 | }while(0); | |
928 | ||
929 | if(Status != STATUS_SUCCESS) | |
930 | up(&Adapter->fw_download_sema); | |
931 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); | |
932 | bcm_kfree(psFwInfo); | |
933 | break; | |
934 | } | |
935 | case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: | |
936 | { | |
937 | INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
938 | if(NVMAccess) | |
939 | { | |
940 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n"); | |
941 | up(&Adapter->fw_download_sema); | |
942 | return -EACCES; | |
943 | } | |
944 | if(down_trylock(&Adapter->fw_download_sema)) | |
945 | { | |
946 | Adapter->bBinDownloaded=TRUE; | |
947 | Adapter->bCfgDownloaded=TRUE; | |
948 | atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
949 | atomic_set(&Adapter->RxRollOverCount, 0); | |
950 | Adapter->CurrNumRecvDescs=0; | |
951 | Adapter->downloadDDR = 0; | |
952 | ||
953 | //setting the Mips to Run | |
954 | Status = run_card_proc(Adapter); | |
955 | if(Status) | |
956 | { | |
957 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); | |
958 | up(&Adapter->fw_download_sema); | |
959 | up(&Adapter->NVMRdmWrmLock); | |
960 | break; | |
961 | } | |
962 | else | |
963 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n"); | |
964 | mdelay(10); | |
965 | /* Wait for MailBox Interrupt */ | |
966 | if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) | |
967 | { | |
968 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); | |
969 | } | |
970 | timeout = 5*HZ; | |
971 | Adapter->waiting_to_fw_download_done = FALSE; | |
972 | wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, | |
973 | Adapter->waiting_to_fw_download_done, timeout); | |
974 | Adapter->fw_download_process_pid=INVALID_PID; | |
975 | Adapter->fw_download_done=TRUE; | |
976 | atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
977 | Adapter->CurrNumRecvDescs = 0; | |
978 | Adapter->PrevNumRecvDescs = 0; | |
979 | atomic_set(&Adapter->cntrlpktCnt,0); | |
980 | Adapter->LinkUpStatus = 0; | |
981 | Adapter->LinkStatus = 0; | |
982 | ||
983 | if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
984 | { | |
985 | Adapter->DriverState = FW_DOWNLOAD_DONE; | |
986 | wake_up(&Adapter->LEDInfo.notify_led_event); | |
987 | } | |
988 | ||
989 | if(!timeout) | |
990 | { | |
991 | Status = -ENODEV; | |
992 | } | |
993 | } | |
994 | else | |
995 | { | |
996 | Status = -EINVAL; | |
997 | } | |
998 | up(&Adapter->fw_download_sema); | |
999 | up(&Adapter->NVMRdmWrmLock); | |
1000 | break; | |
1001 | } | |
1002 | #endif | |
1003 | case IOCTL_BE_BUCKET_SIZE: | |
eccbf04a DC |
1004 | Status = 0; |
1005 | if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) | |
1006 | Status = -EFAULT; | |
f8942e07 SH |
1007 | break; |
1008 | ||
1009 | case IOCTL_RTPS_BUCKET_SIZE: | |
eccbf04a DC |
1010 | Status = 0; |
1011 | if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) | |
1012 | Status = -EFAULT; | |
f8942e07 SH |
1013 | break; |
1014 | case IOCTL_CHIP_RESET: | |
1015 | { | |
1016 | INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
1017 | if(NVMAccess) | |
1018 | { | |
1019 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
1020 | return -EACCES; | |
1021 | } | |
1022 | down(&Adapter->RxAppControlQueuelock); | |
1023 | Status = reset_card_proc(Adapter); | |
1024 | flushAllAppQ(); | |
1025 | up(&Adapter->RxAppControlQueuelock); | |
1026 | up(&Adapter->NVMRdmWrmLock); | |
1027 | ResetCounters(Adapter); | |
1028 | break; | |
1029 | } | |
1030 | case IOCTL_QOS_THRESHOLD: | |
1031 | { | |
1032 | USHORT uiLoopIndex; | |
eccbf04a DC |
1033 | |
1034 | Status = 0; | |
1035 | for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { | |
1036 | if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, | |
1037 | (unsigned long __user *)arg)) { | |
1038 | Status = -EFAULT; | |
1039 | break; | |
1040 | } | |
f8942e07 | 1041 | } |
f8942e07 SH |
1042 | break; |
1043 | } | |
1044 | ||
1045 | case IOCTL_DUMP_PACKET_INFO: | |
1046 | ||
1047 | DumpPackInfo(Adapter); | |
1048 | DumpPhsRules(&Adapter->stBCMPhsContext); | |
1049 | Status = STATUS_SUCCESS; | |
1050 | break; | |
1051 | ||
1052 | case IOCTL_GET_PACK_INFO: | |
44a17eff | 1053 | if(copy_to_user(argp, &Adapter->PackInfo, |
f8942e07 SH |
1054 | sizeof(PacketInfo)*NO_OF_QUEUES)) |
1055 | { | |
1056 | Status = -EFAULT; | |
1057 | break; | |
1058 | } | |
1059 | Status = STATUS_SUCCESS; | |
1060 | break; | |
1061 | case IOCTL_BCM_SWITCH_TRANSFER_MODE: | |
1062 | { | |
1063 | UINT uiData = 0; | |
44a17eff | 1064 | if(copy_from_user(&uiData, argp, sizeof(UINT))) |
f8942e07 SH |
1065 | { |
1066 | Status = -EFAULT; | |
1067 | break; | |
1068 | } | |
1069 | if(uiData) /* Allow All Packets */ | |
1070 | { | |
1071 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); | |
1072 | Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; | |
1073 | } | |
1074 | else /* Allow IP only Packets */ | |
1075 | { | |
1076 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); | |
1077 | Adapter->TransferMode = IP_PACKET_ONLY_MODE; | |
1078 | } | |
1079 | Status = STATUS_SUCCESS; | |
1080 | break; | |
1081 | } | |
1082 | ||
1083 | case IOCTL_BCM_GET_DRIVER_VERSION: | |
1084 | { | |
1085 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 1086 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1087 | { |
1088 | Status = -EFAULT; | |
1089 | break; | |
1090 | } | |
44a17eff | 1091 | if(copy_to_user(IoBuffer.OutputBuffer, |
f8942e07 SH |
1092 | VER_FILEVERSION_STR, (UINT)IoBuffer.OutputLength)) |
1093 | { | |
1094 | Status = -EFAULT; | |
1095 | break; | |
1096 | } | |
1097 | Status = STATUS_SUCCESS; | |
1098 | break; | |
1099 | } | |
1100 | case IOCTL_BCM_GET_CURRENT_STATUS: | |
1101 | { | |
eccbf04a DC |
1102 | LINK_STATE plink_state; |
1103 | ||
f8942e07 | 1104 | /* Copy Ioctl Buffer structure */ |
44a17eff | 1105 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1106 | { |
1107 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); | |
1108 | Status = -EFAULT; | |
1109 | break; | |
1110 | } | |
eccbf04a DC |
1111 | if (IoBuffer.OutputLength != sizeof(plink_state)) { |
1112 | Status = -EINVAL; | |
1113 | break; | |
1114 | } | |
1115 | ||
1116 | if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) { | |
1117 | Status = -EFAULT; | |
1118 | break; | |
1119 | } | |
1120 | plink_state.bIdleMode = (UCHAR)Adapter->IdleMode; | |
1121 | plink_state.bShutdownMode = Adapter->bShutStatus; | |
1122 | plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus; | |
1123 | if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) { | |
f8942e07 SH |
1124 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); |
1125 | Status = -EFAULT; | |
1126 | break; | |
1127 | } | |
1128 | Status = STATUS_SUCCESS; | |
1129 | break; | |
1130 | } | |
1131 | case IOCTL_BCM_SET_MAC_TRACING: | |
1132 | { | |
1133 | UINT tracing_flag; | |
1134 | /* copy ioctl Buffer structure */ | |
44a17eff | 1135 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1136 | { |
1137 | Status = -EFAULT; | |
1138 | break; | |
1139 | } | |
44a17eff | 1140 | if(copy_from_user(&tracing_flag, IoBuffer.InputBuffer,sizeof(UINT))) |
f8942e07 SH |
1141 | { |
1142 | Status = -EFAULT; | |
1143 | break; | |
1144 | } | |
1145 | if (tracing_flag) | |
1146 | Adapter->pTarangs->MacTracingEnabled = TRUE; | |
1147 | else | |
1148 | Adapter->pTarangs->MacTracingEnabled = FALSE; | |
1149 | break; | |
1150 | } | |
1151 | case IOCTL_BCM_GET_DSX_INDICATION: | |
1152 | { | |
1153 | ULONG ulSFId=0; | |
44a17eff | 1154 | if(copy_from_user((PCHAR)&IoBuffer, argp, |
f8942e07 SH |
1155 | sizeof(IOCTL_BUFFER))) |
1156 | { | |
1157 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid IO buffer!!!" ); | |
1158 | Status = -EFAULT; | |
1159 | break; | |
1160 | } | |
1161 | if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) | |
1162 | { | |
3e8acee4 | 1163 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%zx!!!", |
f8942e07 SH |
1164 | IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); |
1165 | return -EINVAL; | |
1166 | } | |
44a17eff | 1167 | if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, |
f8942e07 SH |
1168 | sizeof(ulSFId))) |
1169 | { | |
1170 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid SFID!!! %lu", ulSFId ); | |
1171 | Status = -EFAULT; | |
1172 | break; | |
1173 | } | |
1174 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId ); | |
1175 | get_dsx_sf_data_to_application(Adapter, ulSFId, | |
1176 | IoBuffer.OutputBuffer); | |
1177 | Status=STATUS_SUCCESS; | |
1178 | } | |
1179 | break; | |
1180 | case IOCTL_BCM_GET_HOST_MIBS: | |
1181 | { | |
1182 | PCHAR temp_buff; | |
1183 | ||
44a17eff | 1184 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1185 | { |
1186 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from user for IoBuff failed\n"); | |
1187 | Status = -EFAULT; | |
1188 | break; | |
1189 | } | |
1190 | ||
1191 | if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) | |
1192 | { | |
3e8acee4 | 1193 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length Check failed %lu %zd\n", IoBuffer.OutputLength, |
f8942e07 SH |
1194 | sizeof(S_MIBS_HOST_STATS_MIBS)); |
1195 | return -EINVAL; | |
1196 | } | |
1197 | ||
1198 | temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); | |
1199 | ||
1200 | if(!temp_buff) | |
1201 | { | |
1202 | return STATUS_FAILURE; | |
1203 | } | |
1204 | ||
1205 | Status = ProcessGetHostMibs(Adapter, | |
1206 | (PUCHAR)temp_buff, IoBuffer.OutputLength); | |
1207 | ||
1208 | Status = GetDroppedAppCntrlPktMibs((PVOID)temp_buff, | |
1209 | (PPER_TARANG_DATA)filp->private_data); | |
1210 | ||
44a17eff | 1211 | if(copy_to_user(IoBuffer.OutputBuffer,(PCHAR)temp_buff, |
f8942e07 SH |
1212 | sizeof(S_MIBS_HOST_STATS_MIBS))) |
1213 | { | |
1214 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n"); | |
1215 | bcm_kfree(temp_buff); | |
1216 | return -EFAULT; | |
1217 | } | |
1218 | ||
1219 | bcm_kfree(temp_buff); | |
1220 | break; | |
1221 | } | |
1222 | ||
1223 | case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: | |
1224 | if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode)) | |
1225 | { | |
1226 | Adapter->usIdleModePattern = ABORT_IDLE_MODE; | |
1227 | Adapter->bWakeUpDevice = TRUE; | |
1228 | wake_up(&Adapter->process_rx_cntrlpkt); | |
1229 | #if 0 | |
1230 | Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; | |
1231 | InterfaceAbortIdlemode (Adapter, Adapter->usIdleModePattern); | |
1232 | #endif | |
1233 | } | |
1234 | Status = STATUS_SUCCESS; | |
1235 | break; | |
1236 | ||
1237 | case IOCTL_BCM_BULK_WRM: | |
1238 | { | |
1239 | PBULKWRM_BUFFER pBulkBuffer; | |
1240 | UINT uiTempVar=0; | |
1241 | PCHAR pvBuffer = NULL; | |
1242 | ||
1243 | if((Adapter->IdleMode == TRUE) || | |
1244 | (Adapter->bShutStatus ==TRUE) || | |
1245 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1246 | { | |
1247 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); | |
1248 | Status = -EACCES; | |
1249 | break; | |
1250 | } | |
1251 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 1252 | if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1253 | { |
1254 | Status = -EFAULT; | |
1255 | break; | |
1256 | } | |
1257 | ||
1258 | pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
1259 | if(!pvBuffer) | |
1260 | { | |
1261 | return -ENOMEM; | |
1262 | break; | |
1263 | } | |
1264 | ||
1265 | /* Get WrmBuffer structure */ | |
1266 | if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
1267 | { | |
1268 | bcm_kfree(pvBuffer); | |
1269 | Status = -EFAULT; | |
1270 | break; | |
1271 | } | |
1272 | ||
1273 | pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; | |
1274 | ||
1275 | if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || | |
1276 | ((ULONG)pBulkBuffer->Register & 0x3)) | |
1277 | { | |
1278 | bcm_kfree(pvBuffer); | |
1279 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register); | |
1280 | Status = -EINVAL; | |
1281 | break; | |
1282 | } | |
1283 | ||
1284 | ||
1285 | uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; | |
1286 | if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) | |
1287 | && ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
1288 | (uiTempVar == EEPROM_REJECT_REG_2) || | |
1289 | (uiTempVar == EEPROM_REJECT_REG_3) || | |
1290 | (uiTempVar == EEPROM_REJECT_REG_4)) && | |
1291 | (cmd == IOCTL_BCM_REGISTER_WRITE)) | |
1292 | { | |
1293 | bcm_kfree(pvBuffer); | |
1294 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n"); | |
1295 | Status = -EFAULT; | |
1296 | break; | |
1297 | } | |
1298 | ||
1299 | if(pBulkBuffer->SwapEndian == FALSE) | |
1300 | Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
1301 | else | |
1302 | Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
1303 | ||
1304 | if(Status != STATUS_SUCCESS) | |
1305 | { | |
1306 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); | |
1307 | } | |
1308 | ||
1309 | bcm_kfree(pvBuffer); | |
1310 | break; | |
1311 | } | |
1312 | ||
1313 | case IOCTL_BCM_GET_NVM_SIZE: | |
1314 | { | |
1315 | ||
44a17eff | 1316 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1317 | { |
1318 | //IOLog("failed NVM first"); | |
1319 | Status = -EFAULT; | |
1320 | break; | |
1321 | } | |
1322 | if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) { | |
1323 | if(copy_to_user(IoBuffer.OutputBuffer, | |
1324 | (unsigned char *)&Adapter->uiNVMDSDSize, (UINT)sizeof(UINT))) | |
1325 | { | |
1326 | Status = -EFAULT; | |
1327 | return Status; | |
1328 | } | |
1329 | } | |
1330 | ||
1331 | Status = STATUS_SUCCESS ; | |
1332 | } | |
1333 | break; | |
1334 | ||
1335 | case IOCTL_BCM_CAL_INIT : | |
1336 | ||
1337 | { | |
1338 | UINT uiSectorSize = 0 ; | |
1339 | if(Adapter->eNVMType == NVM_FLASH) | |
1340 | { | |
44a17eff | 1341 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1342 | if(Status) |
1343 | { | |
1344 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); | |
bf58bd66 | 1345 | return -EFAULT; |
f8942e07 | 1346 | } |
eccbf04a DC |
1347 | if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer)) |
1348 | return -EFAULT; | |
1349 | ||
f8942e07 SH |
1350 | if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) |
1351 | { | |
1352 | ||
1353 | Status = copy_to_user(IoBuffer.OutputBuffer, | |
1354 | (unsigned char *)&Adapter->uiSectorSize , | |
1355 | (UINT)sizeof(UINT)); | |
1356 | if(Status) | |
1357 | { | |
1358 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); | |
bf58bd66 | 1359 | return -EFAULT; |
f8942e07 SH |
1360 | } |
1361 | } | |
1362 | else | |
1363 | { | |
1364 | if(IsFlash2x(Adapter)) | |
1365 | { | |
1366 | Status = copy_to_user(IoBuffer.OutputBuffer, | |
1367 | (unsigned char *)&Adapter->uiSectorSize , | |
1368 | (UINT)sizeof(UINT)); | |
1369 | if(Status) | |
1370 | { | |
1371 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); | |
bf58bd66 | 1372 | return -EFAULT; |
f8942e07 SH |
1373 | } |
1374 | ||
1375 | } | |
1376 | else | |
1377 | { | |
1378 | if((TRUE == Adapter->bShutStatus) || | |
1379 | (TRUE == Adapter->IdleMode)) | |
1380 | { | |
1381 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n"); | |
1382 | return -EACCES; | |
1383 | } | |
1384 | ||
1385 | Adapter->uiSectorSize = uiSectorSize ; | |
1386 | BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize); | |
1387 | } | |
1388 | } | |
1389 | Status = STATUS_SUCCESS ; | |
1390 | } | |
1391 | else | |
1392 | { | |
1393 | Status = STATUS_FAILURE; | |
1394 | } | |
1395 | } | |
1396 | break; | |
1397 | case IOCTL_BCM_SET_DEBUG : | |
1398 | { | |
1399 | USER_BCM_DBG_STATE sUserDebugState; | |
1400 | ||
1401 | // BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG ); | |
1402 | ||
1403 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); | |
44a17eff | 1404 | Status = copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1405 | if(Status) |
1406 | { | |
1407 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy from user failed\n"); | |
bf58bd66 | 1408 | Status = -EFAULT; |
f8942e07 SH |
1409 | break; |
1410 | } | |
44a17eff | 1411 | Status = copy_from_user(&sUserDebugState,IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)); |
f8942e07 SH |
1412 | if(Status) |
1413 | { | |
1414 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IoBuffer.InputBuffer failed"); | |
bf58bd66 | 1415 | return -EFAULT; |
f8942e07 SH |
1416 | } |
1417 | ||
1418 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", | |
1419 | sUserDebugState.OnOff, sUserDebugState.Type); | |
1420 | //sUserDebugState.Subtype <<= 1; | |
1421 | sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; | |
1422 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); | |
1423 | ||
1424 | // Update new 'DebugState' in the Adapter | |
1425 | Adapter->stDebugState.type |= sUserDebugState.Type; | |
1426 | /* Subtype: A bitmap of 32 bits for Subtype per Type. | |
1427 | * Valid indexes in 'subtype' array: 1,2,4,8 | |
1428 | * corresponding to valid Type values. Hence we can use the 'Type' field | |
1429 | * as the index value, ignoring the array entries 0,3,5,6,7 ! | |
1430 | */ | |
1431 | if (sUserDebugState.OnOff) | |
1432 | Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; | |
1433 | else | |
1434 | Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; | |
1435 | ||
1436 | BCM_SHOW_DEBUG_BITMAP(Adapter); | |
1437 | ||
1438 | } | |
1439 | break; | |
1440 | case IOCTL_BCM_NVM_READ: | |
1441 | case IOCTL_BCM_NVM_WRITE: | |
1442 | { | |
1443 | ||
44a17eff | 1444 | NVM_READWRITE stNVMReadWrite = {}; |
f8942e07 | 1445 | PUCHAR pReadData = NULL; |
44a17eff | 1446 | void __user * pBuffertobeCopied = NULL; |
f8942e07 SH |
1447 | ULONG ulDSDMagicNumInUsrBuff = 0 ; |
1448 | struct timeval tv0, tv1; | |
1449 | memset(&tv0,0,sizeof(struct timeval)); | |
1450 | memset(&tv1,0,sizeof(struct timeval)); | |
1451 | if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) | |
1452 | { | |
1453 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); | |
1454 | Status = -EFAULT; | |
1455 | break; | |
1456 | } | |
1457 | ||
1458 | if(IsFlash2x(Adapter)) | |
1459 | { | |
1460 | if((Adapter->eActiveDSD != DSD0) && | |
1461 | (Adapter->eActiveDSD != DSD1) && | |
1462 | (Adapter->eActiveDSD != DSD2)) | |
1463 | { | |
1464 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked"); | |
1465 | return STATUS_FAILURE ; | |
1466 | } | |
1467 | } | |
1468 | ||
1469 | /* Copy Ioctl Buffer structure */ | |
1470 | ||
44a17eff | 1471 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
1472 | { |
1473 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copy_from_user failed\n"); | |
bf58bd66 | 1474 | Status = -EFAULT; |
f8942e07 SH |
1475 | break; |
1476 | } | |
1477 | if(IOCTL_BCM_NVM_READ == cmd) | |
1478 | pBuffertobeCopied = IoBuffer.OutputBuffer; | |
1479 | else | |
1480 | pBuffertobeCopied = IoBuffer.InputBuffer; | |
1481 | ||
1482 | if(copy_from_user(&stNVMReadWrite, pBuffertobeCopied,sizeof(NVM_READWRITE))) | |
1483 | { | |
1484 | Status = -EFAULT; | |
1485 | break; | |
1486 | } | |
1487 | ||
1488 | // | |
1489 | // Deny the access if the offset crosses the cal area limit. | |
1490 | // | |
1491 | if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) | |
1492 | { | |
1493 | //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset , | |
1494 | // stNVMReadWrite.uiNumBytes); | |
1495 | Status = STATUS_FAILURE; | |
1496 | break; | |
1497 | } | |
1498 | ||
1499 | pReadData =(PCHAR)kmalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); | |
1500 | ||
1501 | if(!pReadData) | |
1502 | return -ENOMEM; | |
1503 | ||
1504 | memset(pReadData,0,stNVMReadWrite.uiNumBytes); | |
1505 | ||
1506 | if(copy_from_user(pReadData, stNVMReadWrite.pBuffer, | |
1507 | stNVMReadWrite.uiNumBytes)) | |
1508 | { | |
1509 | Status = -EFAULT; | |
1510 | bcm_kfree(pReadData); | |
1511 | break; | |
1512 | } | |
1513 | ||
1514 | do_gettimeofday(&tv0); | |
1515 | if(IOCTL_BCM_NVM_READ == cmd) | |
1516 | { | |
1517 | down(&Adapter->NVMRdmWrmLock); | |
1518 | ||
1519 | if((Adapter->IdleMode == TRUE) || | |
1520 | (Adapter->bShutStatus ==TRUE) || | |
1521 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1522 | { | |
1523 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1524 | up(&Adapter->NVMRdmWrmLock); | |
1525 | bcm_kfree(pReadData); | |
1526 | return -EACCES; | |
1527 | } | |
1528 | ||
1529 | Status = BeceemNVMRead(Adapter, (PUINT)pReadData, | |
1530 | stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); | |
1531 | ||
1532 | up(&Adapter->NVMRdmWrmLock); | |
1533 | ||
1534 | if(Status != STATUS_SUCCESS) | |
1535 | { | |
1536 | bcm_kfree(pReadData); | |
1537 | return Status; | |
1538 | } | |
44a17eff AB |
1539 | if(copy_to_user(stNVMReadWrite.pBuffer, |
1540 | pReadData, (UINT)stNVMReadWrite.uiNumBytes)) | |
f8942e07 SH |
1541 | { |
1542 | bcm_kfree(pReadData); | |
1543 | Status = -EFAULT; | |
1544 | } | |
1545 | } | |
1546 | else | |
1547 | { | |
1548 | ||
1549 | down(&Adapter->NVMRdmWrmLock); | |
1550 | ||
1551 | if((Adapter->IdleMode == TRUE) || | |
1552 | (Adapter->bShutStatus ==TRUE) || | |
1553 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1554 | { | |
1555 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1556 | up(&Adapter->NVMRdmWrmLock); | |
1557 | bcm_kfree(pReadData); | |
1558 | return -EACCES; | |
1559 | } | |
1560 | ||
1561 | Adapter->bHeaderChangeAllowed = TRUE ; | |
1562 | if(IsFlash2x(Adapter)) | |
1563 | { | |
1564 | /* | |
1565 | New Requirement:- | |
1566 | DSD section updation will be allowed in two case:- | |
1567 | 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull | |
1568 | 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is | |
1569 | corrupted then user space program first modify the DSD header with valid DSD sig so | |
1570 | that this as well as further write may be worthwhile. | |
1571 | ||
1572 | This restriction has been put assuming that if DSD sig is corrupted, DSD | |
1573 | data won't be considered valid. | |
1574 | ||
1575 | ||
1576 | */ | |
1577 | Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD); | |
1578 | if(Status != STATUS_SUCCESS) | |
1579 | { | |
1580 | if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) || | |
1581 | (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) | |
1582 | { | |
1583 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); | |
1584 | up(&Adapter->NVMRdmWrmLock); | |
1585 | bcm_kfree(pReadData); | |
1586 | return Status; | |
1587 | } | |
1588 | ||
1589 | ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); | |
1590 | if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) | |
1591 | { | |
1592 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); | |
1593 | up(&Adapter->NVMRdmWrmLock); | |
1594 | bcm_kfree(pReadData); | |
1595 | return Status; | |
1596 | } | |
1597 | } | |
1598 | } | |
1599 | Status = BeceemNVMWrite(Adapter, (PUINT )pReadData, | |
1600 | stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); | |
1601 | if(IsFlash2x(Adapter)) | |
1602 | BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD); | |
1603 | ||
1604 | Adapter->bHeaderChangeAllowed = FALSE ; | |
1605 | ||
1606 | up(&Adapter->NVMRdmWrmLock); | |
1607 | ||
1608 | ||
1609 | if(Status != STATUS_SUCCESS) | |
1610 | { | |
1611 | bcm_kfree(pReadData); | |
1612 | return Status; | |
1613 | } | |
1614 | } | |
1615 | do_gettimeofday(&tv1); | |
1616 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000); | |
1617 | ||
1618 | ||
1619 | bcm_kfree(pReadData); | |
1620 | Status = STATUS_SUCCESS; | |
1621 | } | |
1622 | break; | |
1623 | case IOCTL_BCM_FLASH2X_SECTION_READ : | |
1624 | { | |
1625 | ||
1626 | FLASH2X_READWRITE sFlash2xRead = {0}; | |
1627 | PUCHAR pReadBuff = NULL ; | |
1628 | UINT NOB = 0; | |
1629 | UINT BuffSize = 0; | |
1630 | UINT ReadBytes = 0; | |
1631 | UINT ReadOffset = 0; | |
44a17eff | 1632 | char __user *OutPutBuff = NULL; |
f8942e07 SH |
1633 | |
1634 | if(IsFlash2x(Adapter) != TRUE) | |
1635 | { | |
1636 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
1637 | return -EINVAL; | |
1638 | } | |
1639 | ||
1640 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); | |
44a17eff | 1641 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1642 | if(Status) |
1643 | { | |
1644 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 1645 | return -EFAULT; |
f8942e07 SH |
1646 | } |
1647 | ||
1648 | //Reading FLASH 2.x READ structure | |
44a17eff | 1649 | Status = copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)); |
f8942e07 SH |
1650 | if(Status) |
1651 | { | |
1652 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Input Buffer failed"); | |
bf58bd66 | 1653 | return -EFAULT; |
f8942e07 SH |
1654 | } |
1655 | ||
1656 | ||
1657 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section); | |
1658 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset); | |
1659 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes); | |
1660 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify); | |
1661 | ||
1662 | //This was internal to driver for raw read. now it has ben exposed to user space app. | |
1663 | if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE) | |
1664 | return STATUS_FAILURE ; | |
1665 | ||
1666 | NOB = sFlash2xRead.numOfBytes; | |
1667 | if(NOB > Adapter->uiSectorSize ) | |
1668 | BuffSize = Adapter->uiSectorSize; | |
1669 | else | |
1670 | BuffSize = NOB ; | |
1671 | ||
1672 | ReadOffset = sFlash2xRead.offset ; | |
44a17eff | 1673 | OutPutBuff = IoBuffer.OutputBuffer; |
f8942e07 SH |
1674 | |
1675 | ||
1676 | pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); | |
1677 | if(pReadBuff == NULL) | |
1678 | { | |
1679 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); | |
1680 | return -ENOMEM; | |
1681 | } | |
1682 | down(&Adapter->NVMRdmWrmLock); | |
1683 | ||
1684 | if((Adapter->IdleMode == TRUE) || | |
1685 | (Adapter->bShutStatus ==TRUE) || | |
1686 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1687 | { | |
1688 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1689 | up(&Adapter->NVMRdmWrmLock); | |
1690 | bcm_kfree(pReadBuff); | |
1691 | return -EACCES; | |
1692 | } | |
1693 | ||
1694 | while(NOB) | |
1695 | { | |
1696 | ||
1697 | if(NOB > Adapter->uiSectorSize ) | |
1698 | ReadBytes = Adapter->uiSectorSize; | |
1699 | else | |
1700 | ReadBytes = NOB; | |
1701 | ||
1702 | ||
1703 | //Reading the data from Flash 2.x | |
1704 | ||
1705 | Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes); | |
1706 | if(Status) | |
1707 | { | |
1708 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status); | |
1709 | break ; | |
1710 | } | |
1711 | ||
1712 | BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); | |
1713 | ||
1714 | Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); | |
1715 | if(Status) | |
1716 | { | |
1717 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status); | |
bf58bd66 | 1718 | Status = -EFAULT; |
f8942e07 SH |
1719 | break; |
1720 | } | |
1721 | NOB = NOB - ReadBytes; | |
1722 | if(NOB) | |
1723 | { | |
1724 | ReadOffset = ReadOffset + ReadBytes ; | |
1725 | OutPutBuff = OutPutBuff + ReadBytes ; | |
1726 | } | |
1727 | ||
1728 | } | |
1729 | up(&Adapter->NVMRdmWrmLock); | |
1730 | bcm_kfree(pReadBuff); | |
1731 | ||
1732 | } | |
1733 | break ; | |
1734 | case IOCTL_BCM_FLASH2X_SECTION_WRITE : | |
1735 | { | |
1736 | FLASH2X_READWRITE sFlash2xWrite = {0}; | |
1737 | PUCHAR pWriteBuff = NULL; | |
44a17eff | 1738 | void __user *InputAddr = NULL; |
f8942e07 SH |
1739 | UINT NOB = 0; |
1740 | UINT BuffSize = 0; | |
1741 | UINT WriteOffset = 0; | |
1742 | UINT WriteBytes = 0; | |
1743 | ||
1744 | if(IsFlash2x(Adapter) != TRUE) | |
1745 | { | |
1746 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
1747 | return -EINVAL; | |
1748 | } | |
1749 | ||
1750 | //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite | |
1751 | Adapter->bAllDSDWriteAllow = FALSE; | |
1752 | ||
1753 | ||
1754 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); | |
44a17eff | 1755 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1756 | if(Status) |
1757 | { | |
1758 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 1759 | return -EFAULT; |
f8942e07 SH |
1760 | } |
1761 | ||
1762 | //Reading FLASH 2.x READ structure | |
44a17eff | 1763 | Status = copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)); |
f8942e07 SH |
1764 | if(Status) |
1765 | { | |
1766 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reading of output Buffer from IOCTL buffer fails"); | |
bf58bd66 | 1767 | return -EFAULT; |
f8942e07 SH |
1768 | } |
1769 | ||
1770 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section); | |
1771 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); | |
1772 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes); | |
1773 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify); | |
1774 | #if 0 | |
1775 | if((sFlash2xWrite.Section == ISO_IMAGE1) ||(sFlash2xWrite.Section == ISO_IMAGE2) || | |
1776 | (sFlash2xWrite.Section == DSD0) || (sFlash2xWrite.Section == DSD1) || (sFlash2xWrite.Section == DSD2)) | |
1777 | { | |
1778 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"ISO/DSD Image write is not allowed.... "); | |
1779 | return STATUS_FAILURE ; | |
1780 | } | |
1781 | #endif | |
1782 | if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && | |
1783 | (sFlash2xWrite.Section != VSA2) ) | |
1784 | { | |
1785 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed"); | |
1786 | return -EINVAL; | |
1787 | } | |
1788 | ||
1789 | if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE) | |
1790 | return STATUS_FAILURE ; | |
1791 | ||
44a17eff | 1792 | InputAddr = sFlash2xWrite.pDataBuff; |
f8942e07 SH |
1793 | WriteOffset = sFlash2xWrite.offset ; |
1794 | NOB = sFlash2xWrite.numOfBytes; | |
1795 | ||
1796 | if(NOB > Adapter->uiSectorSize ) | |
1797 | BuffSize = Adapter->uiSectorSize; | |
1798 | else | |
1799 | BuffSize = NOB ; | |
1800 | ||
1801 | pWriteBuff = (PCHAR)kmalloc(BuffSize, GFP_KERNEL); | |
1802 | if(pWriteBuff == NULL) | |
1803 | { | |
1804 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); | |
1805 | return -ENOMEM; | |
1806 | } | |
1807 | ||
1808 | //extracting the remainder of the given offset. | |
1809 | WriteBytes = Adapter->uiSectorSize ; | |
1810 | if(WriteOffset % Adapter->uiSectorSize) | |
1811 | WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); | |
1812 | if(NOB < WriteBytes) | |
1813 | WriteBytes = NOB; | |
1814 | ||
1815 | down(&Adapter->NVMRdmWrmLock); | |
1816 | ||
1817 | if((Adapter->IdleMode == TRUE) || | |
1818 | (Adapter->bShutStatus ==TRUE) || | |
1819 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1820 | { | |
1821 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1822 | up(&Adapter->NVMRdmWrmLock); | |
1823 | bcm_kfree(pWriteBuff); | |
1824 | return -EACCES; | |
1825 | } | |
1826 | ||
1827 | BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section); | |
1828 | do | |
1829 | { | |
1830 | Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes); | |
1831 | if(Status) | |
1832 | { | |
1833 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status); | |
bf58bd66 | 1834 | Status = -EFAULT; |
f8942e07 SH |
1835 | break ; |
1836 | } | |
1837 | BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes); | |
1838 | //Writing the data from Flash 2.x | |
1839 | Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify); | |
1840 | ||
1841 | if(Status) | |
1842 | { | |
1843 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); | |
1844 | break ; | |
1845 | } | |
1846 | ||
1847 | NOB = NOB - WriteBytes; | |
1848 | if(NOB) | |
1849 | { | |
1850 | WriteOffset = WriteOffset + WriteBytes ; | |
1851 | InputAddr = InputAddr + WriteBytes ; | |
1852 | if(NOB > Adapter->uiSectorSize ) | |
1853 | WriteBytes = Adapter->uiSectorSize; | |
1854 | else | |
1855 | WriteBytes = NOB; | |
1856 | } | |
1857 | ||
1858 | ||
1859 | } while(NOB > 0); | |
1860 | BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section); | |
1861 | up(&Adapter->NVMRdmWrmLock); | |
1862 | bcm_kfree(pWriteBuff); | |
1863 | } | |
1864 | break ; | |
1865 | case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : | |
1866 | { | |
1867 | ||
1868 | PFLASH2X_BITMAP psFlash2xBitMap = NULL ; | |
1869 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); | |
1870 | ||
44a17eff | 1871 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1872 | if(Status) |
1873 | { | |
1874 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 1875 | return -EFAULT; |
f8942e07 SH |
1876 | } |
1877 | if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) | |
1878 | { | |
3e8acee4 | 1879 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Structure size mismatch Lib :0x%lx Driver :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_BITMAP)); |
f8942e07 SH |
1880 | break; |
1881 | } | |
1882 | ||
1883 | psFlash2xBitMap = (PFLASH2X_BITMAP)kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); | |
1884 | if(psFlash2xBitMap == NULL) | |
1885 | { | |
1886 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available"); | |
1887 | return -ENOMEM ; | |
1888 | } | |
1889 | //Reading the Flash Sectio Bit map | |
1890 | down(&Adapter->NVMRdmWrmLock); | |
1891 | ||
1892 | if((Adapter->IdleMode == TRUE) || | |
1893 | (Adapter->bShutStatus ==TRUE) || | |
1894 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1895 | { | |
1896 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1897 | up(&Adapter->NVMRdmWrmLock); | |
1898 | bcm_kfree(psFlash2xBitMap); | |
1899 | return -EACCES; | |
1900 | } | |
1901 | ||
1902 | BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); | |
1903 | up(&Adapter->NVMRdmWrmLock); | |
44a17eff | 1904 | Status = copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)); |
f8942e07 SH |
1905 | if(Status) |
1906 | { | |
1907 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed"); | |
1908 | bcm_kfree(psFlash2xBitMap); | |
bf58bd66 | 1909 | return -EFAULT; |
f8942e07 SH |
1910 | } |
1911 | bcm_kfree(psFlash2xBitMap); | |
1912 | } | |
1913 | break ; | |
1914 | case IOCTL_BCM_SET_ACTIVE_SECTION : | |
1915 | { | |
1916 | FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; | |
1917 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); | |
1918 | ||
1919 | if(IsFlash2x(Adapter) != TRUE) | |
1920 | { | |
1921 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
1922 | return -EINVAL; | |
1923 | } | |
1924 | ||
44a17eff | 1925 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
1926 | if(Status) |
1927 | { | |
1928 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 1929 | return -EFAULT; |
f8942e07 SH |
1930 | } |
1931 | ||
44a17eff | 1932 | Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); |
f8942e07 SH |
1933 | if(Status) |
1934 | { | |
1935 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
bf58bd66 | 1936 | return -EFAULT; |
f8942e07 SH |
1937 | } |
1938 | ||
1939 | down(&Adapter->NVMRdmWrmLock); | |
1940 | ||
1941 | if((Adapter->IdleMode == TRUE) || | |
1942 | (Adapter->bShutStatus ==TRUE) || | |
1943 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
1944 | { | |
1945 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
1946 | up(&Adapter->NVMRdmWrmLock); | |
1947 | return -EACCES; | |
1948 | } | |
1949 | ||
1950 | Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal); | |
1951 | if(Status) | |
1952 | { | |
1953 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status); | |
1954 | } | |
1955 | up(&Adapter->NVMRdmWrmLock); | |
1956 | } | |
1957 | break ; | |
1958 | case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION : | |
1959 | { | |
1960 | //Right Now we are taking care of only DSD | |
1961 | Adapter->bAllDSDWriteAllow = FALSE ; | |
1962 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); | |
1963 | ||
1964 | #if 0 | |
1965 | SECTION_TYPE section = 0 ; | |
1966 | ||
1967 | ||
1968 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION Called"); | |
1969 | Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); | |
1970 | if(Status) | |
1971 | { | |
1972 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 1973 | return -EFAULT; |
f8942e07 SH |
1974 | } |
1975 | Status = copy_from_user((PCHAR)section,(PCHAR)&IoBuffer, sizeof(INT)); | |
1976 | if(Status) | |
1977 | { | |
1978 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of section type failed failed"); | |
bf58bd66 | 1979 | return -EFAULT; |
f8942e07 SH |
1980 | } |
1981 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", section); | |
1982 | if(section == DSD) | |
1983 | Adapter->ulFlashCalStart = Adapter->uiActiveDSDOffsetAtFwDld ; | |
1984 | else | |
1985 | Status = STATUS_FAILURE ; | |
1986 | #endif | |
1987 | Status = STATUS_SUCCESS ; | |
1988 | } | |
1989 | break ; | |
1990 | case IOCTL_BCM_COPY_SECTION : | |
1991 | { | |
1992 | FLASH2X_COPY_SECTION sCopySectStrut = {0}; | |
1993 | Status = STATUS_SUCCESS; | |
1994 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); | |
1995 | ||
1996 | Adapter->bAllDSDWriteAllow = FALSE ; | |
1997 | if(IsFlash2x(Adapter) != TRUE) | |
1998 | { | |
1999 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
2000 | return -EINVAL; | |
2001 | } | |
2002 | ||
44a17eff | 2003 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2004 | if(Status) |
2005 | { | |
2006 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); | |
bf58bd66 | 2007 | return -EFAULT; |
f8942e07 SH |
2008 | } |
2009 | ||
44a17eff | 2010 | Status = copy_from_user(&sCopySectStrut,IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); |
f8942e07 SH |
2011 | if(Status) |
2012 | { | |
2013 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); | |
bf58bd66 | 2014 | return -EFAULT; |
f8942e07 SH |
2015 | } |
2016 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); | |
2017 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); | |
2018 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); | |
2019 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); | |
2020 | ||
2021 | ||
2022 | if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE) | |
2023 | { | |
2024 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); | |
2025 | return -EINVAL; | |
2026 | } | |
2027 | ||
2028 | if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE) | |
2029 | { | |
2030 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); | |
2031 | return -EINVAL; | |
2032 | } | |
2033 | ||
2034 | if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection) | |
2035 | { | |
2036 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different"); | |
2037 | return -EINVAL; | |
2038 | } | |
2039 | ||
2040 | down(&Adapter->NVMRdmWrmLock); | |
2041 | ||
2042 | if((Adapter->IdleMode == TRUE) || | |
2043 | (Adapter->bShutStatus ==TRUE) || | |
2044 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
2045 | { | |
2046 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
2047 | up(&Adapter->NVMRdmWrmLock); | |
2048 | return -EACCES; | |
2049 | } | |
2050 | ||
2051 | if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) | |
2052 | { | |
2053 | if(IsNonCDLessDevice(Adapter)) | |
2054 | { | |
2055 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!"); | |
2056 | Status = -EINVAL ; | |
2057 | } | |
2058 | else if(sCopySectStrut.numOfBytes == 0) | |
2059 | { | |
2060 | Status = BcmCopyISO(Adapter,sCopySectStrut); | |
2061 | } | |
2062 | else | |
2063 | { | |
2064 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed.."); | |
2065 | Status = STATUS_FAILURE ; | |
2066 | } | |
2067 | up(&Adapter->NVMRdmWrmLock); | |
2068 | return Status; | |
2069 | } | |
2070 | ||
2071 | Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, | |
2072 | sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes); | |
2073 | up(&Adapter->NVMRdmWrmLock); | |
2074 | } | |
2075 | break ; | |
2076 | case IOCTL_BCM_GET_FLASH_CS_INFO : | |
2077 | { | |
2078 | Status = STATUS_SUCCESS; | |
2079 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); | |
2080 | ||
44a17eff | 2081 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2082 | if(Status) |
2083 | { | |
2084 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 2085 | Status = -EFAULT; |
f8942e07 SH |
2086 | break; |
2087 | } | |
2088 | if(Adapter->eNVMType != NVM_FLASH) | |
2089 | { | |
2090 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash"); | |
2091 | Status = -EINVAL; | |
2092 | break; | |
2093 | } | |
2094 | if(IsFlash2x(Adapter) == TRUE) | |
2095 | { | |
2096 | ||
2097 | if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) | |
2098 | { | |
3e8acee4 | 2099 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. \nRequired size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_CS_INFO)); |
f8942e07 SH |
2100 | Status = -EINVAL; |
2101 | break; | |
2102 | } | |
2103 | ||
44a17eff | 2104 | Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)); |
f8942e07 SH |
2105 | if(Status) |
2106 | { | |
2107 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x cs info failed"); | |
bf58bd66 | 2108 | Status = -EFAULT; |
f8942e07 SH |
2109 | break; |
2110 | } | |
2111 | } | |
2112 | else | |
2113 | { | |
2114 | if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) | |
2115 | { | |
3e8acee4 | 2116 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. Required size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH_CS_INFO)); |
f8942e07 SH |
2117 | Status = -EINVAL; |
2118 | break; | |
2119 | } | |
44a17eff | 2120 | Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)); |
f8942e07 SH |
2121 | if(Status) |
2122 | { | |
2123 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash CS info failed"); | |
bf58bd66 | 2124 | Status = -EFAULT; |
f8942e07 SH |
2125 | break; |
2126 | } | |
2127 | ||
2128 | } | |
2129 | } | |
2130 | break ; | |
2131 | case IOCTL_BCM_SELECT_DSD : | |
2132 | { | |
2133 | UINT SectOfset = 0; | |
2134 | FLASH2X_SECTION_VAL eFlash2xSectionVal; | |
2135 | eFlash2xSectionVal = NO_SECTION_VAL ; | |
2136 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called"); | |
2137 | ||
2138 | if(IsFlash2x(Adapter) != TRUE) | |
2139 | { | |
2140 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
2141 | return -EINVAL; | |
2142 | } | |
2143 | ||
44a17eff | 2144 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2145 | if(Status) |
2146 | { | |
2147 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 2148 | return -EFAULT; |
f8942e07 | 2149 | } |
44a17eff | 2150 | Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); |
f8942e07 SH |
2151 | if(Status) |
2152 | { | |
2153 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
bf58bd66 | 2154 | return -EFAULT; |
f8942e07 SH |
2155 | } |
2156 | ||
2157 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal); | |
2158 | if((eFlash2xSectionVal != DSD0) && | |
2159 | (eFlash2xSectionVal != DSD1) && | |
2160 | (eFlash2xSectionVal != DSD2) ) | |
2161 | { | |
2162 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal); | |
2163 | return STATUS_FAILURE ; | |
2164 | } | |
2165 | ||
2166 | SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); | |
2167 | if(SectOfset == INVALID_OFFSET) | |
2168 | { | |
2169 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); | |
2170 | return -EINVAL; | |
2171 | } | |
2172 | ||
2173 | Adapter->bAllDSDWriteAllow = TRUE ; | |
2174 | ||
2175 | Adapter->ulFlashCalStart = SectOfset ; | |
2176 | Adapter->eActiveDSD = eFlash2xSectionVal; | |
2177 | } | |
2178 | Status = STATUS_SUCCESS ; | |
2179 | break; | |
2180 | ||
2181 | case IOCTL_BCM_NVM_RAW_READ : | |
2182 | { | |
2183 | ||
44a17eff | 2184 | NVM_READWRITE stNVMRead = {}; |
f8942e07 SH |
2185 | INT NOB ; |
2186 | INT BuffSize ; | |
2187 | INT ReadOffset = 0; | |
2188 | UINT ReadBytes = 0 ; | |
2189 | PUCHAR pReadBuff = NULL ; | |
44a17eff | 2190 | char __user *OutPutBuff = NULL ; |
f8942e07 SH |
2191 | |
2192 | if(Adapter->eNVMType != NVM_FLASH) | |
2193 | { | |
2194 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash "); | |
2195 | return -EINVAL ; | |
2196 | } | |
2197 | ||
2198 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 2199 | if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
f8942e07 SH |
2200 | { |
2201 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); | |
2202 | Status = -EFAULT; | |
2203 | break; | |
2204 | } | |
2205 | ||
44a17eff | 2206 | if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE))) |
f8942e07 SH |
2207 | { |
2208 | Status = -EFAULT; | |
2209 | break; | |
2210 | } | |
2211 | ||
2212 | NOB = stNVMRead.uiNumBytes; | |
2213 | //In Raw-Read max Buff size : 64MB | |
2214 | ||
2215 | if(NOB > DEFAULT_BUFF_SIZE) | |
2216 | BuffSize = DEFAULT_BUFF_SIZE; | |
2217 | else | |
2218 | BuffSize = NOB ; | |
2219 | ||
2220 | ReadOffset = stNVMRead.uiOffset ; | |
44a17eff | 2221 | OutPutBuff = stNVMRead.pBuffer; |
f8942e07 SH |
2222 | |
2223 | ||
2224 | pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); | |
2225 | if(pReadBuff == NULL) | |
2226 | { | |
2227 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); | |
2228 | Status = -ENOMEM; | |
2229 | break; | |
2230 | } | |
2231 | down(&Adapter->NVMRdmWrmLock); | |
2232 | ||
2233 | if((Adapter->IdleMode == TRUE) || | |
2234 | (Adapter->bShutStatus ==TRUE) || | |
2235 | (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
2236 | { | |
2237 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
2238 | bcm_kfree(pReadBuff); | |
2239 | up(&Adapter->NVMRdmWrmLock); | |
2240 | return -EACCES; | |
2241 | } | |
2242 | ||
2243 | Adapter->bFlashRawRead = TRUE ; | |
2244 | while(NOB) | |
2245 | { | |
2246 | if(NOB > DEFAULT_BUFF_SIZE ) | |
2247 | ReadBytes = DEFAULT_BUFF_SIZE; | |
2248 | else | |
2249 | ReadBytes = NOB; | |
2250 | ||
2251 | //Reading the data from Flash 2.x | |
2252 | Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes); | |
2253 | if(Status) | |
2254 | { | |
2255 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); | |
2256 | break; | |
2257 | } | |
2258 | ||
2259 | BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); | |
2260 | ||
2261 | Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); | |
2262 | if(Status) | |
2263 | { | |
2264 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status); | |
bf58bd66 | 2265 | Status = -EFAULT; |
f8942e07 SH |
2266 | break; |
2267 | } | |
2268 | NOB = NOB - ReadBytes; | |
2269 | if(NOB) | |
2270 | { | |
2271 | ReadOffset = ReadOffset + ReadBytes ; | |
2272 | OutPutBuff = OutPutBuff + ReadBytes ; | |
2273 | } | |
2274 | ||
2275 | } | |
2276 | Adapter->bFlashRawRead = FALSE ; | |
2277 | up(&Adapter->NVMRdmWrmLock); | |
2278 | bcm_kfree(pReadBuff); | |
2279 | break ; | |
2280 | } | |
2281 | ||
2282 | case IOCTL_BCM_CNTRLMSG_MASK: | |
2283 | { | |
2284 | ULONG RxCntrlMsgBitMask = 0 ; | |
2285 | ||
2286 | /* Copy Ioctl Buffer structure */ | |
44a17eff | 2287 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2288 | if(Status) |
2289 | { | |
2290 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); | |
bf58bd66 | 2291 | Status = -EFAULT; |
f8942e07 SH |
2292 | break; |
2293 | } | |
2294 | ||
2295 | Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
2296 | if(Status) | |
2297 | { | |
2298 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); | |
bf58bd66 | 2299 | Status = -EFAULT; |
f8942e07 SH |
2300 | break; |
2301 | } | |
2302 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); | |
2303 | pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ; | |
2304 | } | |
2305 | break; | |
2306 | case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: | |
2307 | { | |
2308 | DEVICE_DRIVER_INFO DevInfo; | |
2309 | ||
2310 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); | |
2311 | ||
2312 | DevInfo.MaxRDMBufferSize = BUFFER_4K; | |
2313 | DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; | |
2314 | DevInfo.u32RxAlignmentCorrection = 0; | |
2315 | DevInfo.u32NVMType = Adapter->eNVMType; | |
2316 | DevInfo.u32InterfaceType = BCM_USB; | |
2317 | ||
44a17eff | 2318 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2319 | if(Status) |
2320 | { | |
2321 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 2322 | Status = -EFAULT; |
f8942e07 SH |
2323 | break; |
2324 | } | |
2325 | if(IoBuffer.OutputLength < sizeof(DevInfo)) | |
2326 | { | |
2327 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length is less than actural buffer size"); | |
3e8acee4 | 2328 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"user passed buffer size :0x%lX, expected size :0x%zx",IoBuffer.OutputLength, sizeof(DevInfo)); |
f8942e07 SH |
2329 | Status = -EINVAL; |
2330 | break; | |
2331 | } | |
44a17eff | 2332 | Status = copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)); |
f8942e07 SH |
2333 | if(Status) |
2334 | { | |
2335 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying Dev info structure to user space buffer failed"); | |
bf58bd66 | 2336 | Status = -EFAULT; |
f8942e07 SH |
2337 | break; |
2338 | } | |
2339 | } | |
2340 | break ; | |
2341 | ||
2342 | case IOCTL_BCM_TIME_SINCE_NET_ENTRY: | |
2343 | { | |
2344 | ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; | |
2345 | struct timeval tv = {0} ; | |
2346 | ||
2347 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); | |
2348 | ||
44a17eff | 2349 | Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); |
f8942e07 SH |
2350 | if(Status) |
2351 | { | |
2352 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
bf58bd66 | 2353 | Status = -EFAULT; |
f8942e07 SH |
2354 | break; |
2355 | } | |
2356 | if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) | |
2357 | { | |
3e8acee4 | 2358 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length:0x%lx is less than expected buff size :0x%zX",IoBuffer.OutputLength,sizeof(ST_TIME_ELAPSED)); |
f8942e07 SH |
2359 | Status = -EINVAL; |
2360 | break; | |
2361 | } | |
2362 | ||
2363 | //stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = Adapter->liTimeSinceLastNetEntry; | |
2364 | do_gettimeofday(&tv); | |
2365 | stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = tv.tv_sec - Adapter->liTimeSinceLastNetEntry; | |
2366 | ||
44a17eff | 2367 | Status = copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)); |
f8942e07 SH |
2368 | if(Status) |
2369 | { | |
2370 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying ST_TIME_ELAPSED structure to user space buffer failed"); | |
bf58bd66 | 2371 | Status = -EFAULT; |
f8942e07 SH |
2372 | break; |
2373 | } | |
2374 | ||
2375 | } | |
2376 | break; | |
2377 | ||
2378 | default: | |
2379 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "wrong input %x",cmd); | |
2380 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In default ioctl %d\n", cmd); | |
2381 | Status = STATUS_FAILURE; | |
2382 | ||
2383 | break; | |
2384 | } | |
2385 | return Status; | |
2386 | } | |
2387 | ||
2388 | ||
2389 | static struct file_operations bcm_fops = { | |
9f1c75ac AB |
2390 | .owner = THIS_MODULE, |
2391 | .open = bcm_char_open, | |
2392 | .release = bcm_char_release, | |
2393 | .read = bcm_char_read, | |
2394 | .unlocked_ioctl = bcm_char_ioctl, | |
d16044cf | 2395 | .llseek = no_llseek, |
f8942e07 SH |
2396 | }; |
2397 | ||
2398 | ||
2399 | int register_control_device_interface(PMINI_ADAPTER Adapter) | |
2400 | { | |
2401 | if(Adapter->major>0) | |
2402 | return Adapter->major; | |
2403 | Adapter->major = register_chrdev(0, "tarang", &bcm_fops); | |
2404 | if(Adapter->major < 0) | |
2405 | { | |
2406 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "register_chrdev:Failed to registering WiMax control char device!"); | |
2407 | return Adapter->major; | |
2408 | } | |
2409 | ||
2410 | bcm_class = NULL; | |
2411 | bcm_class = class_create (THIS_MODULE, "tarang"); | |
2412 | if(IS_ERR (bcm_class)) | |
2413 | { | |
2414 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unable to create class\n"); | |
2415 | unregister_chrdev(Adapter->major, "tarang"); | |
2416 | Adapter->major = 0; | |
2417 | return -ENODEV; | |
2418 | } | |
2419 | Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL, | |
2420 | MKDEV(Adapter->major, 0), | |
2421 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) | |
2422 | NULL , | |
2423 | #endif | |
2424 | "tarang"); | |
2425 | ||
2426 | if(IS_ERR(Adapter->pstCreatedClassDevice)) | |
2427 | { | |
2428 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "class device did not get created : %ld", PTR_ERR(Adapter->pstCreatedClassDevice) ); | |
2429 | } | |
2430 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Got Major No: %d", Adapter->major); | |
2431 | return 0; | |
2432 | } | |
2433 | ||
2434 | void unregister_control_device_interface(PMINI_ADAPTER Adapter) | |
2435 | { | |
2436 | if(Adapter->major > 0) | |
2437 | { | |
2438 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying class device"); | |
2439 | device_destroy (bcm_class, MKDEV(Adapter->major, 0)); | |
2440 | } | |
2441 | if(!IS_ERR(bcm_class)) | |
2442 | { | |
2443 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying created class "); | |
2444 | class_destroy (bcm_class); | |
2445 | bcm_class = NULL; | |
2446 | } | |
2447 | if(Adapter->major > 0) | |
2448 | { | |
2449 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"unregistering character interface"); | |
2450 | unregister_chrdev(Adapter->major, "tarang"); | |
2451 | } | |
2452 | ||
2453 | } |