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