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