]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/compat-wireless-3.5-libertas_uap.patch
snort: Update urls for rules download (2.9.7.0) in 'ids.cgi'
[ipfire-2.x.git] / src / patches / compat-wireless-3.5-libertas_uap.patch
1 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile
2 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile 1970-01-01 01:00:00.000000000 +0100
3 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile 2012-07-31 14:23:04.000000000 +0200
4 @@ -0,0 +1,6 @@
5 +obj-$(CONFIG_LIBERTAS_UAP) += uap8xxx.o
6 +
7 +uap8xxx-y += uap_main.o uap_sdio_mmc.o
8 +uap8xxx-$(CONFIG_PROC_FS) += uap_proc.o uap_debug.o
9 +
10 +EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1
11 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c
12 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c 1970-01-01 01:00:00.000000000 +0100
13 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c 2012-07-31 14:23:04.000000000 +0200
14 @@ -0,0 +1,261 @@
15 +/** @file uap_debug.c
16 + * @brief This file contains functions for debug proc file.
17 + *
18 + * Copyright (C) 2008-2009, Marvell International Ltd.
19 + *
20 + * This software file (the "File") is distributed by Marvell International
21 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
22 + * (the "License"). You may use, redistribute and/or modify this File in
23 + * accordance with the terms and conditions of the License, a copy of which
24 + * is available along with the File in the gpl.txt file or by writing to
25 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
27 + *
28 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
29 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
30 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
31 + * this warranty disclaimer.
32 + *
33 + */
34 +#ifdef CONFIG_PROC_FS
35 +#include "uap_headers.h"
36 +
37 +/********************************************************
38 + Local Variables
39 +********************************************************/
40 +
41 +#define item_size(n) (sizeof ((uap_adapter *)0)->n)
42 +#define item_addr(n) ((u32) &((uap_adapter *)0)->n)
43 +
44 +#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n))
45 +#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n))
46 +
47 +#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n)
48 +#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n)
49 +
50 +/** MicroAp device offset */
51 +#define OFFSET_UAP_DEV 0x01
52 +/** Bluetooth adapter offset */
53 +#define OFFSET_UAP_ADAPTER 0x02
54 +
55 +struct debug_data
56 +{
57 + /** Name */
58 + char name[32];
59 + /** Size */
60 + u32 size;
61 + /** Address */
62 + u32 addr;
63 + /** Offset */
64 + u32 offset;
65 + /** Flag */
66 + u32 flag;
67 +};
68 +
69 +/* To debug any member of uap_adapter, simply add one line here.
70 + */
71 +static struct debug_data items[] = {
72 + {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent),
73 + OFFSET_UAP_DEV},
74 + {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent),
75 + OFFSET_UAP_DEV},
76 + {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter),
77 + OFFSET_UAP_ADAPTER},
78 + {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending),
79 + OFFSET_UAP_ADAPTER},
80 + {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0,
81 + item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER},
82 + {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0,
83 + item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER},
84 + {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER},
85 + {"ps_state", item_size(ps_state), 0, item_addr(ps_state),
86 + OFFSET_UAP_ADAPTER},
87 +#ifdef DEBUG_LEVEL1
88 + {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0}
89 +#endif
90 +};
91 +
92 +static int num_of_items = sizeof(items) / sizeof(items[0]);
93 +
94 +/********************************************************
95 + Global Variables
96 +********************************************************/
97 +
98 +/********************************************************
99 + Local Functions
100 +********************************************************/
101 +/**
102 + * @brief proc read function
103 + *
104 + * @param page pointer to buffer
105 + * @param s read data starting position
106 + * @param off offset
107 + * @param cnt counter
108 + * @param eof end of file flag
109 + * @param data data to output
110 + * @return number of output data
111 + */
112 +static int
113 +uap_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data)
114 +{
115 + int val = 0;
116 + char *p = page;
117 + int i;
118 +
119 + struct debug_data *d = (struct debug_data *) data;
120 +
121 + if (MODULE_GET == 0)
122 + return UAP_STATUS_FAILURE;
123 +
124 + for (i = 0; i < num_of_items; i++) {
125 + if (d[i].size == 1)
126 + val = *((u8 *) d[i].addr);
127 + else if (d[i].size == 2)
128 + val = *((u16 *) d[i].addr);
129 + else if (d[i].size == 4)
130 + val = *((u32 *) d[i].addr);
131 +
132 + p += sprintf(p, "%s=%d\n", d[i].name, val);
133 + }
134 + MODULE_PUT;
135 + return p - page;
136 +}
137 +
138 +/**
139 + * @brief proc write function
140 + *
141 + * @param f file pointer
142 + * @param buf pointer to data buffer
143 + * @param cnt data number to write
144 + * @param data data to write
145 + * @return number of data
146 + */
147 +static int
148 +uap_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data)
149 +{
150 + int r, i;
151 + char *pdata;
152 + char *p;
153 + char *p0;
154 + char *p1;
155 + char *p2;
156 + struct debug_data *d = (struct debug_data *) data;
157 +
158 + if (MODULE_GET == 0)
159 + return UAP_STATUS_FAILURE;
160 +
161 + pdata = (char *) kmalloc(cnt, GFP_KERNEL);
162 + if (pdata == NULL) {
163 + MODULE_PUT;
164 + return 0;
165 + }
166 +
167 + if (copy_from_user(pdata, buf, cnt)) {
168 + PRINTM(INFO, "Copy from user failed\n");
169 + kfree(pdata);
170 + MODULE_PUT;
171 + return 0;
172 + }
173 +
174 + p0 = pdata;
175 + for (i = 0; i < num_of_items; i++) {
176 + do {
177 + p = strstr(p0, d[i].name);
178 + if (p == NULL)
179 + break;
180 + p1 = strchr(p, '\n');
181 + if (p1 == NULL)
182 + break;
183 + p0 = p1++;
184 + p2 = strchr(p, '=');
185 + if (!p2)
186 + break;
187 + p2++;
188 + r = string_to_number(p2);
189 + if (d[i].size == 1)
190 + *((u8 *) d[i].addr) = (u8) r;
191 + else if (d[i].size == 2)
192 + *((u16 *) d[i].addr) = (u16) r;
193 + else if (d[i].size == 4)
194 + *((u32 *) d[i].addr) = (u32) r;
195 + break;
196 + } while (TRUE);
197 + }
198 + kfree(pdata);
199 +#ifdef DEBUG_LEVEL1
200 + printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg);
201 + printk(KERN_ALERT "INFO (%08lx) %s\n", DBG_INFO,
202 + (drvdbg & DBG_INFO) ? "X" : "");
203 + printk(KERN_ALERT "WARN (%08lx) %s\n", DBG_WARN,
204 + (drvdbg & DBG_WARN) ? "X" : "");
205 + printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY,
206 + (drvdbg & DBG_ENTRY) ? "X" : "");
207 + printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D,
208 + (drvdbg & DBG_CMD_D) ? "X" : "");
209 + printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D,
210 + (drvdbg & DBG_DAT_D) ? "X" : "");
211 + printk(KERN_ALERT "CMND (%08lx) %s\n", DBG_CMND,
212 + (drvdbg & DBG_CMND) ? "X" : "");
213 + printk(KERN_ALERT "DATA (%08lx) %s\n", DBG_DATA,
214 + (drvdbg & DBG_DATA) ? "X" : "");
215 + printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR,
216 + (drvdbg & DBG_ERROR) ? "X" : "");
217 + printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL,
218 + (drvdbg & DBG_FATAL) ? "X" : "");
219 + printk(KERN_ALERT "MSG (%08lx) %s\n", DBG_MSG,
220 + (drvdbg & DBG_MSG) ? "X" : "");
221 +#endif
222 + MODULE_PUT;
223 + return cnt;
224 +}
225 +
226 +/********************************************************
227 + Global Functions
228 +********************************************************/
229 +/**
230 + * @brief create debug proc file
231 + *
232 + * @param priv pointer uap_private
233 + * @param dev pointer net_device
234 + * @return N/A
235 + */
236 +void
237 +uap_debug_entry(uap_private * priv, struct net_device *dev)
238 +{
239 + int i;
240 + struct proc_dir_entry *r;
241 +
242 + if (priv->proc_entry == NULL)
243 + return;
244 +
245 + for (i = 0; i < num_of_items; i++) {
246 + if (items[i].flag & OFFSET_UAP_ADAPTER)
247 + items[i].addr = items[i].offset + (u32) priv->adapter;
248 + if (items[i].flag & OFFSET_UAP_DEV)
249 + items[i].addr = items[i].offset + (u32) & priv->uap_dev;
250 + }
251 + r = create_proc_entry("debug", 0644, priv->proc_entry);
252 + if (r == NULL)
253 + return;
254 +
255 + r->data = &items[0];
256 + r->read_proc = uap_debug_read;
257 + r->write_proc = uap_debug_write;
258 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
259 + r->owner = THIS_MODULE;
260 +#endif
261 +}
262 +
263 +/**
264 + * @brief remove proc file
265 + *
266 + * @param priv pointer uap_private
267 + * @return N/A
268 + */
269 +void
270 +uap_debug_remove(uap_private * priv)
271 +{
272 + remove_proc_entry("debug", priv->proc_entry);
273 +}
274 +
275 +#endif
276 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h
277 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h 1970-01-01 01:00:00.000000000 +0100
278 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h 2012-07-31 14:23:04.000000000 +0200
279 @@ -0,0 +1,667 @@
280 +/** @file uap_drv.h
281 + * @brief This file contains Linux OS related definitions and
282 + * declarations, uAP driver
283 + *
284 + * Copyright (C) 2008-2009, Marvell International Ltd.
285 + *
286 + * This software file (the "File") is distributed by Marvell International
287 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
288 + * (the "License"). You may use, redistribute and/or modify this File in
289 + * accordance with the terms and conditions of the License, a copy of which
290 + * is available along with the File in the gpl.txt file or by writing to
291 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
292 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
293 + *
294 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
295 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
296 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
297 + * this warranty disclaimer.
298 + *
299 + */
300 +
301 +#ifndef _UAP_DRV_H
302 +#define _UAP_DRV_H
303 +
304 +/** Driver release version */
305 +#define DRIVER_VERSION "26146"
306 +
307 +/** True */
308 +#ifndef TRUE
309 +#define TRUE 1
310 +#endif
311 +/** False */
312 +#ifndef FALSE
313 +#define FALSE 0
314 +#endif
315 +
316 +/** Bit definitions */
317 +#ifndef BIT
318 +#define BIT(x) (1UL << (x))
319 +#endif
320 +
321 +/** Dma addresses are 32-bits wide. */
322 +#ifndef __ATTRIB_ALIGN__
323 +#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
324 +#endif
325 +
326 +/** attribute pack */
327 +#ifndef __ATTRIB_PACK__
328 +#define __ATTRIB_PACK__ __attribute__ ((packed))
329 +#endif
330 +
331 +/** Debug Macro definition*/
332 +#ifdef DEBUG_LEVEL1
333 +
334 +extern u32 drvdbg;
335 +
336 +/** Debug message control bit definition for drvdbg */
337 +/** Debug message */
338 +#define DBG_MSG BIT(0)
339 +/** Debug fatal message */
340 +#define DBG_FATAL BIT(1)
341 +/** Debug error message */
342 +#define DBG_ERROR BIT(2)
343 +/** Debug data message */
344 +#define DBG_DATA BIT(3)
345 +/** Debug command message */
346 +#define DBG_CMND BIT(4)
347 +
348 +/** Debug data */
349 +#define DBG_DAT_D BIT(16)
350 +/** Debug command */
351 +#define DBG_CMD_D BIT(17)
352 +
353 +/** Debug entry */
354 +#define DBG_ENTRY BIT(28)
355 +/** Debug warning */
356 +#define DBG_WARN BIT(29)
357 +/** Debug info */
358 +#define DBG_INFO BIT(30)
359 +
360 +/** Print info */
361 +#define PRINTM_INFO(msg...) {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);}
362 +/** Print warn message */
363 +#define PRINTM_WARN(msg...) {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);}
364 +/** Print entry */
365 +#define PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);}
366 +/** Print cmd_d */
367 +#define PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);}
368 +/** Print data_d */
369 +#define PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);}
370 +/** Print command */
371 +#define PRINTM_CMND(msg...) {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);}
372 +/** Print data */
373 +#define PRINTM_DATA(msg...) {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);}
374 +/** Print error message */
375 +#define PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);}
376 +/** Print fatal message */
377 +#define PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);}
378 +/** Print message */
379 +#define PRINTM_MSG(msg...) {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);}
380 +/** Print level */
381 +#define PRINTM(level,msg...) PRINTM_##level(msg)
382 +
383 +#else
384 +
385 +#define PRINTM(level,msg...) do {} while (0)
386 +
387 +#endif /* DEBUG_LEVEL1 */
388 +
389 +/** Wait until a condition becomes true */
390 +#define ASSERT(cond) \
391 +do { \
392 + if (!(cond)) \
393 + PRINTM(INFO, "ASSERT: %s, %s:%i\n", \
394 + __FUNCTION__, __FILE__, __LINE__); \
395 +} while(0)
396 +
397 +/** Log enrty point for debugging */
398 +#define ENTER() PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \
399 + __FILE__, __LINE__)
400 +/** Log exit point for debugging */
401 +#define LEAVE() PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \
402 + __FILE__, __LINE__)
403 +
404 +#ifdef DEBUG_LEVEL1
405 +/** Dump buffer length */
406 +#define DBG_DUMP_BUF_LEN 64
407 +/** Maximum dump per line */
408 +#define MAX_DUMP_PER_LINE 16
409 +/** Data dump length */
410 +#define DATA_DUMP_LEN 32
411 +
412 +static inline void
413 +hexdump(char *prompt, u8 * buf, int len)
414 +{
415 + int i;
416 + char dbgdumpbuf[DBG_DUMP_BUF_LEN];
417 + char *ptr = dbgdumpbuf;
418 +
419 + printk(KERN_DEBUG "%s:\n", prompt);
420 + for (i = 1; i <= len; i++) {
421 + ptr += sprintf(ptr, "%02x ", *buf);
422 + buf++;
423 + if (i % MAX_DUMP_PER_LINE == 0) {
424 + *ptr = 0;
425 + printk(KERN_DEBUG "%s\n", dbgdumpbuf);
426 + ptr = dbgdumpbuf;
427 + }
428 + }
429 + if (len % MAX_DUMP_PER_LINE) {
430 + *ptr = 0;
431 + printk(KERN_DEBUG "%s\n", dbgdumpbuf);
432 + }
433 +}
434 +
435 +/** Debug command */
436 +#define DBG_HEXDUMP_CMD_D(x,y,z) {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);}
437 +/** Debug data */
438 +#define DBG_HEXDUMP_DAT_D(x,y,z) {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);}
439 +/** Debug hexdump */
440 +#define DBG_HEXDUMP(level,x,y,z) DBG_HEXDUMP_##level(x,y,z)
441 +/** hexdump */
442 +#define HEXDUMP(x,y,z) {if (drvdbg & DBG_INFO) hexdump(x,y,z);}
443 +#else
444 +/** Do nothing since debugging is not turned on */
445 +#define DBG_HEXDUMP(level,x,y,z) do {} while (0)
446 +/** Do nothing since debugging is not turned on */
447 +#define HEXDUMP(x,y,z) do {} while (0)
448 +#endif
449 +
450 +/**
451 + * Typedefs
452 + */
453 +/** Unsigned char */
454 +typedef u8 BOOLEAN;
455 +
456 +/*
457 + * OS macro definitions
458 + */
459 +/** OS macro to get time */
460 +#define os_time_get() jiffies
461 +
462 +/** OS macro to update transfer start time */
463 +#define UpdateTransStart(dev) { \
464 + dev->trans_start = jiffies; \
465 +}
466 +
467 +/** Try to get a reference to the module */
468 +#define MODULE_GET try_module_get(THIS_MODULE)
469 +/** Decrease module reference count */
470 +#define MODULE_PUT module_put(THIS_MODULE)
471 +
472 +/** OS macro to initialize semaphore */
473 +#define OS_INIT_SEMAPHORE(x) sema_init(x,1)
474 +/** OS macro to acquire blocking semaphore */
475 +#define OS_ACQ_SEMAPHORE_BLOCK(x) down_interruptible(x)
476 +/** OS macro to acquire non-blocking semaphore */
477 +#define OS_ACQ_SEMAPHORE_NOBLOCK(x) down_trylock(x)
478 +/** OS macro to release semaphore */
479 +#define OS_REL_SEMAPHORE(x) up(x)
480 +
481 +static inline void
482 +os_sched_timeout(u32 millisec)
483 +{
484 + set_current_state(TASK_INTERRUPTIBLE);
485 + schedule_timeout((millisec * HZ) / 1000);
486 +}
487 +
488 +/** Maximum size of ethernet packet */
489 +#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE 1514
490 +
491 +/** Maximum size of multicast list */
492 +#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
493 +
494 +/** Find minimum */
495 +#ifndef MIN
496 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
497 +#endif
498 +
499 +/** Find maximum */
500 +#ifndef MAX
501 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
502 +#endif
503 +
504 +/** Find number of elements */
505 +#ifndef NELEMENTS
506 +#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
507 +#endif
508 +
509 +/** Buffer Constants */
510 +
511 +/** Size of command buffer */
512 +#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
513 +
514 +/** Length of device length */
515 +#define DEV_NAME_LEN 32
516 +
517 +/** Length of ethernet address */
518 +#ifndef ETH_ALEN
519 +#define ETH_ALEN 6
520 +#endif
521 +
522 +/** Default watchdog timeout */
523 +#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ)
524 +
525 +/** Success */
526 +#define UAP_STATUS_SUCCESS (0)
527 +/** Failure */
528 +#define UAP_STATUS_FAILURE (-1)
529 +/** Not accepted */
530 +#define UAP_STATUS_NOT_ACCEPTED (-2)
531 +
532 +/** Max loop count (* 100ms) for waiting device ready at init time */
533 +#define MAX_WAIT_DEVICE_READY_COUNT 50
534 +
535 +/** Tx high watermark. Stop Tx queue after this is crossed */
536 +#define TX_HIGH_WATERMARK 4
537 +/** Tx low watermark. Restart Tx queue after this is crossed */
538 +#define TX_LOW_WATERMARK 2
539 +
540 +/** Netlink protocol number */
541 +#define NETLINK_MARVELL (MAX_LINKS - 1)
542 +/** Netlink maximum payload size */
543 +#define NL_MAX_PAYLOAD 1024
544 +/** Netlink multicast group number */
545 +#define NL_MULTICAST_GROUP 1
546 +
547 +/** 20 seconds */
548 +#define MRVDRV_TIMER_20S 20000
549 +
550 +/** Host Command option for wait till Send */
551 +#define HostCmd_OPTION_WAITFORSEND 0x0001
552 +/** Host Command option for wait for RSP */
553 +#define HostCmd_OPTION_WAITFORRSP 0x0002
554 +/** Host Command option for wait for RSP or Timeout */
555 +#define HostCmd_OPTION_WAITFORRSP_TIMEOUT 0x0003
556 +/** Host Command option for wait for RSP of sleep confirm */
557 +#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM 0x0004
558 +
559 +/** Sleep until a condition gets true or a timeout elapses */
560 +#define os_wait_interruptible_timeout(waitq, cond, timeout) \
561 + wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000))
562 +
563 +/** Private command ID to Host command */
564 +#define UAPHOSTCMD (SIOCDEVPRIVATE + 1)
565 +
566 +/** Private command ID to Power Mode */
567 +#define UAP_POWER_MODE (SIOCDEVPRIVATE + 3)
568 +/** sleep_param */
569 +typedef struct _ps_sleep_param
570 +{
571 + /** control bitmap */
572 + u32 ctrl_bitmap;
573 + /** minimum sleep period (micro second) */
574 + u32 min_sleep;
575 + /** maximum sleep period (micro second) */
576 + u32 max_sleep;
577 +} ps_sleep_param;
578 +
579 +/** inactivity sleep_param */
580 +typedef struct _inact_sleep_param
581 +{
582 + /** inactivity timeout (micro second) */
583 + u32 inactivity_to;
584 + /** miniumu awake period (micro second) */
585 + u32 min_awake;
586 + /** maximum awake period (micro second) */
587 + u32 max_awake;
588 +} inact_sleep_param;
589 +
590 +/** flag for ps mode */
591 +#define PS_FLAG_PS_MODE 1
592 +/** flag for sleep param */
593 +#define PS_FLAG_SLEEP_PARAM 2
594 +/** flag for inactivity sleep param */
595 +#define PS_FLAG_INACT_SLEEP_PARAM 4
596 +
597 +/** Disable power mode */
598 +#define PS_MODE_DISABLE 0
599 +/** Enable periodic dtim ps */
600 +#define PS_MODE_PERIODIC_DTIM 1
601 +/** Enable inactivity ps */
602 +#define PS_MODE_INACTIVITY 2
603 +
604 +/** sleep parameter */
605 +#define SLEEP_PARAMETER 1
606 +/** inactivity sleep parameter */
607 +#define INACTIVITY_SLEEP_PARAMETER 2
608 +/** ps_mgmt */
609 +typedef struct _ps_mgmt
610 +{
611 + /** flags for valid field */
612 + u16 flags;
613 + /** power mode */
614 + u16 ps_mode;
615 + /** sleep param */
616 + ps_sleep_param sleep_param;
617 + /** inactivity sleep param */
618 + inact_sleep_param inact_param;
619 +} ps_mgmt;
620 +
621 +/** Semaphore structure */
622 +typedef struct semaphore SEMAPHORE;
623 +
624 +/** Global Varibale Declaration */
625 +/** Private data structure of the device */
626 +typedef struct _uap_private uap_private;
627 +/** Adapter data structure of the device */
628 +typedef struct _uap_adapter uap_adapter;
629 +/** private structure */
630 +extern uap_private *uappriv;
631 +
632 +/** ENUM definition*/
633 +
634 +/** Hardware status codes */
635 +typedef enum _HARDWARE_STATUS
636 +{
637 + HWReady,
638 + HWInitializing,
639 + HWReset,
640 + HWClosing,
641 + HWNotReady
642 +} HARDWARE_STATUS;
643 +
644 +/** info for debug purpose */
645 +typedef struct _uap_dbg
646 +{
647 + /** Number of host to card command failures */
648 + u32 num_cmd_host_to_card_failure;
649 + /** Number of host to card Tx failures */
650 + u32 num_tx_host_to_card_failure;
651 +} uap_dbg;
652 +
653 +/** Set thread state */
654 +#define OS_SET_THREAD_STATE(x) set_current_state(x)
655 +
656 +typedef struct
657 +{
658 + /** Task */
659 + struct task_struct *task;
660 + /** Queue */
661 + wait_queue_head_t waitQ;
662 + /** PID */
663 + pid_t pid;
664 + /** Private structure */
665 + void *priv;
666 +} uap_thread;
667 +
668 +static inline void
669 +uap_activate_thread(uap_thread * thr)
670 +{
671 + /** Record the thread pid */
672 + thr->pid = current->pid;
673 +
674 + /** Initialize the wait queue */
675 + init_waitqueue_head(&thr->waitQ);
676 +}
677 +
678 +static inline void
679 +uap_deactivate_thread(uap_thread * thr)
680 +{
681 + thr->pid = 0;
682 + return;
683 +}
684 +
685 +static inline void
686 +uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name)
687 +{
688 + thr->task = kthread_run(uapfunc, thr, "%s", name);
689 +}
690 +
691 +static inline int
692 +uap_terminate_thread(uap_thread * thr)
693 +{
694 + /* Check if the thread is active or not */
695 + if (!thr->pid)
696 + return -1;
697 + kthread_stop(thr->task);
698 + return 0;
699 +}
700 +
701 +/** Data structure for the Marvell uAP device */
702 +typedef struct _uap_dev
703 +{
704 + /** device name */
705 + char name[DEV_NAME_LEN];
706 + /** card pointer */
707 + void *card;
708 + /** IO port */
709 + u32 ioport;
710 + /** Rx unit */
711 + u8 rx_unit;
712 + /** Data sent:
713 + TRUE - Data is sent to fw, no Tx Done received
714 + FALSE - Tx done received for previous Tx */
715 + BOOLEAN data_sent;
716 + /** CMD sent:
717 + TRUE - CMD is sent to fw, no CMD Done received
718 + FALSE - CMD done received for previous CMD */
719 + BOOLEAN cmd_sent;
720 + /** netdev pointer */
721 + struct net_device *netdev;
722 +} uap_dev_t, *puap_dev_t;
723 +
724 +/** Private structure for the MV device */
725 +struct _uap_private
726 +{
727 + /** Device open */
728 + int open;
729 +
730 + /** Device adapter structure */
731 + uap_adapter *adapter;
732 + /** Device structure */
733 + uap_dev_t uap_dev;
734 +
735 + /** Net device statistics structure */
736 + struct net_device_stats stats;
737 +
738 + /** Number of Tx timeouts */
739 + u32 num_tx_timeout;
740 +
741 + /** Media connection status */
742 + BOOLEAN MediaConnected;
743 +
744 +#ifdef CONFIG_PROC_FS
745 + struct proc_dir_entry *proc_uap;
746 + struct proc_dir_entry *proc_entry;
747 +#endif /* CONFIG_PROC_FS */
748 +
749 + /** Firmware helper */
750 + const struct firmware *fw_helper;
751 + /** Firmware */
752 + const struct firmware *firmware;
753 + /** Hotplug device */
754 + struct device *hotplug_device;
755 + /** thread to service interrupts */
756 + uap_thread MainThread;
757 + /** Driver lock */
758 + spinlock_t driver_lock;
759 + /** Driver lock flags */
760 + ulong driver_flags;
761 +
762 +};
763 +
764 +/** PS_CMD_ConfirmSleep */
765 +typedef struct _PS_CMD_ConfirmSleep
766 +{
767 + /** SDIO Length */
768 + u16 SDLen;
769 + /** SDIO Type */
770 + u16 SDType;
771 + /** Command */
772 + u16 Command;
773 + /** Size */
774 + u16 Size;
775 + /** Sequence number */
776 + u16 SeqNum;
777 + /** Result */
778 + u16 Result;
779 +} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep;
780 +
781 +/** Wlan Adapter data structure*/
782 +struct _uap_adapter
783 +{
784 + /** Power save confirm sleep command */
785 + PS_CMD_ConfirmSleep PSConfirmSleep;
786 + /** Device status */
787 + HARDWARE_STATUS HardwareStatus;
788 + /** Interrupt counter */
789 + u32 IntCounter;
790 + /** Tx packet queue */
791 + struct sk_buff_head tx_queue;
792 + /** Cmd packet queue */
793 + struct sk_buff_head cmd_queue;
794 + /** Command sequence number */
795 + u16 SeqNum;
796 + /** Command buffer */
797 + u8 *CmdBuf;
798 + /** cmd pending flag */
799 + u8 cmd_pending;
800 + /** cmd wait option */
801 + u8 cmd_wait_option;
802 + /** Command buffer length */
803 + u32 CmdSize;
804 + /** Command wait queue */
805 + wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__;
806 + /** Command wait queue state flag */
807 + u8 CmdWaitQWoken;
808 + /** PnP support */
809 + BOOLEAN SurpriseRemoved;
810 + /** Debug */
811 + uap_dbg dbg;
812 + /** Netlink kernel socket */
813 + struct sock *nl_sk;
814 + /** Semaphore for CMD */
815 + SEMAPHORE CmdSem;
816 + /** Power Save mode */
817 + u8 psmode;
818 + /** Power Save state */
819 + u8 ps_state;
820 + /** Number of wakeup tries */
821 + u32 WakeupTries;
822 +};
823 +
824 +static inline int
825 +os_upload_rx_packet(uap_private * priv, struct sk_buff *skb)
826 +{
827 + skb->dev = priv->uap_dev.netdev;
828 + skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev);
829 + skb->ip_summed = CHECKSUM_UNNECESSARY;
830 + if (in_interrupt())
831 + netif_rx(skb);
832 + else
833 + netif_rx_ni(skb);
834 + return 0;
835 +}
836 +
837 +/*
838 + * netif carrier_on/off and start(wake)/stop_queue handling
839 + */
840 +static inline void
841 +os_carrier_on(uap_private * priv)
842 +{
843 + if (!netif_carrier_ok(priv->uap_dev.netdev) &&
844 + (priv->MediaConnected == TRUE)) {
845 + netif_carrier_on(priv->uap_dev.netdev);
846 + }
847 +}
848 +
849 +static inline void
850 +os_carrier_off(uap_private * priv)
851 +{
852 + if (netif_carrier_ok(priv->uap_dev.netdev)) {
853 + netif_carrier_off(priv->uap_dev.netdev);
854 + }
855 +}
856 +
857 +static inline void
858 +os_start_queue(uap_private * priv)
859 +{
860 + if (netif_queue_stopped(priv->uap_dev.netdev) &&
861 + (priv->MediaConnected == TRUE)) {
862 + netif_wake_queue(priv->uap_dev.netdev);
863 + }
864 +}
865 +
866 +static inline void
867 +os_stop_queue(uap_private * priv)
868 +{
869 + if (!netif_queue_stopped(priv->uap_dev.netdev)) {
870 + netif_stop_queue(priv->uap_dev.netdev);
871 + }
872 +}
873 +
874 +/** Interface specific header */
875 +#define INTF_HEADER_LEN 4
876 +
877 +/** headroom alignment for tx packet */
878 +#define HEADER_ALIGNMENT 8
879 +
880 +/** The number of times to try when polling for status bits */
881 +#define MAX_POLL_TRIES 100
882 +
883 +/** Length of SNAP header */
884 +#define MRVDRV_SNAP_HEADER_LEN 8
885 +
886 +/** Extra length of Tx packet buffer */
887 +#define EXTRA_LEN 36
888 +
889 +/** Buffer size for ethernet Tx packets */
890 +#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
891 + (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN)
892 +
893 +/** Buffer size for ethernet Rx packets */
894 +#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
895 + (ETH_FRAME_LEN + sizeof(RxPD) \
896 + + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
897 +
898 +/** Packet type: data, command & event */
899 +typedef enum _mv_type
900 +{
901 + MV_TYPE_DAT = 0,
902 + MV_TYPE_CMD = 1,
903 + MV_TYPE_EVENT = 3
904 +} mv_type;
905 +
906 +/** Disable interrupt */
907 +#define OS_INT_DISABLE spin_lock_irqsave(&priv->driver_lock, priv->driver_flags)
908 +/** Enable interrupt */
909 +#define OS_INT_RESTORE spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags)
910 +
911 +int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb);
912 +void uap_interrupt(uap_private * priv);
913 +uap_private *uap_add_card(void *card);
914 +int uap_remove_card(void *card);
915 +int uap_process_event(uap_private * priv, u8 * payload, uint len);
916 +int uap_soft_reset(uap_private * priv);
917 +int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len);
918 +
919 +#ifdef CONFIG_PROC_FS
920 +/** The proc fs interface */
921 +void uap_proc_entry(uap_private * priv, struct net_device *dev);
922 +void uap_proc_remove(uap_private * priv);
923 +int string_to_number(char *s);
924 +void uap_debug_entry(uap_private * priv, struct net_device *dev);
925 +void uap_debug_remove(uap_private * priv);
926 +#endif /* CONFIG_PROC_FS */
927 +
928 +int sbi_register(void);
929 +
930 +void sbi_unregister(void);
931 +int sbi_register_dev(uap_private * priv);
932 +int sbi_unregister_dev(uap_private * priv);
933 +int sbi_prog_fw_w_helper(uap_private *);
934 +
935 +int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb);
936 +int sbi_enable_host_int(uap_private * priv);
937 +int sbi_disable_host_int(uap_private * priv);
938 +
939 +int sbi_get_int_status(uap_private * priv, u8 * ireg);
940 +/** Check firmware status */
941 +int sbi_check_fw_status(uap_private *, int);
942 +int sbi_prog_helper(uap_private *);
943 +
944 +int sbi_wakeup_firmware(uap_private * priv);
945 +
946 +#endif /* _UAP_DRV_H */
947 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h
948 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h 1970-01-01 01:00:00.000000000 +0100
949 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h 2012-07-31 14:23:04.000000000 +0200
950 @@ -0,0 +1,359 @@
951 +/** @file uap_fw.h
952 + *
953 + * @brief This file contains firmware specific defines.
954 + *
955 + * Copyright (C) 2008-2009, Marvell International Ltd.
956 + *
957 + * This software file (the "File") is distributed by Marvell International
958 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
959 + * (the "License"). You may use, redistribute and/or modify this File in
960 + * accordance with the terms and conditions of the License, a copy of which
961 + * is available along with the File in the gpl.txt file or by writing to
962 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
963 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
964 + *
965 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
966 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
967 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
968 + * this warranty disclaimer.
969 + *
970 + */
971 +/********************************************************
972 +Change log:
973 + 02/26/08: Initial creation
974 +********************************************************/
975 +
976 +#ifndef _UAP_FW_H
977 +#define _UAP_FW_H
978 +
979 +/** uap upload size */
980 +#define UAP_UPLD_SIZE 2312
981 +/** Packet type Micro AP */
982 +#define PKT_TYPE_MICROAP 1
983 +/** Packet type client */
984 +#define PKT_TYPE_CLIENT 0
985 +
986 +/** TxPD descriptor */
987 +typedef struct _TxPD
988 +{
989 + /** Bss Type */
990 + u8 BssType;
991 + /** Bss num */
992 + u8 BssNum;
993 + /** Tx packet length */
994 + u16 TxPktLength;
995 + /** Tx packet offset */
996 + u16 TxPktOffset;
997 + /** Tx packet type */
998 + u16 TxPktType;
999 + /** Tx Control */
1000 + u32 TxControl;
1001 + /** reserved */
1002 + u32 reserved[2];
1003 +} __ATTRIB_PACK__ TxPD, *PTxPD;
1004 +
1005 +/** RxPD Descriptor */
1006 +typedef struct _RxPD
1007 +{
1008 + /** Bss Type */
1009 + u8 BssType;
1010 + /** Bss Num */
1011 + u8 BssNum;
1012 + /** Tx packet length */
1013 + u16 RxPktLength;
1014 + /** Tx packet offset */
1015 + u16 RxPktOffset;
1016 +} __ATTRIB_PACK__ RxPD, *PRxPD;
1017 +
1018 +#ifdef BIG_ENDIAN
1019 +/** Convert from 16 bit little endian format to CPU format */
1020 +#define uap_le16_to_cpu(x) le16_to_cpu(x)
1021 +/** Convert from 32 bit little endian format to CPU format */
1022 +#define uap_le32_to_cpu(x) le32_to_cpu(x)
1023 +/** Convert from 64 bit little endian format to CPU format */
1024 +#define uap_le64_to_cpu(x) le64_to_cpu(x)
1025 +/** Convert to 16 bit little endian format from CPU format */
1026 +#define uap_cpu_to_le16(x) cpu_to_le16(x)
1027 +/** Convert to 32 bit little endian format from CPU format */
1028 +#define uap_cpu_to_le32(x) cpu_to_le32(x)
1029 +/** Convert to 64 bit little endian format from CPU format */
1030 +#define uap_cpu_to_le64(x) cpu_to_le64(x)
1031 +
1032 +/** Convert TxPD to little endian format from CPU format */
1033 +#define endian_convert_TxPD(x); \
1034 + { \
1035 + (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength); \
1036 + (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset); \
1037 + (x)->TxControl = uap_cpu_to_le32((x)->TxControl); \
1038 + (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType); \
1039 + }
1040 +
1041 +/** Convert RxPD from little endian format to CPU format */
1042 +#define endian_convert_RxPD(x); \
1043 + { \
1044 + (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength); \
1045 + (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset); \
1046 + }
1047 +#else /* BIG_ENDIAN */
1048 +/** Do nothing */
1049 +#define uap_le16_to_cpu(x) x
1050 +/** Do nothing */
1051 +#define uap_le32_to_cpu(x) x
1052 +/** Do nothing */
1053 +#define uap_le64_to_cpu(x) x
1054 +/** Do nothing */
1055 +#define uap_cpu_to_le16(x) x
1056 +/** Do nothing */
1057 +#define uap_cpu_to_le32(x) x
1058 +/** Do nothing */
1059 +#define uap_cpu_to_le64(x) x
1060 +
1061 +/** Do nothing */
1062 +#define endian_convert_TxPD(x)
1063 +/** Do nothing */
1064 +#define endian_convert_RxPD(x)
1065 +#endif /* BIG_ENDIAN */
1066 +
1067 +/** Host Command ID : Function initialization */
1068 +#define HostCmd_CMD_FUNC_INIT 0x00a9
1069 +/** Host Command ID : Function shutdown */
1070 +#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
1071 +
1072 +/** Host Command id: SYS_INFO */
1073 +#define HOST_CMD_APCMD_SYS_INFO 0x00ae
1074 +/** Host Command id: SYS_RESET */
1075 +#define HOST_CMD_APCMD_SYS_RESET 0x00af
1076 +/** Host Command id: SYS_CONFIGURE */
1077 +#define HOST_CMD_APCMD_SYS_CONFIGURE 0x00b0
1078 +/** Host Command id: BSS_START */
1079 +#define HOST_CMD_APCMD_BSS_START 0x00b1
1080 +/** Host Command id: SYS_STOP */
1081 +#define HOST_CMD_APCMD_BSS_STOP 0x00b2
1082 +/** Host Command id: STA_LIST */
1083 +#define HOST_CMD_APCMD_STA_LIST 0x00b3
1084 +/** Host Command id: STA_FILTER_TABLE */
1085 +#define HOST_CMD_APCMD_STA_FILTER_TABLE 0x00b4
1086 +/** Host Command id: STA_DEAUTH */
1087 +#define HOST_CMD_APCMD_STA_DEAUTH 0x00b5
1088 +/** Host Command id: SOFT_RESET */
1089 +#define HOST_CMD_APCMD_SOFT_RESET 0x00d5
1090 +/** Host Command id: POWER_MGMT_EXT */
1091 +#define HOST_CMD_POWER_MGMT_EXT 0x00ef
1092 +/** Host Command id: SLEEP_CONFIRM*/
1093 +#define HOST_CMD_SLEEP_CONFIRM 0x00d8
1094 +
1095 +/** TLV type : SSID */
1096 +#define TLV_TYPE_SSID 0x0000
1097 +/** TLV type : Rates */
1098 +#define TLV_TYPE_RATES 0x0001
1099 +/** TLV type : PHY DS */
1100 +#define TLV_TYPE_PHY_DS 0x0003
1101 +
1102 +/** TLV Id : Base id */
1103 +#define PROPRIETARY_TLV_BASE_ID 0x0100
1104 +/** TLV Id : AP_MAC_ADDRESS */
1105 +#define MRVL_AP_MAC_ADDRESS_TLV_ID (PROPRIETARY_TLV_BASE_ID + 43)
1106 +/** TLV Id : Beacon period */
1107 +#define MRVL_BEACON_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 44)
1108 +/** TLV Id : Dtim period */
1109 +#define MRVL_DTIM_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 45)
1110 +/** TLV Id : Basic rates */
1111 +#define MRVL_BASIC_RATES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 46)
1112 +/** TLV Id : Tx Power */
1113 +#define MRVL_TX_POWER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 47)
1114 +/** TLV Id : Broadcast SSID control */
1115 +#define MRVL_BCAST_SSID_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 48)
1116 +/** TLV Id : Preamble control */
1117 +#define MRVL_PREAMBLE_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 49)
1118 +/** TLV Id : Antenna control */
1119 +#define MRVL_ANTENNA_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 50)
1120 +/** TLV Id : RTS threshold */
1121 +#define MRVL_RTS_THRESHOLD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 51)
1122 +/** TLV Id : Radio control */
1123 +#define MRVL_RADIO_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 52)
1124 +/** TLV Id : TX data rate */
1125 +#define MRVL_TX_DATA_RATE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 53)
1126 +/** TLV Id : Packet forward control */
1127 +#define MRVL_PKT_FWD_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 54)
1128 +/** TLV Id : STA info */
1129 +#define MRVL_STA_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 55)
1130 +/** TLV Id : STA MAC address filter */
1131 +#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56)
1132 +/** TLV Id : STA ageout timer */
1133 +#define MRVL_STA_AGEOUT_TIMER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 57)
1134 +/** TLV Id : Security config */
1135 +#define MRVL_SECURITY_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 58)
1136 +/** TLV Id : WEP KEY */
1137 +#define MRVL_WEP_KEY_TLV_ID (PROPRIETARY_TLV_BASE_ID + 59)
1138 +/** TLV Id : WPA Passphrase */
1139 +#define MRVL_WPA_PASSPHRASE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 60)
1140 +
1141 +/** Action get */
1142 +#define ACTION_GET 0
1143 +/** Action set */
1144 +#define ACTION_SET 1
1145 +/** Length of ethernet address */
1146 +#ifndef ETH_ALEN
1147 +#define ETH_ALEN 6
1148 +#endif
1149 +
1150 +/** HostCmd_DS_GEN */
1151 +typedef struct
1152 +{
1153 + /** Command */
1154 + u16 Command;
1155 + /** Size */
1156 + u16 Size;
1157 + /** Sequence number */
1158 + u16 SeqNum;
1159 + /** Result */
1160 + u16 Result;
1161 +} __ATTRIB_PACK__ HostCmd_DS_GEN;
1162 +
1163 +/** Size of HostCmd_DS_GEN */
1164 +#define S_DS_GEN sizeof(HostCmd_DS_GEN)
1165 +
1166 +/** _HostCmd_HEADER*/
1167 +typedef struct
1168 +{
1169 + /** Command Header : Command */
1170 + u16 Command;
1171 + /** Command Header : Size */
1172 + u16 Size;
1173 +} __ATTRIB_PACK__ HostCmd_HEADER;
1174 +
1175 +/** HostCmd_SYS_CONFIG */
1176 +typedef struct _HostCmd_SYS_CONFIG
1177 +{
1178 + /** CMD Action GET/SET*/
1179 + u16 Action;
1180 + /** Tlv buffer */
1181 + u8 TlvBuffer[0];
1182 +} __ATTRIB_PACK__ HostCmd_SYS_CONFIG;
1183 +
1184 +/** HostCmd_DS_POWER_MGMT_EXT */
1185 +typedef struct _HostCmd_DS_POWER_MGMT_EXT
1186 +{
1187 + /** CMD Action Get/Set*/
1188 + u16 action;
1189 + /** power mode */
1190 + u16 power_mode;
1191 +} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT;
1192 +
1193 +/** _HostCmd_DS_COMMAND*/
1194 +typedef struct _HostCmd_DS_COMMAND
1195 +{
1196 +
1197 + /** Command Header : Command */
1198 + u16 Command;
1199 + /** Command Header : Size */
1200 + u16 Size;
1201 + /** Command Header : Sequence number */
1202 + u16 SeqNum;
1203 + /** Command Header : Result */
1204 + u16 Result;
1205 + /** Command Body */
1206 + union
1207 + {
1208 + HostCmd_SYS_CONFIG sys_config;
1209 + HostCmd_DS_POWER_MGMT_EXT pm_cfg;
1210 +
1211 + } params;
1212 +} __ATTRIB_PACK__ HostCmd_DS_COMMAND;
1213 +
1214 +/** MrvlIEtypesHeader_*/
1215 +typedef struct _MrvlIEtypesHeader
1216 +{
1217 + /** Header type */
1218 + u16 Type;
1219 + /** Header length */
1220 + u16 Len;
1221 +} __ATTRIB_PACK__ MrvlIEtypesHeader_t;
1222 +
1223 +/** MrvlIEtypes_Data_t */
1224 +typedef struct _MrvlIEtypes_Data_t
1225 +{
1226 + /** Header */
1227 + MrvlIEtypesHeader_t Header;
1228 + /** Data */
1229 + u8 Data[1];
1230 +} __ATTRIB_PACK__ MrvlIEtypes_Data_t;
1231 +
1232 +/** MrvlIEtypes_ChanListParamSet_t */
1233 +typedef struct _MrvlIEtypes_MacAddr_t
1234 +{
1235 + /** Header */
1236 + MrvlIEtypesHeader_t Header;
1237 + /** AP MAC address */
1238 + u8 ApMacAddr[ETH_ALEN];
1239 +} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t;
1240 +
1241 +/** Event ID: BSS started */
1242 +#define MICRO_AP_EV_ID_BSS_START 46
1243 +
1244 +/** Event ID: BSS idle event */
1245 +#define MICRO_AP_EV_BSS_IDLE 67
1246 +
1247 +/** Event ID: BSS active event */
1248 +#define MICRO_AP_EV_BSS_ACTIVE 68
1249 +
1250 +/** Event ID: PS_AWAKE */
1251 +#define EVENT_PS_AWAKE 0x0a
1252 +
1253 +/** Event ID: PS_SLEEP */
1254 +#define EVENT_PS_SLEEP 0x0b
1255 +
1256 +/** PS_STATE */
1257 +typedef enum _PS_STATE
1258 +{
1259 + PS_STATE_AWAKE,
1260 + PS_STATE_PRE_SLEEP,
1261 + PS_STATE_SLEEP
1262 +} PS_STATE;
1263 +
1264 +/** TLV type: AP Sleep param */
1265 +#define TLV_TYPE_AP_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 106)
1266 +/** TLV type: AP Inactivity Sleep param */
1267 +#define TLV_TYPE_AP_INACT_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 107)
1268 +
1269 +/** MrvlIEtypes_sleep_param_t */
1270 +typedef struct _MrvlIEtypes_sleep_param_t
1271 +{
1272 + /** Header */
1273 + MrvlIEtypesHeader_t header;
1274 + /** control bitmap */
1275 + u32 ctrl_bitmap;
1276 + /** min_sleep */
1277 + u32 min_sleep;
1278 + /** max_sleep */
1279 + u32 max_sleep;
1280 +} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t;
1281 +
1282 +/** MrvlIEtypes_inact_sleep_param_t */
1283 +typedef struct _MrvlIEtypes_inact_sleep_param_t
1284 +{
1285 + /** Header */
1286 + MrvlIEtypesHeader_t header;
1287 + /** inactivity timeout */
1288 + u32 inactivity_to;
1289 + /** min_awake */
1290 + u32 min_awake;
1291 + /** max_awake */
1292 + u32 max_awake;
1293 +} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t;
1294 +
1295 +/** AP_Event */
1296 +typedef struct _AP_Event
1297 +{
1298 + /** Event ID */
1299 + u32 EventId;
1300 + /*
1301 + * Reserved for STA_ASSOCIATED event and contains
1302 + * status information for the MIC_COUNTERMEASURES event.
1303 + */
1304 + /** Reserved/status */
1305 + u16 status;
1306 + /** AP MAC address */
1307 + u8 MacAddr[ETH_ALEN];
1308 +} __ATTRIB_PACK__ AP_Event;
1309 +#endif /* _UAP_FW_H */
1310 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h
1311 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h 1970-01-01 01:00:00.000000000 +0100
1312 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h 2012-07-31 14:23:04.000000000 +0200
1313 @@ -0,0 +1,64 @@
1314 +/** @file uap_headers.h
1315 + *
1316 + * @brief This file contains all the necessary include file.
1317 + *
1318 + * Copyright (C) 2008-2009, Marvell International Ltd.
1319 + *
1320 + * This software file (the "File") is distributed by Marvell International
1321 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
1322 + * (the "License"). You may use, redistribute and/or modify this File in
1323 + * accordance with the terms and conditions of the License, a copy of which
1324 + * is available along with the File in the gpl.txt file or by writing to
1325 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1326 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
1327 + *
1328 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
1329 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
1330 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
1331 + * this warranty disclaimer.
1332 + *
1333 + */
1334 +#ifndef _UAP_HEADERS_H
1335 +#define _UAP_HEADERS_H
1336 +
1337 +/* Linux header files */
1338 +#include <linux/kernel.h>
1339 +#include <linux/module.h>
1340 +#include <linux/init.h>
1341 +#include <linux/version.h>
1342 +#include <linux/param.h>
1343 +#include <linux/types.h>
1344 +#include <linux/interrupt.h>
1345 +#include <linux/proc_fs.h>
1346 +#include <linux/kthread.h>
1347 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
1348 +#include <linux/semaphore.h>
1349 +#else
1350 +#include <asm/semaphore.h>
1351 +#endif
1352 +
1353 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
1354 +#include <linux/config.h>
1355 +#endif
1356 +
1357 +/* Net header files */
1358 +#include <linux/netdevice.h>
1359 +#include <linux/net.h>
1360 +#include <linux/skbuff.h>
1361 +#include <linux/if_ether.h>
1362 +#include <linux/etherdevice.h>
1363 +#include <net/sock.h>
1364 +#include <linux/netlink.h>
1365 +#include <linux/firmware.h>
1366 +#include <linux/delay.h>
1367 +
1368 +#include "uap_drv.h"
1369 +#include "uap_fw.h"
1370 +
1371 +#include <linux/mmc/sdio.h>
1372 +#include <linux/mmc/sdio_ids.h>
1373 +#include <linux/mmc/sdio_func.h>
1374 +#include <linux/mmc/card.h>
1375 +#include "uap_sdio_mmc.h"
1376 +
1377 +#endif /* _UAP_HEADERS_H */
1378 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c
1379 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c 1970-01-01 01:00:00.000000000 +0100
1380 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c 2012-07-31 14:25:28.473230753 +0200
1381 @@ -0,0 +1,1815 @@
1382 +/** @file uap_main.c
1383 + * @brief This file contains the major functions in uAP
1384 + * driver. It includes init, exit etc..
1385 + * This file also contains the initialization for SW,
1386 + * FW and HW
1387 + *
1388 + * Copyright (C) 2008-2009, Marvell International Ltd.
1389 + *
1390 + * This software file (the "File") is distributed by Marvell International
1391 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
1392 + * (the "License"). You may use, redistribute and/or modify this File in
1393 + * accordance with the terms and conditions of the License, a copy of which
1394 + * is available along with the File in the gpl.txt file or by writing to
1395 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1396 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
1397 + *
1398 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
1399 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
1400 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
1401 + * this warranty disclaimer.
1402 + *
1403 + */
1404 +/**
1405 + * @mainpage uAP Linux Driver
1406 + *
1407 + * @section overview_sec Overview
1408 + *
1409 + * This is Linux reference driver for Marvell uAP.
1410 + *
1411 + * @section copyright_sec Copyright
1412 + *
1413 + * Copyright (C) 2008, Marvell International Ltd.
1414 + *
1415 + */
1416 +
1417 +#include "uap_headers.h"
1418 +
1419 +/**
1420 + * the global variable of a pointer to uap_private
1421 + * structure variable
1422 + */
1423 +uap_private *uappriv = NULL;
1424 +#ifdef DEBUG_LEVEL1
1425 +#define DEFAULT_DEBUG_MASK (DBG_MSG | DBG_FATAL | DBG_ERROR)
1426 +u32 drvdbg = DEFAULT_DEBUG_MASK;
1427 +#endif
1428 +/** Helper name */
1429 +char *helper_name = NULL;
1430 +/** Firmware name */
1431 +char *fw_name = NULL;
1432 +
1433 +/** Semaphore for add/remove card */
1434 +SEMAPHORE AddRemoveCardSem;
1435 +
1436 +/********************************************************
1437 + Local Functions
1438 +********************************************************/
1439 +/**
1440 + * @brief This function send sleep confirm command to firmware
1441 + *
1442 + * @param priv A pointer to uap_private structure
1443 + * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
1444 + */
1445 +static int
1446 +uap_dnld_sleep_confirm_cmd(uap_private * priv)
1447 +{
1448 + uap_adapter *Adapter = priv->adapter;
1449 + int ret = UAP_STATUS_SUCCESS;
1450 + ENTER();
1451 + PRINTM(CMND, "Sleep confirm\n");
1452 + Adapter->cmd_pending = TRUE;
1453 + Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM;
1454 + ret =
1455 + sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep,
1456 + sizeof(PS_CMD_ConfirmSleep));
1457 + if (ret != UAP_STATUS_SUCCESS) {
1458 + Adapter->ps_state = PS_STATE_AWAKE;
1459 + Adapter->cmd_pending = FALSE;
1460 + Adapter->cmd_wait_option = FALSE;
1461 + }
1462 + LEAVE();
1463 + return ret;
1464 +}
1465 +
1466 +/**
1467 + * @brief This function process sleep confirm resp from firmware
1468 + *
1469 + * @param priv A pointer to uap_private structure
1470 + * @param resp A pointer to resp buf
1471 + * @param resp_len resp buf len
1472 + * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
1473 + */
1474 +int
1475 +uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len)
1476 +{
1477 + int ret = UAP_STATUS_SUCCESS;
1478 + HostCmd_DS_COMMAND *cmd;
1479 + uap_adapter *Adapter = priv->adapter;
1480 + ENTER();
1481 + PRINTM(CMND, "Sleep confirm resp\n");
1482 + if (!resp_len) {
1483 + PRINTM(ERROR, "Cmd Size is 0\n");
1484 + ret = -EFAULT;
1485 + goto done;
1486 + }
1487 + cmd = (HostCmd_DS_COMMAND *) resp;
1488 + cmd->Result = uap_le16_to_cpu(cmd->Result);
1489 + if (cmd->Result != UAP_STATUS_SUCCESS) {
1490 + PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result);
1491 + ret = -EFAULT;
1492 + }
1493 + done:
1494 + if (ret == UAP_STATUS_SUCCESS)
1495 + Adapter->ps_state = PS_STATE_SLEEP;
1496 + else
1497 + Adapter->ps_state = PS_STATE_AWAKE;
1498 + LEAVE();
1499 + return ret;
1500 +}
1501 +
1502 +/**
1503 + * @brief This function checks condition and prepares to
1504 + * send sleep confirm command to firmware if OK.
1505 + *
1506 + * @param priv A pointer to uap_private structure
1507 + * @return n/a
1508 + */
1509 +static void
1510 +uap_ps_cond_check(uap_private * priv)
1511 +{
1512 + uap_adapter *Adapter = priv->adapter;
1513 +
1514 + ENTER();
1515 + if (!priv->uap_dev.cmd_sent &&
1516 + !Adapter->cmd_pending && !Adapter->IntCounter) {
1517 + uap_dnld_sleep_confirm_cmd(priv);
1518 + } else {
1519 + PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n",
1520 + (priv->uap_dev.cmd_sent) ? "D" : "",
1521 + (Adapter->cmd_pending) ? "C" : "",
1522 + (Adapter->IntCounter) ? "I" : "");
1523 + }
1524 + LEAVE();
1525 +}
1526 +
1527 +/**
1528 + * @brief This function add cmd to cmdQ and waiting for response
1529 + *
1530 + * @param priv A pointer to uap_private structure
1531 + * @param skb A pointer to the skb for process
1532 + * @param wait_option Wait option
1533 + * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
1534 + */
1535 +static int
1536 +uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option)
1537 +{
1538 + uap_adapter *Adapter = priv->adapter;
1539 + int ret = UAP_STATUS_SUCCESS;
1540 + HostCmd_DS_COMMAND *cmd;
1541 + u8 *headptr;
1542 + ENTER();
1543 + if (Adapter->HardwareStatus != HWReady) {
1544 + PRINTM(ERROR, "Hw not ready, uap_process_cmd\n");
1545 + kfree(skb);
1546 + LEAVE();
1547 + return -EFAULT;
1548 + }
1549 + skb->cb[0] = wait_option;
1550 + headptr = skb->data;
1551 + *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len);
1552 + *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD);
1553 + cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
1554 + Adapter->SeqNum++;
1555 + cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum);
1556 + PRINTM(CMND, "process_cmd: %x\n", cmd->Command);
1557 + DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size);
1558 + if (!wait_option) {
1559 + skb_queue_tail(&priv->adapter->cmd_queue, skb);
1560 + wake_up_interruptible(&priv->MainThread.waitQ);
1561 + LEAVE();
1562 + return ret;
1563 + }
1564 + if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) {
1565 + PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n");
1566 + kfree(skb);
1567 + LEAVE();
1568 + return -EBUSY;
1569 + }
1570 + skb_queue_tail(&priv->adapter->cmd_queue, skb);
1571 + Adapter->CmdWaitQWoken = FALSE;
1572 + wake_up_interruptible(&priv->MainThread.waitQ);
1573 + /* Sleep until response is generated by FW */
1574 + if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) {
1575 + if (!os_wait_interruptible_timeout
1576 + (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) {
1577 + PRINTM(ERROR, "Cmd timeout\n");
1578 + Adapter->cmd_pending = FALSE;
1579 + ret = -EFAULT;
1580 + }
1581 + } else
1582 + wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken);
1583 + OS_REL_SEMAPHORE(&Adapter->CmdSem);
1584 + LEAVE();
1585 + return ret;
1586 +}
1587 +
1588 +/**
1589 + * @brief Inspect the response buffer for pointers to expected TLVs
1590 + *
1591 + *
1592 + * @param pTlv Pointer to the start of the TLV buffer to parse
1593 + * @param tlvBufSize Size of the TLV buffer
1594 + * @param reqTlvType request tlv's tlvtype
1595 + * @param ppTlv Output parameter: Pointer to the request TLV if found
1596 + *
1597 + * @return void
1598 + */
1599 +static void
1600 +uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize,
1601 + u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv)
1602 +{
1603 + MrvlIEtypes_Data_t *pCurrentTlv;
1604 + int tlvBufLeft;
1605 + u16 tlvType;
1606 + u16 tlvLen;
1607 +
1608 + ENTER();
1609 + pCurrentTlv = pTlv;
1610 + tlvBufLeft = tlvBufSize;
1611 + *ppTlv = NULL;
1612 + PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize,
1613 + reqTlvType);
1614 + while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) {
1615 + tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type);
1616 + tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len);
1617 + if (reqTlvType == tlvType)
1618 + *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv;
1619 + if (*ppTlv) {
1620 + HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen);
1621 + break;
1622 + }
1623 + tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen);
1624 + pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen);
1625 + } /* while */
1626 + LEAVE();
1627 +}
1628 +
1629 +/**
1630 + * @brief This function get mac
1631 + *
1632 + * @param priv A pointer to uap_private structure
1633 + * @return UAP_STATUS_SUCCESS on success, otherwise failure code
1634 + */
1635 +static int
1636 +uap_get_mac_address(uap_private * priv)
1637 +{
1638 + int ret = UAP_STATUS_SUCCESS;
1639 + u32 CmdSize;
1640 + HostCmd_DS_COMMAND *cmd;
1641 + uap_adapter *Adapter = priv->adapter;
1642 + struct sk_buff *skb;
1643 + MrvlIEtypes_MacAddr_t *pMacAddrTlv;
1644 + MrvlIEtypes_Data_t *pTlv;
1645 + u16 tlvBufSize;
1646 + ENTER();
1647 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
1648 + if (!skb) {
1649 + PRINTM(ERROR, "No free skb\n");
1650 + ret = -ENOMEM;
1651 + goto done;
1652 + }
1653 + CmdSize =
1654 + S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
1655 + cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
1656 + cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
1657 + cmd->Size = uap_cpu_to_le16(CmdSize);
1658 + cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET);
1659 + pMacAddrTlv =
1660 + (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN +
1661 + sizeof(HostCmd_SYS_CONFIG));
1662 + pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
1663 + pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
1664 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
1665 + if (UAP_STATUS_SUCCESS !=
1666 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
1667 + PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n");
1668 + ret = -EFAULT;
1669 + goto done;
1670 + }
1671 + if (!Adapter->CmdSize) {
1672 + PRINTM(ERROR, "Cmd Size is 0\n");
1673 + ret = -EFAULT;
1674 + goto done;
1675 + }
1676 + cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
1677 + cmd->Result = uap_le16_to_cpu(cmd->Result);
1678 + if (cmd->Result != UAP_STATUS_SUCCESS) {
1679 + PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result);
1680 + ret = -EFAULT;
1681 + goto done;
1682 + }
1683 + pTlv =
1684 + (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN +
1685 + sizeof(HostCmd_SYS_CONFIG));
1686 + tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG);
1687 + uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID,
1688 + (MrvlIEtypes_Data_t **) & pMacAddrTlv);
1689 + if (pMacAddrTlv) {
1690 + memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr,
1691 + ETH_ALEN);
1692 + HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN);
1693 + }
1694 + done:
1695 + LEAVE();
1696 + return ret;
1697 +}
1698 +
1699 +/**
1700 + * @brief This function checks the conditions and sends packet to device
1701 + *
1702 + * @param priv A pointer to uap_private structure
1703 + * @param skb A pointer to the skb for process
1704 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
1705 + */
1706 +static int
1707 +uap_process_tx(uap_private * priv, struct sk_buff *skb)
1708 +{
1709 + uap_adapter *Adapter = priv->adapter;
1710 + int ret = UAP_STATUS_SUCCESS;
1711 + TxPD *pLocalTxPD;
1712 + u8 *headptr;
1713 + struct sk_buff *newskb;
1714 + int newheadlen;
1715 + ENTER();
1716 + ASSERT(skb);
1717 + if (!skb) {
1718 + LEAVE();
1719 + return UAP_STATUS_FAILURE;
1720 + }
1721 + if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) {
1722 + newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT;
1723 + PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb));
1724 + /* Insufficient skb headroom - allocate a new skb */
1725 + newskb = skb_realloc_headroom(skb, newheadlen);
1726 + if (unlikely(newskb == NULL)) {
1727 + PRINTM(ERROR, "Tx: Cannot allocate skb\n");
1728 + ret = UAP_STATUS_FAILURE;
1729 + goto done;
1730 + }
1731 + kfree_skb(skb);
1732 + skb = newskb;
1733 + PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb));
1734 + }
1735 + /* headptr should be aligned */
1736 + headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN;
1737 + headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1)));
1738 +
1739 + pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN);
1740 + memset(pLocalTxPD, 0, sizeof(TxPD));
1741 + pLocalTxPD->BssType = PKT_TYPE_MICROAP;
1742 + pLocalTxPD->TxPktLength = skb->len;
1743 + /* offset of actual data */
1744 + pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD;
1745 + endian_convert_TxPD(pLocalTxPD);
1746 + *(u16 *) & headptr[0] =
1747 + uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr));
1748 + *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT);
1749 + ret =
1750 + sbi_host_to_card(priv, headptr,
1751 + skb->len + ((long) skb->data - (long) headptr));
1752 + if (ret) {
1753 + PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n",
1754 + ret);
1755 + Adapter->dbg.num_tx_host_to_card_failure++;
1756 + goto done;
1757 + }
1758 + PRINTM(DATA, "Data => FW\n");
1759 + DBG_HEXDUMP(DAT_D, "Tx", headptr,
1760 + MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN));
1761 + done:
1762 + /* Freed skb */
1763 + kfree_skb(skb);
1764 + LEAVE();
1765 + return ret;
1766 +}
1767 +
1768 +/**
1769 + * @brief This function initializes the adapter structure
1770 + * and set default value to the member of adapter.
1771 + *
1772 + * @param priv A pointer to uap_private structure
1773 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
1774 + */
1775 +static int
1776 +uap_init_sw(uap_private * priv)
1777 +{
1778 + uap_adapter *Adapter = priv->adapter;
1779 +
1780 + ENTER();
1781 +
1782 + if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) {
1783 + PRINTM(INFO, "Failed to allocate command buffer!\n");
1784 + LEAVE();
1785 + return UAP_STATUS_FAILURE;
1786 + }
1787 +
1788 + Adapter->cmd_pending = FALSE;
1789 + Adapter->CmdWaitQWoken = FALSE;
1790 + Adapter->ps_state = PS_STATE_AWAKE;
1791 + Adapter->WakeupTries = 0;
1792 +
1793 + memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep));
1794 + /** SDIO header */
1795 + Adapter->PSConfirmSleep.SDLen =
1796 + uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
1797 + Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD);
1798 + Adapter->PSConfirmSleep.SeqNum = 0;
1799 + Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM);
1800 + Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN));
1801 + Adapter->PSConfirmSleep.Result = 0;
1802 +
1803 + init_waitqueue_head(&Adapter->cmdwait_q);
1804 + OS_INIT_SEMAPHORE(&Adapter->CmdSem);
1805 +
1806 + skb_queue_head_init(&Adapter->tx_queue);
1807 + skb_queue_head_init(&Adapter->cmd_queue);
1808 +
1809 + /* Status variable */
1810 + Adapter->HardwareStatus = HWInitializing;
1811 +
1812 + /* PnP support */
1813 + Adapter->SurpriseRemoved = FALSE;
1814 +
1815 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
1816 + Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
1817 + NL_MULTICAST_GROUP, NULL,
1818 + THIS_MODULE);
1819 +#else
1820 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1821 + Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
1822 + NL_MULTICAST_GROUP, NULL, NULL,
1823 + THIS_MODULE);
1824 +#else
1825 + Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL,
1826 + NL_MULTICAST_GROUP, NULL, NULL,
1827 + THIS_MODULE);
1828 +#endif
1829 +#endif
1830 + if (!Adapter->nl_sk) {
1831 + PRINTM(ERROR,
1832 + "Could not initialize netlink event passing mechanism!\n");
1833 + }
1834 + LEAVE();
1835 + return UAP_STATUS_SUCCESS;
1836 +}
1837 +
1838 +/**
1839 + * @brief This function sends FUNC_INIT command to firmware
1840 + *
1841 + * @param priv A pointer to uap_private structure
1842 + * @return UAP_STATUS_SUCCESS on success, otherwise failure code
1843 + */
1844 +static int
1845 +uap_func_init(uap_private * priv)
1846 +{
1847 + int ret = UAP_STATUS_SUCCESS;
1848 + u32 CmdSize;
1849 + HostCmd_DS_GEN *cmd;
1850 + uap_adapter *Adapter = priv->adapter;
1851 + struct sk_buff *skb;
1852 + ENTER();
1853 + if (Adapter->HardwareStatus != HWReady) {
1854 + PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n");
1855 + ret = -EFAULT;
1856 + goto done;
1857 + }
1858 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
1859 + if (!skb) {
1860 + PRINTM(ERROR, "No free skb\n");
1861 + ret = -ENOMEM;
1862 + goto done;
1863 + }
1864 + CmdSize = sizeof(HostCmd_DS_GEN);
1865 + cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
1866 + cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT);
1867 + cmd->Size = uap_cpu_to_le16(CmdSize);
1868 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
1869 + PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n");
1870 + if (UAP_STATUS_SUCCESS !=
1871 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
1872 + PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n");
1873 + ret = -EFAULT;
1874 + goto done;
1875 + }
1876 + done:
1877 + LEAVE();
1878 + return ret;
1879 +}
1880 +
1881 +/**
1882 + * @brief This function sends FUNC_SHUTDOWN command to firmware
1883 + *
1884 + * @param priv A pointer to uap_private structure
1885 + * @return UAP_STATUS_SUCCESS on success, otherwise failure code
1886 + */
1887 +static int __exit
1888 +uap_func_shutdown(uap_private * priv)
1889 +{
1890 + int ret = UAP_STATUS_SUCCESS;
1891 + u32 CmdSize;
1892 + HostCmd_DS_GEN *cmd;
1893 + uap_adapter *Adapter = priv->adapter;
1894 + struct sk_buff *skb;
1895 + ENTER();
1896 + if (Adapter->HardwareStatus != HWReady) {
1897 + PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n");
1898 + ret = -EFAULT;
1899 + goto done;
1900 + }
1901 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
1902 + if (!skb) {
1903 + PRINTM(ERROR, "No free skb\n");
1904 + ret = -ENOMEM;
1905 + goto done;
1906 + }
1907 + CmdSize = sizeof(HostCmd_DS_GEN);
1908 + cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
1909 + cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN);
1910 + cmd->Size = uap_cpu_to_le16(CmdSize);
1911 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
1912 + PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n");
1913 + if (UAP_STATUS_SUCCESS !=
1914 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
1915 + PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n");
1916 + ret = -EFAULT;
1917 + goto done;
1918 + }
1919 + done:
1920 + LEAVE();
1921 + return ret;
1922 +}
1923 +
1924 +/**
1925 + * @brief This function initializes firmware
1926 + *
1927 + * @param priv A pointer to uap_private structure
1928 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
1929 + */
1930 +static int
1931 +uap_init_fw(uap_private * priv)
1932 +{
1933 + int ret = UAP_STATUS_SUCCESS;
1934 + ENTER();
1935 + sbi_disable_host_int(priv);
1936 + /* Check if firmware is already running */
1937 + if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) {
1938 + PRINTM(MSG, "UAP FW already running! Skip FW download\n");
1939 + } else {
1940 + if ((ret = request_firmware(&priv->fw_helper, helper_name,
1941 + priv->hotplug_device)) < 0) {
1942 + PRINTM(FATAL,
1943 + "request_firmware() failed (helper), error code = %#x\n",
1944 + ret);
1945 + goto done;
1946 + }
1947 +
1948 + /* Download the helper */
1949 + ret = sbi_prog_helper(priv);
1950 +
1951 + if (ret) {
1952 + PRINTM(FATAL,
1953 + "Bootloader in invalid state! Helper download failed!\n");
1954 + ret = UAP_STATUS_FAILURE;
1955 + goto done;
1956 + }
1957 + if ((ret = request_firmware(&priv->firmware, fw_name,
1958 + priv->hotplug_device)) < 0) {
1959 + PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret);
1960 + goto done;
1961 + }
1962 +
1963 + /* Download the main firmware via the helper firmware */
1964 + if (sbi_prog_fw_w_helper(priv)) {
1965 + PRINTM(FATAL, "UAP FW download failed!\n");
1966 + ret = UAP_STATUS_FAILURE;
1967 + goto done;
1968 + }
1969 + /* Check if the firmware is downloaded successfully or not */
1970 + if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) ==
1971 + UAP_STATUS_FAILURE) {
1972 + PRINTM(FATAL, "FW failed to be active in time!\n");
1973 + ret = UAP_STATUS_FAILURE;
1974 + goto done;
1975 + }
1976 + PRINTM(MSG, "UAP FW is active\n");
1977 + }
1978 + sbi_enable_host_int(priv);
1979 + priv->adapter->HardwareStatus = HWReady;
1980 + if (uap_func_init(priv) != UAP_STATUS_SUCCESS) {
1981 + ret = UAP_STATUS_FAILURE;
1982 + goto done;
1983 + }
1984 + done:
1985 + if (priv->fw_helper)
1986 + release_firmware(priv->fw_helper);
1987 + if (priv->firmware)
1988 + release_firmware(priv->firmware);
1989 + LEAVE();
1990 + return ret;
1991 +
1992 +}
1993 +
1994 +/**
1995 + * @brief This function frees the structure of adapter
1996 + *
1997 + * @param priv A pointer to uap_private structure
1998 + * @return n/a
1999 + */
2000 +static void
2001 +uap_free_adapter(uap_private * priv)
2002 +{
2003 + uap_adapter *Adapter = priv->adapter;
2004 +
2005 + ENTER();
2006 +
2007 + if (Adapter) {
2008 + if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
2009 + sock_release((Adapter->nl_sk)->sk_socket);
2010 + Adapter->nl_sk = NULL;
2011 + }
2012 + if (Adapter->CmdBuf)
2013 + kfree(Adapter->CmdBuf);
2014 + skb_queue_purge(&priv->adapter->tx_queue);
2015 + skb_queue_purge(&priv->adapter->cmd_queue);
2016 + /* Free the adapter object itself */
2017 + kfree(Adapter);
2018 + priv->adapter = NULL;
2019 + }
2020 +
2021 + LEAVE();
2022 +}
2023 +
2024 +/**
2025 + * @brief This function handles the major job in uap driver.
2026 + * it handles the event generated by firmware, rx data received
2027 + * from firmware and tx data sent from kernel.
2028 + *
2029 + * @param data A pointer to uap_thread structure
2030 + * @return BT_STATUS_SUCCESS
2031 + */
2032 +static int
2033 +uap_service_main_thread(void *data)
2034 +{
2035 + uap_thread *thread = data;
2036 + uap_private *priv = thread->priv;
2037 + uap_adapter *Adapter = priv->adapter;
2038 + wait_queue_t wait;
2039 + u8 ireg = 0;
2040 + struct sk_buff *skb;
2041 + ENTER();
2042 + uap_activate_thread(thread);
2043 + init_waitqueue_entry(&wait, current);
2044 + current->flags |= PF_NOFREEZE;
2045 +
2046 + for (;;) {
2047 + add_wait_queue(&thread->waitQ, &wait);
2048 + OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
2049 + if ((Adapter->WakeupTries) ||
2050 + (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) ||
2051 + (!priv->adapter->IntCounter
2052 + && (priv->uap_dev.data_sent ||
2053 + skb_queue_empty(&priv->adapter->tx_queue))
2054 + && (priv->uap_dev.cmd_sent || Adapter->cmd_pending ||
2055 + skb_queue_empty(&priv->adapter->cmd_queue))
2056 + )) {
2057 + PRINTM(INFO, "Main: Thread sleeping...\n");
2058 + schedule();
2059 + }
2060 + OS_SET_THREAD_STATE(TASK_RUNNING);
2061 + remove_wait_queue(&thread->waitQ, &wait);
2062 + if (kthread_should_stop() || Adapter->SurpriseRemoved) {
2063 + PRINTM(INFO, "main-thread: break from main thread: "
2064 + "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved);
2065 + /* Cancel pending command */
2066 + if (Adapter->cmd_pending == TRUE) {
2067 + /* Wake up cmd Q */
2068 + Adapter->CmdWaitQWoken = TRUE;
2069 + wake_up_interruptible(&Adapter->cmdwait_q);
2070 + }
2071 + break;
2072 + }
2073 +
2074 + PRINTM(INFO, "Main: Thread waking up...\n");
2075 + if (priv->adapter->IntCounter) {
2076 + OS_INT_DISABLE;
2077 + Adapter->IntCounter = 0;
2078 + OS_INT_RESTORE;
2079 + sbi_get_int_status(priv, &ireg);
2080 + } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) &&
2081 + (!skb_queue_empty(&priv->adapter->cmd_queue) ||
2082 + !skb_queue_empty(&priv->adapter->tx_queue))) {
2083 + priv->adapter->WakeupTries++;
2084 + PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get());
2085 + sbi_wakeup_firmware(priv);
2086 + continue;
2087 + }
2088 + if (Adapter->ps_state == PS_STATE_PRE_SLEEP)
2089 + uap_ps_cond_check(priv);
2090 +
2091 + /* The PS state is changed during processing of Sleep Request event
2092 + above */
2093 + if ((Adapter->ps_state == PS_STATE_SLEEP) ||
2094 + (Adapter->ps_state == PS_STATE_PRE_SLEEP))
2095 + continue;
2096 + /* Execute the next command */
2097 + if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending &&
2098 + (Adapter->HardwareStatus == HWReady)) {
2099 + if (!skb_queue_empty(&priv->adapter->cmd_queue)) {
2100 + skb = skb_dequeue(&priv->adapter->cmd_queue);
2101 + if (skb) {
2102 + Adapter->CmdSize = 0;
2103 + Adapter->cmd_pending = TRUE;
2104 + Adapter->cmd_wait_option = skb->cb[0];
2105 + if (sbi_host_to_card(priv, skb->data, skb->len)) {
2106 + PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n");
2107 + Adapter->cmd_pending = FALSE;
2108 + Adapter->dbg.num_cmd_host_to_card_failure++;
2109 + /* Wake up cmd Q */
2110 + Adapter->CmdWaitQWoken = TRUE;
2111 + wake_up_interruptible(&Adapter->cmdwait_q);
2112 + } else {
2113 + if (Adapter->cmd_wait_option ==
2114 + HostCmd_OPTION_WAITFORSEND) {
2115 + /* Wake up cmd Q */
2116 + Adapter->CmdWaitQWoken = TRUE;
2117 + wake_up_interruptible(&Adapter->cmdwait_q);
2118 + Adapter->cmd_wait_option = FALSE;
2119 + }
2120 + }
2121 + kfree_skb(skb);
2122 + }
2123 + }
2124 + }
2125 + if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) {
2126 + if (!skb_queue_empty(&priv->adapter->tx_queue)) {
2127 + skb = skb_dequeue(&priv->adapter->tx_queue);
2128 + if (skb) {
2129 + if (uap_process_tx(priv, skb)) {
2130 + priv->stats.tx_dropped++;
2131 + priv->stats.tx_errors++;
2132 + os_start_queue(priv);
2133 + } else {
2134 + priv->stats.tx_packets++;
2135 + priv->stats.tx_bytes += skb->len;
2136 + }
2137 +
2138 + }
2139 + }
2140 + }
2141 + }
2142 + uap_deactivate_thread(thread);
2143 + LEAVE();
2144 + return UAP_STATUS_SUCCESS;
2145 +}
2146 +
2147 +/**
2148 + * @brief uap hostcmd ioctl handler
2149 + *
2150 + * @param dev A pointer to net_device structure
2151 + * @param req A pointer to ifreq structure
2152 + * @return UAP_STATUS_SUCCESS --success, otherwise fail
2153 + */
2154 +/********* format of ifr_data *************/
2155 +/* buf_len + Hostcmd_body */
2156 +/* buf_len: 4 bytes */
2157 +/* the length of the buf which */
2158 +/* can be used to return data */
2159 +/* to application */
2160 +/* Hostcmd_body */
2161 +/*******************************************/
2162 +static int
2163 +uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
2164 +{
2165 + u32 buf_len;
2166 + HostCmd_HEADER head;
2167 + uap_private *priv = (uap_private *) netdev_priv(dev);
2168 + uap_adapter *Adapter = priv->adapter;
2169 + int ret = UAP_STATUS_SUCCESS;
2170 + struct sk_buff *skb;
2171 +
2172 + ENTER();
2173 +
2174 + /* Sanity check */
2175 + if (req->ifr_data == NULL) {
2176 + PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n");
2177 + LEAVE();
2178 + return -EFAULT;
2179 + }
2180 + if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) {
2181 + PRINTM(ERROR, "Copy from user failed\n");
2182 + LEAVE();
2183 + return -EFAULT;
2184 + }
2185 + memset(&head, 0, sizeof(HostCmd_HEADER));
2186 + /* Get the command size from user space */
2187 + if (copy_from_user
2188 + (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) {
2189 + PRINTM(ERROR, "Copy from user failed\n");
2190 + LEAVE();
2191 + return -EFAULT;
2192 + }
2193 + head.Size = uap_le16_to_cpu(head.Size);
2194 + if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) {
2195 + PRINTM(ERROR, "CmdSize too big=%d\n", head.Size);
2196 + LEAVE();
2197 + return -EFAULT;
2198 + }
2199 + PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command,
2200 + head.Size, buf_len);
2201 + skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN);
2202 + if (!skb) {
2203 + PRINTM(ERROR, "No free skb\n");
2204 + LEAVE();
2205 + return -ENOMEM;
2206 + }
2207 +
2208 + /* Get the command from user space */
2209 + if (copy_from_user
2210 + (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len),
2211 + head.Size)) {
2212 + PRINTM(ERROR, "Copy from user failed\n");
2213 + LEAVE();
2214 + return -EFAULT;
2215 + }
2216 + skb_put(skb, head.Size + INTF_HEADER_LEN);
2217 + if (UAP_STATUS_SUCCESS !=
2218 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
2219 + PRINTM(ERROR, "Fail to process cmd\n");
2220 + LEAVE();
2221 + return -EFAULT;
2222 + }
2223 + if (!Adapter->CmdSize) {
2224 + PRINTM(ERROR, "Cmd Size is 0\n");
2225 + LEAVE();
2226 + return -EFAULT;
2227 + }
2228 + if (Adapter->CmdSize > buf_len) {
2229 + PRINTM(ERROR, "buf_len is too small\n");
2230 + LEAVE();
2231 + return -EFAULT;
2232 + }
2233 + /* Copy to user */
2234 + if (copy_to_user
2235 + (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) {
2236 + PRINTM(ERROR, "Copy to user failed!\n");
2237 + LEAVE();
2238 + return -EFAULT;
2239 + }
2240 + LEAVE();
2241 + return ret;
2242 +}
2243 +
2244 +/**
2245 + * @brief uap power mode ioctl handler
2246 + *
2247 + * @param dev A pointer to net_device structure
2248 + * @param req A pointer to ifreq structure
2249 + * @return UAP_STATUS_SUCCESS --success, otherwise fail
2250 + */
2251 +static int
2252 +uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req)
2253 +{
2254 + ps_mgmt pm_cfg;
2255 + int ret = UAP_STATUS_SUCCESS;
2256 + uap_private *priv = (uap_private *) netdev_priv(dev);
2257 + uap_adapter *Adapter = priv->adapter;
2258 + struct sk_buff *skb = NULL;
2259 + HostCmd_DS_COMMAND *cmd;
2260 + u32 CmdSize;
2261 + u8 *tlv = NULL;
2262 + MrvlIEtypes_sleep_param_t *sleep_tlv = NULL;
2263 + MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL;
2264 + u16 tlv_buf_left = 0;
2265 + MrvlIEtypesHeader_t *tlvbuf = NULL;
2266 + u16 tlv_type = 0;
2267 + u16 tlv_len = 0;
2268 +
2269 + ENTER();
2270 +
2271 + /* Sanity check */
2272 + if (req->ifr_data == NULL) {
2273 + PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n");
2274 + LEAVE();
2275 + return -EFAULT;
2276 + }
2277 +
2278 + memset(&pm_cfg, 0, sizeof(ps_mgmt));
2279 + if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) {
2280 + PRINTM(ERROR, "Copy from user failed\n");
2281 + LEAVE();
2282 + return -EFAULT;
2283 + }
2284 + PRINTM(CMND,
2285 + "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d "
2286 + "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags,
2287 + (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap,
2288 + (int) pm_cfg.sleep_param.min_sleep,
2289 + (int) pm_cfg.sleep_param.max_sleep,
2290 + (int) pm_cfg.inact_param.inactivity_to,
2291 + (int) pm_cfg.inact_param.min_awake,
2292 + (int) pm_cfg.inact_param.max_awake);
2293 +
2294 + if (pm_cfg.
2295 + flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM |
2296 + PS_FLAG_INACT_SLEEP_PARAM)) {
2297 + PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags);
2298 + ret = -EINVAL;
2299 + goto done;
2300 + }
2301 + if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) {
2302 + PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags);
2303 + ret = -EINVAL;
2304 + goto done;
2305 + }
2306 +
2307 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
2308 + if (!skb) {
2309 + PRINTM(INFO, "No free skb\n");
2310 + ret = -ENOMEM;
2311 + goto done;
2312 + }
2313 +
2314 + CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT);
2315 +
2316 + cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
2317 + cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT);
2318 + if (!pm_cfg.flags) {
2319 + cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET);
2320 + } else {
2321 + cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET);
2322 + cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode);
2323 + tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT);
2324 +
2325 + if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) {
2326 + sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv;
2327 + sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM);
2328 + sleep_tlv->header.Len =
2329 + uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) -
2330 + sizeof(MrvlIEtypesHeader_t));
2331 + sleep_tlv->ctrl_bitmap =
2332 + uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap);
2333 + sleep_tlv->min_sleep =
2334 + uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep);
2335 + sleep_tlv->max_sleep =
2336 + uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep);
2337 + CmdSize += sizeof(MrvlIEtypes_sleep_param_t);
2338 + tlv += sizeof(MrvlIEtypes_sleep_param_t);
2339 + }
2340 + if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) &&
2341 + (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) {
2342 + inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv;
2343 + inact_tlv->header.Type =
2344 + uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM);
2345 + inact_tlv->header.Len =
2346 + uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) -
2347 + sizeof(MrvlIEtypesHeader_t));
2348 + inact_tlv->inactivity_to =
2349 + uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to);
2350 + inact_tlv->min_awake =
2351 + uap_cpu_to_le32(pm_cfg.inact_param.min_awake);
2352 + inact_tlv->max_awake =
2353 + uap_cpu_to_le32(pm_cfg.inact_param.max_awake);
2354 + CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t);
2355 + tlv += sizeof(MrvlIEtypes_inact_sleep_param_t);
2356 + }
2357 + }
2358 + cmd->Size = uap_cpu_to_le16(CmdSize);
2359 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
2360 + if (UAP_STATUS_SUCCESS !=
2361 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
2362 + PRINTM(ERROR, "Fail to process cmd POWER_MODE\n");
2363 + ret = -EFAULT;
2364 + goto done;
2365 + }
2366 + if (!Adapter->CmdSize) {
2367 + PRINTM(ERROR, "Cmd Size is 0\n");
2368 + ret = -EFAULT;
2369 + goto done;
2370 + }
2371 + cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
2372 + cmd->Result = uap_le16_to_cpu(cmd->Result);
2373 + if (cmd->Result != UAP_STATUS_SUCCESS) {
2374 + PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result);
2375 + ret = -EFAULT;
2376 + goto done;
2377 + }
2378 + if (pm_cfg.flags) {
2379 + Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
2380 + } else {
2381 + pm_cfg.flags = PS_FLAG_PS_MODE;
2382 + pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
2383 + tlv_buf_left =
2384 + cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN);
2385 + tlvbuf =
2386 + (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg +
2387 + sizeof(HostCmd_DS_POWER_MGMT_EXT));
2388 + while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
2389 + tlv_type = uap_le16_to_cpu(tlvbuf->Type);
2390 + tlv_len = uap_le16_to_cpu(tlvbuf->Len);
2391 + switch (tlv_type) {
2392 + case TLV_TYPE_AP_SLEEP_PARAM:
2393 + sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf;
2394 + pm_cfg.flags |= PS_FLAG_SLEEP_PARAM;
2395 + pm_cfg.sleep_param.ctrl_bitmap =
2396 + uap_le32_to_cpu(sleep_tlv->ctrl_bitmap);
2397 + pm_cfg.sleep_param.min_sleep =
2398 + uap_le32_to_cpu(sleep_tlv->min_sleep);
2399 + pm_cfg.sleep_param.max_sleep =
2400 + uap_le32_to_cpu(sleep_tlv->max_sleep);
2401 + break;
2402 + case TLV_TYPE_AP_INACT_SLEEP_PARAM:
2403 + inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf;
2404 + pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM;
2405 + pm_cfg.inact_param.inactivity_to =
2406 + uap_le32_to_cpu(inact_tlv->inactivity_to);
2407 + pm_cfg.inact_param.min_awake =
2408 + uap_le32_to_cpu(inact_tlv->min_awake);
2409 + pm_cfg.inact_param.max_awake =
2410 + uap_le32_to_cpu(inact_tlv->max_awake);
2411 + break;
2412 + }
2413 + tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
2414 + tlvbuf =
2415 + (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len +
2416 + sizeof(MrvlIEtypesHeader_t));
2417 + }
2418 + /* Copy to user */
2419 + if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) {
2420 + PRINTM(ERROR, "Copy to user failed!\n");
2421 + LEAVE();
2422 + return -EFAULT;
2423 + }
2424 + }
2425 + done:
2426 + LEAVE();
2427 + return ret;
2428 +}
2429 +
2430 +/**
2431 + * @brief This function send bss_stop command to firmware
2432 + *
2433 + * @param priv A pointer to uap_private structure
2434 + * @return UAP_STATUS_SUCCESS on success, otherwise failure code
2435 + */
2436 +static int
2437 +uap_bss_stop(uap_private * priv)
2438 +{
2439 + int ret = UAP_STATUS_SUCCESS;
2440 + u32 CmdSize;
2441 + HostCmd_DS_GEN *cmd;
2442 + uap_adapter *Adapter = priv->adapter;
2443 + struct sk_buff *skb;
2444 + ENTER();
2445 + if (Adapter->HardwareStatus != HWReady) {
2446 + PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n");
2447 + ret = -EFAULT;
2448 + goto done;
2449 + }
2450 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
2451 + if (!skb) {
2452 + PRINTM(ERROR, "No free skb\n");
2453 + ret = -ENOMEM;
2454 + goto done;
2455 + }
2456 + CmdSize = sizeof(HostCmd_DS_GEN);
2457 + cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
2458 + cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP);
2459 + cmd->Size = uap_cpu_to_le16(CmdSize);
2460 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
2461 + PRINTM(CMND, "APCMD_BSS_STOP\n");
2462 + if (UAP_STATUS_SUCCESS !=
2463 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
2464 + PRINTM(ERROR, "Fail to process cmd BSS_STOP\n");
2465 + ret = -EFAULT;
2466 + goto done;
2467 + }
2468 + done:
2469 + LEAVE();
2470 + return ret;
2471 +}
2472 +
2473 +/********************************************************
2474 + Global Functions
2475 +********************************************************/
2476 +/**
2477 + * @brief This function send soft_reset command to firmware
2478 + *
2479 + * @param priv A pointer to uap_private structure
2480 + * @return UAP_STATUS_SUCCESS on success, otherwise failure code
2481 + */
2482 +int
2483 +uap_soft_reset(uap_private * priv)
2484 +{
2485 + int ret = UAP_STATUS_SUCCESS;
2486 + u32 CmdSize;
2487 + HostCmd_DS_GEN *cmd;
2488 + uap_adapter *Adapter = priv->adapter;
2489 + struct sk_buff *skb;
2490 + ENTER();
2491 + ret = uap_bss_stop(priv);
2492 + if (ret != UAP_STATUS_SUCCESS)
2493 + goto done;
2494 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
2495 + if (!skb) {
2496 + PRINTM(ERROR, "No free skb\n");
2497 + ret = -ENOMEM;
2498 + goto done;
2499 + }
2500 + CmdSize = sizeof(HostCmd_DS_GEN);
2501 + cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
2502 + cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET);
2503 + cmd->Size = uap_cpu_to_le16(CmdSize);
2504 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
2505 + PRINTM(CMND, "APCMD_SOFT_RESET\n");
2506 + if (UAP_STATUS_SUCCESS !=
2507 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) {
2508 + PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n");
2509 + ret = -EFAULT;
2510 + goto done;
2511 + }
2512 + Adapter->SurpriseRemoved = TRUE;
2513 + /* delay to allow hardware complete reset */
2514 + os_sched_timeout(5);
2515 + if (priv->MediaConnected == TRUE) {
2516 + os_stop_queue(priv);
2517 + os_carrier_off(priv);
2518 + priv->MediaConnected = FALSE;
2519 + }
2520 + Adapter->CmdSize = 0;
2521 + Adapter->CmdWaitQWoken = TRUE;
2522 + wake_up_interruptible(&Adapter->cmdwait_q);
2523 + skb_queue_purge(&priv->adapter->tx_queue);
2524 + skb_queue_purge(&priv->adapter->cmd_queue);
2525 + done:
2526 + LEAVE();
2527 + return ret;
2528 +}
2529 +
2530 +/**
2531 + * @brief This function processes received packet and forwards it
2532 + * to kernel/upper layer
2533 + *
2534 + * @param priv A pointer to uap_private
2535 + * @param skb A pointer to skb which includes the received packet
2536 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
2537 + */
2538 +int
2539 +uap_process_rx_packet(uap_private * priv, struct sk_buff *skb)
2540 +{
2541 + int ret = UAP_STATUS_SUCCESS;
2542 + RxPD *pRxPD;
2543 + ENTER();
2544 + priv->adapter->ps_state = PS_STATE_AWAKE;
2545 + pRxPD = (RxPD *) skb->data;
2546 + endian_convert_RxPD(pRxPD);
2547 + DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
2548 + skb_pull(skb, pRxPD->RxPktOffset);
2549 + priv->stats.rx_packets++;
2550 + priv->stats.rx_bytes += skb->len;
2551 + os_upload_rx_packet(priv, skb);
2552 + LEAVE();
2553 + return ret;
2554 +}
2555 +
2556 +/**
2557 + * @brief This function opens the network device
2558 + *
2559 + * @param dev A pointer to net_device structure
2560 + * @return UAP_STATUS_SUCCESS
2561 + */
2562 +static int
2563 +uap_open(struct net_device *dev)
2564 +{
2565 + uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev);
2566 + uap_adapter *Adapter = priv->adapter;
2567 + int i = 0;
2568 +
2569 + ENTER();
2570 +
2571 + /* On some systems the device open handler will be called before HW ready. */
2572 + /* Use the following flag check and wait function to work around the issue. */
2573 + while ((Adapter->HardwareStatus != HWReady) &&
2574 + (i < MAX_WAIT_DEVICE_READY_COUNT)) {
2575 + i++;
2576 + os_sched_timeout(100);
2577 + }
2578 + if (i >= MAX_WAIT_DEVICE_READY_COUNT) {
2579 + PRINTM(FATAL, "HW not ready, uap_open() return failure\n");
2580 + LEAVE();
2581 + return UAP_STATUS_FAILURE;
2582 + }
2583 +
2584 + if (MODULE_GET == 0)
2585 + return UAP_STATUS_FAILURE;
2586 +
2587 + priv->open = TRUE;
2588 + if (priv->MediaConnected == TRUE) {
2589 + os_carrier_on(priv);
2590 + os_start_queue(priv);
2591 + } else {
2592 + os_stop_queue(priv);
2593 + os_carrier_off(priv);
2594 + }
2595 + LEAVE();
2596 + return UAP_STATUS_SUCCESS;
2597 +}
2598 +
2599 +/**
2600 + * @brief This function closes the network device
2601 + *
2602 + * @param dev A pointer to net_device structure
2603 + * @return UAP_STATUS_SUCCESS
2604 + */
2605 +static int
2606 +uap_close(struct net_device *dev)
2607 +{
2608 + uap_private *priv = (uap_private *) netdev_priv(dev);
2609 +
2610 + ENTER();
2611 + skb_queue_purge(&priv->adapter->tx_queue);
2612 + os_stop_queue(priv);
2613 + os_carrier_off(priv);
2614 +
2615 + MODULE_PUT;
2616 + priv->open = FALSE;
2617 + LEAVE();
2618 + return UAP_STATUS_SUCCESS;
2619 +}
2620 +
2621 +/**
2622 + * @brief This function returns the network statistics
2623 + *
2624 + * @param dev A pointer to uap_private structure
2625 + * @return A pointer to net_device_stats structure
2626 + */
2627 +static struct net_device_stats *
2628 +uap_get_stats(struct net_device *dev)
2629 +{
2630 + uap_private *priv = (uap_private *) netdev_priv(dev);
2631 +
2632 + return &priv->stats;
2633 +}
2634 +
2635 +/**
2636 + * @brief This function sets the MAC address to firmware.
2637 + *
2638 + * @param dev A pointer to uap_private structure
2639 + * @param addr MAC address to set
2640 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
2641 + */
2642 +static int
2643 +uap_set_mac_address(struct net_device *dev, void *addr)
2644 +{
2645 + int ret = UAP_STATUS_SUCCESS;
2646 + uap_private *priv = (uap_private *) netdev_priv(dev);
2647 + struct sockaddr *pHwAddr = (struct sockaddr *) addr;
2648 + u32 CmdSize;
2649 + HostCmd_DS_COMMAND *cmd;
2650 + MrvlIEtypes_MacAddr_t *pMacAddrTlv;
2651 + uap_adapter *Adapter = priv->adapter;
2652 + struct sk_buff *skb;
2653 +
2654 + ENTER();
2655 +
2656 + /* Dump MAC address */
2657 + DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN);
2658 + DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN);
2659 + if (priv->open && (priv->MediaConnected == TRUE)) {
2660 + os_carrier_on(priv);
2661 + os_start_queue(priv);
2662 + }
2663 + skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
2664 + if (!skb) {
2665 + PRINTM(ERROR, "No free skb\n");
2666 + LEAVE();
2667 + return -ENOMEM;
2668 + }
2669 + CmdSize =
2670 + S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
2671 + cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
2672 + cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
2673 + cmd->Size = uap_cpu_to_le16(CmdSize);
2674 + cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET);
2675 + pMacAddrTlv =
2676 + (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN +
2677 + sizeof(HostCmd_SYS_CONFIG));
2678 + pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
2679 + pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
2680 + memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN);
2681 + skb_put(skb, CmdSize + INTF_HEADER_LEN);
2682 + PRINTM(CMND, "set_mac_address\n");
2683 + if (UAP_STATUS_SUCCESS !=
2684 + uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
2685 + PRINTM(ERROR, "Fail to set mac address\n");
2686 + LEAVE();
2687 + return -EFAULT;
2688 + }
2689 + if (!Adapter->CmdSize) {
2690 + PRINTM(ERROR, "Cmd Size is 0\n");
2691 + LEAVE();
2692 + return -EFAULT;
2693 + }
2694 + cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
2695 + cmd->Result = uap_cpu_to_le16(cmd->Result);
2696 + if (cmd->Result != UAP_STATUS_SUCCESS) {
2697 + PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result);
2698 + ret = -EFAULT;
2699 + } else
2700 + memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN);
2701 + LEAVE();
2702 + return ret;
2703 +}
2704 +
2705 +/**
2706 + * @brief This function handles the timeout of packet
2707 + * transmission
2708 + *
2709 + * @param dev A pointer to net_device structure
2710 + * @return n/a
2711 + */
2712 +static void
2713 +uap_tx_timeout(struct net_device *dev)
2714 +{
2715 + uap_private *priv = (uap_private *) netdev_priv(dev);
2716 +
2717 + ENTER();
2718 +
2719 + PRINTM(DATA, "Tx timeout\n");
2720 + UpdateTransStart(dev);
2721 + priv->num_tx_timeout++;
2722 + priv->adapter->IntCounter++;
2723 + wake_up_interruptible(&priv->MainThread.waitQ);
2724 +
2725 + LEAVE();
2726 +}
2727 +
2728 +/**
2729 + * @brief This function handles packet transmission
2730 + *
2731 + * @param skb A pointer to sk_buff structure
2732 + * @param dev A pointer to net_device structure
2733 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
2734 + */
2735 +static int
2736 +uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2737 +{
2738 + uap_private *priv = (uap_private *) netdev_priv(dev);
2739 + int ret = UAP_STATUS_SUCCESS;
2740 +
2741 + ENTER();
2742 + PRINTM(DATA, "Data <= kernel\n");
2743 + DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
2744 + /* skb sanity check */
2745 + if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) {
2746 + PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len,
2747 + MRVDRV_MAXIMUM_ETH_PACKET_SIZE);
2748 + priv->stats.tx_dropped++;
2749 + kfree(skb);
2750 + goto done;
2751 + }
2752 + skb_queue_tail(&priv->adapter->tx_queue, skb);
2753 + wake_up_interruptible(&priv->MainThread.waitQ);
2754 + if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) {
2755 + UpdateTransStart(dev);
2756 + os_stop_queue(priv);
2757 + }
2758 + done:
2759 + LEAVE();
2760 + return ret;
2761 +}
2762 +
2763 +/**
2764 + * @brief ioctl function - entry point
2765 + *
2766 + * @param dev A pointer to net_device structure
2767 + * @param req A pointer to ifreq structure
2768 + * @param cmd command
2769 + * @return UAP_STATUS_SUCCESS--success, otherwise fail
2770 + */
2771 +static int
2772 +uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
2773 +{
2774 + int ret = UAP_STATUS_SUCCESS;
2775 +
2776 + ENTER();
2777 +
2778 + PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd);
2779 +
2780 + switch (cmd) {
2781 + case UAPHOSTCMD:
2782 + ret = uap_hostcmd_ioctl(dev, req);
2783 + break;
2784 + case UAP_POWER_MODE:
2785 + ret = uap_power_mode_ioctl(dev, req);
2786 + break;
2787 + default:
2788 + ret = -EINVAL;
2789 + break;
2790 + }
2791 +
2792 + LEAVE();
2793 + return ret;
2794 +}
2795 +
2796 +/**
2797 + * @brief This function handles events generated by firmware
2798 + *
2799 + * @param priv A pointer to uap_private structure
2800 + * @param payload A pointer to payload buffer
2801 + * @param len Length of the payload
2802 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
2803 + */
2804 +int
2805 +uap_process_event(uap_private * priv, u8 * payload, uint len)
2806 +{
2807 + int ret = UAP_STATUS_SUCCESS;
2808 + uap_adapter *Adapter = priv->adapter;
2809 + struct sk_buff *skb = NULL;
2810 + struct nlmsghdr *nlh = NULL;
2811 + struct sock *sk = Adapter->nl_sk;
2812 + AP_Event *pEvent;
2813 +
2814 + ENTER();
2815 + Adapter->ps_state = PS_STATE_AWAKE;
2816 + if (len > NL_MAX_PAYLOAD) {
2817 + PRINTM(ERROR, "event size is too big!!! len=%d\n", len);
2818 + ret = UAP_STATUS_FAILURE;
2819 + goto done;
2820 + }
2821 + pEvent = (AP_Event *) payload;
2822 + PRINTM(CMND, "Event: %d\n", pEvent->EventId);
2823 + switch (pEvent->EventId) {
2824 + case MICRO_AP_EV_ID_BSS_START:
2825 + memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN);
2826 + DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr,
2827 + ETH_ALEN);
2828 + break;
2829 + case MICRO_AP_EV_BSS_ACTIVE:
2830 + // carrier on
2831 + priv->MediaConnected = TRUE;
2832 + os_carrier_on(priv);
2833 + os_start_queue(priv);
2834 + break;
2835 + case MICRO_AP_EV_BSS_IDLE:
2836 + os_stop_queue(priv);
2837 + os_carrier_off(priv);
2838 + priv->MediaConnected = FALSE;
2839 + break;
2840 + case EVENT_PS_AWAKE:
2841 + PRINTM(CMND, "UAP: PS_AWAKE\n");
2842 + Adapter->ps_state = PS_STATE_AWAKE;
2843 + Adapter->WakeupTries = 0;
2844 + break;
2845 + case EVENT_PS_SLEEP:
2846 + PRINTM(CMND, "UAP: PS_SLEEP\n");
2847 + Adapter->ps_state = PS_STATE_PRE_SLEEP;
2848 + break;
2849 + default:
2850 + break;
2851 + }
2852 + if ((pEvent->EventId == EVENT_PS_AWAKE) ||
2853 + (pEvent->EventId == EVENT_PS_SLEEP))
2854 + goto done;
2855 + if (sk) {
2856 + /* Allocate skb */
2857 + if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) {
2858 + PRINTM(ERROR, "Could not allocate skb for netlink.\n");
2859 + ret = UAP_STATUS_FAILURE;
2860 + goto done;
2861 + }
2862 + nlh = (struct nlmsghdr *) skb->data;
2863 + nlh->nlmsg_len = NLMSG_SPACE(len);
2864 +
2865 + /* From kernel */
2866 + nlh->nlmsg_pid = 0;
2867 + nlh->nlmsg_flags = 0;
2868 +
2869 + /* Data */
2870 + skb_put(skb, nlh->nlmsg_len);
2871 + memcpy(NLMSG_DATA(nlh), payload, len);
2872 +
2873 + /* From Kernel */
2874 + NETLINK_CB(skb).pid = 0;
2875 +
2876 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2877 + /* Multicast message */
2878 + NETLINK_CB(skb).dst_pid = 0;
2879 +#endif
2880 +
2881 + /* Multicast group number */
2882 + NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP;
2883 +
2884 + /* Send message */
2885 + netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL);
2886 +
2887 + ret = UAP_STATUS_SUCCESS;
2888 + } else {
2889 + PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n");
2890 + ret = UAP_STATUS_FAILURE;
2891 + }
2892 + done:
2893 + LEAVE();
2894 + return ret;
2895 +}
2896 +
2897 +/**
2898 + * @brief This function handles the interrupt. it will change PS
2899 + * state if applicable. it will wake up main_thread to handle
2900 + * the interrupt event as well.
2901 + *
2902 + * @param priv A pointer to uap_private structure
2903 + * @return n/a
2904 + */
2905 +void
2906 +uap_interrupt(uap_private * priv)
2907 +{
2908 + ENTER();
2909 + priv->adapter->IntCounter++;
2910 + priv->adapter->WakeupTries = 0;
2911 + PRINTM(INFO, "*\n");
2912 + wake_up_interruptible(&priv->MainThread.waitQ);
2913 +
2914 + LEAVE();
2915 +
2916 +}
2917 +
2918 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
2919 +/** Network device handlers */
2920 +static const struct net_device_ops uap_netdev_ops = {
2921 + .ndo_open = uap_open,
2922 + .ndo_start_xmit = uap_hard_start_xmit,
2923 + .ndo_stop = uap_close,
2924 + .ndo_do_ioctl = uap_do_ioctl,
2925 + .ndo_set_mac_address = uap_set_mac_address,
2926 + .ndo_tx_timeout = uap_tx_timeout,
2927 + .ndo_get_stats = uap_get_stats,
2928 +};
2929 +#endif
2930 +
2931 +/**
2932 + * @brief This function adds the card. it will probe the
2933 + * card, allocate the uap_priv and initialize the device.
2934 + *
2935 + * @param card A pointer to card
2936 + * @return A pointer to uap_private structure
2937 + */
2938 +uap_private *
2939 +uap_add_card(void *card)
2940 +{
2941 + struct net_device *dev = NULL;
2942 + uap_private *priv = NULL;
2943 +
2944 + ENTER();
2945 +
2946 + if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
2947 + goto exit_sem_err;
2948 +
2949 + /* Allocate an Ethernet device */
2950 + if (!(dev = alloc_etherdev(sizeof(uap_private)))) {
2951 + PRINTM(FATAL, "Init ethernet device failed!\n");
2952 + goto error;
2953 + }
2954 + priv = (uap_private *) netdev_priv(dev);
2955 +
2956 + /* Allocate name */
2957 + if (dev_alloc_name(dev, "uap%d") < 0) {
2958 + PRINTM(ERROR, "Could not allocate device name!\n");
2959 + goto error;
2960 + }
2961 +
2962 + /* Allocate buffer for uap_adapter */
2963 + if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) {
2964 + PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n");
2965 + goto error;
2966 + }
2967 + memset(priv->adapter, 0, sizeof(uap_adapter));
2968 +
2969 + priv->uap_dev.netdev = dev;
2970 + priv->uap_dev.card = card;
2971 + priv->MediaConnected = FALSE;
2972 + uappriv = priv;
2973 + ((struct sdio_mmc_card *) card)->priv = priv;
2974 +
2975 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
2976 + SET_MODULE_OWNER(dev);
2977 +#endif
2978 +
2979 + /* Setup the OS Interface to our functions */
2980 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
2981 + dev->open = uap_open;
2982 + dev->stop = uap_close;
2983 + dev->hard_start_xmit = uap_hard_start_xmit;
2984 + dev->tx_timeout = uap_tx_timeout;
2985 + dev->get_stats = uap_get_stats;
2986 + dev->do_ioctl = uap_do_ioctl;
2987 + dev->set_mac_address = uap_set_mac_address;
2988 + dev->set_multicast_list = uap_set_multicast_list;
2989 +#else
2990 + dev->netdev_ops = &uap_netdev_ops;
2991 +#endif
2992 + dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
2993 + dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN;
2994 + dev->hard_header_len += HEADER_ALIGNMENT;
2995 +#define NETIF_F_DYNALLOC 16
2996 + dev->features |= NETIF_F_DYNALLOC;
2997 + dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
2998 +
2999 + /* Init SW */
3000 + if (uap_init_sw(priv)) {
3001 + PRINTM(FATAL, "Software Init Failed\n");
3002 + goto error;
3003 + }
3004 +
3005 + PRINTM(INFO, "Starting kthread...\n");
3006 + priv->MainThread.priv = priv;
3007 + spin_lock_init(&priv->driver_lock);
3008 + uap_create_thread(uap_service_main_thread, &priv->MainThread,
3009 + "uap_main_service");
3010 + while (priv->MainThread.pid == 0) {
3011 + os_sched_timeout(2);
3012 + }
3013 +
3014 + /* Register the device */
3015 + if (sbi_register_dev(priv) < 0) {
3016 + PRINTM(FATAL, "Failed to register uap device!\n");
3017 + goto err_registerdev;
3018 + }
3019 +#ifdef FW_DNLD_NEEDED
3020 + SET_NETDEV_DEV(dev, priv->hotplug_device);
3021 +#endif
3022 +
3023 + /* Init FW and HW */
3024 + if (uap_init_fw(priv)) {
3025 + PRINTM(FATAL, "Firmware Init Failed\n");
3026 + goto err_init_fw;
3027 + }
3028 +
3029 + priv->uap_dev.cmd_sent = FALSE;
3030 + priv->uap_dev.data_sent = FALSE;
3031 +
3032 + /* Get mac address from firmware */
3033 + if (uap_get_mac_address(priv)) {
3034 + PRINTM(FATAL, "Fail to get mac address\n");
3035 + goto err_init_fw;
3036 + }
3037 + /* Register network device */
3038 + if (register_netdev(dev)) {
3039 + printk(KERN_ERR "Cannot register network device!\n");
3040 + goto err_init_fw;
3041 + }
3042 +#ifdef CONFIG_PROC_FS
3043 + uap_proc_entry(priv, dev);
3044 + uap_debug_entry(priv, dev);
3045 +#endif /* CPNFIG_PROC_FS */
3046 + OS_REL_SEMAPHORE(&AddRemoveCardSem);
3047 +
3048 + LEAVE();
3049 + return priv;
3050 + err_init_fw:
3051 + sbi_unregister_dev(priv);
3052 + err_registerdev:
3053 + ((struct sdio_mmc_card *) card)->priv = NULL;
3054 + /* Stop the thread servicing the interrupts */
3055 + priv->adapter->SurpriseRemoved = TRUE;
3056 + wake_up_interruptible(&priv->MainThread.waitQ);
3057 + while (priv->MainThread.pid) {
3058 + os_sched_timeout(1);
3059 + }
3060 + error:
3061 + if (dev) {
3062 + if (dev->reg_state == NETREG_REGISTERED)
3063 + unregister_netdev(dev);
3064 + if (priv->adapter)
3065 + uap_free_adapter(priv);
3066 + free_netdev(dev);
3067 + uappriv = NULL;
3068 + }
3069 + OS_REL_SEMAPHORE(&AddRemoveCardSem);
3070 + exit_sem_err:
3071 + LEAVE();
3072 + return NULL;
3073 +}
3074 +
3075 +/**
3076 + * @brief This function removes the card.
3077 + *
3078 + * @param card A pointer to card
3079 + * @return UAP_STATUS_SUCCESS
3080 + */
3081 +int
3082 +uap_remove_card(void *card)
3083 +{
3084 + uap_private *priv = uappriv;
3085 + uap_adapter *Adapter;
3086 + struct net_device *dev;
3087 +
3088 + ENTER();
3089 +
3090 + if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
3091 + goto exit_sem_err;
3092 +
3093 + if (!priv || !(Adapter = priv->adapter)) {
3094 + goto exit_remove;
3095 + }
3096 + Adapter->SurpriseRemoved = TRUE;
3097 + if (Adapter->cmd_pending == TRUE) {
3098 + /* Wake up cmd Q */
3099 + Adapter->CmdWaitQWoken = TRUE;
3100 + wake_up_interruptible(&Adapter->cmdwait_q);
3101 + }
3102 + dev = priv->uap_dev.netdev;
3103 + if (priv->MediaConnected == TRUE) {
3104 + os_stop_queue(priv);
3105 + os_carrier_off(priv);
3106 + priv->MediaConnected = FALSE;
3107 + }
3108 + Adapter->CmdSize = 0;
3109 + Adapter->CmdWaitQWoken = TRUE;
3110 + wake_up_interruptible(&Adapter->cmdwait_q);
3111 + skb_queue_purge(&priv->adapter->tx_queue);
3112 + skb_queue_purge(&priv->adapter->cmd_queue);
3113 +
3114 + /* Disable interrupts on the card */
3115 + sbi_disable_host_int(priv);
3116 + PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name,
3117 + (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style");
3118 + unregister_netdev(dev);
3119 + PRINTM(INFO, "Unregister finish\n");
3120 + wake_up_interruptible(&priv->MainThread.waitQ);
3121 + while (priv->MainThread.pid) {
3122 + os_sched_timeout(1);
3123 + }
3124 +
3125 + if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
3126 + sock_release((Adapter->nl_sk)->sk_socket);
3127 + Adapter->nl_sk = NULL;
3128 + }
3129 +#ifdef CONFIG_PROC_FS
3130 + uap_debug_remove(priv);
3131 + uap_proc_remove(priv);
3132 +#endif
3133 + sbi_unregister_dev(priv);
3134 + PRINTM(INFO, "Free Adapter\n");
3135 + uap_free_adapter(priv);
3136 + priv->uap_dev.netdev = NULL;
3137 + free_netdev(dev);
3138 + uappriv = NULL;
3139 +
3140 + exit_remove:
3141 + OS_REL_SEMAPHORE(&AddRemoveCardSem);
3142 + exit_sem_err:
3143 + LEAVE();
3144 + return UAP_STATUS_SUCCESS;
3145 +}
3146 +
3147 +/**
3148 + * @brief This function initializes module.
3149 + *
3150 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3151 + */
3152 +static int __init
3153 +uap_init_module(void)
3154 +{
3155 + int ret = UAP_STATUS_SUCCESS;
3156 + ENTER();
3157 +
3158 + OS_INIT_SEMAPHORE(&AddRemoveCardSem);
3159 + ret = sbi_register();
3160 + LEAVE();
3161 + return ret;
3162 +}
3163 +
3164 +/**
3165 + * @brief This function cleans module
3166 + *
3167 + * @return n/a
3168 + */
3169 +static void __exit
3170 +uap_cleanup_module(void)
3171 +{
3172 + ENTER();
3173 +
3174 + if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
3175 + goto exit_sem_err;
3176 +
3177 + if ((uappriv) && (uappriv->adapter)) {
3178 + uap_func_shutdown(uappriv);
3179 + }
3180 + OS_REL_SEMAPHORE(&AddRemoveCardSem);
3181 + exit_sem_err:
3182 + sbi_unregister();
3183 + LEAVE();
3184 +}
3185 +
3186 +module_init(uap_init_module);
3187 +module_exit(uap_cleanup_module);
3188 +module_param(helper_name, charp, 0);
3189 +MODULE_PARM_DESC(helper_name, "Helper name");
3190 +module_param(fw_name, charp, 0);
3191 +MODULE_PARM_DESC(fw_name, "Firmware name");
3192 +
3193 +MODULE_DESCRIPTION("M-UAP Driver");
3194 +MODULE_AUTHOR("Marvell International Ltd.");
3195 +MODULE_VERSION(DRIVER_VERSION);
3196 +MODULE_LICENSE("GPL");
3197 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c
3198 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c 1970-01-01 01:00:00.000000000 +0100
3199 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c 2012-07-31 14:23:04.000000000 +0200
3200 @@ -0,0 +1,296 @@
3201 +/** @file uap_proc.c
3202 + * @brief This file contains functions for proc file.
3203 + *
3204 + * Copyright (C) 2008-2009, Marvell International Ltd.
3205 + *
3206 + * This software file (the "File") is distributed by Marvell International
3207 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
3208 + * (the "License"). You may use, redistribute and/or modify this File in
3209 + * accordance with the terms and conditions of the License, a copy of which
3210 + * is available along with the File in the gpl.txt file or by writing to
3211 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3212 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
3213 + *
3214 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
3215 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
3216 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
3217 + * this warranty disclaimer.
3218 + *
3219 + */
3220 +#ifdef CONFIG_PROC_FS
3221 +#include "uap_headers.h"
3222 +
3223 +/** /proc directory root */
3224 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
3225 +#define PROC_DIR NULL
3226 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
3227 +#define PROC_DIR &proc_root
3228 +#else
3229 +#define PROC_DIR proc_net
3230 +#endif
3231 +
3232 +/********************************************************
3233 + Local Variables
3234 +********************************************************/
3235 +
3236 +/********************************************************
3237 + Global Variables
3238 +********************************************************/
3239 +
3240 +/********************************************************
3241 + Local Functions
3242 +********************************************************/
3243 +
3244 +/**
3245 + * @brief proc read function
3246 + *
3247 + * @param page pointer to buffer
3248 + * @param start read data starting position
3249 + * @param offset offset
3250 + * @param count counter
3251 + * @param eof end of file flag
3252 + * @param data data to output
3253 + * @return number of output data
3254 + */
3255 +static int
3256 +uap_proc_read(char *page, char **start, off_t offset,
3257 + int count, int *eof, void *data)
3258 +{
3259 + int i;
3260 + char *p = page;
3261 + struct net_device *netdev = data;
3262 + struct netdev_hw_addr *ha;
3263 + char fmt[64];
3264 + uap_private *priv = (uap_private *) netdev_priv(netdev);
3265 +
3266 + if (offset != 0) {
3267 + *eof = 1;
3268 + goto exit;
3269 + }
3270 +
3271 + strcpy(fmt, DRIVER_VERSION);
3272 +
3273 + p += sprintf(p, "driver_name = " "\"uap\"\n");
3274 + p += sprintf(p, "driver_version = %s-(FP%s)", fmt, FPNUM);
3275 + p += sprintf(p, "\nInterfaceName=\"%s\"\n", netdev->name);
3276 + p += sprintf(p, "State=\"%s\"\n",
3277 + ((priv->MediaConnected ==
3278 + FALSE) ? "Disconnected" : "Connected"));
3279 + p += sprintf(p, "MACAddress=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
3280 + netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
3281 + netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
3282 + i = 0;
3283 + netdev_for_each_mc_addr(ha, netdev) {
3284 + ++i;
3285 + }
3286 + p += sprintf(p, "MCCount=\"%d\"\n", i);
3287 +
3288 + /*
3289 + * Put out the multicast list
3290 + */
3291 + i = 0;
3292 + netdev_for_each_mc_addr(ha, netdev) {
3293 + p += sprintf(p,
3294 + "MCAddr[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
3295 + i++,
3296 + ha->addr[0], ha->addr[1],
3297 + ha->addr[2], ha->addr[3],
3298 + ha->addr[4], ha->addr[5]);
3299 + }
3300 +
3301 + p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
3302 + p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
3303 + p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
3304 + p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
3305 + p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
3306 + p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
3307 + p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
3308 + p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
3309 + p += sprintf(p, "num_tx_timeout = %u\n", priv->num_tx_timeout);
3310 + p += sprintf(p, "carrier %s\n",
3311 + ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off"));
3312 + p += sprintf(p, "tx queue %s\n",
3313 + ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" :
3314 + "started"));
3315 +
3316 + exit:
3317 + return (p - page);
3318 +}
3319 +
3320 +/**
3321 + * @brief hwstatus proc write function
3322 + *
3323 + * @param f file pointer
3324 + * @param buf pointer to data buffer
3325 + * @param cnt data number to write
3326 + * @param data data to write
3327 + * @return number of data
3328 + */
3329 +static int
3330 +uap_hwstatus_write(struct file *f, const char *buf, unsigned long cnt,
3331 + void *data)
3332 +{
3333 + struct net_device *netdev = data;
3334 + uap_private *priv = (uap_private *) netdev_priv(netdev);
3335 + char databuf[10];
3336 + int hwstatus;
3337 + MODULE_GET;
3338 + if (cnt > 10) {
3339 + MODULE_PUT;
3340 + return cnt;
3341 + }
3342 + if (copy_from_user(databuf, buf, cnt)) {
3343 + MODULE_PUT;
3344 + return 0;
3345 + }
3346 + hwstatus = string_to_number(databuf);
3347 + switch (hwstatus) {
3348 + case HWReset:
3349 + PRINTM(MSG, "reset hw\n");
3350 + uap_soft_reset(priv);
3351 + priv->adapter->HardwareStatus = HWReset;
3352 + break;
3353 + default:
3354 + break;
3355 + }
3356 + MODULE_PUT;
3357 + return cnt;
3358 +}
3359 +
3360 +/**
3361 + * @brief hwstatus proc read function
3362 + *
3363 + * @param page pointer to buffer
3364 + * @param s read data starting position
3365 + * @param off offset
3366 + * @param cnt counter
3367 + * @param eof end of file flag
3368 + * @param data data to output
3369 + * @return number of output data
3370 + */
3371 +static int
3372 +uap_hwstatus_read(char *page, char **s, off_t off, int cnt, int *eof,
3373 + void *data)
3374 +{
3375 + char *p = page;
3376 + struct net_device *netdev = data;
3377 + uap_private *priv = (uap_private *) netdev_priv(netdev);
3378 + MODULE_GET;
3379 + p += sprintf(p, "%d\n", priv->adapter->HardwareStatus);
3380 + MODULE_PUT;
3381 + return p - page;
3382 +}
3383 +
3384 +/********************************************************
3385 + Global Functions
3386 +********************************************************/
3387 +/**
3388 + * @brief create uap proc file
3389 + *
3390 + * @param priv pointer uap_private
3391 + * @param dev pointer net_device
3392 + * @return N/A
3393 + */
3394 +void
3395 +uap_proc_entry(uap_private * priv, struct net_device *dev)
3396 +{
3397 + struct proc_dir_entry *r = PROC_DIR;
3398 +
3399 + PRINTM(INFO, "Creating Proc Interface\n");
3400 + /* Check if uap directory already exists */
3401 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
3402 + for (r = r->subdir; r; r = r->next) {
3403 + if (r->namelen && !strcmp("uap", r->name)) {
3404 + /* Directory exists */
3405 + PRINTM(WARN, "proc directory already exists!\n");
3406 + priv->proc_uap = r;
3407 + break;
3408 + }
3409 + }
3410 +#endif
3411 + if (!priv->proc_uap) {
3412 + priv->proc_uap = proc_mkdir("uap", PROC_DIR);
3413 + if (!priv->proc_uap)
3414 + return;
3415 + else
3416 + atomic_set(&priv->proc_uap->count, 1);
3417 + } else {
3418 + atomic_inc(&priv->proc_uap->count);
3419 + }
3420 + priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap);
3421 +
3422 + if (priv->proc_entry) {
3423 + r = create_proc_read_entry("info", 0, priv->proc_entry, uap_proc_read,
3424 + dev);
3425 + r = create_proc_entry("hwstatus", 0644, priv->proc_entry);
3426 + if (r) {
3427 + r->data = dev;
3428 + r->read_proc = uap_hwstatus_read;
3429 + r->write_proc = uap_hwstatus_write;
3430 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
3431 + r->owner = THIS_MODULE;
3432 +#endif
3433 + } else
3434 + PRINTM(MSG, "Fail to create proc hwstatus\n");
3435 + }
3436 +}
3437 +
3438 +/**
3439 + * @brief remove proc file
3440 + *
3441 + * @param priv pointer uap_private
3442 + * @return N/A
3443 + */
3444 +void
3445 +uap_proc_remove(uap_private * priv)
3446 +{
3447 + if (priv->proc_uap) {
3448 + if (priv->proc_entry) {
3449 + remove_proc_entry("info", priv->proc_entry);
3450 + remove_proc_entry("hwstatus", priv->proc_entry);
3451 + }
3452 + remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap);
3453 + atomic_dec(&priv->proc_uap->count);
3454 + if (atomic_read(&(priv->proc_uap->count)) == 0)
3455 + remove_proc_entry("uap", PROC_DIR);
3456 + }
3457 +}
3458 +
3459 +/**
3460 + * @brief convert string to number
3461 + *
3462 + * @param s pointer to numbered string
3463 + * @return converted number from string s
3464 + */
3465 +int
3466 +string_to_number(char *s)
3467 +{
3468 + int r = 0;
3469 + int base = 0;
3470 + int pn = 1;
3471 +
3472 + if (strncmp(s, "-", 1) == 0) {
3473 + pn = -1;
3474 + s++;
3475 + }
3476 + if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) {
3477 + base = 16;
3478 + s += 2;
3479 + } else
3480 + base = 10;
3481 +
3482 + for (s = s; *s != 0; s++) {
3483 + if ((*s >= '0') && (*s <= '9'))
3484 + r = (r * base) + (*s - '0');
3485 + else if ((*s >= 'A') && (*s <= 'F'))
3486 + r = (r * base) + (*s - 'A' + 10);
3487 + else if ((*s >= 'a') && (*s <= 'f'))
3488 + r = (r * base) + (*s - 'a' + 10);
3489 + else
3490 + break;
3491 + }
3492 +
3493 + return (r * pn);
3494 +}
3495 +
3496 +#endif
3497 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c
3498 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 1970-01-01 01:00:00.000000000 +0100
3499 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 2012-07-31 14:23:04.000000000 +0200
3500 @@ -0,0 +1,1428 @@
3501 +/** @file uap_sdio_mmc.c
3502 + * @brief This file contains SDIO IF (interface) module
3503 + * related functions.
3504 + *
3505 + * Copyright (C) 2007-2009, Marvell International Ltd.
3506 + *
3507 + * This software file (the "File") is distributed by Marvell International
3508 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
3509 + * (the "License"). You may use, redistribute and/or modify this File in
3510 + * accordance with the terms and conditions of the License, a copy of which
3511 + * is available along with the File in the gpl.txt file or by writing to
3512 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3513 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
3514 + *
3515 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
3516 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
3517 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
3518 + * this warranty disclaimer.
3519 + *
3520 + */
3521 +/****************************************************
3522 +Change log:
3523 +****************************************************/
3524 +
3525 +#include "uap_sdio_mmc.h"
3526 +
3527 +#include <linux/firmware.h>
3528 +
3529 +/** define SDIO block size */
3530 +/* We support up to 480-byte block size due to FW buffer limitation. */
3531 +#define SD_BLOCK_SIZE 256
3532 +
3533 +/** define allocated buffer size */
3534 +#define ALLOC_BUF_SIZE (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \
3535 + MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \
3536 + + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE)
3537 +
3538 +/** Max retry number of CMD53 write */
3539 +#define MAX_WRITE_IOMEM_RETRY 2
3540 +
3541 +/********************************************************
3542 + Local Variables
3543 +********************************************************/
3544 +
3545 +/** SDIO Rx unit */
3546 +static u8 sdio_rx_unit = 0;
3547 +
3548 +/**Interrupt status */
3549 +static u8 sd_ireg = 0;
3550 +/********************************************************
3551 + Global Variables
3552 +********************************************************/
3553 +extern u8 *helper_name;
3554 +extern u8 *fw_name;
3555 +/** Default helper name */
3556 +#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin"
3557 +/** Default firmware name */
3558 +#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin"
3559 +
3560 +/********************************************************
3561 + Local Functions
3562 +********************************************************/
3563 +/**
3564 + * @brief This function reads the IO register.
3565 + *
3566 + * @param priv A pointer to uap_private structure
3567 + * @param reg register to be read
3568 + * @param dat A pointer to variable that keeps returned value
3569 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3570 + */
3571 +static int
3572 +sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat)
3573 +{
3574 + struct sdio_mmc_card *card;
3575 + int ret = UAP_STATUS_FAILURE;
3576 +
3577 + ENTER();
3578 +
3579 + card = priv->uap_dev.card;
3580 + if (!card || !card->func) {
3581 + PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n");
3582 + goto done;
3583 + }
3584 +
3585 + *dat = sdio_readb(card->func, reg, &ret);
3586 + if (ret) {
3587 + PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret);
3588 + goto done;
3589 + }
3590 +
3591 + PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
3592 + card->func->num, reg, *dat);
3593 +
3594 + done:
3595 + LEAVE();
3596 + return ret;
3597 +}
3598 +
3599 +/**
3600 + * @brief This function writes the IO register.
3601 + *
3602 + * @param priv A pointer to uap_private structure
3603 + * @param reg register to be written
3604 + * @param dat the value to be written
3605 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3606 + */
3607 +static int
3608 +sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat)
3609 +{
3610 + struct sdio_mmc_card *card;
3611 + int ret = UAP_STATUS_FAILURE;
3612 +
3613 + ENTER();
3614 +
3615 + card = priv->uap_dev.card;
3616 + if (!card || !card->func) {
3617 + PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n");
3618 + goto done;
3619 + }
3620 +
3621 + PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
3622 + card->func->num, reg, dat);
3623 +
3624 + sdio_writeb(card->func, dat, reg, &ret);
3625 + if (ret) {
3626 + PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret);
3627 + goto done;
3628 + }
3629 +
3630 + done:
3631 + LEAVE();
3632 + return ret;
3633 +}
3634 +
3635 +/**
3636 + * @brief This function get rx_unit value
3637 + *
3638 + * @param priv A pointer to uap_private structure
3639 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3640 + */
3641 +static int
3642 +sd_get_rx_unit(uap_private * priv)
3643 +{
3644 + int ret = UAP_STATUS_SUCCESS;
3645 + u8 reg;
3646 +
3647 + ENTER();
3648 +
3649 + ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, &reg);
3650 + if (ret == UAP_STATUS_SUCCESS)
3651 + sdio_rx_unit = reg;
3652 +
3653 + LEAVE();
3654 + return ret;
3655 +}
3656 +
3657 +/**
3658 + * @brief This function reads rx length
3659 + *
3660 + * @param priv A pointer to uap_private structure
3661 + * @param dat A pointer to keep returned data
3662 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3663 + */
3664 +static int
3665 +sd_read_rx_len(uap_private * priv, u16 * dat)
3666 +{
3667 + int ret = UAP_STATUS_SUCCESS;
3668 + u8 reg;
3669 +
3670 + ENTER();
3671 +
3672 + ret = sbi_read_ioreg(priv, CARD_RX_LEN_REG, &reg);
3673 + if (ret == UAP_STATUS_SUCCESS)
3674 + *dat = (u16) reg << sdio_rx_unit;
3675 +
3676 + LEAVE();
3677 + return ret;
3678 +}
3679 +
3680 +/**
3681 + * @brief This function reads fw status registers
3682 + *
3683 + * @param priv A pointer to uap_private structure
3684 + * @param dat A pointer to keep returned data
3685 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3686 + */
3687 +static int
3688 +sd_read_firmware_status(uap_private * priv, u16 * dat)
3689 +{
3690 + int ret = UAP_STATUS_SUCCESS;
3691 + u8 fws0;
3692 + u8 fws1;
3693 +
3694 + ENTER();
3695 +
3696 + ret = sbi_read_ioreg(priv, CARD_FW_STATUS0_REG, &fws0);
3697 + if (ret < 0) {
3698 + LEAVE();
3699 + return UAP_STATUS_FAILURE;
3700 + }
3701 +
3702 + ret = sbi_read_ioreg(priv, CARD_FW_STATUS1_REG, &fws1);
3703 + if (ret < 0) {
3704 + LEAVE();
3705 + return UAP_STATUS_FAILURE;
3706 + }
3707 +
3708 + *dat = (((u16) fws1) << 8) | fws0;
3709 +
3710 + LEAVE();
3711 + return UAP_STATUS_SUCCESS;
3712 +}
3713 +
3714 +/**
3715 + * @brief This function polls the card status register.
3716 + *
3717 + * @param priv A pointer to uap_private structure
3718 + * @param bits the bit mask
3719 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3720 + */
3721 +static int
3722 +mv_sdio_poll_card_status(uap_private * priv, u8 bits)
3723 +{
3724 + int tries;
3725 + u8 cs;
3726 +
3727 + ENTER();
3728 +
3729 + for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
3730 + if (sbi_read_ioreg(priv, CARD_STATUS_REG, &cs) < 0)
3731 + break;
3732 + else if ((cs & bits) == bits) {
3733 + LEAVE();
3734 + return UAP_STATUS_SUCCESS;
3735 + }
3736 + udelay(10);
3737 + }
3738 +
3739 + PRINTM(WARN, "mv_sdio_poll_card_status failed, tries = %d\n", tries);
3740 +
3741 + LEAVE();
3742 + return UAP_STATUS_FAILURE;
3743 +}
3744 +
3745 +/**
3746 + * @brief This function set the sdio bus width.
3747 + *
3748 + * @param priv A pointer to uap_private structure
3749 + * @param mode 1--1 bit mode, 4--4 bit mode
3750 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3751 + */
3752 +#if 0
3753 +static int
3754 +sdio_set_bus_width(uap_private * priv, u8 mode)
3755 +{
3756 + ENTER();
3757 + LEAVE();
3758 + return UAP_STATUS_SUCCESS;
3759 +}
3760 +#endif
3761 +
3762 +/**
3763 + * @brief This function reads data from the card.
3764 + *
3765 + * @param priv A pointer to uap_private structure
3766 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3767 + */
3768 +static int
3769 +sd_card_to_host(uap_private * priv)
3770 +{
3771 + int ret = UAP_STATUS_SUCCESS;
3772 + u16 buf_len = 0;
3773 + int buf_block_len;
3774 + int blksz;
3775 + struct sk_buff *skb = NULL;
3776 + u16 type;
3777 + u8 *payload = NULL;
3778 + struct sdio_mmc_card *card = priv->uap_dev.card;
3779 +
3780 + ENTER();
3781 +
3782 + if (!card || !card->func) {
3783 + PRINTM(ERROR, "card or function is NULL!\n");
3784 + ret = UAP_STATUS_FAILURE;
3785 + goto exit;
3786 + }
3787 +
3788 + /* Read the length of data to be transferred */
3789 + ret = sd_read_rx_len(priv, &buf_len);
3790 + if (ret < 0) {
3791 + PRINTM(ERROR, "card_to_host, read scratch reg failed\n");
3792 + ret = UAP_STATUS_FAILURE;
3793 + goto exit;
3794 + }
3795 +
3796 + /* Allocate buffer */
3797 + blksz = SD_BLOCK_SIZE;
3798 + buf_block_len = (buf_len + blksz - 1) / blksz;
3799 + if (buf_len <= INTF_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
3800 + PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len);
3801 + ret = UAP_STATUS_FAILURE;
3802 + goto exit;
3803 + }
3804 +#ifdef PXA3XX_DMA_ALIGN
3805 + skb = dev_alloc_skb(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT);
3806 +#else
3807 + skb = dev_alloc_skb(buf_block_len * blksz);
3808 +#endif
3809 + if (skb == NULL) {
3810 + PRINTM(WARN, "No free skb\n");
3811 + goto exit;
3812 + }
3813 +#ifdef PXA3XX_DMA_ALIGN
3814 + if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) {
3815 + skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
3816 + skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
3817 + }
3818 +#endif /* PXA3XX_DMA_ALIGN */
3819 +
3820 + payload = skb->tail;
3821 + ret = sdio_readsb(card->func, payload, priv->uap_dev.ioport,
3822 + buf_block_len * blksz);
3823 + if (ret < 0) {
3824 + PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret);
3825 + ret = UAP_STATUS_FAILURE;
3826 + goto exit;
3827 + }
3828 + HEXDUMP("SDIO Blk Rd", payload, blksz * buf_block_len);
3829 + /*
3830 + * This is SDIO specific header
3831 + * u16 length,
3832 + * u16 type (MV_TYPE_DAT = 0, MV_TYPE_CMD = 1, MV_TYPE_EVENT = 3)
3833 + */
3834 + buf_len = uap_le16_to_cpu(*(u16 *) & payload[0]);
3835 + type = uap_le16_to_cpu(*(u16 *) & payload[2]);
3836 + switch (type) {
3837 + case MV_TYPE_EVENT:
3838 + skb_put(skb, buf_len);
3839 + skb_pull(skb, INTF_HEADER_LEN);
3840 + uap_process_event(priv, skb->data, skb->len);
3841 + kfree_skb(skb);
3842 + skb = NULL;
3843 + break;
3844 + case MV_TYPE_CMD:
3845 + skb_put(skb, buf_len);
3846 + skb_pull(skb, INTF_HEADER_LEN);
3847 + priv->adapter->cmd_pending = FALSE;
3848 + if (priv->adapter->cmd_wait_option ==
3849 + HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM) {
3850 + priv->adapter->cmd_wait_option = FALSE;
3851 + uap_process_sleep_confirm_resp(priv, skb->data, skb->len);
3852 + } else if (priv->adapter->cmd_wait_option) {
3853 + memcpy(priv->adapter->CmdBuf, skb->data, skb->len);
3854 + priv->adapter->CmdSize = skb->len;
3855 + priv->adapter->cmd_wait_option = FALSE;
3856 + priv->adapter->CmdWaitQWoken = TRUE;
3857 + wake_up_interruptible(&priv->adapter->cmdwait_q);
3858 + }
3859 + kfree_skb(skb);
3860 + skb = NULL;
3861 + break;
3862 + case MV_TYPE_DAT:
3863 + skb_put(skb, buf_len);
3864 + skb_pull(skb, INTF_HEADER_LEN);
3865 + uap_process_rx_packet(priv, skb);
3866 + break;
3867 + default:
3868 + priv->stats.rx_errors++;
3869 + priv->stats.rx_dropped++;
3870 + /* Driver specified event and command resp should be handle here */
3871 + PRINTM(INFO, "Unknown PKT type:%d\n", type);
3872 + kfree_skb(skb);
3873 + skb = NULL;
3874 + break;
3875 + }
3876 + exit:
3877 + if (ret) {
3878 + if (skb)
3879 + kfree_skb(skb);
3880 + }
3881 +
3882 + LEAVE();
3883 + return ret;
3884 +}
3885 +
3886 +/**
3887 + * @brief This function enables the host interrupts mask
3888 + *
3889 + * @param priv A pointer to uap_private structure
3890 + * @param mask the interrupt mask
3891 + * @return UAP_STATUS_SUCCESS
3892 + */
3893 +static int
3894 +enable_host_int_mask(uap_private * priv, u8 mask)
3895 +{
3896 + int ret = UAP_STATUS_SUCCESS;
3897 +
3898 + ENTER();
3899 +
3900 + /* Simply write the mask to the register */
3901 + ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, mask);
3902 +
3903 + if (ret) {
3904 + PRINTM(WARN, "Unable to enable the host interrupt!\n");
3905 + ret = UAP_STATUS_FAILURE;
3906 + }
3907 +
3908 + LEAVE();
3909 + return ret;
3910 +}
3911 +
3912 +/** @brief This function disables the host interrupts mask.
3913 + *
3914 + * @param priv A pointer to uap_private structure
3915 + * @param mask the interrupt mask
3916 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
3917 + */
3918 +static int
3919 +disable_host_int_mask(uap_private * priv, u8 mask)
3920 +{
3921 + int ret = UAP_STATUS_SUCCESS;
3922 + u8 host_int_mask;
3923 +
3924 + ENTER();
3925 +
3926 + /* Read back the host_int_mask register */
3927 + ret = sbi_read_ioreg(priv, HOST_INT_MASK_REG, &host_int_mask);
3928 + if (ret) {
3929 + ret = UAP_STATUS_FAILURE;
3930 + goto done;
3931 + }
3932 +
3933 + /* Update with the mask and write back to the register */
3934 + host_int_mask &= ~mask;
3935 + ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, host_int_mask);
3936 + if (ret < 0) {
3937 + PRINTM(WARN, "Unable to diable the host interrupt!\n");
3938 + ret = UAP_STATUS_FAILURE;
3939 + goto done;
3940 + }
3941 +
3942 + done:
3943 + LEAVE();
3944 + return ret;
3945 +}
3946 +
3947 +/********************************************************
3948 + Global Functions
3949 +********************************************************/
3950 +
3951 +/**
3952 + * @brief This function handles the interrupt.
3953 + *
3954 + * @param func A pointer to sdio_func structure.
3955 + * @return n/a
3956 + */
3957 +static void
3958 +sbi_interrupt(struct sdio_func *func)
3959 +{
3960 + struct sdio_mmc_card *card;
3961 + uap_private *priv;
3962 + u8 ireg = 0;
3963 + int ret = UAP_STATUS_SUCCESS;
3964 +
3965 + ENTER();
3966 +
3967 + card = sdio_get_drvdata(func);
3968 + if (!card || !card->priv) {
3969 + PRINTM(MSG, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n",
3970 + __FUNCTION__, func, card);
3971 + LEAVE();
3972 + return;
3973 + }
3974 + priv = card->priv;
3975 +#ifdef FW_WAKEUP_TIME
3976 + if ((priv->adapter->wt_pwrup_sending != 0L) &&
3977 + (priv->adapter->wt_int == 0L))
3978 + priv->adapter->wt_int = get_utimeofday();
3979 +#endif
3980 +
3981 + ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
3982 + if (ret) {
3983 + PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n");
3984 + goto done;
3985 + }
3986 + if (ireg != 0) {
3987 + /*
3988 + * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
3989 + * Clear the interrupt status register and re-enable the interrupt
3990 + */
3991 + PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg);
3992 + sdio_writeb(card->func,
3993 + ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS),
3994 + HOST_INTSTATUS_REG, &ret);
3995 + if (ret) {
3996 + PRINTM(WARN,
3997 + "sdio_write_ioreg: clear int status register failed\n");
3998 + goto done;
3999 + }
4000 + }
4001 + OS_INT_DISABLE;
4002 + sd_ireg |= ireg;
4003 + OS_INT_RESTORE;
4004 +
4005 + uap_interrupt(priv);
4006 + done:
4007 + LEAVE();
4008 +}
4009 +
4010 +/**
4011 + * @brief This function probe the card
4012 + *
4013 + * @param func A pointer to sdio_func structure
4014 + * @param id A pointer to structure sd_device_id
4015 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4016 + */
4017 +static int
4018 +uap_probe(struct sdio_func *func, const struct sdio_device_id *id)
4019 +{
4020 + int ret = UAP_STATUS_FAILURE;
4021 + struct sdio_mmc_card *card = NULL;
4022 +
4023 + ENTER();
4024 +
4025 + PRINTM(MSG, "%s: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
4026 + __FUNCTION__, func->vendor, func->device, func->class, func->num);
4027 +
4028 + card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
4029 + if (!card) {
4030 + ret = -ENOMEM;
4031 + goto done;
4032 + }
4033 +
4034 + card->func = func;
4035 +
4036 + if (!uap_add_card(card)) {
4037 + PRINTM(ERROR, "%s: uap_add_callback failed\n", __FUNCTION__);
4038 + kfree(card);
4039 + ret = UAP_STATUS_FAILURE;
4040 + goto done;
4041 + }
4042 +
4043 + ret = UAP_STATUS_SUCCESS;
4044 +
4045 + done:
4046 + LEAVE();
4047 + return ret;
4048 +}
4049 +
4050 +/**
4051 + * @brief This function removes the card
4052 + *
4053 + * @param func A pointer to sdio_func structure
4054 + * @return N/A
4055 + */
4056 +static void
4057 +uap_remove(struct sdio_func *func)
4058 +{
4059 + struct sdio_mmc_card *card;
4060 +
4061 + ENTER();
4062 +
4063 + if (func) {
4064 + card = sdio_get_drvdata(func);
4065 + if (card) {
4066 + uap_remove_card(card);
4067 + kfree(card);
4068 + }
4069 + }
4070 +
4071 + LEAVE();
4072 +}
4073 +
4074 +#ifdef CONFIG_PM
4075 +/**
4076 + * @brief This function handles client driver suspend
4077 + *
4078 + * @param func A pointer to sdio_func structure
4079 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4080 + */
4081 +int
4082 +uap_suspend(struct sdio_func *func)
4083 +{
4084 + ENTER();
4085 + LEAVE();
4086 + return 0;
4087 +}
4088 +
4089 +/**
4090 + * @brief This function handles client driver resume
4091 + *
4092 + * @param func A pointer to sdio_func structure
4093 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4094 + */
4095 +int
4096 +uap_resume(struct sdio_func *func)
4097 +{
4098 + ENTER();
4099 + LEAVE();
4100 + return 0;
4101 +}
4102 +#endif
4103 +
4104 +/** Device ID for SD8688 */
4105 +#define SD_DEVICE_ID_8688_UAP 0x9104
4106 +/** UAP IDs */
4107 +static const struct sdio_device_id uap_ids[] = {
4108 + {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SD_DEVICE_ID_8688_UAP)},
4109 + {},
4110 +};
4111 +
4112 +MODULE_DEVICE_TABLE(sdio, uap_ids);
4113 +
4114 +static struct sdio_driver uap_sdio = {
4115 + .name = "uap_sdio",
4116 + .id_table = uap_ids,
4117 + .probe = uap_probe,
4118 + .remove = uap_remove,
4119 +#ifdef CONFIG_PM
4120 +/* .suspend = uap_suspend, */
4121 +/* .resume = uap_resume, */
4122 +#endif
4123 +
4124 +};
4125 +
4126 +/**
4127 + * @brief This function registers the IF module in bus driver.
4128 + *
4129 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4130 + */
4131 +int __init
4132 +sbi_register()
4133 +{
4134 + int ret = UAP_STATUS_SUCCESS;
4135 +
4136 + ENTER();
4137 +
4138 + /* SDIO Driver Registration */
4139 + if (sdio_register_driver(&uap_sdio) != 0) {
4140 + PRINTM(FATAL, "SDIO Driver Registration Failed \n");
4141 + ret = UAP_STATUS_FAILURE;
4142 + }
4143 +
4144 + LEAVE();
4145 + return ret;
4146 +}
4147 +
4148 +/**
4149 + * @brief This function de-registers the IF module in bus driver.
4150 + *
4151 + * @return n/a
4152 + */
4153 +void __exit
4154 +sbi_unregister(void)
4155 +{
4156 + ENTER();
4157 +
4158 + /* SDIO Driver Unregistration */
4159 + sdio_unregister_driver(&uap_sdio);
4160 +
4161 + LEAVE();
4162 +}
4163 +
4164 +/**
4165 + * @brief This function checks the interrupt status and handle it accordingly.
4166 + *
4167 + * @param priv A pointer to uap_private structure
4168 + * @param ireg A pointer to variable that keeps returned value
4169 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4170 + */
4171 +int
4172 +sbi_get_int_status(uap_private * priv, u8 * ireg)
4173 +{
4174 + int ret = UAP_STATUS_SUCCESS;
4175 + u8 sdio_ireg = 0;
4176 + struct sdio_mmc_card *card = priv->uap_dev.card;
4177 +
4178 + ENTER();
4179 +
4180 + *ireg = 0;
4181 + OS_INT_DISABLE;
4182 + sdio_ireg = sd_ireg;
4183 + sd_ireg = 0;
4184 + OS_INT_RESTORE;
4185 +
4186 + sdio_claim_host(card->func);
4187 +
4188 + if (sdio_ireg & DN_LD_HOST_INT_STATUS) { /* tx_done INT */
4189 + if (!priv->uap_dev.cmd_sent) { /* tx_done already received */
4190 + PRINTM(INFO,
4191 + "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n",
4192 + priv->uap_dev.cmd_sent, sdio_ireg);
4193 + } else {
4194 + priv->uap_dev.cmd_sent = FALSE;
4195 + priv->uap_dev.data_sent = FALSE;
4196 + if ( (priv->uap_dev.netdev->reg_state == NETREG_REGISTERED) && (skb_queue_len(&priv->adapter->tx_queue) < TX_LOW_WATERMARK)) {
4197 + os_start_queue(priv);
4198 + }
4199 + }
4200 + }
4201 + if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
4202 + sd_card_to_host(priv);
4203 + }
4204 +
4205 + *ireg = sdio_ireg;
4206 + ret = UAP_STATUS_SUCCESS;
4207 + sdio_release_host(card->func);
4208 +
4209 + LEAVE();
4210 + return ret;
4211 +}
4212 +
4213 +/**
4214 + * @brief This function disables the host interrupts.
4215 + *
4216 + * @param priv A pointer to uap_private structure
4217 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4218 + */
4219 +int
4220 +sbi_disable_host_int(uap_private * priv)
4221 +{
4222 + struct sdio_mmc_card *card = priv->uap_dev.card;
4223 + int ret;
4224 +
4225 + ENTER();
4226 +
4227 + sdio_claim_host(card->func);
4228 + ret = disable_host_int_mask(priv, HIM_DISABLE);
4229 + sdio_release_host(card->func);
4230 +
4231 + LEAVE();
4232 + return ret;
4233 +}
4234 +
4235 +/**
4236 + * @brief This function enables the host interrupts.
4237 + *
4238 + * @param priv A pointer to uap_private structure
4239 + * @return UAP_STATUS_SUCCESS
4240 + */
4241 +int
4242 +sbi_enable_host_int(uap_private * priv)
4243 +{
4244 + struct sdio_mmc_card *card = priv->uap_dev.card;
4245 + int ret;
4246 +
4247 + ENTER();
4248 +
4249 + sdio_claim_host(card->func);
4250 + ret = enable_host_int_mask(priv, HIM_ENABLE);
4251 + sdio_release_host(card->func);
4252 +
4253 + LEAVE();
4254 + return ret;
4255 +}
4256 +
4257 +/**
4258 + * @brief This function de-registers the device.
4259 + *
4260 + * @param priv A pointer to uap_private structure
4261 + * @return UAP_STATUS_SUCCESS
4262 + */
4263 +int
4264 +sbi_unregister_dev(uap_private * priv)
4265 +{
4266 + struct sdio_mmc_card *card = priv->uap_dev.card;
4267 +
4268 + ENTER();
4269 +
4270 + if (!card || !card->func) {
4271 + PRINTM(ERROR, "Error: card or function is NULL!\n");
4272 + goto done;
4273 + }
4274 +
4275 + sdio_claim_host(card->func);
4276 + sdio_release_irq(card->func);
4277 + sdio_disable_func(card->func);
4278 + sdio_release_host(card->func);
4279 +
4280 + sdio_set_drvdata(card->func, NULL);
4281 +
4282 + done:
4283 + LEAVE();
4284 + return UAP_STATUS_SUCCESS;
4285 +}
4286 +
4287 +/**
4288 + * @brief This function registers the device.
4289 + *
4290 + * @param priv A pointer to uap_private structure
4291 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4292 + */
4293 +int
4294 +sbi_register_dev(uap_private * priv)
4295 +{
4296 + int ret = UAP_STATUS_FAILURE;
4297 + u8 reg;
4298 + struct sdio_mmc_card *card = priv->uap_dev.card;
4299 + struct sdio_func *func;
4300 +
4301 + ENTER();
4302 +
4303 + if (!card || !card->func) {
4304 + PRINTM(ERROR, "Error: card or function is NULL!\n");
4305 + goto done;
4306 + }
4307 +
4308 + func = card->func;
4309 +
4310 + /* Initialize the private structure */
4311 + priv->uap_dev.ioport = 0;
4312 +
4313 + sdio_claim_host(func);
4314 +
4315 + ret = sdio_enable_func(func);
4316 + if (ret) {
4317 + PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret);
4318 + goto release_host;
4319 + }
4320 +
4321 + ret = sdio_claim_irq(func, sbi_interrupt);
4322 + if (ret) {
4323 + PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret);
4324 + goto disable_func;
4325 + }
4326 +
4327 + /* Read the IO port */
4328 + ret = sbi_read_ioreg(priv, IO_PORT_0_REG, &reg);
4329 + if (ret)
4330 + goto release_irq;
4331 + else
4332 + priv->uap_dev.ioport |= reg;
4333 +
4334 + ret = sbi_read_ioreg(priv, IO_PORT_1_REG, &reg);
4335 + if (ret)
4336 + goto release_irq;
4337 + else
4338 + priv->uap_dev.ioport |= (reg << 8);
4339 +
4340 + ret = sbi_read_ioreg(priv, IO_PORT_2_REG, &reg);
4341 + if (ret)
4342 + goto release_irq;
4343 + else
4344 + priv->uap_dev.ioport |= (reg << 16);
4345 +
4346 + PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num,
4347 + priv->uap_dev.ioport);
4348 +
4349 + ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE);
4350 + if (ret) {
4351 + PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__);
4352 + ret = UAP_STATUS_FAILURE;
4353 + goto release_irq;
4354 + }
4355 + priv->hotplug_device = &func->dev;
4356 +
4357 + if (helper_name == NULL) {
4358 + helper_name = DEFAULT_HELPER_NAME;
4359 + }
4360 + if (fw_name == NULL) {
4361 + fw_name = DEFAULT_FW_NAME;
4362 + }
4363 + sdio_release_host(func);
4364 +
4365 + sdio_set_drvdata(func, card);
4366 +
4367 + ret = UAP_STATUS_SUCCESS;
4368 + goto done;
4369 +
4370 + release_irq:
4371 + sdio_release_irq(func);
4372 + disable_func:
4373 + sdio_disable_func(func);
4374 + release_host:
4375 + sdio_release_host(func);
4376 +
4377 + done:
4378 + LEAVE();
4379 + return ret;
4380 +}
4381 +
4382 +/**
4383 + * @brief This function sends data to the card.
4384 + *
4385 + * @param priv A pointer to uap_private structure
4386 + * @param payload A pointer to the data/cmd buffer
4387 + * @param nb the length of data/cmd
4388 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4389 + */
4390 +int
4391 +sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb)
4392 +{
4393 + struct sdio_mmc_card *card = priv->uap_dev.card;
4394 + int ret = UAP_STATUS_SUCCESS;
4395 + int buf_block_len;
4396 + int blksz;
4397 + int i = 0;
4398 + u8 *buf = NULL;
4399 +#ifdef PXA3XX_DMA_ALIGN
4400 + void *tmpbuf = NULL;
4401 + int tmpbufsz;
4402 +#endif
4403 +
4404 + ENTER();
4405 +
4406 + if (!card || !card->func) {
4407 + PRINTM(ERROR, "card or function is NULL!\n");
4408 + LEAVE();
4409 + return UAP_STATUS_FAILURE;
4410 + }
4411 + buf = payload;
4412 +#ifdef PXA3XX_DMA_ALIGN
4413 + if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) {
4414 + tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT);
4415 + tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL);
4416 + memset(tmpbuf, 0, tmpbufsz);
4417 + /* Ensure 8-byte aligned CMD buffer */
4418 + buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT);
4419 + memcpy(buf, payload, nb);
4420 + }
4421 +#endif
4422 + /* Allocate buffer and copy payload */
4423 + blksz = SD_BLOCK_SIZE;
4424 + buf_block_len = (nb + blksz - 1) / blksz;
4425 + sdio_claim_host(card->func);
4426 +#define MAX_WRITE_IOMEM_RETRY 2
4427 + priv->uap_dev.cmd_sent = TRUE;
4428 + priv->uap_dev.data_sent = TRUE;
4429 + do {
4430 + /* Transfer data to card */
4431 + ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf,
4432 + buf_block_len * blksz);
4433 + if (ret < 0) {
4434 + i++;
4435 + PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i,
4436 + ret);
4437 + ret = UAP_STATUS_FAILURE;
4438 + if (i > MAX_WRITE_IOMEM_RETRY)
4439 + goto exit;
4440 + } else {
4441 + HEXDUMP("SDIO Blk Wr", payload, nb);
4442 + }
4443 + } while (ret == UAP_STATUS_FAILURE);
4444 + exit:
4445 + sdio_release_host(card->func);
4446 +#ifdef PXA3XX_DMA_ALIGN
4447 + if (tmpbuf)
4448 + kfree(tmpbuf);
4449 +#endif
4450 + if (ret == UAP_STATUS_FAILURE) {
4451 + priv->uap_dev.cmd_sent = FALSE;
4452 + priv->uap_dev.data_sent = FALSE;
4453 + }
4454 + LEAVE();
4455 + return ret;
4456 +}
4457 +
4458 +/**
4459 + * @brief This function reads CIS information.
4460 + *
4461 + * @param priv A pointer to uap_private structure
4462 + * @param cisinfo A pointer to CIS information output buffer
4463 + * @param cislen A pointer to length of CIS info output buffer
4464 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4465 + */
4466 +#if 0
4467 +static int
4468 +sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen)
4469 +{
4470 +#define CIS_PTR (0x8000)
4471 + struct sdio_mmc_card *card = priv->uap_dev.card;
4472 + unsigned int i, cis_ptr = CIS_PTR;
4473 + int ret = UAP_STATUS_FAILURE;
4474 +
4475 + ENTER();
4476 +
4477 + if (!card || !card->func) {
4478 + PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n");
4479 + goto exit;
4480 + }
4481 +#define MAX_SDIO_CIS_INFO_LEN (256)
4482 + if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) {
4483 + PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n");
4484 + goto exit;
4485 + }
4486 +
4487 + *cislen = MAX_SDIO_CIS_INFO_LEN;
4488 +
4489 + sdio_claim_host(card->func);
4490 +
4491 + PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr);
4492 +
4493 + /* Read the Tuple Data */
4494 + for (i = 0; i < *cislen; i++) {
4495 + ((unsigned char *) cisinfo)[i] =
4496 + sdio_readb(card->func, cis_ptr + i, &ret);
4497 + if (ret) {
4498 + PRINTM(WARN, "get_cis_info error: ret=%d\n", ret);
4499 + ret = UAP_STATUS_FAILURE;
4500 + goto done;
4501 + }
4502 + PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]);
4503 + }
4504 +
4505 + done:
4506 + sdio_release_host(card->func);
4507 + exit:
4508 + LEAVE();
4509 + return ret;
4510 +}
4511 +#endif
4512 +/**
4513 + * @brief This function downloads helper image to the card.
4514 + *
4515 + * @param priv A pointer to uap_private structure
4516 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4517 + */
4518 +int
4519 +sbi_prog_helper(uap_private * priv)
4520 +{
4521 + struct sdio_mmc_card *card = priv->uap_dev.card;
4522 + u8 *helper = NULL;
4523 + int helperlen;
4524 + int ret = UAP_STATUS_SUCCESS;
4525 + void *tmphlprbuf = NULL;
4526 + int tmphlprbufsz;
4527 + u8 *hlprbuf;
4528 + int hlprblknow;
4529 + u32 tx_len;
4530 +#ifdef FW_DOWNLOAD_SPEED
4531 + u32 tv1, tv2;
4532 +#endif
4533 +
4534 + ENTER();
4535 +
4536 + if (!card || !card->func) {
4537 + PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n");
4538 + goto done;
4539 + }
4540 +
4541 + if (priv->fw_helper) {
4542 + helper = (u8 *) priv->fw_helper->data;
4543 + helperlen = priv->fw_helper->size;
4544 + } else {
4545 + PRINTM(MSG, "No helper image found! Terminating download.\n");
4546 + LEAVE();
4547 + return UAP_STATUS_FAILURE;
4548 + }
4549 +
4550 + PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n",
4551 + helperlen, SD_BLOCK_SIZE);
4552 +
4553 +#ifdef FW_DOWNLOAD_SPEED
4554 + tv1 = get_utimeofday();
4555 +#endif
4556 +
4557 +#ifdef PXA3XX_DMA_ALIGN
4558 + tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
4559 +#else /* !PXA3XX_DMA_ALIGN */
4560 + tmphlprbufsz = UAP_UPLD_SIZE;
4561 +#endif /* !PXA3XX_DMA_ALIGN */
4562 + tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
4563 + if (!tmphlprbuf) {
4564 + PRINTM(ERROR,
4565 + "Unable to allocate buffer for helper. Terminating download\n");
4566 + ret = UAP_STATUS_FAILURE;
4567 + goto done;
4568 + }
4569 + memset(tmphlprbuf, 0, tmphlprbufsz);
4570 +#ifdef PXA3XX_DMA_ALIGN
4571 + hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT);
4572 +#else /* !PXA3XX_DMA_ALIGN */
4573 + hlprbuf = (u8 *) tmphlprbuf;
4574 +#endif /* !PXA3XX_DMA_ALIGN */
4575 +
4576 + sdio_claim_host(card->func);
4577 +
4578 + /* Perform helper data transfer */
4579 + tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN;
4580 + hlprblknow = 0;
4581 + do {
4582 + /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
4583 + ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
4584 + if (ret < 0) {
4585 + PRINTM(FATAL, "Helper download poll status timeout @ %d\n",
4586 + hlprblknow);
4587 + goto done;
4588 + }
4589 +
4590 + /* More data? */
4591 + if (hlprblknow >= helperlen)
4592 + break;
4593 +
4594 + /* Set blocksize to transfer - checking for last block */
4595 + if (helperlen - hlprblknow < tx_len)
4596 + tx_len = helperlen - hlprblknow;
4597 +
4598 + /* Set length to the 4-byte header */
4599 + *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len);
4600 +
4601 + /* Copy payload to buffer */
4602 + memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len);
4603 +
4604 + PRINTM(INFO, ".");
4605 +
4606 + /* Send data */
4607 + ret = sdio_writesb(card->func, priv->uap_dev.ioport,
4608 + hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE);
4609 +
4610 + if (ret < 0) {
4611 + PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow);
4612 + goto done;
4613 + }
4614 +
4615 + hlprblknow += tx_len;
4616 + } while (TRUE);
4617 +
4618 +#ifdef FW_DOWNLOAD_SPEED
4619 + tv2 = get_utimeofday();
4620 + PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000,
4621 + (tv1 % 1000000) / 1000, tv1 % 1000);
4622 + PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000,
4623 + tv2 % 1000);
4624 + tv2 -= tv1;
4625 + PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000,
4626 + tv2 % 1000);
4627 +#endif
4628 +
4629 + /* Write last EOF data */
4630 + PRINTM(INFO, "\nTransferring helper image EOF block\n");
4631 + memset(hlprbuf, 0x0, SD_BLOCK_SIZE);
4632 + ret = sdio_writesb(card->func, priv->uap_dev.ioport,
4633 + hlprbuf, SD_BLOCK_SIZE);
4634 +
4635 + if (ret < 0) {
4636 + PRINTM(FATAL, "IO error in writing helper image EOF block\n");
4637 + goto done;
4638 + }
4639 +
4640 + ret = UAP_STATUS_SUCCESS;
4641 +
4642 + done:
4643 + sdio_release_host(card->func);
4644 + if (tmphlprbuf)
4645 + kfree(tmphlprbuf);
4646 +
4647 + LEAVE();
4648 + return ret;
4649 +}
4650 +
4651 +/**
4652 + * @brief This function downloads firmware image to the card.
4653 + *
4654 + * @param priv A pointer to uap_private structure
4655 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4656 + */
4657 +int
4658 +sbi_prog_fw_w_helper(uap_private * priv)
4659 +{
4660 + struct sdio_mmc_card *card = priv->uap_dev.card;
4661 + u8 *firmware = NULL;
4662 + int firmwarelen;
4663 + u8 base0;
4664 + u8 base1;
4665 + int ret = UAP_STATUS_SUCCESS;
4666 + int offset;
4667 + void *tmpfwbuf = NULL;
4668 + int tmpfwbufsz;
4669 + u8 *fwbuf;
4670 + u16 len;
4671 + int txlen = 0;
4672 + int tx_blocks = 0;
4673 + int i = 0;
4674 + int tries = 0;
4675 +#ifdef FW_DOWNLOAD_SPEED
4676 + u32 tv1, tv2;
4677 +#endif
4678 +
4679 + ENTER();
4680 +
4681 + if (!card || !card->func) {
4682 + PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n");
4683 + goto done;
4684 + }
4685 +
4686 + if (priv->firmware) {
4687 + firmware = (u8 *) priv->firmware->data;
4688 + firmwarelen = priv->firmware->size;
4689 + } else {
4690 + PRINTM(MSG, "No firmware image found! Terminating download.\n");
4691 + LEAVE();
4692 + return UAP_STATUS_FAILURE;
4693 + }
4694 +
4695 + PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen);
4696 +
4697 +#ifdef FW_DOWNLOAD_SPEED
4698 + tv1 = get_utimeofday();
4699 +#endif
4700 +
4701 +#ifdef PXA3XX_DMA_ALIGN
4702 + tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
4703 +#else /* PXA3XX_DMA_ALIGN */
4704 + tmpfwbufsz = UAP_UPLD_SIZE;
4705 +#endif /* PXA3XX_DMA_ALIGN */
4706 + tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
4707 + if (!tmpfwbuf) {
4708 + PRINTM(ERROR,
4709 + "Unable to allocate buffer for firmware. Terminating download.\n");
4710 + ret = UAP_STATUS_FAILURE;
4711 + goto done;
4712 + }
4713 + memset(tmpfwbuf, 0, tmpfwbufsz);
4714 +#ifdef PXA3XX_DMA_ALIGN
4715 + /* Ensure 8-byte aligned firmware buffer */
4716 + fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT);
4717 +#else /* PXA3XX_DMA_ALIGN */
4718 + fwbuf = (u8 *) tmpfwbuf;
4719 +#endif /* PXA3XX_DMA_ALIGN */
4720 +
4721 + sdio_claim_host(card->func);
4722 +
4723 + /* Perform firmware data transfer */
4724 + offset = 0;
4725 + do {
4726 + /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
4727 + ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
4728 + if (ret < 0) {
4729 + PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n",
4730 + offset);
4731 + goto done;
4732 + }
4733 +
4734 + /* More data? */
4735 + if (offset >= firmwarelen)
4736 + break;
4737 +
4738 + for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
4739 + if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) {
4740 + PRINTM(WARN, "Dev BASE0 register read failed:"
4741 + " base0=0x%04X(%d). Terminating download.\n", base0,
4742 + base0);
4743 + ret = UAP_STATUS_FAILURE;
4744 + goto done;
4745 + }
4746 + if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) {
4747 + PRINTM(WARN, "Dev BASE1 register read failed:"
4748 + " base1=0x%04X(%d). Terminating download.\n", base1,
4749 + base1);
4750 + ret = UAP_STATUS_FAILURE;
4751 + goto done;
4752 + }
4753 + len = (((u16) base1) << 8) | base0;
4754 +
4755 + /* For SD8688 wait until the length is not 0, 1 or 2 before
4756 + downloading the first FW block, since BOOT code writes the
4757 + register to indicate the helper/FW download winner, the value
4758 + could be 1 or 2 (Func1 or Func2). */
4759 + if ((len && offset) || (len > 2))
4760 + break;
4761 + udelay(10);
4762 + }
4763 +
4764 + if (len == 0)
4765 + break;
4766 + else if (len > UAP_UPLD_SIZE) {
4767 + PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n",
4768 + offset, len);
4769 + ret = UAP_STATUS_FAILURE;
4770 + goto done;
4771 + }
4772 +
4773 + txlen = len;
4774 +
4775 + if (len & BIT(0)) {
4776 + i++;
4777 + if (i > MAX_WRITE_IOMEM_RETRY) {
4778 + PRINTM(FATAL,
4779 + "FW download failure @ %d, over max retry count\n",
4780 + offset);
4781 + ret = UAP_STATUS_FAILURE;
4782 + goto done;
4783 + }
4784 + PRINTM(ERROR, "FW CRC error indicated by the helper:"
4785 + " len = 0x%04X, txlen = %d\n", len, txlen);
4786 + len &= ~BIT(0);
4787 + /* Setting this to 0 to resend from same offset */
4788 + txlen = 0;
4789 + } else {
4790 + i = 0;
4791 +
4792 + /* Set blocksize to transfer - checking for last block */
4793 + if (firmwarelen - offset < txlen) {
4794 + txlen = firmwarelen - offset;
4795 + }
4796 + PRINTM(INFO, ".");
4797 +
4798 + tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE;
4799 +
4800 + /* Copy payload to buffer */
4801 + memcpy(fwbuf, &firmware[offset], txlen);
4802 + }
4803 +
4804 + /* Send data */
4805 + ret = sdio_writesb(card->func, priv->uap_dev.ioport,
4806 + fwbuf, tx_blocks * SD_BLOCK_SIZE);
4807 +
4808 + if (ret < 0) {
4809 + PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i,
4810 + offset);
4811 + if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) {
4812 + PRINTM(ERROR, "write ioreg failed (CFG)\n");
4813 + }
4814 + }
4815 +
4816 + offset += txlen;
4817 + } while (TRUE);
4818 +
4819 + PRINTM(INFO, "\nFW download over, size %d bytes\n", offset);
4820 +
4821 + ret = UAP_STATUS_SUCCESS;
4822 + done:
4823 +#ifdef FW_DOWNLOAD_SPEED
4824 + tv2 = get_utimeofday();
4825 + PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000,
4826 + (tv1 % 1000000) / 1000, tv1 % 1000);
4827 + PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000,
4828 + (tv2 % 1000000) / 1000, tv2 % 1000);
4829 + tv2 -= tv1;
4830 + PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000,
4831 + (tv2 % 1000000) / 1000, tv2 % 1000);
4832 +#endif
4833 + sdio_release_host(card->func);
4834 + if (tmpfwbuf)
4835 + kfree(tmpfwbuf);
4836 +
4837 + LEAVE();
4838 + return ret;
4839 +}
4840 +
4841 +/**
4842 + * @brief This function checks if the firmware is ready to accept
4843 + * command or not.
4844 + *
4845 + * @param priv A pointer to uap_private structure
4846 + * @param pollnum Poll number
4847 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4848 + */
4849 +int
4850 +sbi_check_fw_status(uap_private * priv, int pollnum)
4851 +{
4852 + struct sdio_mmc_card *card = priv->uap_dev.card;
4853 + int ret = UAP_STATUS_SUCCESS;
4854 + u16 firmwarestat;
4855 + int tries;
4856 +
4857 + ENTER();
4858 +
4859 + sdio_claim_host(card->func);
4860 +
4861 + /* Wait for firmware initialization event */
4862 + for (tries = 0; tries < pollnum; tries++) {
4863 + if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0)
4864 + continue;
4865 + if (firmwarestat == FIRMWARE_READY) {
4866 + ret = UAP_STATUS_SUCCESS;
4867 + break;
4868 + } else {
4869 + mdelay(10);
4870 + ret = UAP_STATUS_FAILURE;
4871 + }
4872 + }
4873 +
4874 + if (ret < 0)
4875 + goto done;
4876 +
4877 + ret = UAP_STATUS_SUCCESS;
4878 + sd_get_rx_unit(priv);
4879 +
4880 + done:
4881 + sdio_release_host(card->func);
4882 +
4883 + LEAVE();
4884 + return ret;
4885 +}
4886 +
4887 +/**
4888 + * @brief This function set bus clock on/off
4889 + *
4890 + * @param priv A pointer to uap_private structure
4891 + * @param option TRUE--on , FALSE--off
4892 + * @return UAP_STATUS_SUCCESS
4893 + */
4894 +#if 0
4895 +static int
4896 +sbi_set_bus_clock(uap_private * priv, u8 option)
4897 +{
4898 + ENTER();
4899 + LEAVE();
4900 + return UAP_STATUS_SUCCESS;
4901 +}
4902 +#endif
4903 +
4904 +/**
4905 + * @brief This function wakeup firmware
4906 + *
4907 + * @param priv A pointer to uap_private structure
4908 + * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
4909 + */
4910 +int
4911 +sbi_wakeup_firmware(uap_private * priv)
4912 +{
4913 + struct sdio_mmc_card *card = priv->uap_dev.card;
4914 + int ret = UAP_STATUS_SUCCESS;
4915 +
4916 + ENTER();
4917 +
4918 + if (!card || !card->func) {
4919 + PRINTM(ERROR, "card or function is NULL!\n");
4920 + LEAVE();
4921 + return UAP_STATUS_FAILURE;
4922 + }
4923 + sdio_claim_host(card->func);
4924 + sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
4925 + sdio_release_host(card->func);
4926 + LEAVE();
4927 + return ret;
4928 +}
4929 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h
4930 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 1970-01-01 01:00:00.000000000 +0100
4931 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 2012-07-31 14:23:04.000000000 +0200
4932 @@ -0,0 +1,136 @@
4933 +/** @file uap_sdio_mmc.h
4934 + * @brief This file contains SDIO IF (interface) module
4935 + * related macros, enum, and structure.
4936 + *
4937 + * Copyright (C) 2007-2009, Marvell International Ltd.
4938 + *
4939 + * This software file (the "File") is distributed by Marvell International
4940 + * Ltd. under the terms of the GNU General Public License Version 2, June 1991
4941 + * (the "License"). You may use, redistribute and/or modify this File in
4942 + * accordance with the terms and conditions of the License, a copy of which
4943 + * is available along with the File in the gpl.txt file or by writing to
4944 + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
4945 + * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
4946 + *
4947 + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
4948 + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
4949 + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
4950 + * this warranty disclaimer.
4951 + *
4952 + */
4953 +/****************************************************
4954 +Change log:
4955 + 10/10/07: initial version
4956 +****************************************************/
4957 +
4958 +#ifndef _UAP_SDIO_MMC_H
4959 +#define _UAP_SDIO_MMC_H
4960 +
4961 +#include <linux/mmc/sdio.h>
4962 +#include <linux/mmc/sdio_ids.h>
4963 +#include <linux/mmc/sdio_func.h>
4964 +#include <linux/mmc/card.h>
4965 +
4966 +#include "uap_headers.h"
4967 +
4968 +/** The number of times to try when waiting for downloaded firmware to
4969 + become active. (polling the scratch register). */
4970 +#define MAX_FIRMWARE_POLL_TRIES 100
4971 +
4972 +/** Firmware ready */
4973 +#define FIRMWARE_READY 0xfedc
4974 +
4975 +/** Number of firmware blocks to transfer */
4976 +#define FIRMWARE_TRANSFER_NBLOCK 2
4977 +
4978 +/* Host Control Registers */
4979 +/** Host Control Registers : I/O port 0 */
4980 +#define IO_PORT_0_REG 0x00
4981 +/** Host Control Registers : I/O port 1 */
4982 +#define IO_PORT_1_REG 0x01
4983 +/** Host Control Registers : I/O port 2 */
4984 +#define IO_PORT_2_REG 0x02
4985 +
4986 +/** Host Control Registers : Configuration */
4987 +#define CONFIGURATION_REG 0x03
4988 +/** Host Control Registers : Host without Command 53 finish host */
4989 +#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
4990 +/** Host Control Registers : Host power up */
4991 +#define HOST_POWER_UP (0x1U << 1)
4992 +/** Host Control Registers : Host power down */
4993 +#define HOST_POWER_DOWN (0x1U << 0)
4994 +
4995 +/** Host Control Registers : Host interrupt mask */
4996 +#define HOST_INT_MASK_REG 0x04
4997 +/** Host Control Registers : Upload host interrupt mask */
4998 +#define UP_LD_HOST_INT_MASK (0x1U)
4999 +/** Host Control Registers : Download host interrupt mask */
5000 +#define DN_LD_HOST_INT_MASK (0x2U)
5001 +/** Enable Host interrupt mask */
5002 +#define HIM_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
5003 +/** Disable Host interrupt mask */
5004 +#define HIM_DISABLE 0xff
5005 +
5006 +/** Host Control Registers : Host interrupt status */
5007 +#define HOST_INTSTATUS_REG 0x05
5008 +/** Host Control Registers : Upload host interrupt status */
5009 +#define UP_LD_HOST_INT_STATUS (0x1U)
5010 +/** Host Control Registers : Download host interrupt status */
5011 +#define DN_LD_HOST_INT_STATUS (0x2U)
5012 +
5013 +/** Host F1 read base 0 */
5014 +#define HOST_F1_RD_BASE_0 0x10
5015 +/** Host F1 read base 1 */
5016 +#define HOST_F1_RD_BASE_1 0x11
5017 +
5018 +/** Card Control Registers : Card status register */
5019 +#define CARD_STATUS_REG 0x20
5020 +/** Card Control Registers : Card I/O ready */
5021 +#define CARD_IO_READY (0x1U << 3)
5022 +/** Card Control Registers : CIS card ready */
5023 +#define CIS_CARD_RDY (0x1U << 2)
5024 +/** Card Control Registers : Upload card ready */
5025 +#define UP_LD_CARD_RDY (0x1U << 1)
5026 +/** Card Control Registers : Download card ready */
5027 +#define DN_LD_CARD_RDY (0x1U << 0)
5028 +
5029 +/** Card Control Registers : Card OCR 0 register */
5030 +#define CARD_OCR_0_REG 0x34
5031 +/** Card Control Registers : Card OCR 1 register */
5032 +#define CARD_OCR_1_REG 0x35
5033 +
5034 +/** Firmware status 0 register */
5035 +#define CARD_FW_STATUS0_REG 0x40
5036 +/** Firmware status 1 register */
5037 +#define CARD_FW_STATUS1_REG 0x41
5038 +/** Rx length register */
5039 +#define CARD_RX_LEN_REG 0x42
5040 +/** Rx unit register */
5041 +#define CARD_RX_UNIT_REG 0x43
5042 +
5043 +/** Chip Id Register 0 */
5044 +#define CARD_CHIP_ID_0_REG 0x801c
5045 +/** Chip Id Register 1 */
5046 +#define CARD_CHIP_ID_1_REG 0x801d
5047 +
5048 +#ifdef PXA3XX_DMA_ALIGN
5049 +/** DMA alignment value for PXA3XX platforms */
5050 +#define PXA3XX_DMA_ALIGNMENT 8
5051 +/** Macros for Data Alignment : size */
5052 +#define ALIGN_SZ(p, a) \
5053 + (((p) + ((a) - 1)) & ~((a) - 1))
5054 +
5055 +/** Macros for Data Alignment : address */
5056 +#define ALIGN_ADDR(p, a) \
5057 + ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1))
5058 +#endif /* PXA3XX_DMA_ALIGN */
5059 +
5060 +struct sdio_mmc_card
5061 +{
5062 + /** sdio_func structure pointer */
5063 + struct sdio_func *func;
5064 + /** uap_private structure pointer */
5065 + uap_private *priv;
5066 +};
5067 +
5068 +#endif /* _UAP_SDIO_MMC_H */
5069 diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile
5070 --- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile 2012-07-05 03:48:01.000000000 +0200
5071 +++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile 2012-07-31 14:20:01.343608619 +0200
5072 @@ -22,6 +22,8 @@
5073
5074 obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
5075
5076 +obj-$(CONFIG_LIBERTAS_UAP) += libertas_uap/
5077 +
5078 obj-$(CONFIG_ADM8211) += adm8211.o
5079
5080 obj-$(CONFIG_MWL8K) += mwl8k.o