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.7-rc3 1147 lines 32 kB view raw
1/* 2 * --------------------------------------------------------------------------- 3 * FILE: io.c 4 * 5 * PURPOSE: 6 * This file contains routines that the SDIO driver can call when a 7 * UniFi card is first inserted (or detected) and removed. 8 * 9 * When used with sdioemb, the udev scripts (at least on Ubuntu) don't 10 * recognise a UniFi being added to the system. This is because sdioemb 11 * does not register itself as a device_driver, it uses it's own code 12 * to handle insert and remove. 13 * To have Ubuntu recognise UniFi, edit /etc/udev/rules.d/85-ifupdown.rules 14 * to change this line: 15 * SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start" 16 * to these: 17 * #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start" 18 * SUBSYSTEM=="net", GOTO="net_start" 19 * 20 * Then you can add a stanza to /etc/network/interfaces like this: 21 * auto eth1 22 * iface eth1 inet dhcp 23 * wpa-conf /etc/wpa_supplicant.conf 24 * This will then automatically associate when a car dis inserted. 25 * 26 * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd. 27 * 28 * Refer to LICENSE.txt included with this source code for details on 29 * the license terms. 30 * 31 * --------------------------------------------------------------------------- 32 */ 33#include <linux/proc_fs.h> 34#include <linux/version.h> 35 36#include "csr_wifi_hip_unifi.h" 37#include "csr_wifi_hip_unifiversion.h" 38#include "csr_wifi_hip_unifi_udi.h" /* for unifi_print_status() */ 39#include "unifiio.h" 40#include "unifi_priv.h" 41 42/* 43 * Array of pointers to context structs for unifi devices that are present. 44 * The index in the array corresponds to the wlan interface number 45 * (if "wlan*" is used). If "eth*" is used, the eth* numbers are allocated 46 * after any Ethernet cards. 47 * 48 * The Arasan PCI-SDIO controller card supported by this driver has 2 slots, 49 * hence a max of 2 devices. 50 */ 51static unifi_priv_t *Unifi_instances[MAX_UNIFI_DEVS]; 52 53/* Array of pointers to netdev objects used by the UniFi driver, as there 54 * are now many per instance. This is used to determine which netdev events 55 * are for UniFi as opposed to other net interfaces. 56 */ 57static netInterface_priv_t *Unifi_netdev_instances[MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES]; 58 59/* 60 * Array to hold the status of each unifi device in each slot. 61 * We only process an insert event when In_use[] for the slot is 62 * UNIFI_DEV_NOT_IN_USE. Otherwise, it means that the slot is in use or 63 * we are in the middle of a cleanup (the action on unplug). 64 */ 65#define UNIFI_DEV_NOT_IN_USE 0 66#define UNIFI_DEV_IN_USE 1 67#define UNIFI_DEV_CLEANUP 2 68static int In_use[MAX_UNIFI_DEVS]; 69/* 70 * Mutex to prevent UDI clients to open the character device before the priv 71 * is created and initialised. 72 */ 73DEFINE_SEMAPHORE(Unifi_instance_mutex); 74/* 75 * When the device is removed, unregister waits on Unifi_cleanup_wq 76 * until all the UDI clients release the character device. 77 */ 78DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq); 79 80 81static int uf_read_proc(char *page, char **start, off_t offset, int count, 82 int *eof, void *data); 83 84#ifdef CSR_WIFI_RX_PATH_SPLIT 85 86static CsrResult signal_buffer_init(unifi_priv_t * priv, int size) 87{ 88 int i; 89 func_enter(); 90 91 priv->rxSignalBuffer.writePointer = 92 priv->rxSignalBuffer.readPointer = 0; 93 priv->rxSignalBuffer.size = size; 94 /* Allocating Memory for Signal primitive pointer */ 95 for(i=0; i<size; i++) 96 { 97 priv->rxSignalBuffer.rx_buff[i].sig_len=0; 98 priv->rxSignalBuffer.rx_buff[i].bufptr = kmalloc(UNIFI_PACKED_SIGBUF_SIZE, GFP_KERNEL); 99 if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL) 100 { 101 int j; 102 unifi_error(priv,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n"); 103 for(j=0;j<i;j++) 104 { 105 priv->rxSignalBuffer.rx_buff[j].sig_len=0; 106 kfree(priv->rxSignalBuffer.rx_buff[j].bufptr); 107 priv->rxSignalBuffer.rx_buff[j].bufptr = NULL; 108 } 109 func_exit(); 110 return -1; 111 } 112 } 113 func_exit(); 114 return 0; 115} 116 117 118static void signal_buffer_free(unifi_priv_t * priv, int size) 119{ 120 int i; 121 122 for(i=0; i<size; i++) 123 { 124 priv->rxSignalBuffer.rx_buff[i].sig_len=0; 125 kfree(priv->rxSignalBuffer.rx_buff[i].bufptr); 126 priv->rxSignalBuffer.rx_buff[i].bufptr = NULL; 127 } 128} 129#endif 130/* 131 * --------------------------------------------------------------------------- 132 * uf_register_netdev 133 * 134 * Registers the network interface, installes the qdisc, 135 * and registers the inet handler. 136 * In the porting exercise, register the driver to the network 137 * stack if necessary. 138 * 139 * Arguments: 140 * priv Pointer to driver context. 141 * 142 * Returns: 143 * O on success, non-zero otherwise. 144 * 145 * Notes: 146 * We will only unregister when the card is ejected, so we must 147 * only do it once. 148 * --------------------------------------------------------------------------- 149 */ 150int 151uf_register_netdev(unifi_priv_t *priv, int interfaceTag) 152{ 153 int r; 154 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; 155 156 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { 157 unifi_error(priv, "uf_register_netdev bad interfaceTag\n"); 158 return -EINVAL; 159 } 160 161 /* 162 * Allocates a device number and registers device with the network 163 * stack. 164 */ 165 unifi_trace(priv, UDBG5, "uf_register_netdev: netdev %d - 0x%p\n", 166 interfaceTag, priv->netdev[interfaceTag]); 167 r = register_netdev(priv->netdev[interfaceTag]); 168 if (r) { 169 unifi_error(priv, "Failed to register net device\n"); 170 return -EINVAL; 171 } 172 173 /* The device is registed */ 174 interfacePriv->netdev_registered = 1; 175 176#ifdef CSR_SUPPORT_SME 177 /* 178 * Register the inet handler; it notifies us for changes in the IP address. 179 */ 180 uf_register_inet_notifier(); 181#endif /* CSR_SUPPORT_SME */ 182 183 unifi_notice(priv, "unifi%d is %s\n", 184 priv->instance, priv->netdev[interfaceTag]->name); 185 186 return 0; 187} /* uf_register_netdev */ 188 189 190/* 191 * --------------------------------------------------------------------------- 192 * uf_unregister_netdev 193 * 194 * Unregisters the network interface and the inet handler. 195 * 196 * Arguments: 197 * priv Pointer to driver context. 198 * 199 * Returns: 200 * None. 201 * 202 * --------------------------------------------------------------------------- 203 */ 204void 205uf_unregister_netdev(unifi_priv_t *priv) 206{ 207 int i=0; 208 209#ifdef CSR_SUPPORT_SME 210 /* Unregister the inet handler... */ 211 uf_unregister_inet_notifier(); 212#endif /* CSR_SUPPORT_SME */ 213 214 for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) { 215 netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; 216 if (interfacePriv->netdev_registered) { 217 unifi_trace(priv, UDBG5, 218 "uf_unregister_netdev: netdev %d - 0x%p\n", 219 i, priv->netdev[i]); 220 221 /* ... and the netdev */ 222 unregister_netdev(priv->netdev[i]); 223 interfacePriv->netdev_registered = 0; 224 } 225 226 interfacePriv->interfaceMode = 0; 227 228 /* Enable all queues by default */ 229 interfacePriv->queueEnabled[0] = 1; 230 interfacePriv->queueEnabled[1] = 1; 231 interfacePriv->queueEnabled[2] = 1; 232 interfacePriv->queueEnabled[3] = 1; 233 } 234 235 priv->totalInterfaceCount = 0; 236} /* uf_unregister_netdev() */ 237 238 239/* 240 * --------------------------------------------------------------------------- 241 * register_unifi_sdio 242 * 243 * This function is called from the Probe (or equivalent) method of 244 * the SDIO driver when a UniFi card is detected. 245 * We allocate the Linux net_device struct, initialise the HIP core 246 * lib, create the char device nodes and start the userspace helper 247 * to initialise the device. 248 * 249 * Arguments: 250 * sdio_dev Pointer to SDIO context handle to use for all 251 * SDIO ops. 252 * bus_id A small number indicating the SDIO card position on the 253 * bus. Typically this is the slot number, e.g. 0, 1 etc. 254 * Valid values are 0 to MAX_UNIFI_DEVS-1. 255 * dev Pointer to kernel device manager struct. 256 * 257 * Returns: 258 * Pointer to the unifi instance, or NULL on error. 259 * --------------------------------------------------------------------------- 260 */ 261static unifi_priv_t * 262register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) 263{ 264 unifi_priv_t *priv = NULL; 265 int r = -1; 266 CsrResult csrResult; 267 268 func_enter(); 269 270 if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { 271 unifi_error(priv, "register_unifi_sdio: invalid device %d\n", 272 bus_id); 273 return NULL; 274 } 275 276 down(&Unifi_instance_mutex); 277 278 if (In_use[bus_id] != UNIFI_DEV_NOT_IN_USE) { 279 unifi_error(priv, "register_unifi_sdio: device %d is already in use\n", 280 bus_id); 281 goto failed0; 282 } 283 284 285 /* Allocate device private and net_device structs */ 286 priv = uf_alloc_netdevice(sdio_dev, bus_id); 287 if (priv == NULL) { 288 unifi_error(priv, "Failed to allocate driver private\n"); 289 goto failed0; 290 } 291 292 priv->unifi_device = dev; 293 294 SET_NETDEV_DEV(priv->netdev[0], dev); 295 296 /* We are not ready to send data yet. */ 297 netif_carrier_off(priv->netdev[0]); 298 299 /* Allocate driver context. */ 300 priv->card = unifi_alloc_card(priv->sdio, priv); 301 if (priv->card == NULL) { 302 unifi_error(priv, "Failed to allocate UniFi driver card struct.\n"); 303 goto failed1; 304 } 305 306 if (Unifi_instances[bus_id]) { 307 unifi_error(priv, "Internal error: instance for slot %d is already taken\n", 308 bus_id); 309 } 310 Unifi_instances[bus_id] = priv; 311 In_use[bus_id] = UNIFI_DEV_IN_USE; 312 313 /* Save the netdev_priv for use by the netdev event callback mechanism */ 314 Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES] = netdev_priv(priv->netdev[0]); 315 316 /* Initialise the mini-coredump capture buffers */ 317 csrResult = unifi_coredump_init(priv->card, (u16)coredump_max); 318 if (csrResult != CSR_RESULT_SUCCESS) { 319 unifi_error(priv, "Couldn't allocate mini-coredump buffers\n"); 320 } 321 322 /* Create the character device nodes */ 323 r = uf_create_device_nodes(priv, bus_id); 324 if (r) { 325 goto failed1; 326 } 327 328 /* 329 * We use the slot number as unifi device index. 330 */ 331 scnprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance); 332 /* 333 * The following complex casting is in place in order to eliminate 64-bit compilation warning 334 * "cast to/from pointer from/to integer of different size" 335 */ 336 if (!create_proc_read_entry(priv->proc_entry_name, 0, 0, 337 uf_read_proc, (void *)(long)priv->instance)) 338 { 339 unifi_error(priv, "unifi: can't create /proc/driver/unifi\n"); 340 } 341 342 /* Allocate the net_device for interfaces other than 0. */ 343 { 344 int i; 345 priv->totalInterfaceCount =0; 346 347 for(i=1;i<CSR_WIFI_NUM_INTERFACES;i++) 348 { 349 if( !uf_alloc_netdevice_for_other_interfaces(priv,i) ) 350 { 351 /* error occured while allocating the net_device for interface[i]. The net_device are 352 * allocated for the interfaces with id<i. Dont worry, all the allocated net_device will 353 * be releasing chen the control goes to the label failed0. 354 */ 355 unifi_error(priv, "Failed to allocate driver private for interface[%d]\n",i); 356 goto failed0; 357 } 358 else 359 { 360 SET_NETDEV_DEV(priv->netdev[i], dev); 361 362 /* We are not ready to send data yet. */ 363 netif_carrier_off(priv->netdev[i]); 364 365 /* Save the netdev_priv for use by the netdev event callback mechanism */ 366 Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES + i] = netdev_priv(priv->netdev[i]); 367 } 368 } 369 370 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++) 371 { 372 netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; 373 interfacePriv->netdev_registered=0; 374 } 375 } 376 377#ifdef CSR_WIFI_RX_PATH_SPLIT 378 if (signal_buffer_init(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE)) 379 { 380 unifi_error(priv,"Failed to allocate shared memory for T-H signals\n"); 381 goto failed2; 382 } 383 priv->rx_workqueue = create_singlethread_workqueue("rx_workq"); 384 if (priv->rx_workqueue == NULL) { 385 unifi_error(priv,"create_singlethread_workqueue failed \n"); 386 goto failed3; 387 } 388 INIT_WORK(&priv->rx_work_struct, rx_wq_handler); 389#endif 390 391#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE 392 if (log_hip_signals) 393 { 394 uf_register_hip_offline_debug(priv); 395 } 396#endif 397 398 /* Initialise the SME related threads and parameters */ 399 r = uf_sme_init(priv); 400 if (r) { 401 unifi_error(priv, "SME initialisation failed.\n"); 402 goto failed4; 403 } 404 405 /* 406 * Run the userspace helper program (unififw) to perform 407 * the device initialisation. 408 */ 409 unifi_trace(priv, UDBG1, "run UniFi helper app...\n"); 410 r = uf_run_unifihelper(priv); 411 if (r) { 412 unifi_notice(priv, "unable to run UniFi helper app\n"); 413 /* Not a fatal error. */ 414 } 415 416 up(&Unifi_instance_mutex); 417 418 func_exit(); 419 return priv; 420 421failed4: 422#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE 423if (log_hip_signals) 424{ 425 uf_unregister_hip_offline_debug(priv); 426} 427#endif 428#ifdef CSR_WIFI_RX_PATH_SPLIT 429 flush_workqueue(priv->rx_workqueue); 430 destroy_workqueue(priv->rx_workqueue); 431failed3: 432 signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE); 433failed2: 434#endif 435 /* Remove the device nodes */ 436 uf_destroy_device_nodes(priv); 437failed1: 438 /* Deregister priv->netdev_client */ 439 ul_deregister_client(priv->netdev_client); 440 441failed0: 442 if (priv && priv->card) { 443 unifi_coredump_free(priv->card); 444 unifi_free_card(priv->card); 445 } 446 if (priv) { 447 uf_free_netdevice(priv); 448 } 449 450 up(&Unifi_instance_mutex); 451 452 func_exit(); 453 return NULL; 454} /* register_unifi_sdio() */ 455 456 457/* 458 * --------------------------------------------------------------------------- 459 * ask_unifi_sdio_cleanup 460 * 461 * We can not free our private context, until all the char device 462 * clients have closed the file handles. unregister_unifi_sdio() which 463 * is called when a card is removed, waits on Unifi_cleanup_wq until 464 * the reference count becomes zero. It is time to wake it up now. 465 * 466 * Arguments: 467 * priv Pointer to driver context. 468 * 469 * Returns: 470 * None. 471 * --------------------------------------------------------------------------- 472 */ 473static void 474ask_unifi_sdio_cleanup(unifi_priv_t *priv) 475{ 476 func_enter(); 477 478 /* 479 * Now clear the flag that says the old instance is in use. 480 * This is used to prevent a new instance being started before old 481 * one has finshed closing down, for example if bounce makes the card 482 * appear to be ejected and re-inserted quickly. 483 */ 484 In_use[priv->instance] = UNIFI_DEV_CLEANUP; 485 486 unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n"); 487 wake_up(&Unifi_cleanup_wq); 488 489 func_exit(); 490 491} /* ask_unifi_sdio_cleanup() */ 492 493 494/* 495 * --------------------------------------------------------------------------- 496 * cleanup_unifi_sdio 497 * 498 * Release any resources owned by a unifi instance. 499 * 500 * Arguments: 501 * priv Pointer to the instance to free. 502 * 503 * Returns: 504 * None. 505 * --------------------------------------------------------------------------- 506 */ 507static void 508cleanup_unifi_sdio(unifi_priv_t *priv) 509{ 510 int priv_instance; 511 int i; 512 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; 513 514 func_enter(); 515 516 /* Remove the device nodes */ 517 uf_destroy_device_nodes(priv); 518 519 /* Mark this device as gone away by NULLing the entry in Unifi_instances */ 520 Unifi_instances[priv->instance] = NULL; 521 522 unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: remove_proc_entry\n"); 523 /* 524 * Free the children of priv before unifi_free_netdevice() frees 525 * the priv struct 526 */ 527 remove_proc_entry(priv->proc_entry_name, 0); 528 529 530 /* Unregister netdev as a client. */ 531 if (priv->netdev_client) { 532 unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is unregistered\n", 533 priv->netdev_client->client_id, priv->netdev_client->sender_id); 534 ul_deregister_client(priv->netdev_client); 535 } 536 537 /* Destroy the SME related threads and parameters */ 538 uf_sme_deinit(priv); 539 540#ifdef CSR_SME_USERSPACE 541 priv->smepriv = NULL; 542#endif 543 544#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE 545 if (log_hip_signals) 546 { 547 uf_unregister_hip_offline_debug(priv); 548 } 549#endif 550 551 /* Free any packets left in the Rx queues */ 552 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++) 553 { 554 uf_free_pending_rx_packets(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address,i); 555 uf_free_pending_rx_packets(priv, UF_CONTROLLED_PORT_Q, broadcast_address,i); 556 } 557 /* 558 * We need to free the resources held by the core, which include tx skbs, 559 * otherwise we can not call unregister_netdev(). 560 */ 561 if (priv->card) { 562 unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: free card\n"); 563 unifi_coredump_free(priv->card); 564 unifi_free_card(priv->card); 565 priv->card = NULL; 566 } 567 568 /* 569 * Unregister the network device. 570 * We can not unregister the netdev before we release 571 * all pending packets in the core. 572 */ 573 uf_unregister_netdev(priv); 574 priv->totalInterfaceCount = 0; 575 576 /* Clear the table of registered netdev_priv's */ 577 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { 578 Unifi_netdev_instances[priv->instance * CSR_WIFI_NUM_INTERFACES + i] = NULL; 579 } 580 581 unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: uf_free_netdevice\n"); 582 /* 583 * When uf_free_netdevice() returns, the priv is invalid 584 * so we need to remember the instance to clear the global flag later. 585 */ 586 priv_instance = priv->instance; 587 588#ifdef CSR_WIFI_RX_PATH_SPLIT 589 flush_workqueue(priv->rx_workqueue); 590 destroy_workqueue(priv->rx_workqueue); 591 signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE); 592#endif 593 594 /* Priv is freed as part of the net_device */ 595 uf_free_netdevice(priv); 596 597 /* 598 * Now clear the flag that says the old instance is in use. 599 * This is used to prevent a new instance being started before old 600 * one has finshed closing down, for example if bounce makes the card 601 * appear to be ejected and re-inserted quickly. 602 */ 603 In_use[priv_instance] = UNIFI_DEV_NOT_IN_USE; 604 605 unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n"); 606 607 func_exit(); 608 609} /* cleanup_unifi_sdio() */ 610 611 612/* 613 * --------------------------------------------------------------------------- 614 * unregister_unifi_sdio 615 * 616 * Call from SDIO driver when it detects that UniFi has been removed. 617 * 618 * Arguments: 619 * bus_id Number of the card that was ejected. 620 * 621 * Returns: 622 * None. 623 * --------------------------------------------------------------------------- 624 */ 625static void 626unregister_unifi_sdio(int bus_id) 627{ 628 unifi_priv_t *priv; 629 int interfaceTag=0; 630 u8 reason = CONFIG_IND_EXIT; 631 632 if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { 633 unifi_error(NULL, "unregister_unifi_sdio: invalid device %d\n", 634 bus_id); 635 return; 636 } 637 638 priv = Unifi_instances[bus_id]; 639 if (priv == NULL) { 640 unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n", 641 bus_id); 642 func_exit(); 643 return; 644 } 645 646 /* Stop the network traffic before freeing the core. */ 647 for(interfaceTag=0;interfaceTag<priv->totalInterfaceCount;interfaceTag++) 648 { 649 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; 650 if(interfacePriv->netdev_registered) 651 { 652 netif_carrier_off(priv->netdev[interfaceTag]); 653 netif_tx_stop_all_queues(priv->netdev[interfaceTag]); 654 } 655 } 656 657#ifdef CSR_NATIVE_LINUX 658 /* 659 * If the unifi thread was started, signal it to stop. This 660 * should cause any userspace processes with open unifi device to 661 * close them. 662 */ 663 uf_stop_thread(priv, &priv->bh_thread); 664 665 /* Unregister the interrupt handler */ 666 if (csr_sdio_linux_remove_irq(priv->sdio)) { 667 unifi_notice(priv, 668 "csr_sdio_linux_remove_irq failed to talk to card.\n"); 669 } 670 671 /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */ 672 uf_abort_mlme(priv); 673#endif /* CSR_NATIVE_LINUX */ 674 675 ul_log_config_ind(priv, &reason, sizeof(u8)); 676 677 /* Deregister the UDI hook from the core. */ 678 unifi_remove_udi_hook(priv->card, logging_handler); 679 680 uf_put_instance(bus_id); 681 682 /* 683 * Wait until the device is cleaned up. i.e., when all userspace 684 * processes have closed any open unifi devices. 685 */ 686 wait_event(Unifi_cleanup_wq, In_use[bus_id] == UNIFI_DEV_CLEANUP); 687 unifi_trace(NULL, UDBG5, "Received clean up event\n"); 688 689 /* Now we can free the private context and the char device nodes */ 690 cleanup_unifi_sdio(priv); 691 692} /* unregister_unifi_sdio() */ 693 694 695/* 696 * --------------------------------------------------------------------------- 697 * uf_find_instance 698 * 699 * Find the context structure for a given UniFi device instance. 700 * 701 * Arguments: 702 * inst The instance number to look for. 703 * 704 * Returns: 705 * None. 706 * --------------------------------------------------------------------------- 707 */ 708unifi_priv_t * 709uf_find_instance(int inst) 710{ 711 if ((inst < 0) || (inst >= MAX_UNIFI_DEVS)) { 712 return NULL; 713 } 714 return Unifi_instances[inst]; 715} /* uf_find_instance() */ 716 717 718/* 719 * --------------------------------------------------------------------------- 720 * uf_find_priv 721 * 722 * Find the device instance for a given context structure. 723 * 724 * Arguments: 725 * priv The context structure pointer to look for. 726 * 727 * Returns: 728 * index of instance, -1 otherwise. 729 * --------------------------------------------------------------------------- 730 */ 731int 732uf_find_priv(unifi_priv_t *priv) 733{ 734 int inst; 735 736 if (!priv) { 737 return -1; 738 } 739 740 for (inst = 0; inst < MAX_UNIFI_DEVS; inst++) { 741 if (Unifi_instances[inst] == priv) { 742 return inst; 743 } 744 } 745 746 return -1; 747} /* uf_find_priv() */ 748 749/* 750 * --------------------------------------------------------------------------- 751 * uf_find_netdev_priv 752 * 753 * Find the device instance for a given netdev context structure. 754 * 755 * Arguments: 756 * priv The context structure pointer to look for. 757 * 758 * Returns: 759 * index of instance, -1 otherwise. 760 * --------------------------------------------------------------------------- 761 */ 762int 763uf_find_netdev_priv(netInterface_priv_t *priv) 764{ 765 int inst; 766 767 if (!priv) { 768 return -1; 769 } 770 771 for (inst = 0; inst < MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES; inst++) { 772 if (Unifi_netdev_instances[inst] == priv) { 773 return inst; 774 } 775 } 776 777 return -1; 778} /* uf_find_netdev_priv() */ 779 780/* 781 * --------------------------------------------------------------------------- 782 * uf_get_instance 783 * 784 * Find the context structure for a given UniFi device instance 785 * and increment the reference count. 786 * 787 * Arguments: 788 * inst The instance number to look for. 789 * 790 * Returns: 791 * Pointer to the instance or NULL if no instance exists. 792 * --------------------------------------------------------------------------- 793 */ 794unifi_priv_t * 795uf_get_instance(int inst) 796{ 797 unifi_priv_t *priv; 798 799 down(&Unifi_instance_mutex); 800 801 priv = uf_find_instance(inst); 802 if (priv) { 803 priv->ref_count++; 804 } 805 806 up(&Unifi_instance_mutex); 807 808 return priv; 809} 810 811/* 812 * --------------------------------------------------------------------------- 813 * uf_put_instance 814 * 815 * Decrement the context reference count, freeing resources and 816 * shutting down the driver when the count reaches zero. 817 * 818 * Arguments: 819 * inst The instance number to look for. 820 * 821 * Returns: 822 * Pointer to the instance or NULL if no instance exists. 823 * --------------------------------------------------------------------------- 824 */ 825void 826uf_put_instance(int inst) 827{ 828 unifi_priv_t *priv; 829 830 down(&Unifi_instance_mutex); 831 832 priv = uf_find_instance(inst); 833 if (priv) { 834 priv->ref_count--; 835 if (priv->ref_count == 0) { 836 ask_unifi_sdio_cleanup(priv); 837 } 838 } 839 840 up(&Unifi_instance_mutex); 841} 842 843 844/* 845 * --------------------------------------------------------------------------- 846 * uf_read_proc 847 * 848 * Read method for driver node in /proc/driver/unifi0 849 * 850 * Arguments: 851 * page 852 * start 853 * offset 854 * count 855 * eof 856 * data 857 * 858 * Returns: 859 * None. 860 * --------------------------------------------------------------------------- 861 */ 862#ifdef CONFIG_PROC_FS 863static int 864uf_read_proc(char *page, char **start, off_t offset, int count, 865 int *eof, void *data) 866{ 867#define UNIFI_DEBUG_TXT_BUFFER 8*1024 868 unifi_priv_t *priv; 869 int actual_amount_to_copy; 870 char *p, *orig_p; 871 s32 remain = UNIFI_DEBUG_TXT_BUFFER; 872 s32 written; 873 int i; 874 875 /* 876 * The following complex casting is in place in order to eliminate 64-bit compilation warning 877 * "cast to/from pointer from/to integer of different size" 878 */ 879 priv = uf_find_instance((int)(long)data); 880 if (!priv) { 881 return 0; 882 } 883 884 p = kmalloc( UNIFI_DEBUG_TXT_BUFFER, GFP_KERNEL ); 885 886 orig_p = p; 887 888 written = scnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n", 889 CSR_WIFI_VERSION, __DATE__, __TIME__); 890 UNIFI_SNPRINTF_RET(p, remain, written); 891#ifdef CSR_SME_USERSPACE 892 written = scnprintf(p, remain, "SME: CSR userspace "); 893 UNIFI_SNPRINTF_RET(p, remain, written); 894#ifdef CSR_SUPPORT_WEXT 895 written = scnprintf(p, remain, "with WEXT support\n"); 896#else 897 written = scnprintf(p, remain, "\n"); 898#endif /* CSR_SUPPORT_WEXT */ 899 UNIFI_SNPRINTF_RET(p, remain, written); 900#endif /* CSR_SME_USERSPACE */ 901#ifdef CSR_NATIVE_LINUX 902 written = scnprintf(p, remain, "SME: native\n"); 903 UNIFI_SNPRINTF_RET(p, remain, written); 904#endif 905 906#ifdef CSR_SUPPORT_SME 907 written = scnprintf(p, remain, 908 "Firmware (ROM) build:%u, Patch:%u\n", 909 priv->card_info.fw_build, 910 priv->sme_versions.firmwarePatch); 911 UNIFI_SNPRINTF_RET(p, remain, written); 912#endif 913 p += unifi_print_status(priv->card, p, &remain); 914 915 written = scnprintf(p, remain, "Last dbg str: %s\n", 916 priv->last_debug_string); 917 UNIFI_SNPRINTF_RET(p, remain, written); 918 919 written = scnprintf(p, remain, "Last dbg16:"); 920 UNIFI_SNPRINTF_RET(p, remain, written); 921 for (i = 0; i < 8; i++) { 922 written = scnprintf(p, remain, " %04X", 923 priv->last_debug_word16[i]); 924 UNIFI_SNPRINTF_RET(p, remain, written); 925 } 926 written = scnprintf(p, remain, "\n"); 927 UNIFI_SNPRINTF_RET(p, remain, written); 928 written = scnprintf(p, remain, " "); 929 UNIFI_SNPRINTF_RET(p, remain, written); 930 for (; i < 16; i++) { 931 written = scnprintf(p, remain, " %04X", 932 priv->last_debug_word16[i]); 933 UNIFI_SNPRINTF_RET(p, remain, written); 934 } 935 written = scnprintf(p, remain, "\n"); 936 UNIFI_SNPRINTF_RET(p, remain, written); 937 *start = page; 938 939 written = UNIFI_DEBUG_TXT_BUFFER - remain; 940 941 if( offset >= written ) 942 { 943 *eof = 1; 944 kfree( orig_p ); 945 return(0); 946 } 947 948 if( offset + count > written ) 949 { 950 actual_amount_to_copy = written - offset; 951 *eof = 1; 952 } 953 else 954 { 955 actual_amount_to_copy = count; 956 } 957 958 memcpy( page, &(orig_p[offset]), actual_amount_to_copy ); 959 960 kfree( orig_p ); 961 962 return( actual_amount_to_copy ); 963} /* uf_read_proc() */ 964#endif 965 966 967 968 969static void 970uf_lx_suspend(CsrSdioFunction *sdio_ctx) 971{ 972 unifi_priv_t *priv = sdio_ctx->driverData; 973 unifi_suspend(priv); 974 975 CsrSdioSuspendAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); 976} 977 978static void 979uf_lx_resume(CsrSdioFunction *sdio_ctx) 980{ 981 unifi_priv_t *priv = sdio_ctx->driverData; 982 unifi_resume(priv); 983 984 CsrSdioResumeAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); 985} 986 987static int active_slot = MAX_UNIFI_DEVS; 988static struct device *os_devices[MAX_UNIFI_DEVS]; 989 990void 991uf_add_os_device(int bus_id, struct device *os_device) 992{ 993 if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { 994 unifi_error(NULL, "uf_add_os_device: invalid device %d\n", 995 bus_id); 996 return; 997 } 998 999 active_slot = bus_id; 1000 os_devices[bus_id] = os_device; 1001} /* uf_add_os_device() */ 1002 1003void 1004uf_remove_os_device(int bus_id) 1005{ 1006 if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { 1007 unifi_error(NULL, "uf_remove_os_device: invalid device %d\n", 1008 bus_id); 1009 return; 1010 } 1011 1012 active_slot = bus_id; 1013 os_devices[bus_id] = NULL; 1014} /* uf_remove_os_device() */ 1015 1016static void 1017uf_sdio_inserted(CsrSdioFunction *sdio_ctx) 1018{ 1019 unifi_priv_t *priv; 1020 1021 unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n", 1022 sdio_ctx, active_slot, os_devices[active_slot]); 1023 1024 priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]); 1025 if (priv == NULL) { 1026 CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE); 1027 return; 1028 } 1029 1030 sdio_ctx->driverData = priv; 1031 1032 CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); 1033} /* uf_sdio_inserted() */ 1034 1035 1036static void 1037uf_sdio_removed(CsrSdioFunction *sdio_ctx) 1038{ 1039 unregister_unifi_sdio(active_slot); 1040 CsrSdioRemovedAcknowledge(sdio_ctx); 1041} /* uf_sdio_removed() */ 1042 1043 1044static void 1045uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx) 1046{ 1047 unifi_priv_t *priv = sdio_ctx->driverData; 1048 1049 unifi_sdio_interrupt_handler(priv->card); 1050} /* uf_sdio_dsr_handler() */ 1051 1052/* 1053 * --------------------------------------------------------------------------- 1054 * uf_sdio_int_handler 1055 * 1056 * Interrupt callback function for SDIO interrupts. 1057 * This is called in kernel context (i.e. not interrupt context). 1058 * We retrieve the unifi context pointer and call the main UniFi 1059 * interrupt handler. 1060 * 1061 * Arguments: 1062 * fdev SDIO context pointer 1063 * 1064 * Returns: 1065 * None. 1066 * --------------------------------------------------------------------------- 1067 */ 1068static CsrSdioInterruptDsrCallback 1069uf_sdio_int_handler(CsrSdioFunction *sdio_ctx) 1070{ 1071 return uf_sdio_dsr_handler; 1072} /* uf_sdio_int_handler() */ 1073 1074 1075 1076 1077static CsrSdioFunctionId unifi_ids[] = 1078{ 1079 { 1080 .manfId = SDIO_MANF_ID_CSR, 1081 .cardId = SDIO_CARD_ID_UNIFI_3, 1082 .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3, 1083 .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, 1084 }, 1085 { 1086 .manfId = SDIO_MANF_ID_CSR, 1087 .cardId = SDIO_CARD_ID_UNIFI_4, 1088 .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4, 1089 .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, 1090 } 1091}; 1092 1093 1094/* 1095 * Structure to register with the glue layer. 1096 */ 1097static CsrSdioFunctionDriver unifi_sdioFunction_drv = 1098{ 1099 .inserted = uf_sdio_inserted, 1100 .removed = uf_sdio_removed, 1101 .intr = uf_sdio_int_handler, 1102 .suspend = uf_lx_suspend, 1103 .resume = uf_lx_resume, 1104 1105 .ids = unifi_ids, 1106 .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0]) 1107}; 1108 1109 1110/* 1111 * --------------------------------------------------------------------------- 1112 * uf_sdio_load 1113 * uf_sdio_unload 1114 * 1115 * These functions are called from the main module load and unload 1116 * functions. They perform the appropriate operations for the monolithic 1117 * driver. 1118 * 1119 * Arguments: 1120 * None. 1121 * 1122 * Returns: 1123 * None. 1124 * --------------------------------------------------------------------------- 1125 */ 1126int __init 1127uf_sdio_load(void) 1128{ 1129 CsrResult csrResult; 1130 1131 csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv); 1132 if (csrResult != CSR_RESULT_SUCCESS) { 1133 unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult); 1134 return -EIO; 1135 } 1136 1137 return 0; 1138} /* uf_sdio_load() */ 1139 1140 1141 1142void __exit 1143uf_sdio_unload(void) 1144{ 1145 CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv); 1146} /* uf_sdio_unload() */ 1147