2 * ---------------------------------------------------------------------------
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.
10 * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
12 * Refer to LICENSE.txt included with this source code for details on
15 * ---------------------------------------------------------------------------
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.
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.
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>
41 #include "csr_wifi_hip_unifiversion.h"
42 #include "unifi_priv.h"
43 #include "csr_wifi_hip_conversions.h"
44 #include "unifi_native.h"
46 /* Module parameter variables */
47 int buswidth
= 0; /* 0 means use default, values 1,4 */
48 int sdio_clock
= 50000; /* kHz */
50 /* fw_init prevents f/w initialisation on error. */
51 int fw_init
[MAX_UNIFI_DEVS
] = {-1, -1};
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
;
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 */
65 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
66 #define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA (1 << 1)
67 #define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP (1 << 2)
68 int log_hip_signals
= 0;
71 MODULE_DESCRIPTION("CSR UniFi (SDIO)");
73 module_param(buswidth
, int, S_IRUGO
|S_IWUSR
);
74 module_param(sdio_clock
, int, S_IRUGO
|S_IWUSR
);
75 module_param(unifi_debug
, int, S_IRUGO
|S_IWUSR
);
76 module_param_array(fw_init
, int, NULL
, S_IRUGO
|S_IWUSR
);
77 module_param(use_5g
, int, S_IRUGO
|S_IWUSR
);
78 module_param(led_mask
, int, S_IRUGO
|S_IWUSR
);
79 module_param(disable_hw_reset
, int, S_IRUGO
|S_IWUSR
);
80 module_param(disable_power_control
, int, S_IRUGO
|S_IWUSR
);
81 module_param(enable_wol
, int, S_IRUGO
|S_IWUSR
);
82 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
83 module_param(tl_80211d
, int, S_IRUGO
|S_IWUSR
);
85 module_param(sdio_block_size
, int, S_IRUGO
|S_IWUSR
);
86 module_param(sdio_byte_mode
, int, S_IRUGO
|S_IWUSR
);
87 module_param(coredump_max
, int, S_IRUGO
|S_IWUSR
);
88 module_param(run_bh_once
, int, S_IRUGO
|S_IWUSR
);
89 module_param(bh_priority
, int, S_IRUGO
|S_IWUSR
);
90 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
91 module_param(log_hip_signals
, int, S_IRUGO
|S_IWUSR
);
94 MODULE_PARM_DESC(buswidth
, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
95 MODULE_PARM_DESC(sdio_clock
, "SDIO bus frequency in kHz, (default = 50 MHz)");
96 MODULE_PARM_DESC(unifi_debug
, "Diagnostic reporting level");
97 MODULE_PARM_DESC(fw_init
, "Set to 0 to prevent f/w initialization on error");
98 MODULE_PARM_DESC(use_5g
, "Use the 5G (802.11a) radio band");
99 MODULE_PARM_DESC(led_mask
, "LED mask flags");
100 MODULE_PARM_DESC(disable_hw_reset
, "Set to 1 to disable hardware reset");
101 MODULE_PARM_DESC(disable_power_control
, "Set to 1 to disable SDIO power control");
102 MODULE_PARM_DESC(enable_wol
, "Enable wake-on-wlan function 0=off, 1=SDIO, 2=PIO");
103 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
104 MODULE_PARM_DESC(tl_80211d
, "802.11d Trust Level (1-6, default = 5)");
106 MODULE_PARM_DESC(sdio_block_size
, "Set to override SDIO block size");
107 MODULE_PARM_DESC(sdio_byte_mode
, "Set to 1 for byte mode SDIO");
108 MODULE_PARM_DESC(coredump_max
, "Number of chip mini-coredump buffers to allocate");
109 MODULE_PARM_DESC(run_bh_once
, "Run BH only when firmware interrupts");
110 MODULE_PARM_DESC(bh_priority
, "Modify the BH thread priority");
111 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
112 MODULE_PARM_DESC(log_hip_signals
, "Set to 1 to enable HIP signal offline logging");
116 /* Callback for event logging to UDI clients */
117 static void udi_log_event(ul_client_t
*client
,
118 const u8
*signal
, int signal_len
,
119 const bulk_data_param_t
*bulkdata
,
122 static void udi_set_log_filter(ul_client_t
*pcli
,
123 unifiio_filter_t
*udi_filter
);
126 /* Mutex to protect access to priv->sme_cli */
127 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
128 DEFINE_SEMAPHORE(udi_mutex
);
130 DECLARE_MUTEX(udi_mutex
);
133 CsrInt32
CsrHipResultToStatus(CsrResult csrResult
)
139 case CSR_RESULT_SUCCESS
:
142 case CSR_WIFI_HIP_RESULT_RANGE
:
145 case CSR_WIFI_HIP_RESULT_NO_DEVICE
:
148 case CSR_WIFI_HIP_RESULT_INVALID_VALUE
:
151 case CSR_WIFI_HIP_RESULT_NOT_FOUND
:
154 case CSR_WIFI_HIP_RESULT_NO_SPACE
:
157 case CSR_WIFI_HIP_RESULT_NO_MEMORY
:
160 case CSR_RESULT_FAILURE
:
164 /*unifi_warning(card->ospriv, "CsrHipResultToStatus: Unrecognised csrResult error code: %d\n", csrResult);*/
172 trace_putest_cmdid(unifi_putest_command_t putest_cmd
)
176 case UNIFI_PUTEST_START
:
178 case UNIFI_PUTEST_STOP
:
180 case UNIFI_PUTEST_SET_SDIO_CLOCK
:
182 case UNIFI_PUTEST_CMD52_READ
:
184 case UNIFI_PUTEST_CMD52_BLOCK_READ
:
186 case UNIFI_PUTEST_CMD52_WRITE
:
188 case UNIFI_PUTEST_DL_FW
:
190 case UNIFI_PUTEST_DL_FW_BUFF
:
191 return "D/L FW BUFFER";
192 case UNIFI_PUTEST_COREDUMP_PREPARE
:
193 return "PREPARE COREDUMP";
194 case UNIFI_PUTEST_GP_READ16
:
196 case UNIFI_PUTEST_GP_WRITE16
:
199 return "ERROR: unrecognised command";
203 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
204 int uf_register_hip_offline_debug(unifi_priv_t
*priv
)
206 ul_client_t
*udi_cli
;
209 udi_cli
= ul_register_client(priv
, CLI_USING_WIRE_FORMAT
, udi_log_event
);
210 if (udi_cli
== NULL
) {
211 /* Too many clients already using this device */
212 unifi_error(priv
, "Too many UDI clients already open\n");
215 unifi_trace(priv
, UDBG1
, "Offline HIP client is registered\n");
217 down(&priv
->udi_logging_mutex
);
218 udi_cli
->event_hook
= udi_log_event
;
219 unifi_set_udi_hook(priv
->card
, logging_handler
);
220 /* Log all signals by default */
221 for (i
= 0; i
< SIG_FILTER_SIZE
; i
++) {
222 udi_cli
->signal_filter
[i
] = 0xFFFF;
224 priv
->logging_client
= udi_cli
;
225 up(&priv
->udi_logging_mutex
);
230 int uf_unregister_hip_offline_debug(unifi_priv_t
*priv
)
232 ul_client_t
*udi_cli
= priv
->logging_client
;
235 unifi_error(priv
, "Unknown HIP client unregister request\n");
239 unifi_trace(priv
, UDBG1
, "Offline HIP client is unregistered\n");
241 down(&priv
->udi_logging_mutex
);
242 priv
->logging_client
= NULL
;
243 udi_cli
->event_hook
= NULL
;
244 up(&priv
->udi_logging_mutex
);
246 ul_deregister_client(udi_cli
);
254 * ---------------------------------------------------------------------------
258 * Open and release entry points for the UniFi debug driver.
261 * Normal linux driver args.
265 * ---------------------------------------------------------------------------
268 unifi_open(struct inode
*inode
, struct file
*file
)
272 ul_client_t
*udi_cli
;
276 devno
= MINOR(inode
->i_rdev
) >> 1;
279 * Increase the ref_count for the char device clients.
280 * Make sure you call uf_put_instance() to decreace it if
281 * unifi_open returns an error.
283 priv
= uf_get_instance(devno
);
285 unifi_error(NULL
, "unifi_open: No device present\n");
290 /* Register this instance in the client's list. */
291 /* The minor number determines the nature of the client (Unicli or SME). */
292 if (MINOR(inode
->i_rdev
) & 0x1) {
293 udi_cli
= ul_register_client(priv
, CLI_USING_WIRE_FORMAT
, udi_log_event
);
294 if (udi_cli
== NULL
) {
295 /* Too many clients already using this device */
296 unifi_error(priv
, "Too many clients already open\n");
297 uf_put_instance(devno
);
301 unifi_trace(priv
, UDBG1
, "Client is registered to /dev/unifiudi%d\n", devno
);
304 * Even-numbered device nodes are the control application.
305 * This is the userspace helper containing SME or
311 #ifdef CSR_SME_USERSPACE
312 /* Check if a config client is already attached */
315 uf_put_instance(devno
);
317 unifi_info(priv
, "There is already a configuration client using the character device\n");
321 #endif /* CSR_SME_USERSPACE */
323 #ifdef CSR_SUPPORT_SME
324 udi_cli
= ul_register_client(priv
,
325 CLI_USING_WIRE_FORMAT
| CLI_SME_USERSPACE
,
328 /* Config client for native driver */
329 udi_cli
= ul_register_client(priv
,
331 sme_native_log_event
);
333 if (udi_cli
== NULL
) {
334 /* Too many clients already using this device */
336 uf_put_instance(devno
);
338 unifi_error(priv
, "Too many clients already open\n");
344 * Fill-in the pointer to the configuration client.
345 * This is the SME userspace helper or unifi_manager.
346 * Not used in the SME embedded version.
348 unifi_trace(priv
, UDBG1
, "SME client (id:%d s:0x%X) is registered\n",
349 udi_cli
->client_id
, udi_cli
->sender_id
);
350 /* Store the SME UniFi Linux Client */
351 if (priv
->sme_cli
== NULL
) {
352 priv
->sme_cli
= udi_cli
;
360 * Store the pointer to the client.
361 * All char driver's entry points will pass this pointer.
363 file
->private_data
= udi_cli
;
371 unifi_release(struct inode
*inode
, struct file
*filp
)
373 ul_client_t
*udi_cli
= (void*)filp
->private_data
;
379 priv
= uf_find_instance(udi_cli
->instance
);
381 unifi_error(priv
, "unifi_close: instance for device not found\n");
385 devno
= MINOR(inode
->i_rdev
) >> 1;
387 /* Even device nodes are the config client (i.e. SME or unifi_manager) */
388 if ((MINOR(inode
->i_rdev
) & 0x1) == 0) {
390 if (priv
->sme_cli
!= udi_cli
) {
391 unifi_notice(priv
, "Surprise closing config device: not the sme client\n");
393 unifi_notice(priv
, "SME client close (unifi%d)\n", devno
);
396 * Clear sme_cli before calling unifi_sys_... so it doesn't try to
397 * queue a reply to the (now gone) SME.
400 priv
->sme_cli
= NULL
;
403 #ifdef CSR_SME_USERSPACE
404 /* Power-down when config client closes */
406 CsrWifiRouterCtrlWifiOffReq req
= {{CSR_WIFI_ROUTER_CTRL_HIP_REQ
, 0, 0, 0, NULL
}};
407 CsrWifiRouterCtrlWifiOffReqHandler(priv
, &req
.common
);
412 /* It is possible that a blocking SME request was made from another process
413 * which did not get read by the SME before the WifiOffReq.
414 * So check for a pending request which will go unanswered and cancel
415 * the wait for event. As only one blocking request can be in progress at
416 * a time, up to one event should be completed.
418 uf_sme_cancel_request(priv
, 0);
420 #endif /* CSR_SME_USERSPACE */
423 unifi_trace(priv
, UDBG2
, "UDI client close (unifiudi%d)\n", devno
);
425 /* If the pointer matches the logging client, stop logging. */
426 down(&priv
->udi_logging_mutex
);
427 if (udi_cli
== priv
->logging_client
) {
428 priv
->logging_client
= NULL
;
430 up(&priv
->udi_logging_mutex
);
432 if (udi_cli
== priv
->amp_client
) {
433 priv
->amp_client
= NULL
;
437 /* Deregister this instance from the client's list. */
438 ul_deregister_client(udi_cli
);
440 uf_put_instance(devno
);
443 } /* unifi_release() */
448 * ---------------------------------------------------------------------------
451 * The read() driver entry point.
454 * filp The file descriptor returned by unifi_open()
455 * p The user space buffer to copy the read data
456 * len The size of the p buffer
460 * number of bytes read or an error code on failure
461 * ---------------------------------------------------------------------------
464 unifi_read(struct file
*filp
, char *p
, size_t len
, loff_t
*poff
)
466 ul_client_t
*pcli
= (void*)filp
->private_data
;
468 udi_log_t
*logptr
= NULL
;
475 priv
= uf_find_instance(pcli
->instance
);
477 unifi_error(priv
, "invalid priv\n");
481 if (!pcli
->udi_enabled
) {
482 unifi_error(priv
, "unifi_read: unknown client.");
486 if (list_empty(&pcli
->udi_log
)) {
487 if (filp
->f_flags
& O_NONBLOCK
) {
488 /* Non-blocking - just return if the udi_log is empty */
491 /* Blocking - wait on the UDI wait queue */
492 if (wait_event_interruptible(pcli
->udi_wq
,
493 !list_empty(&pcli
->udi_log
)))
495 unifi_error(priv
, "unifi_read: wait_event_interruptible failed.");
501 /* Read entry from list head and remove it from the list */
502 if (down_interruptible(&pcli
->udi_sem
)) {
505 l
= pcli
->udi_log
.next
;
509 /* Get a pointer to whole struct */
510 logptr
= list_entry(l
, udi_log_t
, q
);
511 if (logptr
== NULL
) {
512 unifi_error(priv
, "unifi_read: failed to get event.\n");
516 /* Get the real message */
517 msgptr
= &logptr
->msg
;
518 msglen
= msgptr
->length
;
520 printk(KERN_WARNING
"truncated read to %d actual msg len is %lu\n", msglen
, (long unsigned int)len
);
524 /* and pass it to the client (SME or Unicli). */
525 if (copy_to_user(p
, msgptr
, msglen
))
527 printk(KERN_ERR
"Failed to copy UDI log to user\n");
532 /* It is our resposibility to free the message buffer. */
543 * ---------------------------------------------------------------------------
544 * udi_send_signal_unpacked
546 * Sends an unpacked signal to UniFi.
549 * priv Pointer to private context struct
550 * data Pointer to request structure and data to send
551 * data_len Length of data in data pointer.
554 * Number of bytes written, error otherwise.
557 * All clients that use this function to send a signal to the unifi
558 * must use the host formatted structures.
559 * ---------------------------------------------------------------------------
562 udi_send_signal_unpacked(unifi_priv_t
*priv
, unsigned char* data
, uint data_len
)
564 CSR_SIGNAL
*sigptr
= (CSR_SIGNAL
*)data
;
565 CSR_DATAREF
*datarefptr
;
566 bulk_data_param_t bulk_data
;
568 uint bulk_data_offset
= 0;
572 /* Number of bytes in the signal */
573 signal_size
= SigGetSize(sigptr
);
574 if (!signal_size
|| (signal_size
> data_len
)) {
575 unifi_error(priv
, "unifi_sme_mlme_req - Invalid signal 0x%x size should be %d bytes\n",
576 sigptr
->SignalPrimitiveHeader
.SignalId
,
580 bytecount
= signal_size
;
582 /* Get a pointer to the information of the first data reference */
583 datarefptr
= (CSR_DATAREF
*)&sigptr
->u
;
585 /* Initialize the offset in the data buffer, bulk data is right after the signal. */
586 bulk_data_offset
= signal_size
;
588 /* store the references and the size of the bulk data to the bulkdata structure */
589 for (i
= 0; i
< UNIFI_MAX_DATA_REFERENCES
; i
++) {
590 /* the length of the bulk data is in the signal */
591 if ((datarefptr
+i
)->DataLength
) {
594 csrResult
= unifi_net_data_malloc(priv
, &bulk_data
.d
[i
], (datarefptr
+i
)->DataLength
);
595 if (csrResult
!= CSR_RESULT_SUCCESS
) {
596 unifi_error(priv
, "udi_send_signal_unpacked: failed to allocate request_data.\n");
600 dest
= (void*)bulk_data
.d
[i
].os_data_ptr
;
601 memcpy(dest
, data
+ bulk_data_offset
, bulk_data
.d
[i
].data_length
);
603 bulk_data
.d
[i
].data_length
= 0;
606 bytecount
+= bulk_data
.d
[i
].data_length
;
607 /* advance the offset, to point the next bulk data */
608 bulk_data_offset
+= bulk_data
.d
[i
].data_length
;
612 unifi_trace(priv
, UDBG3
, "SME Send: signal 0x%.4X\n", sigptr
->SignalPrimitiveHeader
.SignalId
);
614 /* Send the signal. */
615 r
= ul_send_signal_unpacked(priv
, sigptr
, &bulk_data
);
617 unifi_error(priv
, "udi_send_signal_unpacked: send failed (%d)\n", r
);
618 for(i
=0;i
<UNIFI_MAX_DATA_REFERENCES
;i
++) {
619 if(bulk_data
.d
[i
].data_length
!= 0) {
620 unifi_net_data_free(priv
, &bulk_data
.d
[i
]);
628 } /* udi_send_signal_unpacked() */
633 * ---------------------------------------------------------------------------
634 * udi_send_signal_raw
636 * Sends a packed signal to UniFi.
639 * priv Pointer to private context struct
640 * buf Pointer to request structure and data to send
641 * buflen Length of data in data pointer.
644 * Number of bytes written, error otherwise.
647 * All clients that use this function to send a signal to the unifi
648 * must use the wire formatted structures.
649 * ---------------------------------------------------------------------------
652 udi_send_signal_raw(unifi_priv_t
*priv
, unsigned char *buf
, int buflen
)
656 bulk_data_param_t data_ptrs
;
658 unsigned int num_data_refs
;
665 * The signal is the first thing in buf, the signal id is the
666 * first 16 bits of the signal.
668 /* Number of bytes in the signal */
669 sig_id
= GET_SIGNAL_ID(buf
);
670 signal_size
= buflen
;
671 signal_size
-= GET_PACKED_DATAREF_LEN(buf
, 0);
672 signal_size
-= GET_PACKED_DATAREF_LEN(buf
, 1);
673 if ((signal_size
<= 0) || (signal_size
> buflen
)) {
674 unifi_error(priv
, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n",
679 unifi_trace(priv
, UDBG2
, "udi_send_signal_raw: signal 0x%.4X len:%d\n",
680 sig_id
, signal_size
);
681 /* Zero the data ref arrays */
682 memset(&data_ptrs
, 0, sizeof(data_ptrs
));
685 * Find the number of associated bulk data packets. Scan through
686 * the data refs to check that we have enough data and pick out
687 * pointers to appended bulk data.
690 bytecount
= signal_size
;
692 for (i
= 0; i
< UNIFI_MAX_DATA_REFERENCES
; ++i
)
694 unsigned int len
= GET_PACKED_DATAREF_LEN(buf
, i
);
695 unifi_trace(priv
, UDBG3
, "udi_send_signal_raw: data_ref length = %d\n", len
);
700 csrResult
= unifi_net_data_malloc(priv
, &data_ptrs
.d
[i
], len
);
701 if (csrResult
!= CSR_RESULT_SUCCESS
) {
702 unifi_error(priv
, "udi_send_signal_raw: failed to allocate request_data.\n");
706 dest
= (void*)data_ptrs
.d
[i
].os_data_ptr
;
707 memcpy(dest
, buf
+ bytecount
, len
);
712 data_ptrs
.d
[i
].data_length
= len
;
715 unifi_trace(priv
, UDBG3
, "Queueing signal 0x%.4X from UDI with %u data refs\n",
719 if (bytecount
> buflen
) {
720 unifi_error(priv
, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen
, bytecount
);
725 /* Send the signal calling the function that uses the wire-formatted signals. */
726 r
= ul_send_signal_raw(priv
, buf
, signal_size
, &data_ptrs
);
728 unifi_error(priv
, "udi_send_signal_raw: send failed (%d)\n", r
);
733 #ifdef CSR_NATIVE_LINUX
734 if (sig_id
== CSR_MLME_POWERMGT_REQUEST_ID
) {
735 int power_mode
= CSR_GET_UINT16_FROM_LITTLE_ENDIAN((buf
+
736 SIZEOF_SIGNAL_HEADER
+ (UNIFI_MAX_DATA_REFERENCES
*SIZEOF_DATAREF
)));
737 #ifdef CSR_SUPPORT_WEXT
738 /* Overide the wext power mode to the new value */
739 priv
->wext_conf
.power_mode
= power_mode
;
741 /* Configure deep sleep signaling */
742 if (power_mode
|| (priv
->interfacePriv
[0]->connected
== UnifiNotConnected
)) {
743 csrResult
= unifi_configure_low_power_mode(priv
->card
,
744 UNIFI_LOW_POWER_ENABLED
,
745 UNIFI_PERIODIC_WAKE_HOST_DISABLED
);
747 csrResult
= unifi_configure_low_power_mode(priv
->card
,
748 UNIFI_LOW_POWER_DISABLED
,
749 UNIFI_PERIODIC_WAKE_HOST_DISABLED
);
754 func_exit_r(bytecount
);
757 } /* udi_send_signal_raw */
760 * ---------------------------------------------------------------------------
763 * The write() driver entry point.
764 * A UniFi Debug Interface client such as unicli can write a signal
765 * plus bulk data to the driver for sending to the UniFi chip.
767 * Only one signal may be sent per write operation.
770 * filp The file descriptor returned by unifi_open()
771 * p The user space buffer to get the data from
772 * len The size of the p buffer
776 * number of bytes written or an error code on failure
777 * ---------------------------------------------------------------------------
780 unifi_write(struct file
*filp
, const char *p
, size_t len
, loff_t
*poff
)
782 ul_client_t
*pcli
= (ul_client_t
*)filp
->private_data
;
785 unsigned char *bufptr
;
789 bulk_data_param_t bulkdata
;
794 priv
= uf_find_instance(pcli
->instance
);
796 unifi_error(priv
, "invalid priv\n");
800 unifi_trace(priv
, UDBG5
, "unifi_write: len = %d\n", len
);
802 if (!pcli
->udi_enabled
) {
803 unifi_error(priv
, "udi disabled\n");
808 * AMP client sends only one signal at a time, so we can use
809 * unifi_net_data_malloc to save the extra copy.
811 if (pcli
== priv
->amp_client
) {
814 unsigned char *signal_buf
;
817 csrResult
= unifi_net_data_malloc(priv
, &bulkdata
.d
[0], len
);
818 if (csrResult
!= CSR_RESULT_SUCCESS
) {
819 unifi_error(priv
, "unifi_write: failed to allocate request_data.\n");
824 user_data_buf
= (char*)bulkdata
.d
[0].os_data_ptr
;
826 /* Get the data from the AMP client. */
827 if (copy_from_user((void*)user_data_buf
, p
, len
)) {
828 unifi_error(priv
, "unifi_write: copy from user failed\n");
829 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
834 bulkdata
.d
[1].os_data_ptr
= NULL
;
835 bulkdata
.d
[1].data_length
= 0;
837 /* Number of bytes in the signal */
838 sig_id
= GET_SIGNAL_ID(bulkdata
.d
[0].os_data_ptr
);
840 signal_size
-= GET_PACKED_DATAREF_LEN(bulkdata
.d
[0].os_data_ptr
, 0);
841 signal_size
-= GET_PACKED_DATAREF_LEN(bulkdata
.d
[0].os_data_ptr
, 1);
842 if ((signal_size
<= 0) || (signal_size
> len
)) {
843 unifi_error(priv
, "unifi_write - Couldn't find length of signal 0x%x\n",
845 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
850 unifi_trace(priv
, UDBG2
, "unifi_write: signal 0x%.4X len:%d\n",
851 sig_id
, signal_size
);
853 /* Allocate a buffer for the signal */
854 signal_buf
= kmalloc(signal_size
, GFP_KERNEL
);
856 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
861 /* Get the signal from the os_data_ptr */
862 memcpy(signal_buf
, bulkdata
.d
[0].os_data_ptr
, signal_size
);
863 signal_buf
[5] = (pcli
->sender_id
>> 8) & 0xff;
865 if (signal_size
< len
) {
866 /* Remove the signal from the os_data_ptr */
867 bulkdata
.d
[0].data_length
-= signal_size
;
868 bulkdata
.d
[0].os_data_ptr
+= signal_size
;
870 bulkdata
.d
[0].data_length
= 0;
871 bulkdata
.d
[0].os_data_ptr
= NULL
;
874 /* Send the signal calling the function that uses the wire-formatted signals. */
875 r
= ul_send_signal_raw(priv
, signal_buf
, signal_size
, &bulkdata
);
877 unifi_error(priv
, "unifi_write: send failed (%d)\n", r
);
878 if (bulkdata
.d
[0].os_data_ptr
!= NULL
) {
879 unifi_net_data_free(priv
, &bulkdata
.d
[0]);
883 /* Free the signal buffer and return */
888 buf
= kmalloc(len
, GFP_KERNEL
);
893 /* Get the data from the client (SME or Unicli). */
894 if (copy_from_user((void*)buf
, p
, len
)) {
895 unifi_error(priv
, "copy from user failed\n");
901 * In SME userspace build read() contains a SYS or MGT message.
902 * Note that even though the SME sends one signal at a time, we can not
903 * use unifi_net_data_malloc because in the early stages, before having
904 * initialised the core, it will fail since the I/O block size is unknown.
906 #ifdef CSR_SME_USERSPACE
907 if (pcli
->configuration
& CLI_SME_USERSPACE
) {
908 CsrWifiRouterTransportRecv(priv
, buf
, len
);
914 /* ul_send_signal_raw will do a sanity check of len against signal content */
917 * udi_send_signal_raw() and udi_send_signal_unpacked() return the number of bytes consumed.
918 * A write call can pass multiple signal concatenated together.
923 while (remaining
> 0)
928 * Set the SenderProcessId.
929 * The SignalPrimitiveHeader is the first 3 16-bit words of the signal,
930 * the SenderProcessId is bytes 4,5.
931 * The MSB of the sender ID needs to be set to the client ID.
932 * The LSB is controlled by the SME.
934 bufptr
[5] = (pcli
->sender_id
>> 8) & 0xff;
936 /* use the appropriate interface, depending on the clients' configuration */
937 if (pcli
->configuration
& CLI_USING_WIRE_FORMAT
) {
938 unifi_trace(priv
, UDBG1
, "unifi_write: call udi_send_signal().\n");
939 r
= udi_send_signal_raw(priv
, bufptr
, remaining
);
941 r
= udi_send_signal_unpacked(priv
, bufptr
, remaining
);
944 /* Set the return value to the error code */
945 unifi_error(priv
, "unifi_write: (udi or sme)_send_signal() returns %d\n", r
);
956 func_exit_r(bytes_written
);
958 return bytes_written
;
959 } /* unifi_write() */
962 static const char* build_type_to_string(unsigned char build_type
)
966 case UNIFI_BUILD_NME
: return "NME";
967 case UNIFI_BUILD_WEXT
: return "WEXT";
968 case UNIFI_BUILD_AP
: return "AP";
975 * ----------------------------------------------------------------
978 * Ioctl handler for unifi driver.
981 * inodep Pointer to inode structure.
982 * filp Pointer to file structure.
983 * cmd Ioctl cmd passed by user.
984 * arg Ioctl arg passed by user.
987 * 0 on success, -ve error code on error.
988 * ----------------------------------------------------------------
991 unifi_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
993 ul_client_t
*pcli
= (ul_client_t
*)filp
->private_data
;
995 struct net_device
*dev
;
1000 #if (defined CSR_SUPPORT_SME)
1001 unifi_cfg_command_t cfg_cmd
;
1002 #if (defined CSR_SUPPORT_WEXT)
1003 CsrWifiSmeCoexConfig coex_config
;
1004 unsigned char uchar_param
;
1005 unsigned char varbind
[MAX_VARBIND_LENGTH
];
1009 unifi_putest_command_t putest_cmd
;
1011 priv
= uf_find_instance(pcli
->instance
);
1013 unifi_error(priv
, "ioctl error: unknown instance=%d\n", pcli
->instance
);
1017 unifi_trace(priv
, UDBG5
, "unifi_ioctl: cmd=0x%X, arg=0x%lX\n", cmd
, arg
);
1021 case UNIFI_GET_UDI_ENABLE
:
1022 unifi_trace(priv
, UDBG4
, "UniFi Get UDI Enable\n");
1024 down(&priv
->udi_logging_mutex
);
1025 int_param
= (priv
->logging_client
== NULL
) ? 0 : 1;
1026 up(&priv
->udi_logging_mutex
);
1028 if (put_user(int_param
, (int*)arg
))
1030 unifi_error(priv
, "UNIFI_GET_UDI_ENABLE: Failed to copy to user\n");
1036 case UNIFI_SET_UDI_ENABLE
:
1037 unifi_trace(priv
, UDBG4
, "UniFi Set UDI Enable\n");
1038 if (get_user(int_param
, (int*)arg
))
1040 unifi_error(priv
, "UNIFI_SET_UDI_ENABLE: Failed to copy from user\n");
1045 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1046 if (log_hip_signals
) {
1047 unifi_error(priv
, "omnicli cannot be used when log_hip_signals is used\n");
1053 down(&priv
->udi_logging_mutex
);
1055 pcli
->event_hook
= udi_log_event
;
1056 unifi_set_udi_hook(priv
->card
, logging_handler
);
1057 /* Log all signals by default */
1058 for (i
= 0; i
< SIG_FILTER_SIZE
; i
++) {
1059 pcli
->signal_filter
[i
] = 0xFFFF;
1061 priv
->logging_client
= pcli
;
1064 priv
->logging_client
= NULL
;
1065 pcli
->event_hook
= NULL
;
1067 up(&priv
->udi_logging_mutex
);
1072 unifi_trace(priv
, UDBG4
, "UniFi Set MIB\n");
1073 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1074 /* Read first 2 bytes and check length */
1075 if (copy_from_user((void*)varbind
, (void*)arg
, 2)) {
1077 "UNIFI_SET_MIB: Failed to copy in varbind header\n");
1082 if ((vblen
+ 2) > MAX_VARBIND_LENGTH
) {
1084 "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n",
1085 (vblen
+2), MAX_VARBIND_LENGTH
);
1089 /* Read rest of varbind */
1090 if (copy_from_user((void*)(varbind
+2), (void*)(arg
+2), vblen
)) {
1091 unifi_error(priv
, "UNIFI_SET_MIB: Failed to copy in varbind\n");
1098 r
= sme_mgt_mib_set(priv
, varbind
, vblen
);
1103 unifi_notice(priv
, "UNIFI_SET_MIB: Unsupported.\n");
1104 #endif /* CSR_SUPPORT_WEXT */
1108 unifi_trace(priv
, UDBG4
, "UniFi Get MIB\n");
1109 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1110 /* Read first 2 bytes and check length */
1111 if (copy_from_user((void*)varbind
, (void*)arg
, 2)) {
1112 unifi_error(priv
, "UNIFI_GET_MIB: Failed to copy in varbind header\n");
1117 if ((vblen
+2) > MAX_VARBIND_LENGTH
) {
1118 unifi_error(priv
, "UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n",
1119 (vblen
+2), MAX_VARBIND_LENGTH
);
1123 /* Read rest of varbind */
1124 if (copy_from_user((void*)(varbind
+2), (void*)(arg
+2), vblen
)) {
1125 unifi_error(priv
, "UNIFI_GET_MIB: Failed to copy in varbind\n");
1131 r
= sme_mgt_mib_get(priv
, varbind
, &vblen
);
1135 /* copy out varbind */
1136 if (vblen
> MAX_VARBIND_LENGTH
) {
1138 "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n",
1139 vblen
, MAX_VARBIND_LENGTH
);
1143 if (copy_to_user((void*)arg
, varbind
, vblen
)) {
1148 unifi_notice(priv
, "UNIFI_GET_MIB: Unsupported.\n");
1149 #endif /* CSR_SUPPORT_WEXT */
1153 #if (defined CSR_SUPPORT_SME)
1154 if (get_user(cfg_cmd
, (unifi_cfg_command_t
*)arg
))
1156 unifi_error(priv
, "UNIFI_CFG: Failed to get the command\n");
1161 unifi_trace(priv
, UDBG1
, "UNIFI_CFG: Command is %d (t=%u) sz=%d\n",
1162 cfg_cmd
, jiffies_to_msecs(jiffies
), sizeof(unifi_cfg_command_t
));
1164 case UNIFI_CFG_POWER
:
1165 r
= unifi_cfg_power(priv
, (unsigned char*)arg
);
1167 case UNIFI_CFG_POWERSAVE
:
1168 r
= unifi_cfg_power_save(priv
, (unsigned char*)arg
);
1170 case UNIFI_CFG_POWERSUPPLY
:
1171 r
= unifi_cfg_power_supply(priv
, (unsigned char*)arg
);
1173 case UNIFI_CFG_FILTER
:
1174 r
= unifi_cfg_packet_filters(priv
, (unsigned char*)arg
);
1177 r
= unifi_cfg_get_info(priv
, (unsigned char*)arg
);
1179 case UNIFI_CFG_WMM_QOSINFO
:
1180 r
= unifi_cfg_wmm_qos_info(priv
, (unsigned char*)arg
);
1182 case UNIFI_CFG_WMM_ADDTS
:
1183 r
= unifi_cfg_wmm_addts(priv
, (unsigned char*)arg
);
1185 case UNIFI_CFG_WMM_DELTS
:
1186 r
= unifi_cfg_wmm_delts(priv
, (unsigned char*)arg
);
1188 case UNIFI_CFG_STRICT_DRAFT_N
:
1189 r
= unifi_cfg_strict_draft_n(priv
, (unsigned char*)arg
);
1191 case UNIFI_CFG_ENABLE_OKC
:
1192 r
= unifi_cfg_enable_okc(priv
, (unsigned char*)arg
);
1194 #ifdef CSR_SUPPORT_SME
1195 case UNIFI_CFG_CORE_DUMP
:
1196 CsrWifiRouterCtrlWifiOffIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR
);
1197 unifi_trace(priv
, UDBG2
, "UNIFI_CFG_CORE_DUMP: sent wifi off indication\n");
1200 #ifdef CSR_SUPPORT_WEXT_AP
1201 case UNIFI_CFG_SET_AP_CONFIG
:
1202 r
= unifi_cfg_set_ap_config(priv
,(unsigned char*)arg
);
1206 unifi_error(priv
, "UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd
);
1215 if (get_user(putest_cmd
, (unifi_putest_command_t
*)arg
))
1217 unifi_error(priv
, "UNIFI_PUTEST: Failed to get the command\n");
1222 unifi_trace(priv
, UDBG1
, "UNIFI_PUTEST: Command is %s\n",
1223 trace_putest_cmdid(putest_cmd
));
1224 switch (putest_cmd
) {
1225 case UNIFI_PUTEST_START
:
1226 r
= unifi_putest_start(priv
, (unsigned char*)arg
);
1228 case UNIFI_PUTEST_STOP
:
1229 r
= unifi_putest_stop(priv
, (unsigned char*)arg
);
1231 case UNIFI_PUTEST_SET_SDIO_CLOCK
:
1232 r
= unifi_putest_set_sdio_clock(priv
, (unsigned char*)arg
);
1234 case UNIFI_PUTEST_CMD52_READ
:
1235 r
= unifi_putest_cmd52_read(priv
, (unsigned char*)arg
);
1237 case UNIFI_PUTEST_CMD52_BLOCK_READ
:
1238 r
= unifi_putest_cmd52_block_read(priv
, (unsigned char*)arg
);
1240 case UNIFI_PUTEST_CMD52_WRITE
:
1241 r
= unifi_putest_cmd52_write(priv
, (unsigned char*)arg
);
1243 case UNIFI_PUTEST_DL_FW
:
1244 r
= unifi_putest_dl_fw(priv
, (unsigned char*)arg
);
1246 case UNIFI_PUTEST_DL_FW_BUFF
:
1247 r
= unifi_putest_dl_fw_buff(priv
, (unsigned char*)arg
);
1249 case UNIFI_PUTEST_COREDUMP_PREPARE
:
1250 r
= unifi_putest_coredump_prepare(priv
, (unsigned char*)arg
);
1252 case UNIFI_PUTEST_GP_READ16
:
1253 r
= unifi_putest_gp_read16(priv
, (unsigned char*)arg
);
1255 case UNIFI_PUTEST_GP_WRITE16
:
1256 r
= unifi_putest_gp_write16(priv
, (unsigned char*)arg
);
1259 unifi_error(priv
, "UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd
);
1265 case UNIFI_BUILD_TYPE
:
1266 unifi_trace(priv
, UDBG2
, "UNIFI_BUILD_TYPE userspace=%s\n", build_type_to_string(*(unsigned char*)arg
));
1267 #ifndef CSR_SUPPORT_WEXT_AP
1268 if (UNIFI_BUILD_AP
== *(unsigned char*)arg
)
1270 unifi_error(priv
, "Userspace has AP support, which is incompatible\n");
1274 #ifndef CSR_SUPPORT_WEXT
1275 if (UNIFI_BUILD_WEXT
== *(unsigned char*)arg
)
1277 unifi_error(priv
, "Userspace has WEXT support, which is incompatible\n");
1282 unifi_trace(priv
, UDBG2
, "UNIFI_INIT_HW.\n");
1283 priv
->init_progress
= UNIFI_INIT_NONE
;
1285 #if defined(CSR_SUPPORT_WEXT) || defined (CSR_NATIVE_LINUX)
1286 /* At this point we are ready to start the SME. */
1287 r
= sme_mgt_wifi_on(priv
);
1295 case UNIFI_INIT_NETDEV
:
1297 /* get the proper interfaceTagId */
1298 CsrUint16 interfaceTag
=0;
1299 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
1301 dev
= priv
->netdev
[interfaceTag
];
1302 unifi_trace(priv
, UDBG2
, "UNIFI_INIT_NETDEV.\n");
1304 if (copy_from_user((void*)dev
->dev_addr
, (void*)arg
, 6)) {
1309 /* Attach the network device to the stack */
1310 if (!interfacePriv
->netdev_registered
)
1312 r
= uf_register_netdev(priv
,interfaceTag
);
1314 unifi_error(priv
, "Failed to register the network device.\n");
1319 /* Apply scheduled interrupt mode, if requested by module param */
1320 if (run_bh_once
!= -1) {
1321 unifi_set_interrupt_mode(priv
->card
, (CsrUint32
)run_bh_once
);
1324 priv
->init_progress
= UNIFI_INIT_COMPLETED
;
1326 /* Firmware initialisation is complete, so let the SDIO bus
1327 * clock be raised when convienent to the core.
1329 unifi_request_max_sdio_clock(priv
->card
);
1331 #ifdef CSR_SUPPORT_WEXT
1332 /* Notify the Android wpa_supplicant that we are ready */
1333 wext_send_started_event(priv
);
1336 unifi_info(priv
, "UniFi ready\n");
1338 #ifdef ANDROID_BUILD
1339 /* Release the wakelock */
1340 unifi_trace(priv
, UDBG1
, "netdev_init: release wake lock\n");
1341 wake_unlock(&unifi_sdio_wake_lock
);
1343 #ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */
1345 struct net_device
*dev
= priv
->netdev
[interfaceTag
];
1346 #ifdef CSR_SUPPORT_WEXT
1347 interfacePriv
->wait_netdev_change
= TRUE
;
1349 netif_carrier_on(dev
);
1354 case UNIFI_GET_INIT_STATUS
:
1355 unifi_trace(priv
, UDBG2
, "UNIFI_GET_INIT_STATUS.\n");
1356 if (put_user(priv
->init_progress
, (int*)arg
))
1358 printk(KERN_ERR
"UNIFI_GET_INIT_STATUS: Failed to copy to user\n");
1365 unifi_trace(priv
, UDBG4
, "Kick UniFi\n");
1366 unifi_sdio_interrupt_handler(priv
->card
);
1369 case UNIFI_SET_DEBUG
:
1371 unifi_trace(priv
, UDBG4
, "unifi_debug set to %d\n", unifi_debug
);
1374 case UNIFI_SET_TRACE
:
1375 /* no longer supported */
1380 case UNIFI_SET_UDI_LOG_MASK
:
1382 unifiio_filter_t udi_filter
;
1383 uint16_t *sig_ids_addr
;
1384 #define UF_MAX_SIG_IDS 128 /* Impose a sensible limit */
1386 if (copy_from_user((void*)(&udi_filter
), (void*)arg
, sizeof(udi_filter
))) {
1390 if ((udi_filter
.action
< UfSigFil_AllOn
) ||
1391 (udi_filter
.action
> UfSigFil_SelectOff
))
1394 "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n",
1399 /* No signal list for "All" actions */
1400 if ((udi_filter
.action
== UfSigFil_AllOn
) ||
1401 (udi_filter
.action
== UfSigFil_AllOff
))
1403 udi_filter
.num_sig_ids
= 0;
1406 if (udi_filter
.num_sig_ids
> UF_MAX_SIG_IDS
) {
1408 "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n",
1409 udi_filter
.num_sig_ids
, UF_MAX_SIG_IDS
);
1414 /* Copy in signal id list if given */
1415 if (udi_filter
.num_sig_ids
> 0) {
1416 /* Preserve userspace address of sig_ids array */
1417 sig_ids_addr
= udi_filter
.sig_ids
;
1418 /* Allocate kernel memory for sig_ids and copy to it */
1419 udi_filter
.sig_ids
=
1420 kmalloc(udi_filter
.num_sig_ids
* sizeof(uint16_t), GFP_KERNEL
);
1421 if (!udi_filter
.sig_ids
) {
1425 if (copy_from_user((void*)udi_filter
.sig_ids
,
1426 (void*)sig_ids_addr
,
1427 udi_filter
.num_sig_ids
* sizeof(uint16_t)))
1429 kfree(udi_filter
.sig_ids
);
1435 udi_set_log_filter(pcli
, &udi_filter
);
1437 if (udi_filter
.num_sig_ids
> 0) {
1438 kfree(udi_filter
.sig_ids
);
1443 case UNIFI_SET_AMP_ENABLE
:
1444 unifi_trace(priv
, UDBG4
, "UniFi Set AMP Enable\n");
1445 if (get_user(int_param
, (int*)arg
))
1447 unifi_error(priv
, "UNIFI_SET_AMP_ENABLE: Failed to copy from user\n");
1453 priv
->amp_client
= pcli
;
1455 priv
->amp_client
= NULL
;
1459 buf
= (u8
*)&int_param
;
1460 buf
[0] = UNIFI_SOFT_COMMAND_Q_LENGTH
- 1;
1461 buf
[1] = UNIFI_SOFT_TRAFFIC_Q_LENGTH
- 1;
1462 if (copy_to_user((void*)arg
, &int_param
, sizeof(int))) {
1468 case UNIFI_SET_UDI_SNAP_MASK
:
1470 unifiio_snap_filter_t snap_filter
;
1472 if (copy_from_user((void*)(&snap_filter
), (void*)arg
, sizeof(snap_filter
))) {
1477 if (pcli
->snap_filter
.count
) {
1478 pcli
->snap_filter
.count
= 0;
1479 CsrPmemFree(pcli
->snap_filter
.protocols
);
1482 if (snap_filter
.count
== 0) {
1486 pcli
->snap_filter
.protocols
= CsrPmemAlloc(snap_filter
.count
* sizeof(CsrUint16
));
1487 if (!pcli
->snap_filter
.protocols
) {
1491 if (copy_from_user((void*)pcli
->snap_filter
.protocols
,
1492 (void*)snap_filter
.protocols
,
1493 snap_filter
.count
* sizeof(CsrUint16
)))
1495 CsrPmemFree(pcli
->snap_filter
.protocols
);
1500 pcli
->snap_filter
.count
= snap_filter
.count
;
1505 case UNIFI_SME_PRESENT
:
1508 unifi_trace(priv
, UDBG4
, "UniFi SME Present IOCTL.\n");
1509 if (copy_from_user((void*)(&int_param
), (void*)arg
, sizeof(int)))
1511 printk(KERN_ERR
"UNIFI_SME_PRESENT: Failed to copy from user\n");
1516 priv
->sme_is_present
= int_param
;
1517 if (priv
->sme_is_present
== 1) {
1518 ind
= CONFIG_SME_PRESENT
;
1520 ind
= CONFIG_SME_NOT_PRESENT
;
1522 /* Send an indication to the helper app. */
1523 ul_log_config_ind(priv
, &ind
, sizeof(u8
));
1527 case UNIFI_CFG_PERIOD_TRAFFIC
:
1529 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1530 CsrWifiSmeCoexConfig coexConfig
;
1531 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1532 unifi_trace(priv
, UDBG4
, "UniFi Configure Periodic Traffic.\n");
1533 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1534 if (copy_from_user((void*)(&uchar_param
), (void*)arg
, sizeof(unsigned char))) {
1535 unifi_error(priv
, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
1540 if (uchar_param
== 0) {
1541 r
= sme_mgt_coex_config_get(priv
, &coexConfig
);
1543 unifi_error(priv
, "UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n");
1546 if (copy_to_user((void*)(arg
+ 1),
1548 sizeof(CsrWifiSmeCoexConfig
))) {
1555 if (copy_from_user((void*)(&coex_config
), (void*)(arg
+ 1), sizeof(CsrWifiSmeCoexConfig
)))
1557 unifi_error(priv
, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
1562 coexConfig
= coex_config
;
1563 r
= sme_mgt_coex_config_set(priv
, &coexConfig
);
1565 unifi_error(priv
, "UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\n");
1569 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1572 case UNIFI_CFG_UAPSD_TRAFFIC
:
1573 unifi_trace(priv
, UDBG4
, "UniFi Configure U-APSD Mask.\n");
1574 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1575 if (copy_from_user((void*)(&uchar_param
), (void*)arg
, sizeof(unsigned char))) {
1576 unifi_error(priv
, "UNIFI_CFG_UAPSD_TRAFFIC: Failed to copy from user\n");
1580 unifi_trace(priv
, UDBG4
, "New U-APSD Mask: 0x%x\n", uchar_param
);
1581 #endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
1584 #ifndef UNIFI_DISABLE_COREDUMP
1585 case UNIFI_COREDUMP_GET_REG
:
1586 unifi_trace(priv
, UDBG4
, "Mini-coredump data request\n");
1588 unifiio_coredump_req_t dump_req
; /* Public OS layer structure */
1589 unifi_coredump_req_t priv_req
; /* Private HIP structure */
1591 if (copy_from_user((void*)(&dump_req
), (void*)arg
, sizeof(dump_req
))) {
1595 memset(&priv_req
, 0, sizeof(priv_req
));
1596 priv_req
.index
= dump_req
.index
;
1597 priv_req
.offset
= dump_req
.offset
;
1599 /* Convert OS-layer's XAP memory space ID to HIP's ID in case they differ */
1600 switch (dump_req
.space
) {
1601 case UNIFIIO_COREDUMP_MAC_REG
: priv_req
.space
= UNIFI_COREDUMP_MAC_REG
; break;
1602 case UNIFIIO_COREDUMP_PHY_REG
: priv_req
.space
= UNIFI_COREDUMP_PHY_REG
; break;
1603 case UNIFIIO_COREDUMP_SH_DMEM
: priv_req
.space
= UNIFI_COREDUMP_SH_DMEM
; break;
1604 case UNIFIIO_COREDUMP_MAC_DMEM
: priv_req
.space
= UNIFI_COREDUMP_MAC_DMEM
; break;
1605 case UNIFIIO_COREDUMP_PHY_DMEM
: priv_req
.space
= UNIFI_COREDUMP_PHY_DMEM
; break;
1606 case UNIFIIO_COREDUMP_TRIGGER_MAGIC
: priv_req
.space
= UNIFI_COREDUMP_TRIGGER_MAGIC
; break;
1612 if (priv_req
.space
== UNIFI_COREDUMP_TRIGGER_MAGIC
) {
1613 /* Force a coredump grab now */
1614 unifi_trace(priv
, UDBG2
, "UNIFI_COREDUMP_GET_REG: Force capture\n");
1615 csrResult
= unifi_coredump_capture(priv
->card
, &priv_req
);
1616 r
= CsrHipResultToStatus(csrResult
);
1617 unifi_trace(priv
, UDBG5
, "UNIFI_COREDUMP_GET_REG: status %d\n", r
);
1619 /* Retrieve the appropriate register entry */
1620 csrResult
= unifi_coredump_get_value(priv
->card
, &priv_req
);
1621 r
= CsrHipResultToStatus(csrResult
);
1623 unifi_trace(priv
, UDBG5
, "UNIFI_COREDUMP_GET_REG: Status %d\n", r
);
1626 /* Update the OS-layer structure with values returned in the private */
1627 dump_req
.value
= priv_req
.value
;
1628 dump_req
.timestamp
= priv_req
.timestamp
;
1629 dump_req
.requestor
= priv_req
.requestor
;
1630 dump_req
.serial
= priv_req
.serial
;
1631 dump_req
.chip_ver
= priv_req
.chip_ver
;
1632 dump_req
.fw_ver
= priv_req
.fw_ver
;
1633 dump_req
.drv_build
= 0;
1635 unifi_trace(priv
, UDBG6
,
1636 "Dump: %d (seq %d): V:0x%04x (%d) @0x%02x:%04x = 0x%04x\n",
1637 dump_req
.index
, dump_req
.serial
,
1638 dump_req
.chip_ver
, dump_req
.drv_build
,
1639 dump_req
.space
, dump_req
.offset
, dump_req
.value
);
1641 if (copy_to_user((void*)arg
, (void*)&dump_req
, sizeof(dump_req
))) {
1654 } /* unifi_ioctl() */
1659 unifi_poll(struct file
*filp
, poll_table
*wait
)
1661 ul_client_t
*pcli
= (ul_client_t
*)filp
->private_data
;
1662 unsigned int mask
= 0;
1667 ready
= !list_empty(&pcli
->udi_log
);
1669 poll_wait(filp
, &pcli
->udi_wq
, wait
);
1672 mask
|= POLLIN
| POLLRDNORM
; /* readable */
1678 } /* unifi_poll() */
1683 * ---------------------------------------------------------------------------
1684 * udi_set_log_filter
1686 * Configure the bit mask that determines which signal primitives are
1687 * passed to the logging process.
1690 * pcli Pointer to the client to configure.
1691 * udi_filter Pointer to a unifiio_filter_t containing instructions.
1697 * SigGetFilterPos() returns a 32-bit value that contains an index and a
1698 * mask for accessing a signal_filter array. The top 16 bits specify an
1699 * index into a signal_filter, the bottom 16 bits specify a mask to
1701 * ---------------------------------------------------------------------------
1704 udi_set_log_filter(ul_client_t
*pcli
, unifiio_filter_t
*udi_filter
)
1706 CsrUint32 filter_pos
;
1709 if (udi_filter
->action
== UfSigFil_AllOn
)
1711 for (i
= 0; i
< SIG_FILTER_SIZE
; i
++) {
1712 pcli
->signal_filter
[i
] = 0xFFFF;
1715 else if (udi_filter
->action
== UfSigFil_AllOff
)
1717 for (i
= 0; i
< SIG_FILTER_SIZE
; i
++) {
1718 pcli
->signal_filter
[i
] = 0;
1721 else if (udi_filter
->action
== UfSigFil_SelectOn
)
1723 for (i
= 0; i
< udi_filter
->num_sig_ids
; i
++) {
1724 filter_pos
= SigGetFilterPos(udi_filter
->sig_ids
[i
]);
1725 if (filter_pos
== 0xFFFFFFFF)
1728 "Unrecognised signal id (0x%X) specifed in logging filter\n",
1729 udi_filter
->sig_ids
[i
]);
1731 pcli
->signal_filter
[filter_pos
>> 16] |= (filter_pos
& 0xFFFF);
1735 else if (udi_filter
->action
== UfSigFil_SelectOff
)
1737 for (i
= 0; i
< udi_filter
->num_sig_ids
; i
++) {
1738 filter_pos
= SigGetFilterPos(udi_filter
->sig_ids
[i
]);
1739 if (filter_pos
== 0xFFFFFFFF)
1742 "Unrecognised signal id (0x%X) specifed in logging filter\n",
1743 udi_filter
->sig_ids
[i
]);
1745 pcli
->signal_filter
[filter_pos
>> 16] &= ~(filter_pos
& 0xFFFF);
1750 } /* udi_set_log_filter() */
1754 * ---------------------------------------------------------------------------
1757 * Callback function to be registered as the UDI hook callback.
1758 * Copies the signal content into a new udi_log_t struct and adds
1759 * it to the read queue for this UDI client.
1762 * pcli A pointer to the client instance.
1763 * signal Pointer to the received signal.
1764 * signal_len Size of the signal structure in bytes.
1765 * bulkdata Pointers to any associated bulk data.
1766 * dir Direction of the signal. Zero means from host,
1767 * non-zero means to host.
1771 * ---------------------------------------------------------------------------
1774 udi_log_event(ul_client_t
*pcli
,
1775 const u8
*signal
, int signal_len
,
1776 const bulk_data_param_t
*bulkdata
,
1784 CsrUint32 filter_pos
;
1785 #ifdef OMNICLI_LINUX_EXTRA_LOG
1786 static volatile unsigned int printk_cpu
= UINT_MAX
;
1787 unsigned long long t
;
1788 unsigned long nanosec_rem
;
1789 unsigned long n_1000
;
1794 /* Just a sanity check */
1795 if ((signal
== NULL
) || (signal_len
<= 0)) {
1799 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1800 /* When HIP offline signal logging is enabled, omnicli cannot run */
1801 if (log_hip_signals
)
1804 if (log_hip_signals
& UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP
)
1806 int timestamp
= jiffies_to_msecs(jiffies
);
1807 unifi_debug_log_to_buf("T:");
1808 unifi_debug_log_to_buf("%04X%04X ", *(((CsrUint16
*)×tamp
) + 1),
1809 *(CsrUint16
*)×tamp
);
1813 unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ",
1815 *(CsrUint16
*)signal
,
1816 *(CsrUint16
*)(signal
+ 2),
1817 *(CsrUint16
*)(signal
+ 4));
1818 unifi_debug_hex_to_buf(signal
+ 6, signal_len
- 6);
1820 /* Add bulk data (assume 1 bulk data per signal) */
1821 if ((log_hip_signals
& UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA
) &&
1822 (bulkdata
->d
[0].data_length
> 0))
1824 unifi_debug_log_to_buf("\nD:");
1825 unifi_debug_hex_to_buf(bulkdata
->d
[0].os_data_ptr
, bulkdata
->d
[0].data_length
);
1827 unifi_debug_log_to_buf("\n");
1833 #ifdef CSR_NATIVE_LINUX
1834 uf_native_process_udi_signal(pcli
, signal
, signal_len
, bulkdata
, dir
);
1838 * Apply the logging filter - only report signals that have their
1839 * bit set in the filter mask.
1841 filter_pos
= SigGetFilterPos(GET_SIGNAL_ID(signal
));
1843 if ((filter_pos
!= 0xFFFFFFFF) &&
1844 ((pcli
->signal_filter
[filter_pos
>> 16] & (filter_pos
& 0xFFFF)) == 0))
1846 /* Signal is not wanted by client */
1851 /* Calculate the buffer we need to store signal plus bulk data */
1852 total_len
= signal_len
;
1853 for (i
= 0; i
< UNIFI_MAX_DATA_REFERENCES
; i
++) {
1854 total_len
+= bulkdata
->d
[i
].data_length
;
1857 /* Allocate log structure plus actual signal. */
1858 logptr
= (udi_log_t
*)kmalloc(sizeof(udi_log_t
) + total_len
, GFP_KERNEL
);
1860 if (logptr
== NULL
) {
1862 "Failed to allocate %lu bytes for a UDI log record\n",
1863 (long unsigned int)(sizeof(udi_log_t
) + total_len
));
1867 /* Fill in udi_log struct */
1868 INIT_LIST_HEAD(&logptr
->q
);
1869 msgptr
= &logptr
->msg
;
1870 msgptr
->length
= sizeof(udi_msg_t
) + total_len
;
1871 #ifdef OMNICLI_LINUX_EXTRA_LOG
1872 t
= cpu_clock(printk_cpu
);
1873 nanosec_rem
= do_div(t
, 1000000000);
1874 n_1000
= nanosec_rem
/1000;
1875 msgptr
->timestamp
= (t
<<10 ) | ((unsigned long)(n_1000
>> 10) & 0x3ff);
1877 msgptr
->timestamp
= jiffies_to_msecs(jiffies
);
1879 msgptr
->direction
= dir
;
1880 msgptr
->signal_length
= signal_len
;
1882 /* Copy signal and bulk data to the log */
1883 p
= (u8
*)(msgptr
+ 1);
1884 memcpy(p
, signal
, signal_len
);
1887 /* Append any bulk data */
1888 for (i
= 0; i
< UNIFI_MAX_DATA_REFERENCES
; i
++) {
1889 int len
= bulkdata
->d
[i
].data_length
;
1892 * Len here might not be the same as the length in the bulk data slot.
1893 * The slot length will always be even, but len could be odd.
1896 if (bulkdata
->d
[i
].os_data_ptr
) {
1897 memcpy(p
, bulkdata
->d
[i
].os_data_ptr
, len
);
1905 /* Add to tail of log queue */
1906 if (down_interruptible(&pcli
->udi_sem
)) {
1907 printk(KERN_WARNING
"udi_log_event_q: Failed to get udi sem\n");
1912 list_add_tail(&logptr
->q
, &pcli
->udi_log
);
1915 /* Wake any waiting user process */
1916 wake_up_interruptible(&pcli
->udi_wq
);
1919 } /* udi_log_event() */
1921 #ifdef CSR_SME_USERSPACE
1923 uf_sme_queue_message(unifi_priv_t
*priv
, u8
*buffer
, int length
)
1931 /* Just a sanity check */
1932 if ((buffer
== NULL
) || (length
<= 0)) {
1936 /* Allocate log structure plus actual signal. */
1937 logptr
= (udi_log_t
*)kmalloc(sizeof(udi_log_t
) + length
, GFP_ATOMIC
);
1938 if (logptr
== NULL
) {
1939 unifi_error(priv
, "Failed to allocate %d bytes for an SME message\n",
1940 sizeof(udi_log_t
) + length
);
1941 CsrPmemFree(buffer
);
1945 /* Fill in udi_log struct */
1946 INIT_LIST_HEAD(&logptr
->q
);
1947 msgptr
= &logptr
->msg
;
1948 msgptr
->length
= sizeof(udi_msg_t
) + length
;
1949 msgptr
->signal_length
= length
;
1951 /* Copy signal and bulk data to the log */
1952 p
= (u8
*)(msgptr
+ 1);
1953 memcpy(p
, buffer
, length
);
1955 /* Add to tail of log queue */
1957 if (priv
->sme_cli
== NULL
) {
1959 CsrPmemFree(buffer
);
1961 unifi_info(priv
, "Message for the SME dropped, SME has gone away\n");
1965 down(&priv
->sme_cli
->udi_sem
);
1966 list_add_tail(&logptr
->q
, &priv
->sme_cli
->udi_log
);
1967 up(&priv
->sme_cli
->udi_sem
);
1969 /* Wake any waiting user process */
1970 wake_up_interruptible(&priv
->sme_cli
->udi_wq
);
1973 /* It is our responsibility to free the buffer allocated in build_packed_*() */
1974 CsrPmemFree(buffer
);
1980 } /* uf_sme_queue_message() */
1984 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
1985 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
1986 device_create(_class, _parent, _devno, _priv, _fmt, _args)
1987 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
1988 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
1989 device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args)
1991 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
1992 device_create(_class, _parent, _devno, _fmt, _args)
1996 ****************************************************************************
1998 * Driver instantiation
2000 ****************************************************************************
2002 static struct file_operations unifi_fops
= {
2003 .owner
= THIS_MODULE
,
2005 .release
= unifi_release
,
2007 .write
= unifi_write
,
2008 .unlocked_ioctl
= unifi_ioctl
,
2012 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
2013 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
2014 device_create(_class, _parent, _devno, _priv, _fmt, _args)
2015 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
2016 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
2017 device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args)
2019 #define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
2020 device_create(_class, _parent, _devno, _fmt, _args)
2023 static dev_t unifi_first_devno
;
2024 static struct class *unifi_class
;
2027 int uf_create_device_nodes(unifi_priv_t
*priv
, int bus_id
)
2032 cdev_init(&priv
->unifi_cdev
, &unifi_fops
);
2034 /* cdev_init() should set the cdev owner, but it does not */
2035 priv
->unifi_cdev
.owner
= THIS_MODULE
;
2037 devno
= MKDEV(MAJOR(unifi_first_devno
),
2038 MINOR(unifi_first_devno
) + (bus_id
* 2));
2039 r
= cdev_add(&priv
->unifi_cdev
, devno
, 1);
2044 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2045 if (!UF_DEVICE_CREATE(unifi_class
, priv
->unifi_device
,
2046 devno
, priv
, "unifi%d", bus_id
)) {
2048 priv
->unifi_device
= UF_DEVICE_CREATE(unifi_class
, NULL
,
2049 devno
, priv
, "unifi%d", bus_id
);
2050 if (priv
->unifi_device
== NULL
) {
2051 #endif /* SDIO_EXPORTS_STRUCT_DEVICE */
2053 cdev_del(&priv
->unifi_cdev
);
2057 cdev_init(&priv
->unifiudi_cdev
, &unifi_fops
);
2059 /* cdev_init() should set the cdev owner, but it does not */
2060 priv
->unifiudi_cdev
.owner
= THIS_MODULE
;
2062 devno
= MKDEV(MAJOR(unifi_first_devno
),
2063 MINOR(unifi_first_devno
) + (bus_id
* 2) + 1);
2064 r
= cdev_add(&priv
->unifiudi_cdev
, devno
, 1);
2066 device_destroy(unifi_class
, priv
->unifi_cdev
.dev
);
2067 cdev_del(&priv
->unifi_cdev
);
2071 if (!UF_DEVICE_CREATE(unifi_class
,
2072 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2076 #endif /* SDIO_EXPORTS_STRUCT_DEVICE */
2077 devno
, priv
, "unifiudi%d", bus_id
)) {
2078 device_destroy(unifi_class
, priv
->unifi_cdev
.dev
);
2079 cdev_del(&priv
->unifiudi_cdev
);
2080 cdev_del(&priv
->unifi_cdev
);
2088 void uf_destroy_device_nodes(unifi_priv_t
*priv
)
2090 device_destroy(unifi_class
, priv
->unifiudi_cdev
.dev
);
2091 device_destroy(unifi_class
, priv
->unifi_cdev
.dev
);
2092 cdev_del(&priv
->unifiudi_cdev
);
2093 cdev_del(&priv
->unifi_cdev
);
2099 * ----------------------------------------------------------------
2100 * uf_create_debug_device
2102 * Allocates device numbers for unifi character device nodes
2103 * and creates a unifi class in sysfs
2106 * fops Pointer to the char device operations structure.
2109 * 0 on success, -ve error code on error.
2110 * ----------------------------------------------------------------
2113 uf_create_debug_device(struct file_operations
*fops
)
2117 /* Allocate two device numbers for each device. */
2118 ret
= alloc_chrdev_region(&unifi_first_devno
, 0, MAX_UNIFI_DEVS
*2, UNIFI_NAME
);
2120 unifi_error(NULL
, "Failed to add alloc dev numbers: %d\n", ret
);
2124 /* Create a UniFi class */
2125 unifi_class
= class_create(THIS_MODULE
, UNIFI_NAME
);
2126 if (IS_ERR(unifi_class
)) {
2127 unifi_error(NULL
, "Failed to create UniFi class\n");
2129 /* Release device numbers */
2130 unregister_chrdev_region(unifi_first_devno
, MAX_UNIFI_DEVS
*2);
2131 unifi_first_devno
= 0;
2136 } /* uf_create_debug_device() */
2140 * ----------------------------------------------------------------
2141 * uf_remove_debug_device
2143 * Destroys the unifi class and releases the allocated
2144 * device numbers for unifi character device nodes.
2149 * ----------------------------------------------------------------
2152 uf_remove_debug_device(void)
2154 /* Destroy the UniFi class */
2155 class_destroy(unifi_class
);
2157 /* Release device numbers */
2158 unregister_chrdev_region(unifi_first_devno
, MAX_UNIFI_DEVS
*2);
2159 unifi_first_devno
= 0;
2161 } /* uf_remove_debug_device() */
2165 * ---------------------------------------------------------------------------
2169 * ---------------------------------------------------------------------------
2176 printk("UniFi SDIO Driver: %s %s %s\n",
2178 __DATE__
, __TIME__
);
2180 #ifdef CSR_SME_USERSPACE
2181 #ifdef CSR_SUPPORT_WEXT
2182 printk("CSR SME with WEXT support\n");
2184 printk("CSR SME no WEXT support\n");
2185 #endif /* CSR_SUPPORT_WEXT */
2186 #endif /* CSR_SME_USERSPACE */
2188 #ifdef CSR_NATIVE_LINUX
2189 #ifdef CSR_SUPPORT_WEXT
2190 #error WEXT unsupported in the native driver
2192 printk("CSR native no WEXT support\n");
2194 #ifdef CSR_WIFI_SPLIT_PATCH
2195 printk("Split patch support\n");
2197 printk("Kernel %d.%d.%d\n",
2198 ((LINUX_VERSION_CODE
) >> 16) & 0xff,
2199 ((LINUX_VERSION_CODE
) >> 8) & 0xff,
2200 (LINUX_VERSION_CODE
) & 0xff);
2202 * Instantiate the /dev/unifi* device nodes.
2203 * We must do this before registering with the SDIO driver because it
2204 * will immediately call the "insert" callback if the card is
2207 r
= uf_create_debug_device(&unifi_fops
);
2212 /* Now register with the SDIO driver */
2215 uf_remove_debug_device();
2219 if (sdio_block_size
> -1) {
2220 unifi_info(NULL
, "sdio_block_size %d\n", sdio_block_size
);
2223 if (sdio_byte_mode
) {
2224 unifi_info(NULL
, "sdio_byte_mode\n");
2227 if (disable_power_control
) {
2228 unifi_info(NULL
, "disable_power_control\n");
2231 if (disable_hw_reset
) {
2232 unifi_info(NULL
, "disable_hw_reset\n");
2236 unifi_info(NULL
, "enable_wol %d\n", enable_wol
);
2239 if (run_bh_once
!= -1) {
2240 unifi_info(NULL
, "run_bh_once %d\n", run_bh_once
);
2244 } /* unifi_load() */
2250 /* The SDIO remove hook will call unifi_disconnect(). */
2253 uf_remove_debug_device();
2255 } /* unifi_unload() */
2257 module_init(unifi_load
);
2258 module_exit(unifi_unload
);
2260 MODULE_DESCRIPTION("UniFi Device driver");
2261 MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
2262 MODULE_LICENSE("GPL and additional rights");