GFS2: Check for glock already held in gfs2_getxattr
[deliverable/linux.git] / drivers / staging / csr / io.c
CommitLineData
635d2b00
GKH
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>
294a08e4 34#include <linux/seq_file.h>
635d2b00
GKH
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
635d2b00
GKH
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 */
51static 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 */
57static 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
68static 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 */
635d2b00 73DEFINE_SEMAPHORE(Unifi_instance_mutex);
635d2b00
GKH
74/*
75 * When the device is removed, unregister waits on Unifi_cleanup_wq
76 * until all the UDI clients release the character device.
77 */
78DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);
79
294a08e4
DH
80#ifdef CONFIG_PROC_FS
81/*
82 * seq_file wrappers for procfile show routines.
83 */
84static int uf_proc_show(struct seq_file *m, void *v);
85
86#define UNIFI_DEBUG_TXT_BUFFER (8 * 1024)
87
88static 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}
635d2b00 93
294a08e4
DH
94static const struct file_operations uf_proc_fops = {
95 .open = uf_proc_open,
96 .read = seq_read,
97 .llseek = seq_lseek,
bae301d3 98 .release = single_release,
294a08e4
DH
99};
100
101#endif /* CONFIG_PROC_FS */
635d2b00
GKH
102
103#ifdef CSR_WIFI_RX_PATH_SPLIT
104
105static CsrResult signal_buffer_init(unifi_priv_t * priv, int size)
106{
107 int i;
635d2b00
GKH
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;
70128792 116 priv->rxSignalBuffer.rx_buff[i].bufptr = kmalloc(UNIFI_PACKED_SIGBUF_SIZE, GFP_KERNEL);
635d2b00
GKH
117 if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL)
118 {
119 int j;
22d09a1b 120 unifi_error(priv, "signal_buffer_init:Failed to Allocate shared memory for T-H signals \n");
635d2b00
GKH
121 for(j=0;j<i;j++)
122 {
123 priv->rxSignalBuffer.rx_buff[j].sig_len=0;
4fe9db37 124 kfree(priv->rxSignalBuffer.rx_buff[j].bufptr);
635d2b00
GKH
125 priv->rxSignalBuffer.rx_buff[j].bufptr = NULL;
126 }
635d2b00
GKH
127 return -1;
128 }
129 }
635d2b00
GKH
130 return 0;
131}
132
133
134static 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;
4fe9db37 141 kfree(priv->rxSignalBuffer.rx_buff[i].bufptr);
635d2b00
GKH
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 */
166int
167uf_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
635d2b00
GKH
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 */
220void
221uf_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 */
277static unifi_priv_t *
278register_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
635d2b00
GKH
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 */
8c87f69a 331 csrResult = unifi_coredump_init(priv->card, (u16)coredump_max);
635d2b00
GKH
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 */
c4f9e644 345 scnprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance);
635d2b00
GKH
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 */
294a08e4
DH
350 if (!proc_create_data(priv->proc_entry_name, 0, NULL,
351 &uf_proc_fops, (void *)(long)priv->instance))
635d2b00
GKH
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 {
22d09a1b 363 if( !uf_alloc_netdevice_for_other_interfaces(priv, i) )
635d2b00
GKH
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 */
22d09a1b 369 unifi_error(priv, "Failed to allocate driver private for interface[%d]\n", i);
635d2b00
GKH
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 {
22d09a1b 394 unifi_error(priv, "Failed to allocate shared memory for T-H signals\n");
635d2b00
GKH
395 goto failed2;
396 }
397 priv->rx_workqueue = create_singlethread_workqueue("rx_workq");
398 if (priv->rx_workqueue == NULL) {
22d09a1b 399 unifi_error(priv, "create_singlethread_workqueue failed \n");
635d2b00
GKH
400 goto failed3;
401 }
402 INIT_WORK(&priv->rx_work_struct, rx_wq_handler);
403#endif
404
95edd09e
GKH
405#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
406 if (log_hip_signals)
407 {
408 uf_register_hip_offline_debug(priv);
409 }
410#endif
411
635d2b00
GKH
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
635d2b00
GKH
432 return priv;
433
434failed4:
95edd09e
GKH
435#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
436if (log_hip_signals)
437{
438 uf_unregister_hip_offline_debug(priv);
439}
440#endif
635d2b00
GKH
441#ifdef CSR_WIFI_RX_PATH_SPLIT
442 flush_workqueue(priv->rx_workqueue);
443 destroy_workqueue(priv->rx_workqueue);
444failed3:
22d09a1b 445 signal_buffer_free(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
635d2b00
GKH
446failed2:
447#endif
448 /* Remove the device nodes */
449 uf_destroy_device_nodes(priv);
450failed1:
451 /* Deregister priv->netdev_client */
452 ul_deregister_client(priv->netdev_client);
453
454failed0:
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
635d2b00
GKH
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 */
485static void
486ask_unifi_sdio_cleanup(unifi_priv_t *priv)
487{
635d2b00
GKH
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
635d2b00
GKH
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 */
516static void
517cleanup_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
635d2b00
GKH
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
95edd09e
GKH
551#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
552 if (log_hip_signals)
553 {
554 uf_unregister_hip_offline_debug(priv);
555 }
556#endif
557
635d2b00
GKH
558 /* Free any packets left in the Rx queues */
559 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
560 {
22d09a1b
LL
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);
635d2b00
GKH
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);
22d09a1b 598 signal_buffer_free(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
635d2b00
GKH
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
635d2b00
GKH
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 */
630static void
631unregister_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);
635d2b00
GKH
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]);
4febd649 657 netif_tx_stop_all_queues(priv->netdev[interfaceTag]);
635d2b00
GKH
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 */
712unifi_priv_t *
713uf_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 */
735int
736uf_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 */
766int
767uf_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 */
798unifi_priv_t *
799uf_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 */
829void
830uf_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 * ---------------------------------------------------------------------------
294a08e4 850 * uf_proc_show
635d2b00
GKH
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
294a08e4 867static int uf_proc_show(struct seq_file *m, void *v)
635d2b00 868{
294a08e4
DH
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__);
635d2b00 883#ifdef CSR_SME_USERSPACE
294a08e4 884 seq_puts(m, "SME: CSR userspace ");
635d2b00 885#ifdef CSR_SUPPORT_WEXT
294a08e4 886 seq_puts(m, "with WEXT support\n");
635d2b00 887#else
294a08e4 888 seq_putc(m, '\n');
635d2b00 889#endif /* CSR_SUPPORT_WEXT */
635d2b00
GKH
890#endif /* CSR_SME_USERSPACE */
891#ifdef CSR_NATIVE_LINUX
294a08e4 892 seq_puts(m, "SME: native\n");
635d2b00
GKH
893#endif
894
895#ifdef CSR_SUPPORT_SME
294a08e4
DH
896 seq_printf(m, "Firmware (ROM) build:%u, Patch:%u\n",
897 priv->card_info.fw_build,
898 priv->sme_versions.firmwarePatch);
635d2b00 899#endif
635d2b00 900
294a08e4 901 unifi_print_status(priv->card, m);
635d2b00 902
294a08e4 903 seq_printf(m, "Last dbg str: %s\n", priv->last_debug_string);
635d2b00 904
294a08e4
DH
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}
635d2b00
GKH
915#endif
916
917
918
919
920static void
921uf_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
929static void
930uf_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
938static int active_slot = MAX_UNIFI_DEVS;
939static struct device *os_devices[MAX_UNIFI_DEVS];
940
941void
942uf_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
954void
955uf_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
967static void
968uf_sdio_inserted(CsrSdioFunction *sdio_ctx)
969{
f145b4f4 970 unifi_priv_t *priv;
635d2b00 971
f145b4f4
DN
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]);
635d2b00 974
f145b4f4
DN
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 }
635d2b00 980
f145b4f4 981 sdio_ctx->driverData = priv;
635d2b00 982
f145b4f4 983 CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
635d2b00
GKH
984} /* uf_sdio_inserted() */
985
986
987static void
988uf_sdio_removed(CsrSdioFunction *sdio_ctx)
989{
f145b4f4
DN
990 unregister_unifi_sdio(active_slot);
991 CsrSdioRemovedAcknowledge(sdio_ctx);
635d2b00
GKH
992} /* uf_sdio_removed() */
993
994
995static void
996uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx)
997{
f145b4f4 998 unifi_priv_t *priv = sdio_ctx->driverData;
635d2b00 999
f145b4f4 1000 unifi_sdio_interrupt_handler(priv->card);
635d2b00
GKH
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 */
1019static CsrSdioInterruptDsrCallback
1020uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
1021{
f145b4f4 1022 return uf_sdio_dsr_handler;
635d2b00
GKH
1023} /* uf_sdio_int_handler() */
1024
1025
1026
1027
1028static CsrSdioFunctionId unifi_ids[] =
1029{
f145b4f4
DN
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 }
635d2b00
GKH
1042};
1043
1044
1045/*
1046 * Structure to register with the glue layer.
1047 */
1048static CsrSdioFunctionDriver unifi_sdioFunction_drv =
1049{
f145b4f4
DN
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])
635d2b00
GKH
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 */
1077int __init
1078uf_sdio_load(void)
1079{
f145b4f4 1080 CsrResult csrResult;
635d2b00 1081
f145b4f4
DN
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 }
635d2b00 1087
f145b4f4 1088 return 0;
635d2b00
GKH
1089} /* uf_sdio_load() */
1090
1091
1092
1093void __exit
1094uf_sdio_unload(void)
1095{
f145b4f4 1096 CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
635d2b00
GKH
1097} /* uf_sdio_unload() */
1098
This page took 0.177618 seconds and 5 git commands to generate.