]> Pileus Git - ~andy/linux/blob - drivers/staging/csr/io.c
Merge tag 'soc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[~andy/linux] / drivers / staging / csr / io.c
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  */
51 static 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  */
57 static 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
68 static 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  */
73 DEFINE_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  */
78 DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);
79
80
81 static 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
86 static 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
118 static 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  */
150 int
151 uf_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  */
204 void
205 uf_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  */
261 static unifi_priv_t *
262 register_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
421 failed4:
422 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
423 if (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);
431 failed3:
432     signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
433 failed2:
434 #endif
435     /* Remove the device nodes */
436     uf_destroy_device_nodes(priv);
437 failed1:
438     /* Deregister priv->netdev_client */
439     ul_deregister_client(priv->netdev_client);
440
441 failed0:
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  */
473 static void
474 ask_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  */
507 static void
508 cleanup_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  */
625 static void
626 unregister_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  */
708 unifi_priv_t *
709 uf_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  */
731 int
732 uf_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  */
762 int
763 uf_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  */
794 unifi_priv_t *
795 uf_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  */
825 void
826 uf_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
863 static int
864 uf_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
969 static void
970 uf_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
978 static void
979 uf_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
987 static int active_slot = MAX_UNIFI_DEVS;
988 static struct device *os_devices[MAX_UNIFI_DEVS];
989
990 void
991 uf_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
1003 void
1004 uf_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
1016 static void
1017 uf_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
1036 static void
1037 uf_sdio_removed(CsrSdioFunction *sdio_ctx)
1038 {
1039     unregister_unifi_sdio(active_slot);
1040     CsrSdioRemovedAcknowledge(sdio_ctx);
1041 } /* uf_sdio_removed() */
1042
1043
1044 static void
1045 uf_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  */
1068 static CsrSdioInterruptDsrCallback
1069 uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
1070 {
1071     return uf_sdio_dsr_handler;
1072 } /* uf_sdio_int_handler() */
1073
1074
1075
1076
1077 static 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  */
1097 static 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  */
1126 int __init
1127 uf_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
1142 void __exit
1143 uf_sdio_unload(void)
1144 {
1145     CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
1146 } /* uf_sdio_unload() */
1147