2 * ---------------------------------------------------------------------------
6 * This file contains routines that the SDIO driver can call when a
7 * UniFi card is first inserted (or detected) and removed.
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"
17 * #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
18 * SUBSYSTEM=="net", GOTO="net_start"
20 * Then you can add a stanza to /etc/network/interfaces like this:
22 * iface eth1 inet dhcp
23 * wpa-conf /etc/wpa_supplicant.conf
24 * This will then automatically associate when a car dis inserted.
26 * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd.
28 * Refer to LICENSE.txt included with this source code for details on
31 * ---------------------------------------------------------------------------
33 #include <linux/proc_fs.h>
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() */
39 #include "unifi_priv.h"
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.
47 * The Arasan PCI-SDIO controller card supported by this driver has 2 slots,
48 * hence a max of 2 devices.
50 static unifi_priv_t
*Unifi_instances
[MAX_UNIFI_DEVS
];
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.
56 static netInterface_priv_t
*Unifi_netdev_instances
[MAX_UNIFI_DEVS
* CSR_WIFI_NUM_INTERFACES
];
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).
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
];
69 * Mutex to prevent UDI clients to open the character device before the priv
70 * is created and initialised.
72 DEFINE_SEMAPHORE(Unifi_instance_mutex
);
74 * When the device is removed, unregister waits on Unifi_cleanup_wq
75 * until all the UDI clients release the character device.
77 DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq
);
80 static int uf_read_proc(char *page
, char **start
, off_t offset
, int count
,
81 int *eof
, void *data
);
83 #ifdef CSR_WIFI_RX_PATH_SPLIT
85 static CsrResult
signal_buffer_init(unifi_priv_t
* priv
, int size
)
89 priv
->rxSignalBuffer
.writePointer
=
90 priv
->rxSignalBuffer
.readPointer
= 0;
91 priv
->rxSignalBuffer
.size
= size
;
92 /* Allocating Memory for Signal primitive pointer */
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
)
100 unifi_error(priv
,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n");
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
;
114 static void signal_buffer_free(unifi_priv_t
* priv
, int size
)
118 for(i
=0; i
<size
; i
++)
120 priv
->rxSignalBuffer
.rx_buff
[i
].sig_len
=0;
121 kfree(priv
->rxSignalBuffer
.rx_buff
[i
].bufptr
);
122 priv
->rxSignalBuffer
.rx_buff
[i
].bufptr
= NULL
;
127 * ---------------------------------------------------------------------------
130 * Registers the network interface, installes the qdisc,
131 * and registers the inet handler.
132 * In the porting exercise, register the driver to the network
133 * stack if necessary.
136 * priv Pointer to driver context.
139 * O on success, non-zero otherwise.
142 * We will only unregister when the card is ejected, so we must
144 * ---------------------------------------------------------------------------
147 uf_register_netdev(unifi_priv_t
*priv
, int interfaceTag
)
150 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
152 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
153 unifi_error(priv
, "uf_register_netdev bad interfaceTag\n");
158 * Allocates a device number and registers device with the network
161 unifi_trace(priv
, UDBG5
, "uf_register_netdev: netdev %d - 0x%p\n",
162 interfaceTag
, priv
->netdev
[interfaceTag
]);
163 r
= register_netdev(priv
->netdev
[interfaceTag
]);
165 unifi_error(priv
, "Failed to register net device\n");
169 /* The device is registed */
170 interfacePriv
->netdev_registered
= 1;
172 #ifdef CSR_SUPPORT_SME
174 * Register the inet handler; it notifies us for changes in the IP address.
176 uf_register_inet_notifier();
177 #endif /* CSR_SUPPORT_SME */
179 unifi_notice(priv
, "unifi%d is %s\n",
180 priv
->instance
, priv
->netdev
[interfaceTag
]->name
);
183 } /* uf_register_netdev */
187 * ---------------------------------------------------------------------------
188 * uf_unregister_netdev
190 * Unregisters the network interface and the inet handler.
193 * priv Pointer to driver context.
198 * ---------------------------------------------------------------------------
201 uf_unregister_netdev(unifi_priv_t
*priv
)
205 #ifdef CSR_SUPPORT_SME
206 /* Unregister the inet handler... */
207 uf_unregister_inet_notifier();
208 #endif /* CSR_SUPPORT_SME */
210 for (i
=0; i
<CSR_WIFI_NUM_INTERFACES
; i
++) {
211 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
212 if (interfacePriv
->netdev_registered
) {
213 unifi_trace(priv
, UDBG5
,
214 "uf_unregister_netdev: netdev %d - 0x%p\n",
217 /* ... and the netdev */
218 unregister_netdev(priv
->netdev
[i
]);
219 interfacePriv
->netdev_registered
= 0;
222 interfacePriv
->interfaceMode
= 0;
224 /* Enable all queues by default */
225 interfacePriv
->queueEnabled
[0] = 1;
226 interfacePriv
->queueEnabled
[1] = 1;
227 interfacePriv
->queueEnabled
[2] = 1;
228 interfacePriv
->queueEnabled
[3] = 1;
231 priv
->totalInterfaceCount
= 0;
232 } /* uf_unregister_netdev() */
236 * ---------------------------------------------------------------------------
237 * register_unifi_sdio
239 * This function is called from the Probe (or equivalent) method of
240 * the SDIO driver when a UniFi card is detected.
241 * We allocate the Linux net_device struct, initialise the HIP core
242 * lib, create the char device nodes and start the userspace helper
243 * to initialise the device.
246 * sdio_dev Pointer to SDIO context handle to use for all
248 * bus_id A small number indicating the SDIO card position on the
249 * bus. Typically this is the slot number, e.g. 0, 1 etc.
250 * Valid values are 0 to MAX_UNIFI_DEVS-1.
251 * dev Pointer to kernel device manager struct.
254 * Pointer to the unifi instance, or NULL on error.
255 * ---------------------------------------------------------------------------
257 static unifi_priv_t
*
258 register_unifi_sdio(CsrSdioFunction
*sdio_dev
, int bus_id
, struct device
*dev
)
260 unifi_priv_t
*priv
= NULL
;
264 if ((bus_id
< 0) || (bus_id
>= MAX_UNIFI_DEVS
)) {
265 unifi_error(priv
, "register_unifi_sdio: invalid device %d\n",
270 down(&Unifi_instance_mutex
);
272 if (In_use
[bus_id
] != UNIFI_DEV_NOT_IN_USE
) {
273 unifi_error(priv
, "register_unifi_sdio: device %d is already in use\n",
279 /* Allocate device private and net_device structs */
280 priv
= uf_alloc_netdevice(sdio_dev
, bus_id
);
282 unifi_error(priv
, "Failed to allocate driver private\n");
286 priv
->unifi_device
= dev
;
288 SET_NETDEV_DEV(priv
->netdev
[0], dev
);
290 /* We are not ready to send data yet. */
291 netif_carrier_off(priv
->netdev
[0]);
293 /* Allocate driver context. */
294 priv
->card
= unifi_alloc_card(priv
->sdio
, priv
);
295 if (priv
->card
== NULL
) {
296 unifi_error(priv
, "Failed to allocate UniFi driver card struct.\n");
300 if (Unifi_instances
[bus_id
]) {
301 unifi_error(priv
, "Internal error: instance for slot %d is already taken\n",
304 Unifi_instances
[bus_id
] = priv
;
305 In_use
[bus_id
] = UNIFI_DEV_IN_USE
;
307 /* Save the netdev_priv for use by the netdev event callback mechanism */
308 Unifi_netdev_instances
[bus_id
* CSR_WIFI_NUM_INTERFACES
] = netdev_priv(priv
->netdev
[0]);
310 /* Initialise the mini-coredump capture buffers */
311 csrResult
= unifi_coredump_init(priv
->card
, (u16
)coredump_max
);
312 if (csrResult
!= CSR_RESULT_SUCCESS
) {
313 unifi_error(priv
, "Couldn't allocate mini-coredump buffers\n");
316 /* Create the character device nodes */
317 r
= uf_create_device_nodes(priv
, bus_id
);
323 * We use the slot number as unifi device index.
325 scnprintf(priv
->proc_entry_name
, 64, "driver/unifi%d", priv
->instance
);
327 * The following complex casting is in place in order to eliminate 64-bit compilation warning
328 * "cast to/from pointer from/to integer of different size"
330 if (!create_proc_read_entry(priv
->proc_entry_name
, 0, 0,
331 uf_read_proc
, (void *)(long)priv
->instance
))
333 unifi_error(priv
, "unifi: can't create /proc/driver/unifi\n");
336 /* Allocate the net_device for interfaces other than 0. */
339 priv
->totalInterfaceCount
=0;
341 for(i
=1;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
343 if( !uf_alloc_netdevice_for_other_interfaces(priv
,i
) )
345 /* error occured while allocating the net_device for interface[i]. The net_device are
346 * allocated for the interfaces with id<i. Dont worry, all the allocated net_device will
347 * be releasing chen the control goes to the label failed0.
349 unifi_error(priv
, "Failed to allocate driver private for interface[%d]\n",i
);
354 SET_NETDEV_DEV(priv
->netdev
[i
], dev
);
356 /* We are not ready to send data yet. */
357 netif_carrier_off(priv
->netdev
[i
]);
359 /* Save the netdev_priv for use by the netdev event callback mechanism */
360 Unifi_netdev_instances
[bus_id
* CSR_WIFI_NUM_INTERFACES
+ i
] = netdev_priv(priv
->netdev
[i
]);
364 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
366 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[i
];
367 interfacePriv
->netdev_registered
=0;
371 #ifdef CSR_WIFI_RX_PATH_SPLIT
372 if (signal_buffer_init(priv
, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE
))
374 unifi_error(priv
,"Failed to allocate shared memory for T-H signals\n");
377 priv
->rx_workqueue
= create_singlethread_workqueue("rx_workq");
378 if (priv
->rx_workqueue
== NULL
) {
379 unifi_error(priv
,"create_singlethread_workqueue failed \n");
382 INIT_WORK(&priv
->rx_work_struct
, rx_wq_handler
);
385 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
388 uf_register_hip_offline_debug(priv
);
392 /* Initialise the SME related threads and parameters */
393 r
= uf_sme_init(priv
);
395 unifi_error(priv
, "SME initialisation failed.\n");
400 * Run the userspace helper program (unififw) to perform
401 * the device initialisation.
403 unifi_trace(priv
, UDBG1
, "run UniFi helper app...\n");
404 r
= uf_run_unifihelper(priv
);
406 unifi_notice(priv
, "unable to run UniFi helper app\n");
407 /* Not a fatal error. */
410 up(&Unifi_instance_mutex
);
415 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
418 uf_unregister_hip_offline_debug(priv
);
421 #ifdef CSR_WIFI_RX_PATH_SPLIT
422 flush_workqueue(priv
->rx_workqueue
);
423 destroy_workqueue(priv
->rx_workqueue
);
425 signal_buffer_free(priv
,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE
);
428 /* Remove the device nodes */
429 uf_destroy_device_nodes(priv
);
431 /* Deregister priv->netdev_client */
432 ul_deregister_client(priv
->netdev_client
);
435 if (priv
&& priv
->card
) {
436 unifi_coredump_free(priv
->card
);
437 unifi_free_card(priv
->card
);
440 uf_free_netdevice(priv
);
443 up(&Unifi_instance_mutex
);
446 } /* register_unifi_sdio() */
450 * ---------------------------------------------------------------------------
451 * ask_unifi_sdio_cleanup
453 * We can not free our private context, until all the char device
454 * clients have closed the file handles. unregister_unifi_sdio() which
455 * is called when a card is removed, waits on Unifi_cleanup_wq until
456 * the reference count becomes zero. It is time to wake it up now.
459 * priv Pointer to driver context.
463 * ---------------------------------------------------------------------------
466 ask_unifi_sdio_cleanup(unifi_priv_t
*priv
)
470 * Now clear the flag that says the old instance is in use.
471 * This is used to prevent a new instance being started before old
472 * one has finshed closing down, for example if bounce makes the card
473 * appear to be ejected and re-inserted quickly.
475 In_use
[priv
->instance
] = UNIFI_DEV_CLEANUP
;
477 unifi_trace(NULL
, UDBG5
, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n");
478 wake_up(&Unifi_cleanup_wq
);
480 } /* ask_unifi_sdio_cleanup() */
484 * ---------------------------------------------------------------------------
487 * Release any resources owned by a unifi instance.
490 * priv Pointer to the instance to free.
494 * ---------------------------------------------------------------------------
497 cleanup_unifi_sdio(unifi_priv_t
*priv
)
501 static const CsrWifiMacAddress broadcast_address
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
503 /* Remove the device nodes */
504 uf_destroy_device_nodes(priv
);
506 /* Mark this device as gone away by NULLing the entry in Unifi_instances */
507 Unifi_instances
[priv
->instance
] = NULL
;
509 unifi_trace(priv
, UDBG5
, "cleanup_unifi_sdio: remove_proc_entry\n");
511 * Free the children of priv before unifi_free_netdevice() frees
514 remove_proc_entry(priv
->proc_entry_name
, 0);
517 /* Unregister netdev as a client. */
518 if (priv
->netdev_client
) {
519 unifi_trace(priv
, UDBG2
, "Netdev client (id:%d s:0x%X) is unregistered\n",
520 priv
->netdev_client
->client_id
, priv
->netdev_client
->sender_id
);
521 ul_deregister_client(priv
->netdev_client
);
524 /* Destroy the SME related threads and parameters */
527 #ifdef CSR_SME_USERSPACE
528 priv
->smepriv
= NULL
;
531 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
534 uf_unregister_hip_offline_debug(priv
);
538 /* Free any packets left in the Rx queues */
539 for(i
=0;i
<CSR_WIFI_NUM_INTERFACES
;i
++)
541 uf_free_pending_rx_packets(priv
, UF_UNCONTROLLED_PORT_Q
, broadcast_address
,i
);
542 uf_free_pending_rx_packets(priv
, UF_CONTROLLED_PORT_Q
, broadcast_address
,i
);
545 * We need to free the resources held by the core, which include tx skbs,
546 * otherwise we can not call unregister_netdev().
549 unifi_trace(priv
, UDBG5
, "cleanup_unifi_sdio: free card\n");
550 unifi_coredump_free(priv
->card
);
551 unifi_free_card(priv
->card
);
556 * Unregister the network device.
557 * We can not unregister the netdev before we release
558 * all pending packets in the core.
560 uf_unregister_netdev(priv
);
561 priv
->totalInterfaceCount
= 0;
563 /* Clear the table of registered netdev_priv's */
564 for (i
= 0; i
< CSR_WIFI_NUM_INTERFACES
; i
++) {
565 Unifi_netdev_instances
[priv
->instance
* CSR_WIFI_NUM_INTERFACES
+ i
] = NULL
;
568 unifi_trace(priv
, UDBG5
, "cleanup_unifi_sdio: uf_free_netdevice\n");
570 * When uf_free_netdevice() returns, the priv is invalid
571 * so we need to remember the instance to clear the global flag later.
573 priv_instance
= priv
->instance
;
575 #ifdef CSR_WIFI_RX_PATH_SPLIT
576 flush_workqueue(priv
->rx_workqueue
);
577 destroy_workqueue(priv
->rx_workqueue
);
578 signal_buffer_free(priv
,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE
);
581 /* Priv is freed as part of the net_device */
582 uf_free_netdevice(priv
);
585 * Now clear the flag that says the old instance is in use.
586 * This is used to prevent a new instance being started before old
587 * one has finshed closing down, for example if bounce makes the card
588 * appear to be ejected and re-inserted quickly.
590 In_use
[priv_instance
] = UNIFI_DEV_NOT_IN_USE
;
592 unifi_trace(NULL
, UDBG5
, "cleanup_unifi_sdio: DONE.\n");
594 } /* cleanup_unifi_sdio() */
598 * ---------------------------------------------------------------------------
599 * unregister_unifi_sdio
601 * Call from SDIO driver when it detects that UniFi has been removed.
604 * bus_id Number of the card that was ejected.
608 * ---------------------------------------------------------------------------
611 unregister_unifi_sdio(int bus_id
)
615 u8 reason
= CONFIG_IND_EXIT
;
617 if ((bus_id
< 0) || (bus_id
>= MAX_UNIFI_DEVS
)) {
618 unifi_error(NULL
, "unregister_unifi_sdio: invalid device %d\n",
623 priv
= Unifi_instances
[bus_id
];
625 unifi_error(priv
, "unregister_unifi_sdio: device %d is not registered\n",
630 /* Stop the network traffic before freeing the core. */
631 for(interfaceTag
=0;interfaceTag
<priv
->totalInterfaceCount
;interfaceTag
++)
633 netInterface_priv_t
*interfacePriv
= priv
->interfacePriv
[interfaceTag
];
634 if(interfacePriv
->netdev_registered
)
636 netif_carrier_off(priv
->netdev
[interfaceTag
]);
637 netif_tx_stop_all_queues(priv
->netdev
[interfaceTag
]);
641 #ifdef CSR_NATIVE_LINUX
643 * If the unifi thread was started, signal it to stop. This
644 * should cause any userspace processes with open unifi device to
647 uf_stop_thread(priv
, &priv
->bh_thread
);
649 /* Unregister the interrupt handler */
650 if (csr_sdio_linux_remove_irq(priv
->sdio
)) {
652 "csr_sdio_linux_remove_irq failed to talk to card.\n");
655 /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
657 #endif /* CSR_NATIVE_LINUX */
659 ul_log_config_ind(priv
, &reason
, sizeof(u8
));
661 /* Deregister the UDI hook from the core. */
662 unifi_remove_udi_hook(priv
->card
, logging_handler
);
664 uf_put_instance(bus_id
);
667 * Wait until the device is cleaned up. i.e., when all userspace
668 * processes have closed any open unifi devices.
670 wait_event(Unifi_cleanup_wq
, In_use
[bus_id
] == UNIFI_DEV_CLEANUP
);
671 unifi_trace(NULL
, UDBG5
, "Received clean up event\n");
673 /* Now we can free the private context and the char device nodes */
674 cleanup_unifi_sdio(priv
);
676 } /* unregister_unifi_sdio() */
680 * ---------------------------------------------------------------------------
683 * Find the context structure for a given UniFi device instance.
686 * inst The instance number to look for.
690 * ---------------------------------------------------------------------------
693 uf_find_instance(int inst
)
695 if ((inst
< 0) || (inst
>= MAX_UNIFI_DEVS
)) {
698 return Unifi_instances
[inst
];
699 } /* uf_find_instance() */
703 * ---------------------------------------------------------------------------
706 * Find the device instance for a given context structure.
709 * priv The context structure pointer to look for.
712 * index of instance, -1 otherwise.
713 * ---------------------------------------------------------------------------
716 uf_find_priv(unifi_priv_t
*priv
)
724 for (inst
= 0; inst
< MAX_UNIFI_DEVS
; inst
++) {
725 if (Unifi_instances
[inst
] == priv
) {
731 } /* uf_find_priv() */
734 * ---------------------------------------------------------------------------
735 * uf_find_netdev_priv
737 * Find the device instance for a given netdev context structure.
740 * priv The context structure pointer to look for.
743 * index of instance, -1 otherwise.
744 * ---------------------------------------------------------------------------
747 uf_find_netdev_priv(netInterface_priv_t
*priv
)
755 for (inst
= 0; inst
< MAX_UNIFI_DEVS
* CSR_WIFI_NUM_INTERFACES
; inst
++) {
756 if (Unifi_netdev_instances
[inst
] == priv
) {
762 } /* uf_find_netdev_priv() */
765 * ---------------------------------------------------------------------------
768 * Find the context structure for a given UniFi device instance
769 * and increment the reference count.
772 * inst The instance number to look for.
775 * Pointer to the instance or NULL if no instance exists.
776 * ---------------------------------------------------------------------------
779 uf_get_instance(int inst
)
783 down(&Unifi_instance_mutex
);
785 priv
= uf_find_instance(inst
);
790 up(&Unifi_instance_mutex
);
796 * ---------------------------------------------------------------------------
799 * Decrement the context reference count, freeing resources and
800 * shutting down the driver when the count reaches zero.
803 * inst The instance number to look for.
806 * Pointer to the instance or NULL if no instance exists.
807 * ---------------------------------------------------------------------------
810 uf_put_instance(int inst
)
814 down(&Unifi_instance_mutex
);
816 priv
= uf_find_instance(inst
);
819 if (priv
->ref_count
== 0) {
820 ask_unifi_sdio_cleanup(priv
);
824 up(&Unifi_instance_mutex
);
829 * ---------------------------------------------------------------------------
832 * Read method for driver node in /proc/driver/unifi0
844 * ---------------------------------------------------------------------------
846 #ifdef CONFIG_PROC_FS
848 uf_read_proc(char *page
, char **start
, off_t offset
, int count
,
849 int *eof
, void *data
)
851 #define UNIFI_DEBUG_TXT_BUFFER 8*1024
853 int actual_amount_to_copy
;
855 s32 remain
= UNIFI_DEBUG_TXT_BUFFER
;
860 * The following complex casting is in place in order to eliminate 64-bit compilation warning
861 * "cast to/from pointer from/to integer of different size"
863 priv
= uf_find_instance((int)(long)data
);
868 p
= kmalloc( UNIFI_DEBUG_TXT_BUFFER
, GFP_KERNEL
);
872 written
= scnprintf(p
, remain
, "UniFi SDIO Driver: %s %s %s\n",
873 CSR_WIFI_VERSION
, __DATE__
, __TIME__
);
874 UNIFI_SNPRINTF_RET(p
, remain
, written
);
875 #ifdef CSR_SME_USERSPACE
876 written
= scnprintf(p
, remain
, "SME: CSR userspace ");
877 UNIFI_SNPRINTF_RET(p
, remain
, written
);
878 #ifdef CSR_SUPPORT_WEXT
879 written
= scnprintf(p
, remain
, "with WEXT support\n");
881 written
= scnprintf(p
, remain
, "\n");
882 #endif /* CSR_SUPPORT_WEXT */
883 UNIFI_SNPRINTF_RET(p
, remain
, written
);
884 #endif /* CSR_SME_USERSPACE */
885 #ifdef CSR_NATIVE_LINUX
886 written
= scnprintf(p
, remain
, "SME: native\n");
887 UNIFI_SNPRINTF_RET(p
, remain
, written
);
890 #ifdef CSR_SUPPORT_SME
891 written
= scnprintf(p
, remain
,
892 "Firmware (ROM) build:%u, Patch:%u\n",
893 priv
->card_info
.fw_build
,
894 priv
->sme_versions
.firmwarePatch
);
895 UNIFI_SNPRINTF_RET(p
, remain
, written
);
897 p
+= unifi_print_status(priv
->card
, p
, &remain
);
899 written
= scnprintf(p
, remain
, "Last dbg str: %s\n",
900 priv
->last_debug_string
);
901 UNIFI_SNPRINTF_RET(p
, remain
, written
);
903 written
= scnprintf(p
, remain
, "Last dbg16:");
904 UNIFI_SNPRINTF_RET(p
, remain
, written
);
905 for (i
= 0; i
< 8; i
++) {
906 written
= scnprintf(p
, remain
, " %04X",
907 priv
->last_debug_word16
[i
]);
908 UNIFI_SNPRINTF_RET(p
, remain
, written
);
910 written
= scnprintf(p
, remain
, "\n");
911 UNIFI_SNPRINTF_RET(p
, remain
, written
);
912 written
= scnprintf(p
, remain
, " ");
913 UNIFI_SNPRINTF_RET(p
, remain
, written
);
914 for (; i
< 16; i
++) {
915 written
= scnprintf(p
, remain
, " %04X",
916 priv
->last_debug_word16
[i
]);
917 UNIFI_SNPRINTF_RET(p
, remain
, written
);
919 written
= scnprintf(p
, remain
, "\n");
920 UNIFI_SNPRINTF_RET(p
, remain
, written
);
923 written
= UNIFI_DEBUG_TXT_BUFFER
- remain
;
925 if( offset
>= written
)
932 if( offset
+ count
> written
)
934 actual_amount_to_copy
= written
- offset
;
939 actual_amount_to_copy
= count
;
942 memcpy( page
, &(orig_p
[offset
]), actual_amount_to_copy
);
946 return( actual_amount_to_copy
);
947 } /* uf_read_proc() */
954 uf_lx_suspend(CsrSdioFunction
*sdio_ctx
)
956 unifi_priv_t
*priv
= sdio_ctx
->driverData
;
959 CsrSdioSuspendAcknowledge(sdio_ctx
, CSR_RESULT_SUCCESS
);
963 uf_lx_resume(CsrSdioFunction
*sdio_ctx
)
965 unifi_priv_t
*priv
= sdio_ctx
->driverData
;
968 CsrSdioResumeAcknowledge(sdio_ctx
, CSR_RESULT_SUCCESS
);
971 static int active_slot
= MAX_UNIFI_DEVS
;
972 static struct device
*os_devices
[MAX_UNIFI_DEVS
];
975 uf_add_os_device(int bus_id
, struct device
*os_device
)
977 if ((bus_id
< 0) || (bus_id
>= MAX_UNIFI_DEVS
)) {
978 unifi_error(NULL
, "uf_add_os_device: invalid device %d\n",
983 active_slot
= bus_id
;
984 os_devices
[bus_id
] = os_device
;
985 } /* uf_add_os_device() */
988 uf_remove_os_device(int bus_id
)
990 if ((bus_id
< 0) || (bus_id
>= MAX_UNIFI_DEVS
)) {
991 unifi_error(NULL
, "uf_remove_os_device: invalid device %d\n",
996 active_slot
= bus_id
;
997 os_devices
[bus_id
] = NULL
;
998 } /* uf_remove_os_device() */
1001 uf_sdio_inserted(CsrSdioFunction
*sdio_ctx
)
1005 unifi_trace(NULL
, UDBG5
, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n",
1006 sdio_ctx
, active_slot
, os_devices
[active_slot
]);
1008 priv
= register_unifi_sdio(sdio_ctx
, active_slot
, os_devices
[active_slot
]);
1010 CsrSdioInsertedAcknowledge(sdio_ctx
, CSR_RESULT_FAILURE
);
1014 sdio_ctx
->driverData
= priv
;
1016 CsrSdioInsertedAcknowledge(sdio_ctx
, CSR_RESULT_SUCCESS
);
1017 } /* uf_sdio_inserted() */
1021 uf_sdio_removed(CsrSdioFunction
*sdio_ctx
)
1023 unregister_unifi_sdio(active_slot
);
1024 CsrSdioRemovedAcknowledge(sdio_ctx
);
1025 } /* uf_sdio_removed() */
1029 uf_sdio_dsr_handler(CsrSdioFunction
*sdio_ctx
)
1031 unifi_priv_t
*priv
= sdio_ctx
->driverData
;
1033 unifi_sdio_interrupt_handler(priv
->card
);
1034 } /* uf_sdio_dsr_handler() */
1037 * ---------------------------------------------------------------------------
1038 * uf_sdio_int_handler
1040 * Interrupt callback function for SDIO interrupts.
1041 * This is called in kernel context (i.e. not interrupt context).
1042 * We retrieve the unifi context pointer and call the main UniFi
1043 * interrupt handler.
1046 * fdev SDIO context pointer
1050 * ---------------------------------------------------------------------------
1052 static CsrSdioInterruptDsrCallback
1053 uf_sdio_int_handler(CsrSdioFunction
*sdio_ctx
)
1055 return uf_sdio_dsr_handler
;
1056 } /* uf_sdio_int_handler() */
1061 static CsrSdioFunctionId unifi_ids
[] =
1064 .manfId
= SDIO_MANF_ID_CSR
,
1065 .cardId
= SDIO_CARD_ID_UNIFI_3
,
1066 .sdioFunction
= SDIO_WLAN_FUNC_ID_UNIFI_3
,
1067 .sdioInterface
= CSR_SDIO_ANY_SDIO_INTERFACE
,
1070 .manfId
= SDIO_MANF_ID_CSR
,
1071 .cardId
= SDIO_CARD_ID_UNIFI_4
,
1072 .sdioFunction
= SDIO_WLAN_FUNC_ID_UNIFI_4
,
1073 .sdioInterface
= CSR_SDIO_ANY_SDIO_INTERFACE
,
1079 * Structure to register with the glue layer.
1081 static CsrSdioFunctionDriver unifi_sdioFunction_drv
=
1083 .inserted
= uf_sdio_inserted
,
1084 .removed
= uf_sdio_removed
,
1085 .intr
= uf_sdio_int_handler
,
1086 .suspend
= uf_lx_suspend
,
1087 .resume
= uf_lx_resume
,
1090 .idsCount
= sizeof(unifi_ids
) / sizeof(unifi_ids
[0])
1095 * ---------------------------------------------------------------------------
1099 * These functions are called from the main module load and unload
1100 * functions. They perform the appropriate operations for the monolithic
1108 * ---------------------------------------------------------------------------
1113 CsrResult csrResult
;
1115 csrResult
= CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv
);
1116 if (csrResult
!= CSR_RESULT_SUCCESS
) {
1117 unifi_error(NULL
, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult
);
1122 } /* uf_sdio_load() */
1127 uf_sdio_unload(void)
1129 CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv
);
1130 } /* uf_sdio_unload() */