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