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