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