Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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