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