34 #include <linux/slab.h>
35 #include <linux/poll.h>
36 #include <asm/uaccess.h>
38 #include <linux/version.h>
56 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
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;
81 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
89 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
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)
110 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
111 MODULE_PARM_DESC(log_hip_signals,
"Set to 1 to enable HIP signal offline logging");
117 const u8 *signal,
int signal_len,
186 return "D/L FW BUFFER";
188 return "PREPARE COREDUMP";
194 return "ERROR: unrecognised command";
198 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
205 if (udi_cli ==
NULL) {
207 unifi_error(priv,
"Too many UDI clients already open\n");
230 unifi_error(priv,
"Unknown HIP client unregister request\n");
289 if (udi_cli ==
NULL) {
291 unifi_error(priv,
"Too many clients already open\n");
296 unifi_trace(priv,
UDBG1,
"Client is registered to /dev/unifiudi%d\n", devno);
306 #ifdef CSR_SME_USERSPACE
312 unifi_info(priv,
"There is already a configuration client using the character device\n");
318 #ifdef CSR_SUPPORT_SME
328 if (udi_cli ==
NULL) {
333 unifi_error(priv,
"Too many clients already open\n");
366 unifi_release(
struct inode *inode,
struct file *filp)
376 unifi_error(priv,
"unifi_close: instance for device not found\n");
385 if (priv->
sme_cli != udi_cli) {
386 unifi_notice(priv,
"Surprise closing config device: not the sme client\n");
388 unifi_notice(priv,
"SME client close (unifi%d)\n", devno);
398 #ifdef CSR_SME_USERSPACE
459 unifi_read(
struct file *filp,
char *
p,
size_t len, loff_t *poff)
481 if (list_empty(&pcli->
udi_log)) {
490 unifi_error(priv,
"unifi_read: wait_event_interruptible failed.");
506 if (logptr ==
NULL) {
507 unifi_error(priv,
"unifi_read: failed to get event.\n");
512 msgptr = &logptr->msg;
563 uint bulk_data_offset = 0;
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",
575 bytecount = signal_size;
581 bulk_data_offset = signal_size;
586 if ((datarefptr+i)->DataLength) {
591 unifi_error(priv,
"udi_send_signal_unpacked: failed to allocate request_data.\n");
612 unifi_error(priv,
"udi_send_signal_unpacked: send failed (%d)\n", r);
653 unsigned int num_data_refs;
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",
675 sig_id, signal_size);
677 memset(&data_ptrs, 0,
sizeof(data_ptrs));
685 bytecount = signal_size;
690 unifi_trace(priv,
UDBG3,
"udi_send_signal_raw: data_ref length = %d\n", len);
697 unifi_error(priv,
"udi_send_signal_raw: failed to allocate request_data.\n");
702 memcpy(dest, buf + bytecount, len);
710 unifi_trace(priv,
UDBG3,
"Queueing signal 0x%.4X from UDI with %u data refs\n",
714 if (bytecount > buflen) {
715 unifi_error(priv,
"udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount);
723 unifi_error(priv,
"udi_send_signal_raw: send failed (%d)\n", r);
728 #ifdef CSR_NATIVE_LINUX
732 #ifdef CSR_SUPPORT_WEXT
734 priv->wext_conf.power_mode = power_mode;
737 if (power_mode || (priv->
interfacePriv[0]->connected == UnifiNotConnected)) {
775 unifi_write(
struct file *filp,
const char *p,
size_t len, loff_t *poff)
809 unsigned char *signal_buf;
814 unifi_error(priv,
"unifi_write: failed to allocate request_data.\n");
819 user_data_buf = (
char*)bulkdata.d[0].os_data_ptr;
823 unifi_error(priv,
"unifi_write: copy from user failed\n");
829 bulkdata.d[1].os_data_ptr =
NULL;
830 bulkdata.d[1].data_length = 0;
837 if ((signal_size <= 0) || (signal_size > len)) {
838 unifi_error(priv,
"unifi_write - Couldn't find length of signal 0x%x\n",
846 sig_id, signal_size);
857 memcpy(signal_buf, bulkdata.d[0].os_data_ptr, signal_size);
858 signal_buf[5] = (pcli->
sender_id >> 8) & 0xff;
860 if (signal_size < len) {
862 bulkdata.d[0].data_length -= signal_size;
863 bulkdata.d[0].os_data_ptr += signal_size;
865 bulkdata.d[0].data_length = 0;
866 bulkdata.d[0].os_data_ptr =
NULL;
872 unifi_error(priv,
"unifi_write: send failed (%d)\n", r);
873 if (bulkdata.d[0].os_data_ptr !=
NULL) {
901 #ifdef CSR_SME_USERSPACE
918 while (remaining > 0)
934 r = udi_send_signal_raw(priv,
bufptr, remaining);
936 r = udi_send_signal_unpacked(priv,
bufptr, remaining);
940 unifi_error(priv,
"unifi_write: (udi or sme)_send_signal() returns %d\n", r);
953 return bytes_written;
957 static const char* build_type_to_string(
unsigned char build_type)
986 unifi_ioctl(
struct file *filp,
unsigned int cmd,
unsigned long arg)
995 #
if (defined CSR_SUPPORT_SME)
997 #if (defined CSR_SUPPORT_WEXT)
999 unsigned char uchar_param;
1023 if (
put_user(int_param, (
int*)arg))
1025 unifi_error(priv,
"UNIFI_GET_UDI_ENABLE: Failed to copy to user\n");
1033 if (
get_user(int_param, (
int*)arg))
1035 unifi_error(priv,
"UNIFI_SET_UDI_ENABLE: Failed to copy from user\n");
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");
1068 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1072 "UNIFI_SET_MIB: Failed to copy in varbind header\n");
1079 "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n",
1086 unifi_error(priv,
"UNIFI_SET_MIB: Failed to copy in varbind\n");
1093 r = sme_mgt_mib_set(priv, varbind, vblen);
1104 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
1107 unifi_error(priv,
"UNIFI_GET_MIB: Failed to copy in varbind header\n");
1113 unifi_error(priv,
"UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n",
1120 unifi_error(priv,
"UNIFI_GET_MIB: Failed to copy in varbind\n");
1126 r = sme_mgt_mib_get(priv, varbind, &vblen);
1133 "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n",
1148 #if (defined CSR_SUPPORT_SME)
1151 unifi_error(priv,
"UNIFI_CFG: Failed to get the command\n");
1189 #ifdef CSR_SUPPORT_SME
1192 unifi_trace(priv,
UDBG2,
"UNIFI_CFG_CORE_DUMP: sent wifi off indication\n");
1195 #ifdef CSR_SUPPORT_WEXT_AP
1197 r= unifi_cfg_set_ap_config(priv,(
unsigned char*)arg);
1201 unifi_error(priv,
"UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd);
1212 unifi_error(priv,
"UNIFI_PUTEST: Failed to get the command\n");
1218 trace_putest_cmdid(putest_cmd));
1219 switch (putest_cmd) {
1254 unifi_error(priv,
"UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd);
1261 unifi_trace(priv,
UDBG2,
"UNIFI_BUILD_TYPE userspace=%s\n", build_type_to_string(*(
unsigned char*)arg));
1262 #ifndef CSR_SUPPORT_WEXT_AP
1265 unifi_error(priv,
"Userspace has AP support, which is incompatible\n");
1269 #ifndef CSR_SUPPORT_WEXT
1272 unifi_error(priv,
"Userspace has WEXT support, which is incompatible\n");
1280 #if defined(CSR_SUPPORT_WEXT) || defined (CSR_NATIVE_LINUX)
1309 unifi_error(priv,
"Failed to register the network device.\n");
1326 #ifdef CSR_SUPPORT_WEXT
1333 #ifdef ANDROID_BUILD
1336 wake_unlock(&unifi_sdio_wake_lock);
1338 #ifdef CSR_NATIVE_SOFTMAC
1341 #ifdef CSR_SUPPORT_WEXT
1342 interfacePriv->wait_netdev_change =
TRUE;
1353 printk(
KERN_ERR "UNIFI_GET_INIT_STATUS: Failed to copy to user\n");
1379 #define UF_MAX_SIG_IDS 128
1381 if (
copy_from_user((
void*)(&udi_filter), (
void*)arg,
sizeof(udi_filter))) {
1389 "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n",
1403 "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n",
1412 sig_ids_addr = udi_filter.
sig_ids;
1421 (
void*)sig_ids_addr,
1430 udi_set_log_filter(pcli, &udi_filter);
1440 if (
get_user(int_param, (
int*)arg))
1442 unifi_error(priv,
"UNIFI_SET_AMP_ENABLE: Failed to copy from user\n");
1454 buf = (
u8*)&int_param;
1457 if (
copy_to_user((
void*)arg, &int_param,
sizeof(
int))) {
1467 if (
copy_from_user((
void*)(&snap_filter), (
void*)arg,
sizeof(snap_filter))) {
1477 if (snap_filter.
count == 0) {
1504 if (
copy_from_user((
void*)(&int_param), (
void*)arg,
sizeof(
int)))
1506 printk(
KERN_ERR "UNIFI_SME_PRESENT: Failed to copy from user\n");
1524 #if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
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");
1535 if (uchar_param == 0) {
1536 r = sme_mgt_coex_config_get(priv, &coexConfig);
1538 unifi_error(priv,
"UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n");
1552 unifi_error(priv,
"UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
1557 coexConfig = coex_config;
1558 r = sme_mgt_coex_config_set(priv, &coexConfig);
1560 unifi_error(priv,
"UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\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");
1579 #ifndef UNIFI_DISABLE_COREDUMP
1586 if (
copy_from_user((
void*)(&dump_req), (
void*)arg,
sizeof(dump_req))) {
1590 memset(&priv_req, 0,
sizeof(priv_req));
1595 switch (dump_req.
space) {
1631 "Dump: %d (seq %d): V:0x%04x (%d) @0x%02x:%04x = 0x%04x\n",
1636 if (
copy_to_user((
void*)arg, (
void*)&dump_req,
sizeof(dump_req))) {
1657 unsigned int mask = 0;
1664 poll_wait(filp, &pcli->
udi_wq, wait);
1720 if (filter_pos == 0xFFFFFFFF)
1723 "Unrecognised signal id (0x%X) specifed in logging filter\n",
1726 pcli->
signal_filter[filter_pos >> 16] |= (filter_pos & 0xFFFF);
1734 if (filter_pos == 0xFFFFFFFF)
1737 "Unrecognised signal id (0x%X) specifed in logging filter\n",
1740 pcli->
signal_filter[filter_pos >> 16] &= ~(filter_pos & 0xFFFF);
1770 const u8 *signal,
int signal_len,
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;
1790 if ((signal ==
NULL) || (signal_len <= 0)) {
1794 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1796 if (log_hip_signals)
1799 if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP)
1802 unifi_debug_log_to_buf(
"T:");
1803 unifi_debug_log_to_buf(
"%04X%04X ", *(((
u16*)×tamp) + 1),
1808 unifi_debug_log_to_buf(
"S%s:%04X R:%04X D:%04X ",
1811 *(
u16*)(signal + 2),
1812 *(
u16*)(signal + 4));
1813 unifi_debug_hex_to_buf(signal + 6, signal_len - 6);
1816 if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) &&
1819 unifi_debug_log_to_buf(
"\nD:");
1822 unifi_debug_log_to_buf(
"\n");
1828 #ifdef CSR_NATIVE_LINUX
1838 if ((filter_pos != 0xFFFFFFFF) &&
1839 ((pcli->
signal_filter[filter_pos >> 16] & (filter_pos & 0xFFFF)) == 0))
1847 total_len = signal_len;
1855 if (logptr ==
NULL) {
1857 "Failed to allocate %lu bytes for a UDI log record\n",
1858 (
long unsigned int)(
sizeof(
udi_log_t) + total_len));
1863 INIT_LIST_HEAD(&logptr->
q);
1864 msgptr = &logptr->
msg;
1866 #ifdef OMNICLI_LINUX_EXTRA_LOG
1868 nanosec_rem =
do_div(t, 1000000000);
1869 n_1000 = nanosec_rem/1000;
1870 msgptr->
timestamp = (t <<10 ) | ((unsigned long)(n_1000 >> 10) & 0x3ff);
1878 p = (
u8 *)(msgptr + 1);
1879 memcpy(p, signal, signal_len);
1916 #ifdef CSR_SME_USERSPACE
1927 if ((buffer ==
NULL) || (length <= 0)) {
1933 if (logptr ==
NULL) {
1934 unifi_error(priv,
"Failed to allocate %d bytes for an SME message\n",
1941 INIT_LIST_HEAD(&logptr->
q);
1942 msgptr = &logptr->
msg;
1947 p = (
u8 *)(msgptr + 1);
1948 memcpy(p, buffer, length);
1956 unifi_info(priv,
"Message for the SME dropped, SME has gone away\n");
1988 .release = unifi_release,
1990 .write = unifi_write,
1991 .unlocked_ioctl = unifi_ioctl,
1995 static dev_t unifi_first_devno;
1996 static struct class *unifi_class;
2010 MINOR(unifi_first_devno) + (bus_id * 2));
2016 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2018 devno, priv,
"unifi%d", bus_id)) {
2021 devno, priv,
"unifi%d", bus_id);
2035 MINOR(unifi_first_devno) + (bus_id * 2) + 1);
2044 #ifdef SDIO_EXPORTS_STRUCT_DEVICE
2049 devno, priv,
"unifiudi%d", bus_id)) {
2098 if (IS_ERR(unifi_class)) {
2103 unifi_first_devno = 0;
2124 uf_remove_debug_device(
void)
2131 unifi_first_devno = 0;
2148 printk(
"UniFi SDIO Driver: %s %s %s\n",
2150 __DATE__, __TIME__);
2152 #ifdef CSR_SME_USERSPACE
2153 #ifdef CSR_SUPPORT_WEXT
2154 printk(
"CSR SME with WEXT support\n");
2156 printk(
"CSR SME no WEXT support\n");
2160 #ifdef CSR_NATIVE_LINUX
2161 #ifdef CSR_SUPPORT_WEXT
2162 #error WEXT unsupported in the native driver
2164 printk(
"CSR native no WEXT support\n");
2166 #ifdef CSR_WIFI_SPLIT_PATCH
2167 printk(
"Split patch support\n");
2169 printk(
"Kernel %d.%d.%d\n",
2170 ((LINUX_VERSION_CODE) >> 16) & 0xff,
2171 ((LINUX_VERSION_CODE) >> 8) & 0xff,
2172 (LINUX_VERSION_CODE) & 0xff);
2179 r = uf_create_debug_device(&unifi_fops);
2187 uf_remove_debug_device();
2225 uf_remove_debug_device();