Merge tag 'pm2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[cascardo/linux.git] / drivers / staging / csr / drv.c
1 /*
2  * ---------------------------------------------------------------------------
3  *  FILE:     drv.c
4  *
5  *  PURPOSE:
6  *      Conventional device interface for debugging/monitoring of the
7  *      driver and h/w using unicli. This interface is also being used
8  *      by the SME linux implementation and the helper apps.
9  *
10  * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
11  *
12  * Refer to LICENSE.txt included with this source code for details on
13  * the license terms.
14  *
15  * ---------------------------------------------------------------------------
16  */
17
18
19
20 /*
21  * Porting Notes:
22  * Part of this file contains an example for how to glue the OS layer
23  * with the HIP core lib, the SDIO glue layer, and the SME.
24  *
25  * When the unifi_sdio.ko modules loads, the linux kernel calls unifi_load().
26  * unifi_load() calls uf_sdio_load() which is exported by the SDIO glue
27  * layer. uf_sdio_load() registers this driver with the underlying SDIO driver.
28  * When a card is detected, the SDIO glue layer calls register_unifi_sdio()
29  * to pass the SDIO function context and ask the OS layer to initialise
30  * the card. register_unifi_sdio() allocates all the private data of the OS
31  * layer and calls uf_run_unifihelper() to start the SME. The SME calls
32  * unifi_sys_wifi_on_req() which uses the HIP core lib to initialise the card.
33  */
34
35 #include <linux/init.h>
36 #include <linux/slab.h>
37 #include <linux/poll.h>
38 #include <asm/uaccess.h>
39 #include <linux/jiffies.h>
40
41 #include "csr_wifi_hip_unifiversion.h"
42 #include "unifi_priv.h"
43 #include "csr_wifi_hip_conversions.h"
44 #include "unifi_native.h"
45
46 /* Module parameter variables */
47 int buswidth = 0;               /* 0 means use default, values 1,4 */
48 int sdio_clock = 50000;         /* kHz */
49 int unifi_debug = 0;
50 /* fw_init prevents f/w initialisation on error. */
51 int fw_init[MAX_UNIFI_DEVS] = {-1, -1};
52 int use_5g = 0;
53 int led_mask = 0;               /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */
54 int disable_hw_reset = 0;
55 int disable_power_control = 0;
56 int enable_wol = UNIFI_WOL_OFF; /* 0 for none, 1 for SDIO IRQ, 2 for PIO */
57 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
58 int tl_80211d = (int)CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB;
59 #endif
60 int sdio_block_size = -1;      /* Override SDIO block size */
61 int sdio_byte_mode = 0;        /* 0 for block mode + padding, 1 for byte mode */
62 int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS;
63 int run_bh_once = -1;          /* Set for scheduled interrupt mode, -1 = default */
64 int bh_priority = -1;
65 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
66 #define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA   (1 << 1)
67 #define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP  (1 << 2)
68 int log_hip_signals = 0;
69 #endif
70
71 MODULE_DESCRIPTION("CSR UniFi (SDIO)");
72
73 module_param(buswidth,    int, S_IRUGO|S_IWUSR);
74 module_param(sdio_clock,  int, S_IRUGO|S_IWUSR);
75 module_param(unifi_debug, int, S_IRUGO|S_IWUSR);
76 module_param_array(fw_init, int, NULL, S_IRUGO|S_IWUSR);
77 module_param(use_5g,      int, S_IRUGO|S_IWUSR);
78 module_param(led_mask,    int, S_IRUGO|S_IWUSR);
79 module_param(disable_hw_reset,  int, S_IRUGO|S_IWUSR);
80 module_param(disable_power_control,  int, S_IRUGO|S_IWUSR);
81 module_param(enable_wol,  int, S_IRUGO|S_IWUSR);
82 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
83 module_param(tl_80211d,   int, S_IRUGO|S_IWUSR);
84 #endif
85 module_param(sdio_block_size, int, S_IRUGO|S_IWUSR);
86 module_param(sdio_byte_mode, int, S_IRUGO|S_IWUSR);
87 module_param(coredump_max, int, S_IRUGO|S_IWUSR);
88 module_param(run_bh_once, int, S_IRUGO|S_IWUSR);
89 module_param(bh_priority, int, S_IRUGO|S_IWUSR);
90 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
91 module_param(log_hip_signals, int, S_IRUGO|S_IWUSR);
92 #endif
93
94 MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
95 MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)");
96 MODULE_PARM_DESC(unifi_debug, "Diagnostic reporting level");
97 MODULE_PARM_DESC(fw_init, "Set to 0 to prevent f/w initialization on error");
98 MODULE_PARM_DESC(use_5g, "Use the 5G (802.11a) radio band");
99 MODULE_PARM_DESC(led_mask, "LED mask flags");
100 MODULE_PARM_DESC(disable_hw_reset, "Set to 1 to disable hardware reset");
101 MODULE_PARM_DESC(disable_power_control, "Set to 1 to disable SDIO power control");
102 MODULE_PARM_DESC(enable_wol, "Enable wake-on-wlan function 0=off, 1=SDIO, 2=PIO");
103 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
104 MODULE_PARM_DESC(tl_80211d, "802.11d Trust Level (1-6, default = 5)");
105 #endif
106 MODULE_PARM_DESC(sdio_block_size, "Set to override SDIO block size");
107 MODULE_PARM_DESC(sdio_byte_mode, "Set to 1 for byte mode SDIO");
108 MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate");
109 MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts");
110 MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority");
111 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
112 MODULE_PARM_DESC(log_hip_signals, "Set to 1 to enable HIP signal offline logging");
113 #endif
114
115
116 /* Callback for event logging to UDI clients */
117 static void udi_log_event(ul_client_t *client,
118                           const u8 *signal, int signal_len,
119                           const bulk_data_param_t *bulkdata,
120                           int dir);
121
122 static void udi_set_log_filter(ul_client_t *pcli,
123                                unifiio_filter_t *udi_filter);
124
125
126 /* Mutex to protect access to  priv->sme_cli */
127 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
128 DEFINE_SEMAPHORE(udi_mutex);
129 #else
130 DECLARE_MUTEX(udi_mutex);
131 #endif
132
133 s32 CsrHipResultToStatus(CsrResult csrResult)
134 {
135     s32 r = -EIO;
136
137     switch (csrResult)
138     {
139     case CSR_RESULT_SUCCESS:
140         r = 0;
141         break;
142     case CSR_WIFI_HIP_RESULT_RANGE:
143         r = -ERANGE;
144         break;
145     case CSR_WIFI_HIP_RESULT_NO_DEVICE:
146         r = -ENODEV;
147         break;
148     case CSR_WIFI_HIP_RESULT_INVALID_VALUE:
149         r = -EINVAL;
150         break;
151     case CSR_WIFI_HIP_RESULT_NOT_FOUND:
152         r = -ENOENT;
153         break;
154     case CSR_WIFI_HIP_RESULT_NO_SPACE:
155         r = -ENOSPC;
156         break;
157     case CSR_WIFI_HIP_RESULT_NO_MEMORY:
158         r = -ENOMEM;
159         break;
160     case CSR_RESULT_FAILURE:
161         r = -EIO;
162         break;
163     default:
164         /*unifi_warning(card->ospriv, "CsrHipResultToStatus: Unrecognised csrResult error code: %d\n", csrResult);*/
165         r = -EIO;
166     }
167     return r;
168 }
169
170
171 static const char*
172 trace_putest_cmdid(unifi_putest_command_t putest_cmd)
173 {
174     switch (putest_cmd)
175     {
176         case UNIFI_PUTEST_START:
177             return "START";
178         case UNIFI_PUTEST_STOP:
179             return "STOP";
180         case UNIFI_PUTEST_SET_SDIO_CLOCK:
181             return "SET CLOCK";
182         case UNIFI_PUTEST_CMD52_READ:
183             return "CMD52R";
184         case UNIFI_PUTEST_CMD52_BLOCK_READ:
185             return "CMD52BR";
186         case UNIFI_PUTEST_CMD52_WRITE:
187             return "CMD52W";
188         case UNIFI_PUTEST_DL_FW:
189             return "D/L FW";
190         case UNIFI_PUTEST_DL_FW_BUFF:
191             return "D/L FW BUFFER";
192         case UNIFI_PUTEST_COREDUMP_PREPARE:
193             return "PREPARE COREDUMP";
194         case UNIFI_PUTEST_GP_READ16:
195             return "GP16R";
196         case UNIFI_PUTEST_GP_WRITE16:
197             return "GP16W";
198         default:
199             return "ERROR: unrecognised command";
200     }
201  }
202
203 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
204 int uf_register_hip_offline_debug(unifi_priv_t *priv)
205 {
206     ul_client_t *udi_cli;
207     int i;
208
209     udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
210     if (udi_cli == NULL) {
211         /* Too many clients already using this device */
212         unifi_error(priv, "Too many UDI clients already open\n");
213         return -ENOSPC;
214     }
215     unifi_trace(priv, UDBG1, "Offline HIP client is registered\n");
216
217     down(&priv->udi_logging_mutex);
218     udi_cli->event_hook = udi_log_event;
219     unifi_set_udi_hook(priv->card, logging_handler);
220     /* Log all signals by default */
221     for (i = 0; i < SIG_FILTER_SIZE; i++) {
222         udi_cli->signal_filter[i] = 0xFFFF;
223     }
224     priv->logging_client = udi_cli;
225     up(&priv->udi_logging_mutex);
226
227     return 0;
228 }
229
230 int uf_unregister_hip_offline_debug(unifi_priv_t *priv)
231 {
232     ul_client_t *udi_cli = priv->logging_client;
233     if (udi_cli == NULL)
234     {
235         unifi_error(priv, "Unknown HIP client unregister request\n");
236         return -ERANGE;
237     }
238
239     unifi_trace(priv, UDBG1, "Offline HIP client is unregistered\n");
240
241     down(&priv->udi_logging_mutex);
242     priv->logging_client = NULL;
243     udi_cli->event_hook = NULL;
244     up(&priv->udi_logging_mutex);
245
246     ul_deregister_client(udi_cli);
247
248     return 0;
249 }
250 #endif
251
252
253 /*
254  * ---------------------------------------------------------------------------
255  *  unifi_open
256  *  unifi_release
257  *
258  *      Open and release entry points for the UniFi debug driver.
259  *
260  *  Arguments:
261  *      Normal linux driver args.
262  *
263  *  Returns:
264  *      Linux error code.
265  * ---------------------------------------------------------------------------
266  */
267 static int
268 unifi_open(struct inode *inode, struct file *file)
269 {
270     int devno;
271     unifi_priv_t *priv;
272     ul_client_t *udi_cli;
273
274     func_enter();
275
276     devno = MINOR(inode->i_rdev) >> 1;
277
278     /*
279      * Increase the ref_count for the char device clients.
280      * Make sure you call uf_put_instance() to decreace it if
281      * unifi_open returns an error.
282      */
283     priv = uf_get_instance(devno);
284     if (priv == NULL) {
285         unifi_error(NULL, "unifi_open: No device present\n");
286         func_exit();
287         return -ENODEV;
288     }
289
290     /* Register this instance in the client's list. */
291     /* The minor number determines the nature of the client (Unicli or SME). */
292     if (MINOR(inode->i_rdev) & 0x1) {
293         udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
294         if (udi_cli == NULL) {
295             /* Too many clients already using this device */
296             unifi_error(priv, "Too many clients already open\n");
297             uf_put_instance(devno);
298             func_exit();
299             return -ENOSPC;
300         }
301         unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno);
302     } else {
303         /*
304          * Even-numbered device nodes are the control application.
305          * This is the userspace helper containing SME or
306          * unifi_manager.
307          */
308
309         down(&udi_mutex);
310
311 #ifdef CSR_SME_USERSPACE
312         /* Check if a config client is already attached */
313         if (priv->sme_cli) {
314             up(&udi_mutex);
315             uf_put_instance(devno);
316
317             unifi_info(priv, "There is already a configuration client using the character device\n");
318             func_exit();
319             return -EBUSY;
320         }
321 #endif /* CSR_SME_USERSPACE */
322
323 #ifdef CSR_SUPPORT_SME
324         udi_cli = ul_register_client(priv,
325                                      CLI_USING_WIRE_FORMAT | CLI_SME_USERSPACE,
326                                      sme_log_event);
327 #else
328         /* Config client for native driver */
329         udi_cli = ul_register_client(priv,
330                                      0,
331                                      sme_native_log_event);
332 #endif
333         if (udi_cli == NULL) {
334             /* Too many clients already using this device */
335             up(&udi_mutex);
336             uf_put_instance(devno);
337
338             unifi_error(priv, "Too many clients already open\n");
339             func_exit();
340             return -ENOSPC;
341         }
342
343         /*
344          * Fill-in the pointer to the configuration client.
345          * This is the SME userspace helper or unifi_manager.
346          * Not used in the SME embedded version.
347          */
348         unifi_trace(priv, UDBG1, "SME client (id:%d s:0x%X) is registered\n",
349                     udi_cli->client_id, udi_cli->sender_id);
350         /* Store the SME UniFi Linux Client */
351         if (priv->sme_cli == NULL) {
352             priv->sme_cli = udi_cli;
353         }
354
355         up(&udi_mutex);
356     }
357
358
359     /*
360      * Store the pointer to the client.
361      * All char driver's entry points will pass this pointer.
362      */
363     file->private_data = udi_cli;
364
365     func_exit();
366     return 0;
367 } /* unifi_open() */
368
369
370 static int
371 unifi_release(struct inode *inode, struct file *filp)
372 {
373     ul_client_t *udi_cli = (void*)filp->private_data;
374     int devno;
375     unifi_priv_t *priv;
376
377     func_enter();
378
379     priv = uf_find_instance(udi_cli->instance);
380     if (!priv) {
381         unifi_error(priv, "unifi_close: instance for device not found\n");
382         return -ENODEV;
383     }
384
385     devno = MINOR(inode->i_rdev) >> 1;
386
387     /* Even device nodes are the config client (i.e. SME or unifi_manager) */
388     if ((MINOR(inode->i_rdev) & 0x1) == 0) {
389
390         if (priv->sme_cli != udi_cli) {
391             unifi_notice(priv, "Surprise closing config device: not the sme client\n");
392         }
393         unifi_notice(priv, "SME client close (unifi%d)\n", devno);
394
395         /*
396          * Clear sme_cli before calling unifi_sys_... so it doesn't try to
397          * queue a reply to the (now gone) SME.
398          */
399         down(&udi_mutex);
400         priv->sme_cli = NULL;
401         up(&udi_mutex);
402
403 #ifdef CSR_SME_USERSPACE
404         /* Power-down when config client closes */
405         {
406             CsrWifiRouterCtrlWifiOffReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, 0, 0, 0, NULL}};
407             CsrWifiRouterCtrlWifiOffReqHandler(priv, &req.common);
408         }
409
410         uf_sme_deinit(priv);
411
412        /* It is possible that a blocking SME request was made from another process
413         * which did not get read by the SME before the WifiOffReq.
414         * So check for a pending request which will go unanswered and cancel
415         * the wait for event. As only one blocking request can be in progress at
416         * a time, up to one event should be completed.
417         */
418        uf_sme_cancel_request(priv, 0);
419
420 #endif /* CSR_SME_USERSPACE */
421     } else {
422
423         unifi_trace(priv, UDBG2, "UDI client close (unifiudi%d)\n", devno);
424
425         /* If the pointer matches the logging client, stop logging. */
426         down(&priv->udi_logging_mutex);
427         if (udi_cli == priv->logging_client) {
428             priv->logging_client = NULL;
429         }
430         up(&priv->udi_logging_mutex);
431
432         if (udi_cli == priv->amp_client) {
433             priv->amp_client = NULL;
434         }
435     }
436
437     /* Deregister this instance from the client's list. */
438     ul_deregister_client(udi_cli);
439
440     uf_put_instance(devno);
441
442     return 0;
443 } /* unifi_release() */
444
445
446
447 /*
448  * ---------------------------------------------------------------------------
449  *  unifi_read
450  *
451  *      The read() driver entry point.
452  *
453  *  Arguments:
454  *      filp        The file descriptor returned by unifi_open()
455  *      p           The user space buffer to copy the read data
456  *      len         The size of the p buffer
457  *      poff
458  *
459  *  Returns:
460  *      number of bytes read or an error code on failure
461  * ---------------------------------------------------------------------------
462  */
463 static ssize_t
464 unifi_read(struct file *filp, char *p, size_t len, loff_t *poff)
465 {
466     ul_client_t *pcli = (void*)filp->private_data;
467     unifi_priv_t *priv;
468     udi_log_t *logptr = NULL;
469     udi_msg_t *msgptr;
470     struct list_head *l;
471     int msglen;
472
473     func_enter();
474
475     priv = uf_find_instance(pcli->instance);
476     if (!priv) {
477         unifi_error(priv, "invalid priv\n");
478         return -ENODEV;
479     }
480
481     if (!pcli->udi_enabled) {
482         unifi_error(priv, "unifi_read: unknown client.");
483         return -EINVAL;
484     }
485
486     if (list_empty(&pcli->udi_log)) {
487         if (filp->f_flags & O_NONBLOCK) {
488             /* Non-blocking - just return if the udi_log is empty */
489             return 0;
490         } else {
491             /* Blocking - wait on the UDI wait queue */
492             if (wait_event_interruptible(pcli->udi_wq,
493                 !list_empty(&pcli->udi_log)))
494             {
495                 unifi_error(priv, "unifi_read: wait_event_interruptible failed.");
496                 return -ERESTARTSYS;
497             }
498         }
499     }
500
501     /* Read entry from list head and remove it from the list */
502     if (down_interruptible(&pcli->udi_sem)) {
503         return -ERESTARTSYS;
504     }
505     l = pcli->udi_log.next;
506     list_del(l);
507     up(&pcli->udi_sem);
508
509     /* Get a pointer to whole struct */
510     logptr = list_entry(l, udi_log_t, q);
511     if (logptr == NULL) {
512         unifi_error(priv, "unifi_read: failed to get event.\n");
513         return -EINVAL;
514     }
515
516     /* Get the real message */
517     msgptr = &logptr->msg;
518     msglen = msgptr->length;
519     if (msglen > len) {
520         printk(KERN_WARNING "truncated read to %d actual msg len is %lu\n", msglen, (long unsigned int)len);
521         msglen = len;
522     }
523
524     /* and pass it to the client (SME or Unicli). */
525     if (copy_to_user(p, msgptr, msglen))
526     {
527         printk(KERN_ERR "Failed to copy UDI log to user\n");
528         kfree(logptr);
529         return -EFAULT;
530     }
531
532     /* It is our resposibility to free the message buffer. */
533     kfree(logptr);
534
535     func_exit_r(msglen);
536     return msglen;
537
538 } /* unifi_read() */
539
540
541
542 /*
543  * ---------------------------------------------------------------------------
544  * udi_send_signal_unpacked
545  *
546  *      Sends an unpacked signal to UniFi.
547  *
548  * Arguments:
549  *      priv            Pointer to private context struct
550  *      data            Pointer to request structure and data to send
551  *      data_len        Length of data in data pointer.
552  *
553  * Returns:
554  *      Number of bytes written, error otherwise.
555  *
556  * Notes:
557  *      All clients that use this function to send a signal to the unifi
558  *      must use the host formatted structures.
559  * ---------------------------------------------------------------------------
560  */
561 static int
562 udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len)
563 {
564     CSR_SIGNAL *sigptr = (CSR_SIGNAL*)data;
565     CSR_DATAREF *datarefptr;
566     bulk_data_param_t bulk_data;
567     uint signal_size, i;
568     uint bulk_data_offset = 0;
569     int bytecount, r;
570     CsrResult csrResult;
571
572     /* Number of bytes in the signal */
573     signal_size = SigGetSize(sigptr);
574     if (!signal_size || (signal_size > data_len)) {
575         unifi_error(priv, "unifi_sme_mlme_req - Invalid signal 0x%x size should be %d bytes\n",
576                     sigptr->SignalPrimitiveHeader.SignalId,
577                     signal_size);
578         return -EINVAL;
579     }
580     bytecount = signal_size;
581
582     /* Get a pointer to the information of the first data reference */
583     datarefptr = (CSR_DATAREF*)&sigptr->u;
584
585     /* Initialize the offset in the data buffer, bulk data is right after the signal. */
586     bulk_data_offset = signal_size;
587
588     /* store the references and the size of the bulk data to the bulkdata structure */
589     for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
590         /* the length of the bulk data is in the signal */
591         if ((datarefptr+i)->DataLength) {
592             void *dest;
593
594             csrResult = unifi_net_data_malloc(priv, &bulk_data.d[i], (datarefptr+i)->DataLength);
595             if (csrResult != CSR_RESULT_SUCCESS) {
596                 unifi_error(priv, "udi_send_signal_unpacked: failed to allocate request_data.\n");
597                 return -EIO;
598             }
599
600             dest = (void*)bulk_data.d[i].os_data_ptr;
601             memcpy(dest, data + bulk_data_offset, bulk_data.d[i].data_length);
602         } else {
603             bulk_data.d[i].data_length = 0;
604         }
605
606         bytecount += bulk_data.d[i].data_length;
607         /* advance the offset, to point the next bulk data */
608         bulk_data_offset += bulk_data.d[i].data_length;
609     }
610
611
612     unifi_trace(priv, UDBG3, "SME Send: signal 0x%.4X\n", sigptr->SignalPrimitiveHeader.SignalId);
613
614     /* Send the signal. */
615     r = ul_send_signal_unpacked(priv, sigptr, &bulk_data);
616     if (r < 0) {
617         unifi_error(priv, "udi_send_signal_unpacked: send failed (%d)\n", r);
618         for(i=0;i<UNIFI_MAX_DATA_REFERENCES;i++) {
619             if(bulk_data.d[i].data_length != 0) {
620                 unifi_net_data_free(priv, &bulk_data.d[i]);
621             }
622         }
623         func_exit();
624         return -EIO;
625     }
626
627     return bytecount;
628 } /* udi_send_signal_unpacked() */
629
630
631
632 /*
633  * ---------------------------------------------------------------------------
634  * udi_send_signal_raw
635  *
636  *      Sends a packed signal to UniFi.
637  *
638  * Arguments:
639  *      priv            Pointer to private context struct
640  *      buf             Pointer to request structure and data to send
641  *      buflen          Length of data in data pointer.
642  *
643  * Returns:
644  *      Number of bytes written, error otherwise.
645  *
646  * Notes:
647  *      All clients that use this function to send a signal to the unifi
648  *      must use the wire formatted structures.
649  * ---------------------------------------------------------------------------
650  */
651 static int
652 udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
653 {
654     int signal_size;
655     int sig_id;
656     bulk_data_param_t data_ptrs;
657     int i, r;
658     unsigned int num_data_refs;
659     int bytecount;
660     CsrResult csrResult;
661
662     func_enter();
663
664     /*
665      * The signal is the first thing in buf, the signal id is the
666      * first 16 bits of the signal.
667      */
668     /* Number of bytes in the signal */
669     sig_id = GET_SIGNAL_ID(buf);
670     signal_size = buflen;
671     signal_size -= GET_PACKED_DATAREF_LEN(buf, 0);
672     signal_size -= GET_PACKED_DATAREF_LEN(buf, 1);
673     if ((signal_size <= 0) || (signal_size > buflen)) {
674         unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n",
675                     sig_id);
676         func_exit();
677         return -EINVAL;
678     }
679     unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal 0x%.4X len:%d\n",
680                 sig_id, signal_size);
681     /* Zero the data ref arrays */
682     memset(&data_ptrs, 0, sizeof(data_ptrs));
683
684     /*
685      * Find the number of associated bulk data packets.  Scan through
686      * the data refs to check that we have enough data and pick out
687      * pointers to appended bulk data.
688      */
689     num_data_refs = 0;
690     bytecount = signal_size;
691
692     for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
693     {
694         unsigned int len = GET_PACKED_DATAREF_LEN(buf, i);
695         unifi_trace(priv, UDBG3, "udi_send_signal_raw: data_ref length = %d\n", len);
696
697         if (len != 0) {
698             void *dest;
699
700             csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[i], len);
701             if (csrResult != CSR_RESULT_SUCCESS) {
702                 unifi_error(priv, "udi_send_signal_raw: failed to allocate request_data.\n");
703                 return -EIO;
704             }
705
706             dest = (void*)data_ptrs.d[i].os_data_ptr;
707             memcpy(dest, buf + bytecount, len);
708
709             bytecount += len;
710             num_data_refs++;
711         }
712         data_ptrs.d[i].data_length = len;
713     }
714
715     unifi_trace(priv, UDBG3, "Queueing signal 0x%.4X from UDI with %u data refs\n",
716           sig_id,
717           num_data_refs);
718
719     if (bytecount > buflen) {
720         unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount);
721         func_exit();
722         return -EINVAL;
723     }
724
725     /* Send the signal calling the function that uses the wire-formatted signals. */
726     r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs);
727     if (r < 0) {
728         unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r);
729         func_exit();
730         return -EIO;
731     }
732
733 #ifdef CSR_NATIVE_LINUX
734     if (sig_id == CSR_MLME_POWERMGT_REQUEST_ID) {
735         int power_mode = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((buf +
736                                               SIZEOF_SIGNAL_HEADER + (UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF)));
737 #ifdef CSR_SUPPORT_WEXT
738         /* Overide the wext power mode to the new value */
739         priv->wext_conf.power_mode = power_mode;
740 #endif
741         /* Configure deep sleep signaling */
742         if (power_mode || (priv->interfacePriv[0]->connected == UnifiNotConnected)) {
743             csrResult = unifi_configure_low_power_mode(priv->card,
744                                                    UNIFI_LOW_POWER_ENABLED,
745                                                    UNIFI_PERIODIC_WAKE_HOST_DISABLED);
746         } else {
747             csrResult = unifi_configure_low_power_mode(priv->card,
748                                                    UNIFI_LOW_POWER_DISABLED,
749                                                    UNIFI_PERIODIC_WAKE_HOST_DISABLED);
750         }
751     }
752 #endif
753
754     func_exit_r(bytecount);
755
756     return bytecount;
757 } /* udi_send_signal_raw */
758
759 /*
760  * ---------------------------------------------------------------------------
761  *  unifi_write
762  *
763  *      The write() driver entry point.
764  *      A UniFi Debug Interface client such as unicli can write a signal
765  *      plus bulk data to the driver for sending to the UniFi chip.
766  *
767  *      Only one signal may be sent per write operation.
768  *
769  *  Arguments:
770  *      filp        The file descriptor returned by unifi_open()
771  *      p           The user space buffer to get the data from
772  *      len         The size of the p buffer
773  *      poff
774  *
775  *  Returns:
776  *      number of bytes written or an error code on failure
777  * ---------------------------------------------------------------------------
778  */
779 static ssize_t
780 unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
781 {
782     ul_client_t *pcli = (ul_client_t*)filp->private_data;
783     unifi_priv_t *priv;
784     unsigned char *buf;
785     unsigned char *bufptr;
786     int remaining;
787     int bytes_written;
788     int r;
789     bulk_data_param_t bulkdata;
790     CsrResult csrResult;
791
792     func_enter();
793
794     priv = uf_find_instance(pcli->instance);
795     if (!priv) {
796         unifi_error(priv, "invalid priv\n");
797         return -ENODEV;
798     }
799
800     unifi_trace(priv, UDBG5, "unifi_write: len = %d\n", len);
801
802     if (!pcli->udi_enabled) {
803         unifi_error(priv, "udi disabled\n");
804         return -EINVAL;
805     }
806
807     /*
808      * AMP client sends only one signal at a time, so we can use
809      * unifi_net_data_malloc to save the extra copy.
810      */
811     if (pcli == priv->amp_client) {
812         int signal_size;
813         int sig_id;
814         unsigned char *signal_buf;
815         char *user_data_buf;
816
817         csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], len);
818         if (csrResult != CSR_RESULT_SUCCESS) {
819             unifi_error(priv, "unifi_write: failed to allocate request_data.\n");
820             func_exit();
821             return -ENOMEM;
822         }
823
824         user_data_buf = (char*)bulkdata.d[0].os_data_ptr;
825
826         /* Get the data from the AMP client. */
827         if (copy_from_user((void*)user_data_buf, p, len)) {
828             unifi_error(priv, "unifi_write: copy from user failed\n");
829             unifi_net_data_free(priv, &bulkdata.d[0]);
830             func_exit();
831             return -EFAULT;
832         }
833
834         bulkdata.d[1].os_data_ptr = NULL;
835         bulkdata.d[1].data_length = 0;
836
837         /* Number of bytes in the signal */
838         sig_id = GET_SIGNAL_ID(bulkdata.d[0].os_data_ptr);
839         signal_size = len;
840         signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 0);
841         signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 1);
842         if ((signal_size <= 0) || (signal_size > len)) {
843             unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n",
844                         sig_id);
845             unifi_net_data_free(priv, &bulkdata.d[0]);
846             func_exit();
847             return -EINVAL;
848         }
849
850         unifi_trace(priv, UDBG2, "unifi_write: signal 0x%.4X len:%d\n",
851                     sig_id, signal_size);
852
853         /* Allocate a buffer for the signal */
854         signal_buf = kmalloc(signal_size, GFP_KERNEL);
855         if (!signal_buf) {
856             unifi_net_data_free(priv, &bulkdata.d[0]);
857             func_exit();
858             return -ENOMEM;
859         }
860
861         /* Get the signal from the os_data_ptr */
862         memcpy(signal_buf, bulkdata.d[0].os_data_ptr, signal_size);
863         signal_buf[5] = (pcli->sender_id >> 8) & 0xff;
864
865         if (signal_size < len) {
866             /* Remove the signal from the os_data_ptr */
867             bulkdata.d[0].data_length -= signal_size;
868             bulkdata.d[0].os_data_ptr += signal_size;
869         } else {
870             bulkdata.d[0].data_length = 0;
871             bulkdata.d[0].os_data_ptr = NULL;
872         }
873
874         /* Send the signal calling the function that uses the wire-formatted signals. */
875         r = ul_send_signal_raw(priv, signal_buf, signal_size, &bulkdata);
876         if (r < 0) {
877             unifi_error(priv, "unifi_write: send failed (%d)\n", r);
878             if (bulkdata.d[0].os_data_ptr != NULL) {
879                 unifi_net_data_free(priv, &bulkdata.d[0]);
880             }
881         }
882
883         /* Free the signal buffer and return */
884         kfree(signal_buf);
885         return len;
886     }
887
888     buf = kmalloc(len, GFP_KERNEL);
889     if (!buf) {
890         return -ENOMEM;
891     }
892
893     /* Get the data from the client (SME or Unicli). */
894     if (copy_from_user((void*)buf, p, len)) {
895         unifi_error(priv, "copy from user failed\n");
896         kfree(buf);
897         return -EFAULT;
898     }
899
900     /*
901      * In SME userspace build read() contains a SYS or MGT message.
902      * Note that even though the SME sends one signal at a time, we can not
903      * use unifi_net_data_malloc because in the early stages, before having
904      * initialised the core, it will fail since the I/O block size is unknown.
905      */
906 #ifdef CSR_SME_USERSPACE
907     if (pcli->configuration & CLI_SME_USERSPACE) {
908         CsrWifiRouterTransportRecv(priv, buf, len);
909         kfree(buf);
910         return len;
911     }
912 #endif
913
914     /* ul_send_signal_raw will  do a sanity check of len against signal content */
915
916     /*
917      * udi_send_signal_raw() and udi_send_signal_unpacked() return the number of bytes consumed.
918      * A write call can pass multiple signal concatenated together.
919      */
920     bytes_written = 0;
921     remaining = len;
922     bufptr = buf;
923     while (remaining > 0)
924     {
925         int r;
926
927         /*
928          * Set the SenderProcessId.
929          * The SignalPrimitiveHeader is the first 3 16-bit words of the signal,
930          * the SenderProcessId is bytes 4,5.
931          * The MSB of the sender ID needs to be set to the client ID.
932          * The LSB is controlled by the SME.
933          */
934         bufptr[5] = (pcli->sender_id >> 8) & 0xff;
935
936         /* use the appropriate interface, depending on the clients' configuration */
937         if (pcli->configuration & CLI_USING_WIRE_FORMAT) {
938             unifi_trace(priv, UDBG1, "unifi_write: call udi_send_signal().\n");
939             r = udi_send_signal_raw(priv, bufptr, remaining);
940         } else {
941             r = udi_send_signal_unpacked(priv, bufptr, remaining);
942         }
943         if (r < 0) {
944             /* Set the return value to the error code */
945             unifi_error(priv, "unifi_write: (udi or sme)_send_signal() returns %d\n", r);
946             bytes_written = r;
947             break;
948         }
949         bufptr += r;
950         remaining -= r;
951         bytes_written += r;
952     }
953
954     kfree(buf);
955
956     func_exit_r(bytes_written);
957
958     return bytes_written;
959 } /* unifi_write() */
960
961
962 static const char* build_type_to_string(unsigned char build_type)
963 {
964     switch (build_type)
965     {
966     case UNIFI_BUILD_NME: return "NME";
967     case UNIFI_BUILD_WEXT: return "WEXT";
968     case UNIFI_BUILD_AP: return "AP";
969     }
970     return "unknown";
971 }
972
973
974 /*
975  * ----------------------------------------------------------------
976  *  unifi_ioctl
977  *
978  *      Ioctl handler for unifi driver.
979  *
980  * Arguments:
981  *  inodep          Pointer to inode structure.
982  *  filp            Pointer to file structure.
983  *  cmd             Ioctl cmd passed by user.
984  *  arg             Ioctl arg passed by user.
985  *
986  * Returns:
987  *      0 on success, -ve error code on error.
988  * ----------------------------------------------------------------
989  */
990 static long
991 unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
992 {
993     ul_client_t *pcli = (ul_client_t*)filp->private_data;
994     unifi_priv_t *priv;
995     struct net_device *dev;
996     int r = 0;
997     int int_param, i;
998     u8* buf;
999     CsrResult csrResult;
1000 #if (defined CSR_SUPPORT_SME)
1001     unifi_cfg_command_t cfg_cmd;
1002 #if (defined CSR_SUPPORT_WEXT)
1003     CsrWifiSmeCoexConfig coex_config;
1004     unsigned char uchar_param;
1005     unsigned char varbind[MAX_VARBIND_LENGTH];
1006     int vblen;
1007 #endif
1008 #endif
1009     unifi_putest_command_t putest_cmd;
1010
1011     priv = uf_find_instance(pcli->instance);
1012     if (!priv) {
1013         unifi_error(priv, "ioctl error: unknown instance=%d\n", pcli->instance);
1014         r = -ENODEV;
1015         goto out;
1016     }
1017     unifi_trace(priv, UDBG5, "unifi_ioctl: cmd=0x%X, arg=0x%lX\n", cmd, arg);
1018
1019     switch (cmd) {
1020
1021       case UNIFI_GET_UDI_ENABLE:
1022         unifi_trace(priv, UDBG4, "UniFi Get UDI Enable\n");
1023
1024         down(&priv->udi_logging_mutex);
1025         int_param = (priv->logging_client == NULL) ? 0 : 1;
1026         up(&priv->udi_logging_mutex);
1027
1028         if (put_user(int_param, (int*)arg))
1029         {
1030             unifi_error(priv, "UNIFI_GET_UDI_ENABLE: Failed to copy to user\n");
1031             r = -EFAULT;
1032             goto out;
1033         }
1034         break;
1035
1036       case UNIFI_SET_UDI_ENABLE:
1037         unifi_trace(priv, UDBG4, "UniFi Set UDI Enable\n");
1038         if (get_user(int_param, (int*)arg))
1039         {
1040             unifi_error(priv, "UNIFI_SET_UDI_ENABLE: Failed to copy from user\n");
1041             r = -EFAULT;
1042             goto out;
1043         }
1044
1045 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1046         if (log_hip_signals) {
1047             unifi_error(priv, "omnicli cannot be used when log_hip_signals is used\n");
1048             r = -EFAULT;
1049             goto out;
1050         }
1051 #endif
1052
1053         down(&priv->udi_logging_mutex);
1054         if (int_param) {
1055             pcli->event_hook = udi_log_event;
1056             unifi_set_udi_hook(priv->card, logging_handler);
1057             /* Log all signals by default */
1058             for (i = 0; i < SIG_FILTER_SIZE; i++) {
1059                 pcli->signal_filter[i] = 0xFFFF;
1060             }
1061             priv->logging_client = pcli;
1062
1063         } else {
1064             priv->logging_client = NULL;
1065             pcli->event_hook = NULL;
1066         }
1067         up(&priv->udi_logging_mutex);
1068
1069         break;
1070
1071       case UNIFI_SET_MIB:
1072         unifi_trace(priv, UDBG4, "UniFi Set MIB\n");
1073 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1074         /* Read first 2 bytes and check length */
1075         if (copy_from_user((void*)varbind, (void*)arg, 2)) {
1076             unifi_error(priv,
1077                         "UNIFI_SET_MIB: Failed to copy in varbind header\n");
1078             r = -EFAULT;
1079             goto out;
1080         }
1081         vblen = varbind[1];
1082         if ((vblen + 2) > MAX_VARBIND_LENGTH) {
1083             unifi_error(priv,
1084                         "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n",
1085                         (vblen+2), MAX_VARBIND_LENGTH);
1086             r = -EINVAL;
1087             goto out;
1088         }
1089         /* Read rest of varbind */
1090         if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) {
1091             unifi_error(priv, "UNIFI_SET_MIB: Failed to copy in varbind\n");
1092             r = -EFAULT;
1093             goto out;
1094         }
1095
1096         /* send to SME */
1097         vblen += 2;
1098         r = sme_mgt_mib_set(priv, varbind, vblen);
1099         if (r) {
1100             goto out;
1101         }
1102 #else
1103         unifi_notice(priv, "UNIFI_SET_MIB: Unsupported.\n");
1104 #endif /* CSR_SUPPORT_WEXT */
1105         break;
1106
1107       case UNIFI_GET_MIB:
1108         unifi_trace(priv, UDBG4, "UniFi Get MIB\n");
1109 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1110         /* Read first 2 bytes and check length */
1111         if (copy_from_user((void*)varbind, (void*)arg, 2)) {
1112             unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind header\n");
1113             r = -EFAULT;
1114             goto out;
1115         }
1116         vblen = varbind[1];
1117         if ((vblen+2) > MAX_VARBIND_LENGTH) {
1118             unifi_error(priv, "UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n",
1119                         (vblen+2), MAX_VARBIND_LENGTH);
1120             r = -EINVAL;
1121             goto out;
1122         }
1123         /* Read rest of varbind */
1124         if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) {
1125             unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind\n");
1126             r = -EFAULT;
1127             goto out;
1128         }
1129
1130         vblen += 2;
1131         r = sme_mgt_mib_get(priv, varbind, &vblen);
1132         if (r) {
1133             goto out;
1134         }
1135         /* copy out varbind */
1136         if (vblen > MAX_VARBIND_LENGTH) {
1137             unifi_error(priv,
1138                         "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n",
1139                         vblen, MAX_VARBIND_LENGTH);
1140             r = -EINVAL;
1141             goto out;
1142         }
1143         if (copy_to_user((void*)arg, varbind, vblen)) {
1144             r = -EFAULT;
1145             goto out;
1146         }
1147 #else
1148         unifi_notice(priv, "UNIFI_GET_MIB: Unsupported.\n");
1149 #endif /* CSR_SUPPORT_WEXT */
1150         break;
1151
1152       case UNIFI_CFG:
1153 #if (defined CSR_SUPPORT_SME)
1154         if (get_user(cfg_cmd, (unifi_cfg_command_t*)arg))
1155         {
1156             unifi_error(priv, "UNIFI_CFG: Failed to get the command\n");
1157             r = -EFAULT;
1158             goto out;
1159         }
1160
1161         unifi_trace(priv, UDBG1, "UNIFI_CFG: Command is %d (t=%u) sz=%d\n",
1162                     cfg_cmd, jiffies_to_msecs(jiffies), sizeof(unifi_cfg_command_t));
1163         switch (cfg_cmd) {
1164           case UNIFI_CFG_POWER:
1165             r = unifi_cfg_power(priv, (unsigned char*)arg);
1166             break;
1167           case UNIFI_CFG_POWERSAVE:
1168             r = unifi_cfg_power_save(priv, (unsigned char*)arg);
1169             break;
1170           case UNIFI_CFG_POWERSUPPLY:
1171             r = unifi_cfg_power_supply(priv, (unsigned char*)arg);
1172             break;
1173           case UNIFI_CFG_FILTER:
1174             r = unifi_cfg_packet_filters(priv, (unsigned char*)arg);
1175             break;
1176           case UNIFI_CFG_GET:
1177             r = unifi_cfg_get_info(priv, (unsigned char*)arg);
1178             break;
1179           case UNIFI_CFG_WMM_QOSINFO:
1180             r = unifi_cfg_wmm_qos_info(priv, (unsigned char*)arg);
1181             break;
1182           case UNIFI_CFG_WMM_ADDTS:
1183             r = unifi_cfg_wmm_addts(priv, (unsigned char*)arg);
1184             break;
1185           case UNIFI_CFG_WMM_DELTS:
1186             r = unifi_cfg_wmm_delts(priv, (unsigned char*)arg);
1187             break;
1188           case UNIFI_CFG_STRICT_DRAFT_N:
1189             r = unifi_cfg_strict_draft_n(priv, (unsigned char*)arg);
1190             break;
1191           case UNIFI_CFG_ENABLE_OKC:
1192             r = unifi_cfg_enable_okc(priv, (unsigned char*)arg);
1193             break;
1194 #ifdef CSR_SUPPORT_SME
1195           case UNIFI_CFG_CORE_DUMP:
1196             CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
1197             unifi_trace(priv, UDBG2, "UNIFI_CFG_CORE_DUMP: sent wifi off indication\n");
1198             break;
1199 #endif
1200 #ifdef CSR_SUPPORT_WEXT_AP
1201           case UNIFI_CFG_SET_AP_CONFIG:
1202             r= unifi_cfg_set_ap_config(priv,(unsigned char*)arg);
1203             break;
1204 #endif
1205           default:
1206             unifi_error(priv, "UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd);
1207             r = -EINVAL;
1208             goto out;
1209         }
1210 #endif
1211
1212         break;
1213
1214       case UNIFI_PUTEST:
1215         if (get_user(putest_cmd, (unifi_putest_command_t*)arg))
1216         {
1217             unifi_error(priv, "UNIFI_PUTEST: Failed to get the command\n");
1218             r = -EFAULT;
1219             goto out;
1220         }
1221
1222         unifi_trace(priv, UDBG1, "UNIFI_PUTEST: Command is %s\n",
1223                     trace_putest_cmdid(putest_cmd));
1224         switch (putest_cmd) {
1225           case UNIFI_PUTEST_START:
1226             r = unifi_putest_start(priv, (unsigned char*)arg);
1227             break;
1228           case UNIFI_PUTEST_STOP:
1229             r = unifi_putest_stop(priv, (unsigned char*)arg);
1230             break;
1231           case UNIFI_PUTEST_SET_SDIO_CLOCK:
1232             r = unifi_putest_set_sdio_clock(priv, (unsigned char*)arg);
1233             break;
1234           case UNIFI_PUTEST_CMD52_READ:
1235             r = unifi_putest_cmd52_read(priv, (unsigned char*)arg);
1236             break;
1237           case UNIFI_PUTEST_CMD52_BLOCK_READ:
1238             r = unifi_putest_cmd52_block_read(priv, (unsigned char*)arg);
1239             break;
1240           case UNIFI_PUTEST_CMD52_WRITE:
1241             r = unifi_putest_cmd52_write(priv, (unsigned char*)arg);
1242             break;
1243           case UNIFI_PUTEST_DL_FW:
1244             r = unifi_putest_dl_fw(priv, (unsigned char*)arg);
1245             break;
1246           case UNIFI_PUTEST_DL_FW_BUFF:
1247             r = unifi_putest_dl_fw_buff(priv, (unsigned char*)arg);
1248             break;
1249           case UNIFI_PUTEST_COREDUMP_PREPARE:
1250             r = unifi_putest_coredump_prepare(priv, (unsigned char*)arg);
1251             break;
1252           case UNIFI_PUTEST_GP_READ16:
1253             r = unifi_putest_gp_read16(priv, (unsigned char*)arg);
1254             break;
1255           case UNIFI_PUTEST_GP_WRITE16:
1256             r = unifi_putest_gp_write16(priv, (unsigned char*)arg);
1257             break;
1258           default:
1259             unifi_error(priv, "UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd);
1260             r = -EINVAL;
1261             goto out;
1262         }
1263
1264         break;
1265       case UNIFI_BUILD_TYPE:
1266         unifi_trace(priv, UDBG2, "UNIFI_BUILD_TYPE userspace=%s\n", build_type_to_string(*(unsigned char*)arg));
1267 #ifndef CSR_SUPPORT_WEXT_AP
1268         if (UNIFI_BUILD_AP == *(unsigned char*)arg)
1269         {
1270             unifi_error(priv, "Userspace has AP support, which is incompatible\n");
1271         }
1272 #endif
1273
1274 #ifndef CSR_SUPPORT_WEXT
1275         if (UNIFI_BUILD_WEXT == *(unsigned char*)arg)
1276         {
1277             unifi_error(priv, "Userspace has WEXT support, which is incompatible\n");
1278         }
1279 #endif
1280         break;
1281       case UNIFI_INIT_HW:
1282         unifi_trace(priv, UDBG2, "UNIFI_INIT_HW.\n");
1283         priv->init_progress = UNIFI_INIT_NONE;
1284
1285 #if defined(CSR_SUPPORT_WEXT) || defined (CSR_NATIVE_LINUX)
1286         /* At this point we are ready to start the SME. */
1287         r = sme_mgt_wifi_on(priv);
1288         if (r) {
1289             goto out;
1290         }
1291 #endif
1292
1293         break;
1294
1295       case UNIFI_INIT_NETDEV:
1296         {
1297             /* get the proper interfaceTagId */
1298             u16 interfaceTag=0;
1299             netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1300
1301             dev = priv->netdev[interfaceTag];
1302             unifi_trace(priv, UDBG2, "UNIFI_INIT_NETDEV.\n");
1303
1304             if (copy_from_user((void*)dev->dev_addr, (void*)arg, 6)) {
1305                 r = -EFAULT;
1306                 goto out;
1307             }
1308
1309             /* Attach the network device to the stack */
1310             if (!interfacePriv->netdev_registered)
1311             {
1312                 r = uf_register_netdev(priv,interfaceTag);
1313                 if (r) {
1314                     unifi_error(priv, "Failed to register the network device.\n");
1315                     goto out;
1316                 }
1317             }
1318
1319             /* Apply scheduled interrupt mode, if requested by module param */
1320             if (run_bh_once != -1) {
1321                 unifi_set_interrupt_mode(priv->card, (u32)run_bh_once);
1322             }
1323
1324             priv->init_progress = UNIFI_INIT_COMPLETED;
1325
1326             /* Firmware initialisation is complete, so let the SDIO bus
1327              * clock be raised when convienent to the core.
1328              */
1329             unifi_request_max_sdio_clock(priv->card);
1330
1331 #ifdef CSR_SUPPORT_WEXT
1332             /* Notify the Android wpa_supplicant that we are ready */
1333             wext_send_started_event(priv);
1334 #endif
1335
1336             unifi_info(priv, "UniFi ready\n");
1337
1338 #ifdef ANDROID_BUILD
1339             /* Release the wakelock */
1340             unifi_trace(priv, UDBG1, "netdev_init: release wake lock\n");
1341             wake_unlock(&unifi_sdio_wake_lock);
1342 #endif
1343 #ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */
1344             {
1345                 struct net_device *dev = priv->netdev[interfaceTag];
1346 #ifdef CSR_SUPPORT_WEXT
1347                 interfacePriv->wait_netdev_change = TRUE;
1348 #endif
1349                 netif_carrier_on(dev);
1350             }
1351 #endif
1352         }
1353         break;
1354       case UNIFI_GET_INIT_STATUS:
1355         unifi_trace(priv, UDBG2, "UNIFI_GET_INIT_STATUS.\n");
1356         if (put_user(priv->init_progress, (int*)arg))
1357         {
1358             printk(KERN_ERR "UNIFI_GET_INIT_STATUS: Failed to copy to user\n");
1359             r = -EFAULT;
1360             goto out;
1361         }
1362         break;
1363
1364       case UNIFI_KICK:
1365         unifi_trace(priv, UDBG4, "Kick UniFi\n");
1366         unifi_sdio_interrupt_handler(priv->card);
1367         break;
1368
1369       case UNIFI_SET_DEBUG:
1370         unifi_debug = arg;
1371         unifi_trace(priv, UDBG4, "unifi_debug set to %d\n", unifi_debug);
1372         break;
1373
1374       case UNIFI_SET_TRACE:
1375         /* no longer supported */
1376         r = -EINVAL;
1377         break;
1378
1379
1380       case UNIFI_SET_UDI_LOG_MASK:
1381         {
1382             unifiio_filter_t udi_filter;
1383             uint16_t *sig_ids_addr;
1384 #define UF_MAX_SIG_IDS  128     /* Impose a sensible limit */
1385
1386             if (copy_from_user((void*)(&udi_filter), (void*)arg, sizeof(udi_filter))) {
1387                 r = -EFAULT;
1388                 goto out;
1389             }
1390             if ((udi_filter.action < UfSigFil_AllOn) ||
1391                 (udi_filter.action > UfSigFil_SelectOff))
1392             {
1393                 printk(KERN_WARNING
1394                        "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n",
1395                        udi_filter.action);
1396                 r = -EINVAL;
1397                 goto out;
1398             }
1399             /* No signal list for "All" actions */
1400             if ((udi_filter.action == UfSigFil_AllOn) ||
1401                 (udi_filter.action == UfSigFil_AllOff))
1402             {
1403                 udi_filter.num_sig_ids = 0;
1404             }
1405
1406             if (udi_filter.num_sig_ids > UF_MAX_SIG_IDS) {
1407                 printk(KERN_WARNING
1408                        "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n",
1409                        udi_filter.num_sig_ids, UF_MAX_SIG_IDS);
1410                 r = -EINVAL;
1411                 goto out;
1412             }
1413
1414             /* Copy in signal id list if given */
1415             if (udi_filter.num_sig_ids > 0) {
1416                 /* Preserve userspace address of sig_ids array */
1417                 sig_ids_addr = udi_filter.sig_ids;
1418                 /* Allocate kernel memory for sig_ids and copy to it */
1419                 udi_filter.sig_ids =
1420                     kmalloc(udi_filter.num_sig_ids * sizeof(uint16_t), GFP_KERNEL);
1421                 if (!udi_filter.sig_ids) {
1422                     r = -ENOMEM;
1423                     goto out;
1424                 }
1425                 if (copy_from_user((void*)udi_filter.sig_ids,
1426                                    (void*)sig_ids_addr,
1427                                    udi_filter.num_sig_ids * sizeof(uint16_t)))
1428                 {
1429                     kfree(udi_filter.sig_ids);
1430                     r = -EFAULT;
1431                     goto out;
1432                 }
1433             }
1434
1435             udi_set_log_filter(pcli, &udi_filter);
1436
1437             if (udi_filter.num_sig_ids > 0) {
1438                 kfree(udi_filter.sig_ids);
1439             }
1440         }
1441         break;
1442
1443       case UNIFI_SET_AMP_ENABLE:
1444         unifi_trace(priv, UDBG4, "UniFi Set AMP Enable\n");
1445         if (get_user(int_param, (int*)arg))
1446         {
1447             unifi_error(priv, "UNIFI_SET_AMP_ENABLE: Failed to copy from user\n");
1448             r = -EFAULT;
1449             goto out;
1450         }
1451
1452         if (int_param) {
1453             priv->amp_client = pcli;
1454         } else {
1455             priv->amp_client = NULL;
1456         }
1457
1458         int_param = 0;
1459         buf = (u8*)&int_param;
1460         buf[0] = UNIFI_SOFT_COMMAND_Q_LENGTH - 1;
1461         buf[1] = UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1;
1462         if (copy_to_user((void*)arg, &int_param, sizeof(int))) {
1463             r = -EFAULT;
1464             goto out;
1465         }
1466         break;
1467
1468       case UNIFI_SET_UDI_SNAP_MASK:
1469         {
1470             unifiio_snap_filter_t snap_filter;
1471
1472             if (copy_from_user((void*)(&snap_filter), (void*)arg, sizeof(snap_filter))) {
1473                 r = -EFAULT;
1474                 goto out;
1475             }
1476
1477             if (pcli->snap_filter.count) {
1478                 pcli->snap_filter.count = 0;
1479                 kfree(pcli->snap_filter.protocols);
1480             }
1481
1482             if (snap_filter.count == 0) {
1483                 break;
1484             }
1485
1486             pcli->snap_filter.protocols = kmalloc(snap_filter.count * sizeof(u16), GFP_KERNEL);
1487             if (!pcli->snap_filter.protocols) {
1488                 r = -ENOMEM;
1489                 goto out;
1490             }
1491             if (copy_from_user((void*)pcli->snap_filter.protocols,
1492                                (void*)snap_filter.protocols,
1493                                snap_filter.count * sizeof(u16)))
1494             {
1495                 kfree(pcli->snap_filter.protocols);
1496                 r = -EFAULT;
1497                 goto out;
1498             }
1499
1500             pcli->snap_filter.count = snap_filter.count;
1501
1502         }
1503         break;
1504
1505       case UNIFI_SME_PRESENT:
1506         {
1507             u8 ind;
1508             unifi_trace(priv, UDBG4, "UniFi SME Present IOCTL.\n");
1509             if (copy_from_user((void*)(&int_param), (void*)arg, sizeof(int)))
1510             {
1511                 printk(KERN_ERR "UNIFI_SME_PRESENT: Failed to copy from user\n");
1512                 r = -EFAULT;
1513                 goto out;
1514             }
1515
1516             priv->sme_is_present = int_param;
1517             if (priv->sme_is_present == 1) {
1518                 ind = CONFIG_SME_PRESENT;
1519             } else {
1520                 ind = CONFIG_SME_NOT_PRESENT;
1521             }
1522             /* Send an indication to the helper app. */
1523             ul_log_config_ind(priv, &ind, sizeof(u8));
1524         }
1525         break;
1526
1527       case UNIFI_CFG_PERIOD_TRAFFIC:
1528       {
1529 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1530           CsrWifiSmeCoexConfig coexConfig;
1531 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1532         unifi_trace(priv, UDBG4, "UniFi Configure Periodic Traffic.\n");
1533 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1534         if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) {
1535             unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
1536             r = -EFAULT;
1537             goto out;
1538         }
1539
1540         if (uchar_param == 0) {
1541             r = sme_mgt_coex_config_get(priv, &coexConfig);
1542             if (r) {
1543                 unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n");
1544                 goto out;
1545             }
1546             if (copy_to_user((void*)(arg + 1),
1547                              (void*)&coexConfig,
1548                              sizeof(CsrWifiSmeCoexConfig))) {
1549                 r = -EFAULT;
1550                 goto out;
1551             }
1552             goto out;
1553         }
1554
1555         if (copy_from_user((void*)(&coex_config), (void*)(arg + 1), sizeof(CsrWifiSmeCoexConfig)))
1556         {
1557             unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
1558             r = -EFAULT;
1559             goto out;
1560         }
1561
1562         coexConfig = coex_config;
1563         r = sme_mgt_coex_config_set(priv, &coexConfig);
1564         if (r) {
1565             unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\n");
1566             goto out;
1567         }
1568
1569 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1570         break;
1571       }
1572       case UNIFI_CFG_UAPSD_TRAFFIC:
1573         unifi_trace(priv, UDBG4, "UniFi Configure U-APSD Mask.\n");
1574 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1575         if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) {
1576             unifi_error(priv, "UNIFI_CFG_UAPSD_TRAFFIC: Failed to copy from user\n");
1577             r = -EFAULT;
1578             goto out;
1579         }
1580         unifi_trace(priv, UDBG4, "New U-APSD Mask: 0x%x\n", uchar_param);
1581 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1582         break;
1583
1584 #ifndef UNIFI_DISABLE_COREDUMP
1585       case UNIFI_COREDUMP_GET_REG:
1586         unifi_trace(priv, UDBG4, "Mini-coredump data request\n");
1587         {
1588             unifiio_coredump_req_t dump_req;    /* Public OS layer structure */
1589             unifi_coredump_req_t priv_req;      /* Private HIP structure */
1590
1591             if (copy_from_user((void*)(&dump_req), (void*)arg, sizeof(dump_req))) {
1592                 r = -EFAULT;
1593                 goto out;
1594             }
1595             memset(&priv_req, 0, sizeof(priv_req));
1596             priv_req.index = dump_req.index;
1597             priv_req.offset = dump_req.offset;
1598
1599             /* Convert OS-layer's XAP memory space ID to HIP's ID in case they differ */
1600             switch (dump_req.space) {
1601                 case UNIFIIO_COREDUMP_MAC_REG: priv_req.space = UNIFI_COREDUMP_MAC_REG; break;
1602                 case UNIFIIO_COREDUMP_PHY_REG: priv_req.space = UNIFI_COREDUMP_PHY_REG; break;
1603                 case UNIFIIO_COREDUMP_SH_DMEM: priv_req.space = UNIFI_COREDUMP_SH_DMEM; break;
1604                 case UNIFIIO_COREDUMP_MAC_DMEM: priv_req.space = UNIFI_COREDUMP_MAC_DMEM; break;
1605                 case UNIFIIO_COREDUMP_PHY_DMEM: priv_req.space = UNIFI_COREDUMP_PHY_DMEM; break;
1606                 case UNIFIIO_COREDUMP_TRIGGER_MAGIC: priv_req.space = UNIFI_COREDUMP_TRIGGER_MAGIC; break;
1607                 default:
1608                   r = -EINVAL;
1609                   goto out;
1610             }
1611
1612             if (priv_req.space == UNIFI_COREDUMP_TRIGGER_MAGIC) {
1613                 /* Force a coredump grab now */
1614                 unifi_trace(priv, UDBG2, "UNIFI_COREDUMP_GET_REG: Force capture\n");
1615                 csrResult = unifi_coredump_capture(priv->card, &priv_req);
1616                 r = CsrHipResultToStatus(csrResult);
1617                 unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: status %d\n", r);
1618             } else {
1619                 /* Retrieve the appropriate register entry */
1620                 csrResult = unifi_coredump_get_value(priv->card, &priv_req);
1621                 r = CsrHipResultToStatus(csrResult);
1622                 if (r) {
1623                     unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: Status %d\n", r);
1624                     goto out;
1625                 }
1626                 /* Update the OS-layer structure with values returned in the private */
1627                 dump_req.value = priv_req.value;
1628                 dump_req.timestamp = priv_req.timestamp;
1629                 dump_req.requestor = priv_req.requestor;
1630                 dump_req.serial = priv_req.serial;
1631                 dump_req.chip_ver = priv_req.chip_ver;
1632                 dump_req.fw_ver = priv_req.fw_ver;
1633                 dump_req.drv_build = 0;
1634
1635                 unifi_trace(priv, UDBG6,
1636                             "Dump: %d (seq %d): V:0x%04x (%d) @0x%02x:%04x = 0x%04x\n",
1637                             dump_req.index, dump_req.serial,
1638                             dump_req.chip_ver, dump_req.drv_build,
1639                             dump_req.space, dump_req.offset, dump_req.value);
1640             }
1641             if (copy_to_user((void*)arg, (void*)&dump_req, sizeof(dump_req))) {
1642                 r = -EFAULT;
1643                 goto out;
1644             }
1645         }
1646         break;
1647 #endif
1648       default:
1649         r = -EINVAL;
1650     }
1651
1652 out:
1653     return (long)r;
1654 } /* unifi_ioctl() */
1655
1656
1657
1658 static unsigned int
1659 unifi_poll(struct file *filp, poll_table *wait)
1660 {
1661     ul_client_t *pcli = (ul_client_t*)filp->private_data;
1662     unsigned int mask = 0;
1663     int ready;
1664
1665     func_enter();
1666
1667     ready = !list_empty(&pcli->udi_log);
1668
1669     poll_wait(filp, &pcli->udi_wq, wait);
1670
1671     if (ready) {
1672         mask |= POLLIN | POLLRDNORM;    /* readable */
1673     }
1674
1675     func_exit();
1676
1677     return mask;
1678 } /* unifi_poll() */
1679
1680
1681
1682 /*
1683  * ---------------------------------------------------------------------------
1684  *  udi_set_log_filter
1685  *
1686  *      Configure the bit mask that determines which signal primitives are
1687  *      passed to the logging process.
1688  *
1689  *  Arguments:
1690  *      pcli            Pointer to the client to configure.
1691  *      udi_filter      Pointer to a unifiio_filter_t containing instructions.
1692  *
1693  *  Returns:
1694  *      None.
1695  *
1696  *  Notes:
1697  *      SigGetFilterPos() returns a 32-bit value that contains an index and a
1698  *      mask for accessing a signal_filter array. The top 16 bits specify an
1699  *      index into a signal_filter, the bottom 16 bits specify a mask to
1700  *      apply.
1701  * ---------------------------------------------------------------------------
1702  */
1703 static void
1704 udi_set_log_filter(ul_client_t *pcli, unifiio_filter_t *udi_filter)
1705 {
1706     u32 filter_pos;
1707     int i;
1708
1709     if (udi_filter->action == UfSigFil_AllOn)
1710     {
1711         for (i = 0; i < SIG_FILTER_SIZE; i++) {
1712             pcli->signal_filter[i] = 0xFFFF;
1713         }
1714     }
1715     else if (udi_filter->action == UfSigFil_AllOff)
1716     {
1717         for (i = 0; i < SIG_FILTER_SIZE; i++) {
1718             pcli->signal_filter[i] = 0;
1719         }
1720     }
1721     else if (udi_filter->action == UfSigFil_SelectOn)
1722     {
1723         for (i = 0; i < udi_filter->num_sig_ids; i++) {
1724             filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
1725             if (filter_pos == 0xFFFFFFFF)
1726             {
1727                 printk(KERN_WARNING
1728                        "Unrecognised signal id (0x%X) specifed in logging filter\n",
1729                        udi_filter->sig_ids[i]);
1730             } else {
1731                 pcli->signal_filter[filter_pos >> 16] |= (filter_pos & 0xFFFF);
1732             }
1733         }
1734     }
1735     else if (udi_filter->action == UfSigFil_SelectOff)
1736     {
1737         for (i = 0; i < udi_filter->num_sig_ids; i++) {
1738             filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
1739             if (filter_pos == 0xFFFFFFFF)
1740             {
1741                 printk(KERN_WARNING
1742                        "Unrecognised signal id (0x%X) specifed in logging filter\n",
1743                        udi_filter->sig_ids[i]);
1744             } else {
1745                 pcli->signal_filter[filter_pos >> 16] &= ~(filter_pos & 0xFFFF);
1746             }
1747         }
1748     }
1749
1750 } /* udi_set_log_filter() */
1751
1752
1753 /*
1754  * ---------------------------------------------------------------------------
1755  *  udi_log_event
1756  *
1757  *      Callback function to be registered as the UDI hook callback.
1758  *      Copies the signal content into a new udi_log_t struct and adds
1759  *      it to the read queue for this UDI client.
1760  *
1761  *  Arguments:
1762  *      pcli            A pointer to the client instance.
1763  *      signal          Pointer to the received signal.
1764  *      signal_len      Size of the signal structure in bytes.
1765  *      bulkdata        Pointers to any associated bulk data.
1766  *      dir             Direction of the signal. Zero means from host,
1767  *                      non-zero means to host.
1768  *
1769  *  Returns:
1770  *      None.
1771  * ---------------------------------------------------------------------------
1772  */
1773 void
1774 udi_log_event(ul_client_t *pcli,
1775               const u8 *signal, int signal_len,
1776               const bulk_data_param_t *bulkdata,
1777               int dir)
1778 {
1779     udi_log_t *logptr;
1780     u8 *p;
1781     int i;
1782     int total_len;
1783     udi_msg_t *msgptr;
1784     u32 filter_pos;
1785 #ifdef OMNICLI_LINUX_EXTRA_LOG
1786     static volatile unsigned int printk_cpu = UINT_MAX;
1787     unsigned long long t;
1788     unsigned long nanosec_rem;
1789     unsigned long n_1000;
1790 #endif
1791
1792     func_enter();
1793
1794     /* Just a sanity check */
1795     if ((signal == NULL) || (signal_len <= 0)) {
1796         return;
1797     }
1798
1799 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1800     /* When HIP offline signal logging is enabled, omnicli cannot run */
1801     if (log_hip_signals)
1802     {
1803         /* Add timestamp */
1804         if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP)
1805         {
1806             int timestamp = jiffies_to_msecs(jiffies);
1807             unifi_debug_log_to_buf("T:");
1808             unifi_debug_log_to_buf("%04X%04X ", *(((u16*)&timestamp) + 1),
1809                                    *(u16*)&timestamp);
1810         }
1811
1812         /* Add signal */
1813         unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ",
1814                                dir ? "T" : "F",
1815                                *(u16*)signal,
1816                                *(u16*)(signal + 2),
1817                                *(u16*)(signal + 4));
1818         unifi_debug_hex_to_buf(signal + 6, signal_len - 6);
1819
1820         /* Add bulk data (assume 1 bulk data per signal) */
1821         if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) &&
1822             (bulkdata->d[0].data_length > 0))
1823         {
1824             unifi_debug_log_to_buf("\nD:");
1825             unifi_debug_hex_to_buf(bulkdata->d[0].os_data_ptr, bulkdata->d[0].data_length);
1826         }
1827         unifi_debug_log_to_buf("\n");
1828
1829         return;
1830     }
1831 #endif
1832
1833 #ifdef CSR_NATIVE_LINUX
1834     uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir);
1835 #endif
1836
1837     /*
1838      * Apply the logging filter - only report signals that have their
1839      * bit set in the filter mask.
1840      */
1841     filter_pos = SigGetFilterPos(GET_SIGNAL_ID(signal));
1842
1843     if ((filter_pos != 0xFFFFFFFF) &&
1844         ((pcli->signal_filter[filter_pos >> 16] & (filter_pos & 0xFFFF)) == 0))
1845     {
1846         /* Signal is not wanted by client */
1847         return;
1848     }
1849
1850
1851     /* Calculate the buffer we need to store signal plus bulk data */
1852     total_len = signal_len;
1853     for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
1854         total_len += bulkdata->d[i].data_length;
1855     }
1856
1857     /* Allocate log structure plus actual signal. */
1858     logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL);
1859
1860     if (logptr == NULL) {
1861         printk(KERN_ERR
1862                "Failed to allocate %lu bytes for a UDI log record\n",
1863                (long unsigned int)(sizeof(udi_log_t) + total_len));
1864         return;
1865     }
1866
1867     /* Fill in udi_log struct */
1868     INIT_LIST_HEAD(&logptr->q);
1869     msgptr = &logptr->msg;
1870     msgptr->length = sizeof(udi_msg_t) + total_len;
1871 #ifdef OMNICLI_LINUX_EXTRA_LOG
1872     t = cpu_clock(printk_cpu);
1873     nanosec_rem = do_div(t, 1000000000);
1874     n_1000 = nanosec_rem/1000;
1875     msgptr->timestamp = (t <<10 ) | ((unsigned long)(n_1000 >> 10) & 0x3ff);
1876 #else
1877     msgptr->timestamp = jiffies_to_msecs(jiffies);
1878 #endif
1879     msgptr->direction = dir;
1880     msgptr->signal_length = signal_len;
1881
1882     /* Copy signal and bulk data to the log */
1883     p = (u8 *)(msgptr + 1);
1884     memcpy(p, signal, signal_len);
1885     p += signal_len;
1886
1887     /* Append any bulk data */
1888     for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
1889         int len = bulkdata->d[i].data_length;
1890
1891         /*
1892          * Len here might not be the same as the length in the bulk data slot.
1893          * The slot length will always be even, but len could be odd.
1894          */
1895         if (len > 0) {
1896             if (bulkdata->d[i].os_data_ptr) {
1897                 memcpy(p, bulkdata->d[i].os_data_ptr, len);
1898             } else {
1899                 memset(p, 0, len);
1900             }
1901             p += len;
1902         }
1903     }
1904
1905     /* Add to tail of log queue */
1906     if (down_interruptible(&pcli->udi_sem)) {
1907         printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n");
1908         kfree(logptr);
1909         func_exit();
1910         return;
1911     }
1912     list_add_tail(&logptr->q, &pcli->udi_log);
1913     up(&pcli->udi_sem);
1914
1915     /* Wake any waiting user process */
1916     wake_up_interruptible(&pcli->udi_wq);
1917
1918     func_exit();
1919 } /* udi_log_event() */
1920
1921 #ifdef CSR_SME_USERSPACE
1922 int
1923 uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
1924 {
1925     udi_log_t *logptr;
1926     udi_msg_t *msgptr;
1927     u8 *p;
1928
1929     func_enter();
1930
1931     /* Just a sanity check */
1932     if ((buffer == NULL) || (length <= 0)) {
1933         return -EINVAL;
1934     }
1935
1936     /* Allocate log structure plus actual signal. */
1937     logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + length, GFP_ATOMIC);
1938     if (logptr == NULL) {
1939         unifi_error(priv, "Failed to allocate %d bytes for an SME message\n",
1940                     sizeof(udi_log_t) + length);
1941                     kfree(buffer);
1942                     return -ENOMEM;
1943     }
1944
1945     /* Fill in udi_log struct */
1946     INIT_LIST_HEAD(&logptr->q);
1947     msgptr = &logptr->msg;
1948     msgptr->length = sizeof(udi_msg_t) + length;
1949     msgptr->signal_length = length;
1950
1951     /* Copy signal and bulk data to the log */
1952     p = (u8 *)(msgptr + 1);
1953     memcpy(p, buffer, length);
1954
1955     /* Add to tail of log queue */
1956     down(&udi_mutex);
1957     if (priv->sme_cli == NULL) {
1958         kfree(logptr);
1959         kfree(buffer);
1960         up(&udi_mutex);
1961         unifi_info(priv, "Message for the SME dropped, SME has gone away\n");
1962         return 0;
1963     }
1964
1965     down(&priv->sme_cli->udi_sem);
1966     list_add_tail(&logptr->q, &priv->sme_cli->udi_log);
1967     up(&priv->sme_cli->udi_sem);
1968
1969     /* Wake any waiting user process */
1970     wake_up_interruptible(&priv->sme_cli->udi_wq);
1971     up(&udi_mutex);
1972
1973     /* It is our responsibility to free the buffer allocated in build_packed_*() */
1974     kfree(buffer);
1975
1976     func_exit();
1977
1978     return 0;
1979
1980 } /* uf_sme_queue_message() */
1981 #endif
1982
1983
1984 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
1985 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
1986     device_create(_class, _parent, _devno, _priv, _fmt, _args)
1987 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
1988 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
1989     device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args)
1990 #else
1991 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
1992     device_create(_class, _parent, _devno, _fmt, _args)
1993 #endif
1994
1995 /*
1996  ****************************************************************************
1997  *
1998  *      Driver instantiation
1999  *
2000  ****************************************************************************
2001  */
2002 static struct file_operations unifi_fops = {
2003     .owner      = THIS_MODULE,
2004     .open       = unifi_open,
2005     .release    = unifi_release,
2006     .read       = unifi_read,
2007     .write      = unifi_write,
2008     .unlocked_ioctl = unifi_ioctl,
2009     .poll       = unifi_poll,
2010 };
2011
2012 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
2013 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
2014     device_create(_class, _parent, _devno, _priv, _fmt, _args)
2015 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
2016 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
2017     device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args)
2018 #else
2019 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args)       \
2020     device_create(_class, _parent, _devno, _fmt, _args)
2021 #endif
2022
2023 static dev_t unifi_first_devno;
2024 static struct class *unifi_class;
2025
2026
2027 int uf_create_device_nodes(unifi_priv_t *priv, int bus_id)
2028 {
2029     dev_t devno;
2030     int r;
2031
2032     cdev_init(&priv->unifi_cdev, &unifi_fops);
2033
2034     /* cdev_init() should set the cdev owner, but it does not */
2035     priv->unifi_cdev.owner = THIS_MODULE;
2036
2037     devno = MKDEV(MAJOR(unifi_first_devno),
2038                   MINOR(unifi_first_devno) + (bus_id * 2));
2039     r = cdev_add(&priv->unifi_cdev, devno, 1);
2040     if (r) {
2041         return r;
2042     }
2043
2044 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2045     if (!UF_DEVICE_CREATE(unifi_class, priv->unifi_device,
2046                           devno, priv, "unifi%d", bus_id)) {
2047 #else
2048     priv->unifi_device = UF_DEVICE_CREATE(unifi_class, NULL,
2049                                           devno, priv, "unifi%d", bus_id);
2050     if (priv->unifi_device == NULL) {
2051 #endif /* SDIO_EXPORTS_STRUCT_DEVICE */
2052
2053         cdev_del(&priv->unifi_cdev);
2054         return -EINVAL;
2055     }
2056
2057     cdev_init(&priv->unifiudi_cdev, &unifi_fops);
2058
2059     /* cdev_init() should set the cdev owner, but it does not */
2060     priv->unifiudi_cdev.owner = THIS_MODULE;
2061
2062     devno = MKDEV(MAJOR(unifi_first_devno),
2063                   MINOR(unifi_first_devno) + (bus_id * 2) + 1);
2064     r = cdev_add(&priv->unifiudi_cdev, devno, 1);
2065     if (r) {
2066         device_destroy(unifi_class, priv->unifi_cdev.dev);
2067         cdev_del(&priv->unifi_cdev);
2068         return r;
2069     }
2070
2071     if (!UF_DEVICE_CREATE(unifi_class,
2072 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2073                           priv->unifi_device,
2074 #else
2075                           NULL,
2076 #endif /* SDIO_EXPORTS_STRUCT_DEVICE */
2077                           devno, priv, "unifiudi%d", bus_id)) {
2078         device_destroy(unifi_class, priv->unifi_cdev.dev);
2079         cdev_del(&priv->unifiudi_cdev);
2080         cdev_del(&priv->unifi_cdev);
2081         return -EINVAL;
2082     }
2083
2084     return 0;
2085 }
2086
2087
2088 void uf_destroy_device_nodes(unifi_priv_t *priv)
2089 {
2090     device_destroy(unifi_class, priv->unifiudi_cdev.dev);
2091     device_destroy(unifi_class, priv->unifi_cdev.dev);
2092     cdev_del(&priv->unifiudi_cdev);
2093     cdev_del(&priv->unifi_cdev);
2094 }
2095
2096
2097
2098 /*
2099  * ----------------------------------------------------------------
2100  *  uf_create_debug_device
2101  *
2102  *      Allocates device numbers for unifi character device nodes
2103  *      and creates a unifi class in sysfs
2104  *
2105  * Arguments:
2106  *  fops          Pointer to the char device operations structure.
2107  *
2108  * Returns:
2109  *      0 on success, -ve error code on error.
2110  * ----------------------------------------------------------------
2111  */
2112 static int
2113 uf_create_debug_device(struct file_operations *fops)
2114 {
2115     int ret;
2116
2117     /* Allocate two device numbers for each device. */
2118     ret = alloc_chrdev_region(&unifi_first_devno, 0, MAX_UNIFI_DEVS*2, UNIFI_NAME);
2119     if (ret) {
2120         unifi_error(NULL, "Failed to add alloc dev numbers: %d\n", ret);
2121         return ret;
2122     }
2123
2124     /* Create a UniFi class */
2125     unifi_class = class_create(THIS_MODULE, UNIFI_NAME);
2126     if (IS_ERR(unifi_class)) {
2127         unifi_error(NULL, "Failed to create UniFi class\n");
2128
2129         /* Release device numbers */
2130         unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
2131         unifi_first_devno = 0;
2132         return -EINVAL;
2133     }
2134
2135     return 0;
2136 } /* uf_create_debug_device() */
2137
2138
2139 /*
2140  * ----------------------------------------------------------------
2141  *  uf_remove_debug_device
2142  *
2143  *      Destroys the unifi class and releases the allocated
2144  *      device numbers for unifi character device nodes.
2145  *
2146  * Arguments:
2147  *
2148  * Returns:
2149  * ----------------------------------------------------------------
2150  */
2151 static void
2152 uf_remove_debug_device(void)
2153 {
2154     /* Destroy the UniFi class */
2155     class_destroy(unifi_class);
2156
2157     /* Release device numbers */
2158     unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
2159     unifi_first_devno = 0;
2160
2161 } /* uf_remove_debug_device() */
2162
2163
2164 /*
2165  * ---------------------------------------------------------------------------
2166  *
2167  *      Module loading.
2168  *
2169  * ---------------------------------------------------------------------------
2170  */
2171 int __init
2172 unifi_load(void)
2173 {
2174     int r;
2175
2176     printk("UniFi SDIO Driver: %s %s %s\n",
2177             CSR_WIFI_VERSION,
2178            __DATE__, __TIME__);
2179
2180 #ifdef CSR_SME_USERSPACE
2181 #ifdef CSR_SUPPORT_WEXT
2182     printk("CSR SME with WEXT support\n");
2183 #else
2184     printk("CSR SME no WEXT support\n");
2185 #endif /* CSR_SUPPORT_WEXT */
2186 #endif /* CSR_SME_USERSPACE */
2187
2188 #ifdef CSR_NATIVE_LINUX
2189 #ifdef CSR_SUPPORT_WEXT
2190 #error WEXT unsupported in the native driver
2191 #endif
2192     printk("CSR native no WEXT support\n");
2193 #endif
2194 #ifdef CSR_WIFI_SPLIT_PATCH
2195     printk("Split patch support\n");
2196 #endif
2197     printk("Kernel %d.%d.%d\n",
2198            ((LINUX_VERSION_CODE) >> 16) & 0xff,
2199            ((LINUX_VERSION_CODE) >> 8) & 0xff,
2200            (LINUX_VERSION_CODE) & 0xff);
2201     /*
2202      * Instantiate the /dev/unifi* device nodes.
2203      * We must do this before registering with the SDIO driver because it
2204      * will immediately call the "insert" callback if the card is
2205      * already present.
2206      */
2207     r = uf_create_debug_device(&unifi_fops);
2208     if (r) {
2209         return r;
2210     }
2211
2212     /* Now register with the SDIO driver */
2213     r = uf_sdio_load();
2214     if (r) {
2215         uf_remove_debug_device();
2216         return r;
2217     }
2218
2219     if (sdio_block_size > -1) {
2220         unifi_info(NULL, "sdio_block_size %d\n", sdio_block_size);
2221     }
2222
2223     if (sdio_byte_mode) {
2224         unifi_info(NULL, "sdio_byte_mode\n");
2225     }
2226
2227     if (disable_power_control) {
2228         unifi_info(NULL, "disable_power_control\n");
2229     }
2230
2231     if (disable_hw_reset) {
2232         unifi_info(NULL, "disable_hw_reset\n");
2233     }
2234
2235     if (enable_wol) {
2236         unifi_info(NULL, "enable_wol %d\n", enable_wol);
2237     }
2238
2239     if (run_bh_once != -1) {
2240         unifi_info(NULL, "run_bh_once %d\n", run_bh_once);
2241     }
2242
2243     return 0;
2244 } /* unifi_load() */
2245
2246
2247 void __exit
2248 unifi_unload(void)
2249 {
2250     /* The SDIO remove hook will call unifi_disconnect(). */
2251     uf_sdio_unload();
2252
2253     uf_remove_debug_device();
2254
2255 } /* unifi_unload() */
2256
2257 module_init(unifi_load);
2258 module_exit(unifi_unload);
2259
2260 MODULE_DESCRIPTION("UniFi Device driver");
2261 MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
2262 MODULE_LICENSE("GPL and additional rights");