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