From 8340edb2d8a24ee88bad3e230b77cbfedf81cff8 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Tue, 21 Aug 2012 21:36:42 -0400 Subject: commit all files and directions See README and LICENSE. --- ...ell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch | 31 - with-linux-3.4/dreamplug-3.4.0.patch | 107 - with-linux-3.4/linux-3.0-SDIO-micro-AP.patch | 5111 -------------------- .../linux-3.0.4-LIBERTAS-WEXT_PRIV.patch | 10 - with-linux-3.4/mvsdio-1-2.6.30.patch | 18 - with-linux-3.4/mvsdio-2.patch | 35 - with-linux-3.4/mvsdio-3.patch | 13 - with-linux-3.4/phys-virt.diff | 14 - with-linux-3.4/series | 8 - 9 files changed, 5347 deletions(-) delete mode 100644 with-linux-3.4/0002-Driver-for-Marvell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch delete mode 100644 with-linux-3.4/dreamplug-3.4.0.patch delete mode 100644 with-linux-3.4/linux-3.0-SDIO-micro-AP.patch delete mode 100644 with-linux-3.4/linux-3.0.4-LIBERTAS-WEXT_PRIV.patch delete mode 100644 with-linux-3.4/mvsdio-1-2.6.30.patch delete mode 100644 with-linux-3.4/mvsdio-2.patch delete mode 100644 with-linux-3.4/mvsdio-3.patch delete mode 100644 with-linux-3.4/phys-virt.diff delete mode 100644 with-linux-3.4/series (limited to 'with-linux-3.4') diff --git a/with-linux-3.4/0002-Driver-for-Marvell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch b/with-linux-3.4/0002-Driver-for-Marvell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch deleted file mode 100644 index d725ef3..0000000 --- a/with-linux-3.4/0002-Driver-for-Marvell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- ./drivers/net/wireless/libertas_uap/uap_main.c.orig 2012-01-05 02:04:22.082318156 -0700 -+++ ./drivers/net/wireless/libertas_uap/uap_main.c 2012-01-05 02:05:50.161341323 -0700 -@@ -1322,20 +1322,6 @@ uap_set_mac_address(struct net_device *d - } - - /** -- * @brief This function sets multicast addresses to firmware -- * -- * @param dev A pointer to net_device structure -- * @return n/a -- */ --static void --uap_set_multicast_list(struct net_device *dev) --{ -- ENTER(); --#warning uap_set_multicast_list not implemented. Expect problems with IPv6. -- LEAVE(); --} -- --/** - * @brief This function handles the timeout of packet - * transmission - * -@@ -1558,7 +1544,6 @@ static const struct net_device_ops uap_n - .ndo_set_mac_address = uap_set_mac_address, - .ndo_tx_timeout = uap_tx_timeout, - .ndo_get_stats = uap_get_stats, -- .ndo_set_multicast_list = uap_set_multicast_list, - }; - #endif - diff --git a/with-linux-3.4/dreamplug-3.4.0.patch b/with-linux-3.4/dreamplug-3.4.0.patch deleted file mode 100644 index 8840d61..0000000 --- a/with-linux-3.4/dreamplug-3.4.0.patch +++ /dev/null @@ -1,107 +0,0 @@ -Index: linux-3.4/arch/arm/mach-kirkwood/Kconfig -=================================================================== ---- linux-3.4.orig/arch/arm/mach-kirkwood/Kconfig 2012-05-27 17:28:53.529328624 -0300 -+++ linux-3.4/arch/arm/mach-kirkwood/Kconfig 2012-05-27 17:28:56.329418105 -0300 -@@ -44,6 +44,12 @@ - Say 'Y' here if you want your kernel to support the - Marvell GuruPlug Reference Board. - -+config MACH_DREAMPLUG -+ bool "Marvell DreamPlug Reference Board" -+ help -+ Say 'Y' here if you want your kernel to support the -+ Marvell DreamPlug Reference Board. -+ - config ARCH_KIRKWOOD_DT - bool "Marvell Kirkwood Flattened Device Tree" - select USE_OF -Index: linux-3.4/arch/arm/mach-kirkwood/Makefile -=================================================================== ---- linux-3.4.orig/arch/arm/mach-kirkwood/Makefile 2012-05-27 17:28:53.599330861 -0300 -+++ linux-3.4/arch/arm/mach-kirkwood/Makefile 2012-05-27 17:28:56.329418105 -0300 -@@ -7,6 +7,7 @@ - obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o - obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o - obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o -+obj-$(CONFIG_MACH_DREAMPLUG) += board-dreamplug.o - obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o - obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o - obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o -Index: linux-3.4/arch/arm/mach-kirkwood/board-dreamplug.c -=================================================================== ---- linux-3.4.orig/arch/arm/mach-kirkwood/board-dreamplug.c 2012-05-27 17:28:53.479327026 -0300 -+++ linux-3.4/arch/arm/mach-kirkwood/board-dreamplug.c 2012-05-27 17:28:56.329418105 -0300 -@@ -48,11 +48,13 @@ - .size = SZ_64K, - .offset = SZ_512K + SZ_512K, - }, -+#ifdef CONFIG_MACH_DREAMPLUG_DT - { - .name = "dtb", - .size = SZ_64K, - .offset = SZ_512K + SZ_512K + SZ_512K, - }, -+#endif - }; - - static const struct flash_platform_data dreamplug_spi_slave_data = { -@@ -136,8 +138,16 @@ - /* - * Basic setup. Needs to be called early. - */ -+#ifdef CONFIG_MACH_DREAMPLUG -+ kirkwood_init(); -+#endif -+ - kirkwood_mpp_conf(dreamplug_mpp_config); - -+#ifdef CONFIG_MACH_DREAMPLUG -+ kirkwood_uart0_init(); -+#endif -+ - spi_register_board_info(dreamplug_spi_slave_info, - ARRAY_SIZE(dreamplug_spi_slave_info)); - kirkwood_spi_init(); -@@ -150,3 +160,16 @@ - - platform_device_register(&dreamplug_leds); - } -+ -+#ifdef CONFIG_MACH_DREAMPLUG -+MACHINE_START(DREAMPLUG, "Marvell DreamPlug Reference Board") -+ /* Maintainer: ? */ -+ .map_io = kirkwood_map_io, -+ .init_early = kirkwood_init_early, -+ .init_irq = kirkwood_init_irq, -+ .timer = &kirkwood_timer, -+ .init_machine = dreamplug_init, -+ .restart = kirkwood_restart, -+ .atag_offset = 0x100, -+MACHINE_END -+#endif -Index: linux-3.4/arch/arm/tools/mach-types -=================================================================== ---- linux-3.4.orig/arch/arm/tools/mach-types 2012-05-27 17:28:53.429325427 -0300 -+++ linux-3.4/arch/arm/tools/mach-types 2012-05-27 17:28:56.339418425 -0300 -@@ -845,7 +845,7 @@ - mx51_ivy MACH_MX51_IVY MX51_IVY 3547 - mx51_lvd MACH_MX51_LVD MX51_LVD 3548 - omap3_wiser2 MACH_OMAP3_WISER2 OMAP3_WISER2 3549 --dreamplug MACH_DREAMPLUG DREAMPLUG 3550 -+dreamplug MACH_DREAMPLUG DREAMPLUG 2659 - cobas_c_111 MACH_COBAS_C_111 COBAS_C_111 3551 - cobas_u_411 MACH_COBAS_U_411 COBAS_U_411 3552 - hssd MACH_HSSD HSSD 3553 -Index: linux-3.4/arch/arm/mach-kirkwood/common.h -=================================================================== ---- linux-3.4.orig/arch/arm/mach-kirkwood/common.h 2012-05-27 17:29:00.629555522 -0300 -+++ linux-3.4/arch/arm/mach-kirkwood/common.h 2012-05-27 17:36:06.263156553 -0300 -@@ -52,7 +52,7 @@ - void kirkwood_restart(char, const char *); - - /* board init functions for boards not fully converted to fdt */ --#ifdef CONFIG_MACH_DREAMPLUG_DT -+#if defined CONFIG_MACH_DREAMPLUG_DT || defined CONFIG_MACH_DREAMPLUG - void dreamplug_init(void); - #else - static inline void dreamplug_init(void) {}; diff --git a/with-linux-3.4/linux-3.0-SDIO-micro-AP.patch b/with-linux-3.4/linux-3.0-SDIO-micro-AP.patch deleted file mode 100644 index 9998a51..0000000 --- a/with-linux-3.4/linux-3.0-SDIO-micro-AP.patch +++ /dev/null @@ -1,5111 +0,0 @@ -diff -Naupr linux-2.6.37/drivers/net/wireless/Kconfig linux-2.6.37-new/drivers/net/wireless/Kconfig ---- linux-2.6.37/drivers/net/wireless/Kconfig 2011-01-04 17:50:19.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/Kconfig 2011-01-08 06:01:04.034836160 -0700 -@@ -51,6 +51,12 @@ config LIBERTAS_THINFIRM_USB - ---help--- - A driver for Marvell Libertas 8388 USB devices using thinfirm. - -+config LIBERTAS_UAP -+ tristate "Marvell Libertas 8688 micro-AP support" -+ depends on LIBERTAS && MMC -+ ---help--- -+ A driver for Marvell Libertas 8688 SDIO micro-AP support. -+ - config AIRO - tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" - depends on ISA_DMA_API && (PCI || BROKEN) -diff -Naupr linux-2.6.37/drivers/net/wireless/Makefile linux-2.6.37-new/drivers/net/wireless/Makefile ---- linux-2.6.37/drivers/net/wireless/Makefile 2011-01-04 17:50:19.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/Makefile 2011-01-08 06:01:04.034836160 -0700 -@@ -36,6 +36,8 @@ obj-$(CONFIG_LIBERTAS) += libertas/ - - obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ - -+obj-$(CONFIG_LIBERTAS_UAP) += libertas_uap/ -+ - obj-$(CONFIG_ADM8211) += adm8211.o - - obj-$(CONFIG_MWL8K) += mwl8k.o -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/Makefile linux-2.6.37-new/drivers/net/wireless/libertas_uap/Makefile ---- linux-2.6.37/drivers/net/wireless/libertas_uap/Makefile 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/Makefile 2011-01-08 06:01:04.036836021 -0700 -@@ -0,0 +1,6 @@ -+obj-$(CONFIG_LIBERTAS_UAP) += uap8xxx.o -+ -+uap8xxx-y += uap_main.o uap_sdio_mmc.o -+uap8xxx-$(CONFIG_PROC_FS) += uap_proc.o uap_debug.o -+ -+EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1 -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_debug.c linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_debug.c ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_debug.c 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_debug.c 2011-01-08 06:01:04.038835884 -0700 -@@ -0,0 +1,261 @@ -+/** @file uap_debug.c -+ * @brief This file contains functions for debug proc file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifdef CONFIG_PROC_FS -+#include "uap_headers.h" -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+#define item_size(n) (sizeof ((uap_adapter *)0)->n) -+#define item_addr(n) ((u32) &((uap_adapter *)0)->n) -+ -+#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n)) -+#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n)) -+ -+#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n) -+#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n) -+ -+/** MicroAp device offset */ -+#define OFFSET_UAP_DEV 0x01 -+/** Bluetooth adapter offset */ -+#define OFFSET_UAP_ADAPTER 0x02 -+ -+struct debug_data -+{ -+ /** Name */ -+ char name[32]; -+ /** Size */ -+ u32 size; -+ /** Address */ -+ u32 addr; -+ /** Offset */ -+ u32 offset; -+ /** Flag */ -+ u32 flag; -+}; -+ -+/* To debug any member of uap_adapter, simply add one line here. -+ */ -+static struct debug_data items[] = { -+ {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent), -+ OFFSET_UAP_DEV}, -+ {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent), -+ OFFSET_UAP_DEV}, -+ {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter), -+ OFFSET_UAP_ADAPTER}, -+ {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending), -+ OFFSET_UAP_ADAPTER}, -+ {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0, -+ item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER}, -+ {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0, -+ item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER}, -+ {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER}, -+ {"ps_state", item_size(ps_state), 0, item_addr(ps_state), -+ OFFSET_UAP_ADAPTER}, -+#ifdef DEBUG_LEVEL1 -+ {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0} -+#endif -+}; -+ -+static int num_of_items = sizeof(items) / sizeof(items[0]); -+ -+/******************************************************** -+ Global Variables -+********************************************************/ -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief proc read function -+ * -+ * @param page pointer to buffer -+ * @param s read data starting position -+ * @param off offset -+ * @param cnt counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data) -+{ -+ int val = 0; -+ char *p = page; -+ int i; -+ -+ struct debug_data *d = (struct debug_data *) data; -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ for (i = 0; i < num_of_items; i++) { -+ if (d[i].size == 1) -+ val = *((u8 *) d[i].addr); -+ else if (d[i].size == 2) -+ val = *((u16 *) d[i].addr); -+ else if (d[i].size == 4) -+ val = *((u32 *) d[i].addr); -+ -+ p += sprintf(p, "%s=%d\n", d[i].name, val); -+ } -+ MODULE_PUT; -+ return p - page; -+} -+ -+/** -+ * @brief proc write function -+ * -+ * @param f file pointer -+ * @param buf pointer to data buffer -+ * @param cnt data number to write -+ * @param data data to write -+ * @return number of data -+ */ -+static int -+uap_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data) -+{ -+ int r, i; -+ char *pdata; -+ char *p; -+ char *p0; -+ char *p1; -+ char *p2; -+ struct debug_data *d = (struct debug_data *) data; -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ pdata = (char *) kmalloc(cnt, GFP_KERNEL); -+ if (pdata == NULL) { -+ MODULE_PUT; -+ return 0; -+ } -+ -+ if (copy_from_user(pdata, buf, cnt)) { -+ PRINTM(INFO, "Copy from user failed\n"); -+ kfree(pdata); -+ MODULE_PUT; -+ return 0; -+ } -+ -+ p0 = pdata; -+ for (i = 0; i < num_of_items; i++) { -+ do { -+ p = strstr(p0, d[i].name); -+ if (p == NULL) -+ break; -+ p1 = strchr(p, '\n'); -+ if (p1 == NULL) -+ break; -+ p0 = p1++; -+ p2 = strchr(p, '='); -+ if (!p2) -+ break; -+ p2++; -+ r = string_to_number(p2); -+ if (d[i].size == 1) -+ *((u8 *) d[i].addr) = (u8) r; -+ else if (d[i].size == 2) -+ *((u16 *) d[i].addr) = (u16) r; -+ else if (d[i].size == 4) -+ *((u32 *) d[i].addr) = (u32) r; -+ break; -+ } while (TRUE); -+ } -+ kfree(pdata); -+#ifdef DEBUG_LEVEL1 -+ printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg); -+ printk(KERN_ALERT "INFO (%08lx) %s\n", DBG_INFO, -+ (drvdbg & DBG_INFO) ? "X" : ""); -+ printk(KERN_ALERT "WARN (%08lx) %s\n", DBG_WARN, -+ (drvdbg & DBG_WARN) ? "X" : ""); -+ printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY, -+ (drvdbg & DBG_ENTRY) ? "X" : ""); -+ printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D, -+ (drvdbg & DBG_CMD_D) ? "X" : ""); -+ printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D, -+ (drvdbg & DBG_DAT_D) ? "X" : ""); -+ printk(KERN_ALERT "CMND (%08lx) %s\n", DBG_CMND, -+ (drvdbg & DBG_CMND) ? "X" : ""); -+ printk(KERN_ALERT "DATA (%08lx) %s\n", DBG_DATA, -+ (drvdbg & DBG_DATA) ? "X" : ""); -+ printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR, -+ (drvdbg & DBG_ERROR) ? "X" : ""); -+ printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL, -+ (drvdbg & DBG_FATAL) ? "X" : ""); -+ printk(KERN_ALERT "MSG (%08lx) %s\n", DBG_MSG, -+ (drvdbg & DBG_MSG) ? "X" : ""); -+#endif -+ MODULE_PUT; -+ return cnt; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief create debug proc file -+ * -+ * @param priv pointer uap_private -+ * @param dev pointer net_device -+ * @return N/A -+ */ -+void -+uap_debug_entry(uap_private * priv, struct net_device *dev) -+{ -+ int i; -+ struct proc_dir_entry *r; -+ -+ if (priv->proc_entry == NULL) -+ return; -+ -+ for (i = 0; i < num_of_items; i++) { -+ if (items[i].flag & OFFSET_UAP_ADAPTER) -+ items[i].addr = items[i].offset + (u32) priv->adapter; -+ if (items[i].flag & OFFSET_UAP_DEV) -+ items[i].addr = items[i].offset + (u32) & priv->uap_dev; -+ } -+ r = create_proc_entry("debug", 0644, priv->proc_entry); -+ if (r == NULL) -+ return; -+ -+ r->data = &items[0]; -+ r->read_proc = uap_debug_read; -+ r->write_proc = uap_debug_write; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) -+ r->owner = THIS_MODULE; -+#endif -+} -+ -+/** -+ * @brief remove proc file -+ * -+ * @param priv pointer uap_private -+ * @return N/A -+ */ -+void -+uap_debug_remove(uap_private * priv) -+{ -+ remove_proc_entry("debug", priv->proc_entry); -+} -+ -+#endif -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_drv.h linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_drv.h ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_drv.h 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_drv.h 2011-06-26 00:15:04.040835746 -0700 -@@ -0,0 +1,667 @@ -+/** @file uap_drv.h -+ * @brief This file contains Linux OS related definitions and -+ * declarations, uAP driver -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+ -+#ifndef _UAP_DRV_H -+#define _UAP_DRV_H -+ -+/** Driver release version */ -+#define DRIVER_VERSION "26146" -+ -+/** True */ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+/** False */ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+/** Bit definitions */ -+#ifndef BIT -+#define BIT(x) (1UL << (x)) -+#endif -+ -+/** Dma addresses are 32-bits wide. */ -+#ifndef __ATTRIB_ALIGN__ -+#define __ATTRIB_ALIGN__ __attribute__((aligned(4))) -+#endif -+ -+/** attribute pack */ -+#ifndef __ATTRIB_PACK__ -+#define __ATTRIB_PACK__ __attribute__ ((packed)) -+#endif -+ -+/** Debug Macro definition*/ -+#ifdef DEBUG_LEVEL1 -+ -+extern u32 drvdbg; -+ -+/** Debug message control bit definition for drvdbg */ -+/** Debug message */ -+#define DBG_MSG BIT(0) -+/** Debug fatal message */ -+#define DBG_FATAL BIT(1) -+/** Debug error message */ -+#define DBG_ERROR BIT(2) -+/** Debug data message */ -+#define DBG_DATA BIT(3) -+/** Debug command message */ -+#define DBG_CMND BIT(4) -+ -+/** Debug data */ -+#define DBG_DAT_D BIT(16) -+/** Debug command */ -+#define DBG_CMD_D BIT(17) -+ -+/** Debug entry */ -+#define DBG_ENTRY BIT(28) -+/** Debug warning */ -+#define DBG_WARN BIT(29) -+/** Debug info */ -+#define DBG_INFO BIT(30) -+ -+/** Print info */ -+#define PRINTM_INFO(msg...) {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);} -+/** Print warn message */ -+#define PRINTM_WARN(msg...) {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);} -+/** Print entry */ -+#define PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);} -+/** Print cmd_d */ -+#define PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);} -+/** Print data_d */ -+#define PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);} -+/** Print command */ -+#define PRINTM_CMND(msg...) {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);} -+/** Print data */ -+#define PRINTM_DATA(msg...) {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);} -+/** Print error message */ -+#define PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);} -+/** Print fatal message */ -+#define PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);} -+/** Print message */ -+#define PRINTM_MSG(msg...) {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);} -+/** Print level */ -+#define PRINTM(level,msg...) PRINTM_##level(msg) -+ -+#else -+ -+#define PRINTM(level,msg...) do {} while (0) -+ -+#endif /* DEBUG_LEVEL1 */ -+ -+/** Wait until a condition becomes true */ -+#define ASSERT(cond) \ -+do { \ -+ if (!(cond)) \ -+ PRINTM(INFO, "ASSERT: %s, %s:%i\n", \ -+ __FUNCTION__, __FILE__, __LINE__); \ -+} while(0) -+ -+/** Log enrty point for debugging */ -+#define ENTER() PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \ -+ __FILE__, __LINE__) -+/** Log exit point for debugging */ -+#define LEAVE() PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \ -+ __FILE__, __LINE__) -+ -+#ifdef DEBUG_LEVEL1 -+/** Dump buffer length */ -+#define DBG_DUMP_BUF_LEN 64 -+/** Maximum dump per line */ -+#define MAX_DUMP_PER_LINE 16 -+/** Data dump length */ -+#define DATA_DUMP_LEN 32 -+ -+static inline void -+hexdump(char *prompt, u8 * buf, int len) -+{ -+ int i; -+ char dbgdumpbuf[DBG_DUMP_BUF_LEN]; -+ char *ptr = dbgdumpbuf; -+ -+ printk(KERN_DEBUG "%s:\n", prompt); -+ for (i = 1; i <= len; i++) { -+ ptr += sprintf(ptr, "%02x ", *buf); -+ buf++; -+ if (i % MAX_DUMP_PER_LINE == 0) { -+ *ptr = 0; -+ printk(KERN_DEBUG "%s\n", dbgdumpbuf); -+ ptr = dbgdumpbuf; -+ } -+ } -+ if (len % MAX_DUMP_PER_LINE) { -+ *ptr = 0; -+ printk(KERN_DEBUG "%s\n", dbgdumpbuf); -+ } -+} -+ -+/** Debug command */ -+#define DBG_HEXDUMP_CMD_D(x,y,z) {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);} -+/** Debug data */ -+#define DBG_HEXDUMP_DAT_D(x,y,z) {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);} -+/** Debug hexdump */ -+#define DBG_HEXDUMP(level,x,y,z) DBG_HEXDUMP_##level(x,y,z) -+/** hexdump */ -+#define HEXDUMP(x,y,z) {if (drvdbg & DBG_INFO) hexdump(x,y,z);} -+#else -+/** Do nothing since debugging is not turned on */ -+#define DBG_HEXDUMP(level,x,y,z) do {} while (0) -+/** Do nothing since debugging is not turned on */ -+#define HEXDUMP(x,y,z) do {} while (0) -+#endif -+ -+/** -+ * Typedefs -+ */ -+/** Unsigned char */ -+typedef u8 BOOLEAN; -+ -+/* -+ * OS macro definitions -+ */ -+/** OS macro to get time */ -+#define os_time_get() jiffies -+ -+/** OS macro to update transfer start time */ -+#define UpdateTransStart(dev) { \ -+ dev->trans_start = jiffies; \ -+} -+ -+/** Try to get a reference to the module */ -+#define MODULE_GET try_module_get(THIS_MODULE) -+/** Decrease module reference count */ -+#define MODULE_PUT module_put(THIS_MODULE) -+ -+/** OS macro to initialize semaphore */ -+#define OS_INIT_SEMAPHORE(x) sema_init(x,1) -+/** OS macro to acquire blocking semaphore */ -+#define OS_ACQ_SEMAPHORE_BLOCK(x) down_interruptible(x) -+/** OS macro to acquire non-blocking semaphore */ -+#define OS_ACQ_SEMAPHORE_NOBLOCK(x) down_trylock(x) -+/** OS macro to release semaphore */ -+#define OS_REL_SEMAPHORE(x) up(x) -+ -+static inline void -+os_sched_timeout(u32 millisec) -+{ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout((millisec * HZ) / 1000); -+} -+ -+/** Maximum size of ethernet packet */ -+#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE 1514 -+ -+/** Maximum size of multicast list */ -+#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32 -+ -+/** Find minimum */ -+#ifndef MIN -+#define MIN(a,b) ((a) < (b) ? (a) : (b)) -+#endif -+ -+/** Find maximum */ -+#ifndef MAX -+#define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#endif -+ -+/** Find number of elements */ -+#ifndef NELEMENTS -+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0])) -+#endif -+ -+/** Buffer Constants */ -+ -+/** Size of command buffer */ -+#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024) -+ -+/** Length of device length */ -+#define DEV_NAME_LEN 32 -+ -+/** Length of ethernet address */ -+#ifndef ETH_ALEN -+#define ETH_ALEN 6 -+#endif -+ -+/** Default watchdog timeout */ -+#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ) -+ -+/** Success */ -+#define UAP_STATUS_SUCCESS (0) -+/** Failure */ -+#define UAP_STATUS_FAILURE (-1) -+/** Not accepted */ -+#define UAP_STATUS_NOT_ACCEPTED (-2) -+ -+/** Max loop count (* 100ms) for waiting device ready at init time */ -+#define MAX_WAIT_DEVICE_READY_COUNT 50 -+ -+/** Tx high watermark. Stop Tx queue after this is crossed */ -+#define TX_HIGH_WATERMARK 4 -+/** Tx low watermark. Restart Tx queue after this is crossed */ -+#define TX_LOW_WATERMARK 2 -+ -+/** Netlink protocol number */ -+#define NETLINK_MARVELL (MAX_LINKS - 1) -+/** Netlink maximum payload size */ -+#define NL_MAX_PAYLOAD 1024 -+/** Netlink multicast group number */ -+#define NL_MULTICAST_GROUP 1 -+ -+/** 20 seconds */ -+#define MRVDRV_TIMER_20S 20000 -+ -+/** Host Command option for wait till Send */ -+#define HostCmd_OPTION_WAITFORSEND 0x0001 -+/** Host Command option for wait for RSP */ -+#define HostCmd_OPTION_WAITFORRSP 0x0002 -+/** Host Command option for wait for RSP or Timeout */ -+#define HostCmd_OPTION_WAITFORRSP_TIMEOUT 0x0003 -+/** Host Command option for wait for RSP of sleep confirm */ -+#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM 0x0004 -+ -+/** Sleep until a condition gets true or a timeout elapses */ -+#define os_wait_interruptible_timeout(waitq, cond, timeout) \ -+ wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000)) -+ -+/** Private command ID to Host command */ -+#define UAPHOSTCMD (SIOCDEVPRIVATE + 1) -+ -+/** Private command ID to Power Mode */ -+#define UAP_POWER_MODE (SIOCDEVPRIVATE + 3) -+/** sleep_param */ -+typedef struct _ps_sleep_param -+{ -+ /** control bitmap */ -+ u32 ctrl_bitmap; -+ /** minimum sleep period (micro second) */ -+ u32 min_sleep; -+ /** maximum sleep period (micro second) */ -+ u32 max_sleep; -+} ps_sleep_param; -+ -+/** inactivity sleep_param */ -+typedef struct _inact_sleep_param -+{ -+ /** inactivity timeout (micro second) */ -+ u32 inactivity_to; -+ /** miniumu awake period (micro second) */ -+ u32 min_awake; -+ /** maximum awake period (micro second) */ -+ u32 max_awake; -+} inact_sleep_param; -+ -+/** flag for ps mode */ -+#define PS_FLAG_PS_MODE 1 -+/** flag for sleep param */ -+#define PS_FLAG_SLEEP_PARAM 2 -+/** flag for inactivity sleep param */ -+#define PS_FLAG_INACT_SLEEP_PARAM 4 -+ -+/** Disable power mode */ -+#define PS_MODE_DISABLE 0 -+/** Enable periodic dtim ps */ -+#define PS_MODE_PERIODIC_DTIM 1 -+/** Enable inactivity ps */ -+#define PS_MODE_INACTIVITY 2 -+ -+/** sleep parameter */ -+#define SLEEP_PARAMETER 1 -+/** inactivity sleep parameter */ -+#define INACTIVITY_SLEEP_PARAMETER 2 -+/** ps_mgmt */ -+typedef struct _ps_mgmt -+{ -+ /** flags for valid field */ -+ u16 flags; -+ /** power mode */ -+ u16 ps_mode; -+ /** sleep param */ -+ ps_sleep_param sleep_param; -+ /** inactivity sleep param */ -+ inact_sleep_param inact_param; -+} ps_mgmt; -+ -+/** Semaphore structure */ -+typedef struct semaphore SEMAPHORE; -+ -+/** Global Varibale Declaration */ -+/** Private data structure of the device */ -+typedef struct _uap_private uap_private; -+/** Adapter data structure of the device */ -+typedef struct _uap_adapter uap_adapter; -+/** private structure */ -+extern uap_private *uappriv; -+ -+/** ENUM definition*/ -+ -+/** Hardware status codes */ -+typedef enum _HARDWARE_STATUS -+{ -+ HWReady, -+ HWInitializing, -+ HWReset, -+ HWClosing, -+ HWNotReady -+} HARDWARE_STATUS; -+ -+/** info for debug purpose */ -+typedef struct _uap_dbg -+{ -+ /** Number of host to card command failures */ -+ u32 num_cmd_host_to_card_failure; -+ /** Number of host to card Tx failures */ -+ u32 num_tx_host_to_card_failure; -+} uap_dbg; -+ -+/** Set thread state */ -+#define OS_SET_THREAD_STATE(x) set_current_state(x) -+ -+typedef struct -+{ -+ /** Task */ -+ struct task_struct *task; -+ /** Queue */ -+ wait_queue_head_t waitQ; -+ /** PID */ -+ pid_t pid; -+ /** Private structure */ -+ void *priv; -+} uap_thread; -+ -+static inline void -+uap_activate_thread(uap_thread * thr) -+{ -+ /** Record the thread pid */ -+ thr->pid = current->pid; -+ -+ /** Initialize the wait queue */ -+ init_waitqueue_head(&thr->waitQ); -+} -+ -+static inline void -+uap_deactivate_thread(uap_thread * thr) -+{ -+ thr->pid = 0; -+ return; -+} -+ -+static inline void -+uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name) -+{ -+ thr->task = kthread_run(uapfunc, thr, "%s", name); -+} -+ -+static inline int -+uap_terminate_thread(uap_thread * thr) -+{ -+ /* Check if the thread is active or not */ -+ if (!thr->pid) -+ return -1; -+ kthread_stop(thr->task); -+ return 0; -+} -+ -+/** Data structure for the Marvell uAP device */ -+typedef struct _uap_dev -+{ -+ /** device name */ -+ char name[DEV_NAME_LEN]; -+ /** card pointer */ -+ void *card; -+ /** IO port */ -+ u32 ioport; -+ /** Rx unit */ -+ u8 rx_unit; -+ /** Data sent: -+ TRUE - Data is sent to fw, no Tx Done received -+ FALSE - Tx done received for previous Tx */ -+ BOOLEAN data_sent; -+ /** CMD sent: -+ TRUE - CMD is sent to fw, no CMD Done received -+ FALSE - CMD done received for previous CMD */ -+ BOOLEAN cmd_sent; -+ /** netdev pointer */ -+ struct net_device *netdev; -+} uap_dev_t, *puap_dev_t; -+ -+/** Private structure for the MV device */ -+struct _uap_private -+{ -+ /** Device open */ -+ int open; -+ -+ /** Device adapter structure */ -+ uap_adapter *adapter; -+ /** Device structure */ -+ uap_dev_t uap_dev; -+ -+ /** Net device statistics structure */ -+ struct net_device_stats stats; -+ -+ /** Number of Tx timeouts */ -+ u32 num_tx_timeout; -+ -+ /** Media connection status */ -+ BOOLEAN MediaConnected; -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_uap; -+ struct proc_dir_entry *proc_entry; -+#endif /* CONFIG_PROC_FS */ -+ -+ /** Firmware helper */ -+ const struct firmware *fw_helper; -+ /** Firmware */ -+ const struct firmware *firmware; -+ /** Hotplug device */ -+ struct device *hotplug_device; -+ /** thread to service interrupts */ -+ uap_thread MainThread; -+ /** Driver lock */ -+ spinlock_t driver_lock; -+ /** Driver lock flags */ -+ ulong driver_flags; -+ -+}; -+ -+/** PS_CMD_ConfirmSleep */ -+typedef struct _PS_CMD_ConfirmSleep -+{ -+ /** SDIO Length */ -+ u16 SDLen; -+ /** SDIO Type */ -+ u16 SDType; -+ /** Command */ -+ u16 Command; -+ /** Size */ -+ u16 Size; -+ /** Sequence number */ -+ u16 SeqNum; -+ /** Result */ -+ u16 Result; -+} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep; -+ -+/** Wlan Adapter data structure*/ -+struct _uap_adapter -+{ -+ /** Power save confirm sleep command */ -+ PS_CMD_ConfirmSleep PSConfirmSleep; -+ /** Device status */ -+ HARDWARE_STATUS HardwareStatus; -+ /** Interrupt counter */ -+ u32 IntCounter; -+ /** Tx packet queue */ -+ struct sk_buff_head tx_queue; -+ /** Cmd packet queue */ -+ struct sk_buff_head cmd_queue; -+ /** Command sequence number */ -+ u16 SeqNum; -+ /** Command buffer */ -+ u8 *CmdBuf; -+ /** cmd pending flag */ -+ u8 cmd_pending; -+ /** cmd wait option */ -+ u8 cmd_wait_option; -+ /** Command buffer length */ -+ u32 CmdSize; -+ /** Command wait queue */ -+ wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__; -+ /** Command wait queue state flag */ -+ u8 CmdWaitQWoken; -+ /** PnP support */ -+ BOOLEAN SurpriseRemoved; -+ /** Debug */ -+ uap_dbg dbg; -+ /** Netlink kernel socket */ -+ struct sock *nl_sk; -+ /** Semaphore for CMD */ -+ SEMAPHORE CmdSem; -+ /** Power Save mode */ -+ u8 psmode; -+ /** Power Save state */ -+ u8 ps_state; -+ /** Number of wakeup tries */ -+ u32 WakeupTries; -+}; -+ -+static inline int -+os_upload_rx_packet(uap_private * priv, struct sk_buff *skb) -+{ -+ skb->dev = priv->uap_dev.netdev; -+ skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev); -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ if (in_interrupt()) -+ netif_rx(skb); -+ else -+ netif_rx_ni(skb); -+ return 0; -+} -+ -+/* -+ * netif carrier_on/off and start(wake)/stop_queue handling -+ */ -+static inline void -+os_carrier_on(uap_private * priv) -+{ -+ if (!netif_carrier_ok(priv->uap_dev.netdev) && -+ (priv->MediaConnected == TRUE)) { -+ netif_carrier_on(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_carrier_off(uap_private * priv) -+{ -+ if (netif_carrier_ok(priv->uap_dev.netdev)) { -+ netif_carrier_off(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_start_queue(uap_private * priv) -+{ -+ if (netif_queue_stopped(priv->uap_dev.netdev) && -+ (priv->MediaConnected == TRUE)) { -+ netif_wake_queue(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_stop_queue(uap_private * priv) -+{ -+ if (!netif_queue_stopped(priv->uap_dev.netdev)) { -+ netif_stop_queue(priv->uap_dev.netdev); -+ } -+} -+ -+/** Interface specific header */ -+#define INTF_HEADER_LEN 4 -+ -+/** headroom alignment for tx packet */ -+#define HEADER_ALIGNMENT 8 -+ -+/** The number of times to try when polling for status bits */ -+#define MAX_POLL_TRIES 100 -+ -+/** Length of SNAP header */ -+#define MRVDRV_SNAP_HEADER_LEN 8 -+ -+/** Extra length of Tx packet buffer */ -+#define EXTRA_LEN 36 -+ -+/** Buffer size for ethernet Tx packets */ -+#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \ -+ (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN) -+ -+/** Buffer size for ethernet Rx packets */ -+#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \ -+ (ETH_FRAME_LEN + sizeof(RxPD) \ -+ + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN) -+ -+/** Packet type: data, command & event */ -+typedef enum _mv_type -+{ -+ MV_TYPE_DAT = 0, -+ MV_TYPE_CMD = 1, -+ MV_TYPE_EVENT = 3 -+} mv_type; -+ -+/** Disable interrupt */ -+#define OS_INT_DISABLE spin_lock_irqsave(&priv->driver_lock, priv->driver_flags) -+/** Enable interrupt */ -+#define OS_INT_RESTORE spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags) -+ -+int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb); -+void uap_interrupt(uap_private * priv); -+uap_private *uap_add_card(void *card); -+int uap_remove_card(void *card); -+int uap_process_event(uap_private * priv, u8 * payload, uint len); -+int uap_soft_reset(uap_private * priv); -+int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len); -+ -+#ifdef CONFIG_PROC_FS -+/** The proc fs interface */ -+void uap_proc_entry(uap_private * priv, struct net_device *dev); -+void uap_proc_remove(uap_private * priv); -+int string_to_number(char *s); -+void uap_debug_entry(uap_private * priv, struct net_device *dev); -+void uap_debug_remove(uap_private * priv); -+#endif /* CONFIG_PROC_FS */ -+ -+int sbi_register(void); -+ -+void sbi_unregister(void); -+int sbi_register_dev(uap_private * priv); -+int sbi_unregister_dev(uap_private * priv); -+int sbi_prog_fw_w_helper(uap_private *); -+ -+int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb); -+int sbi_enable_host_int(uap_private * priv); -+int sbi_disable_host_int(uap_private * priv); -+ -+int sbi_get_int_status(uap_private * priv, u8 * ireg); -+/** Check firmware status */ -+int sbi_check_fw_status(uap_private *, int); -+int sbi_prog_helper(uap_private *); -+ -+int sbi_wakeup_firmware(uap_private * priv); -+ -+#endif /* _UAP_DRV_H */ -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_fw.h linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_fw.h ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_fw.h 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_fw.h 2011-01-08 06:01:04.042835607 -0700 -@@ -0,0 +1,359 @@ -+/** @file uap_fw.h -+ * -+ * @brief This file contains firmware specific defines. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/******************************************************** -+Change log: -+ 02/26/08: Initial creation -+********************************************************/ -+ -+#ifndef _UAP_FW_H -+#define _UAP_FW_H -+ -+/** uap upload size */ -+#define UAP_UPLD_SIZE 2312 -+/** Packet type Micro AP */ -+#define PKT_TYPE_MICROAP 1 -+/** Packet type client */ -+#define PKT_TYPE_CLIENT 0 -+ -+/** TxPD descriptor */ -+typedef struct _TxPD -+{ -+ /** Bss Type */ -+ u8 BssType; -+ /** Bss num */ -+ u8 BssNum; -+ /** Tx packet length */ -+ u16 TxPktLength; -+ /** Tx packet offset */ -+ u16 TxPktOffset; -+ /** Tx packet type */ -+ u16 TxPktType; -+ /** Tx Control */ -+ u32 TxControl; -+ /** reserved */ -+ u32 reserved[2]; -+} __ATTRIB_PACK__ TxPD, *PTxPD; -+ -+/** RxPD Descriptor */ -+typedef struct _RxPD -+{ -+ /** Bss Type */ -+ u8 BssType; -+ /** Bss Num */ -+ u8 BssNum; -+ /** Tx packet length */ -+ u16 RxPktLength; -+ /** Tx packet offset */ -+ u16 RxPktOffset; -+} __ATTRIB_PACK__ RxPD, *PRxPD; -+ -+#ifdef BIG_ENDIAN -+/** Convert from 16 bit little endian format to CPU format */ -+#define uap_le16_to_cpu(x) le16_to_cpu(x) -+/** Convert from 32 bit little endian format to CPU format */ -+#define uap_le32_to_cpu(x) le32_to_cpu(x) -+/** Convert from 64 bit little endian format to CPU format */ -+#define uap_le64_to_cpu(x) le64_to_cpu(x) -+/** Convert to 16 bit little endian format from CPU format */ -+#define uap_cpu_to_le16(x) cpu_to_le16(x) -+/** Convert to 32 bit little endian format from CPU format */ -+#define uap_cpu_to_le32(x) cpu_to_le32(x) -+/** Convert to 64 bit little endian format from CPU format */ -+#define uap_cpu_to_le64(x) cpu_to_le64(x) -+ -+/** Convert TxPD to little endian format from CPU format */ -+#define endian_convert_TxPD(x); \ -+ { \ -+ (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength); \ -+ (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset); \ -+ (x)->TxControl = uap_cpu_to_le32((x)->TxControl); \ -+ (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType); \ -+ } -+ -+/** Convert RxPD from little endian format to CPU format */ -+#define endian_convert_RxPD(x); \ -+ { \ -+ (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength); \ -+ (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset); \ -+ } -+#else /* BIG_ENDIAN */ -+/** Do nothing */ -+#define uap_le16_to_cpu(x) x -+/** Do nothing */ -+#define uap_le32_to_cpu(x) x -+/** Do nothing */ -+#define uap_le64_to_cpu(x) x -+/** Do nothing */ -+#define uap_cpu_to_le16(x) x -+/** Do nothing */ -+#define uap_cpu_to_le32(x) x -+/** Do nothing */ -+#define uap_cpu_to_le64(x) x -+ -+/** Do nothing */ -+#define endian_convert_TxPD(x) -+/** Do nothing */ -+#define endian_convert_RxPD(x) -+#endif /* BIG_ENDIAN */ -+ -+/** Host Command ID : Function initialization */ -+#define HostCmd_CMD_FUNC_INIT 0x00a9 -+/** Host Command ID : Function shutdown */ -+#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa -+ -+/** Host Command id: SYS_INFO */ -+#define HOST_CMD_APCMD_SYS_INFO 0x00ae -+/** Host Command id: SYS_RESET */ -+#define HOST_CMD_APCMD_SYS_RESET 0x00af -+/** Host Command id: SYS_CONFIGURE */ -+#define HOST_CMD_APCMD_SYS_CONFIGURE 0x00b0 -+/** Host Command id: BSS_START */ -+#define HOST_CMD_APCMD_BSS_START 0x00b1 -+/** Host Command id: SYS_STOP */ -+#define HOST_CMD_APCMD_BSS_STOP 0x00b2 -+/** Host Command id: STA_LIST */ -+#define HOST_CMD_APCMD_STA_LIST 0x00b3 -+/** Host Command id: STA_FILTER_TABLE */ -+#define HOST_CMD_APCMD_STA_FILTER_TABLE 0x00b4 -+/** Host Command id: STA_DEAUTH */ -+#define HOST_CMD_APCMD_STA_DEAUTH 0x00b5 -+/** Host Command id: SOFT_RESET */ -+#define HOST_CMD_APCMD_SOFT_RESET 0x00d5 -+/** Host Command id: POWER_MGMT_EXT */ -+#define HOST_CMD_POWER_MGMT_EXT 0x00ef -+/** Host Command id: SLEEP_CONFIRM*/ -+#define HOST_CMD_SLEEP_CONFIRM 0x00d8 -+ -+/** TLV type : SSID */ -+#define TLV_TYPE_SSID 0x0000 -+/** TLV type : Rates */ -+#define TLV_TYPE_RATES 0x0001 -+/** TLV type : PHY DS */ -+#define TLV_TYPE_PHY_DS 0x0003 -+ -+/** TLV Id : Base id */ -+#define PROPRIETARY_TLV_BASE_ID 0x0100 -+/** TLV Id : AP_MAC_ADDRESS */ -+#define MRVL_AP_MAC_ADDRESS_TLV_ID (PROPRIETARY_TLV_BASE_ID + 43) -+/** TLV Id : Beacon period */ -+#define MRVL_BEACON_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 44) -+/** TLV Id : Dtim period */ -+#define MRVL_DTIM_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 45) -+/** TLV Id : Basic rates */ -+#define MRVL_BASIC_RATES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 46) -+/** TLV Id : Tx Power */ -+#define MRVL_TX_POWER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 47) -+/** TLV Id : Broadcast SSID control */ -+#define MRVL_BCAST_SSID_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 48) -+/** TLV Id : Preamble control */ -+#define MRVL_PREAMBLE_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 49) -+/** TLV Id : Antenna control */ -+#define MRVL_ANTENNA_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 50) -+/** TLV Id : RTS threshold */ -+#define MRVL_RTS_THRESHOLD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 51) -+/** TLV Id : Radio control */ -+#define MRVL_RADIO_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 52) -+/** TLV Id : TX data rate */ -+#define MRVL_TX_DATA_RATE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 53) -+/** TLV Id : Packet forward control */ -+#define MRVL_PKT_FWD_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 54) -+/** TLV Id : STA info */ -+#define MRVL_STA_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 55) -+/** TLV Id : STA MAC address filter */ -+#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56) -+/** TLV Id : STA ageout timer */ -+#define MRVL_STA_AGEOUT_TIMER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 57) -+/** TLV Id : Security config */ -+#define MRVL_SECURITY_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 58) -+/** TLV Id : WEP KEY */ -+#define MRVL_WEP_KEY_TLV_ID (PROPRIETARY_TLV_BASE_ID + 59) -+/** TLV Id : WPA Passphrase */ -+#define MRVL_WPA_PASSPHRASE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 60) -+ -+/** Action get */ -+#define ACTION_GET 0 -+/** Action set */ -+#define ACTION_SET 1 -+/** Length of ethernet address */ -+#ifndef ETH_ALEN -+#define ETH_ALEN 6 -+#endif -+ -+/** HostCmd_DS_GEN */ -+typedef struct -+{ -+ /** Command */ -+ u16 Command; -+ /** Size */ -+ u16 Size; -+ /** Sequence number */ -+ u16 SeqNum; -+ /** Result */ -+ u16 Result; -+} __ATTRIB_PACK__ HostCmd_DS_GEN; -+ -+/** Size of HostCmd_DS_GEN */ -+#define S_DS_GEN sizeof(HostCmd_DS_GEN) -+ -+/** _HostCmd_HEADER*/ -+typedef struct -+{ -+ /** Command Header : Command */ -+ u16 Command; -+ /** Command Header : Size */ -+ u16 Size; -+} __ATTRIB_PACK__ HostCmd_HEADER; -+ -+/** HostCmd_SYS_CONFIG */ -+typedef struct _HostCmd_SYS_CONFIG -+{ -+ /** CMD Action GET/SET*/ -+ u16 Action; -+ /** Tlv buffer */ -+ u8 TlvBuffer[0]; -+} __ATTRIB_PACK__ HostCmd_SYS_CONFIG; -+ -+/** HostCmd_DS_POWER_MGMT_EXT */ -+typedef struct _HostCmd_DS_POWER_MGMT_EXT -+{ -+ /** CMD Action Get/Set*/ -+ u16 action; -+ /** power mode */ -+ u16 power_mode; -+} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT; -+ -+/** _HostCmd_DS_COMMAND*/ -+typedef struct _HostCmd_DS_COMMAND -+{ -+ -+ /** Command Header : Command */ -+ u16 Command; -+ /** Command Header : Size */ -+ u16 Size; -+ /** Command Header : Sequence number */ -+ u16 SeqNum; -+ /** Command Header : Result */ -+ u16 Result; -+ /** Command Body */ -+ union -+ { -+ HostCmd_SYS_CONFIG sys_config; -+ HostCmd_DS_POWER_MGMT_EXT pm_cfg; -+ -+ } params; -+} __ATTRIB_PACK__ HostCmd_DS_COMMAND; -+ -+/** MrvlIEtypesHeader_*/ -+typedef struct _MrvlIEtypesHeader -+{ -+ /** Header type */ -+ u16 Type; -+ /** Header length */ -+ u16 Len; -+} __ATTRIB_PACK__ MrvlIEtypesHeader_t; -+ -+/** MrvlIEtypes_Data_t */ -+typedef struct _MrvlIEtypes_Data_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t Header; -+ /** Data */ -+ u8 Data[1]; -+} __ATTRIB_PACK__ MrvlIEtypes_Data_t; -+ -+/** MrvlIEtypes_ChanListParamSet_t */ -+typedef struct _MrvlIEtypes_MacAddr_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t Header; -+ /** AP MAC address */ -+ u8 ApMacAddr[ETH_ALEN]; -+} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t; -+ -+/** Event ID: BSS started */ -+#define MICRO_AP_EV_ID_BSS_START 46 -+ -+/** Event ID: BSS idle event */ -+#define MICRO_AP_EV_BSS_IDLE 67 -+ -+/** Event ID: BSS active event */ -+#define MICRO_AP_EV_BSS_ACTIVE 68 -+ -+/** Event ID: PS_AWAKE */ -+#define EVENT_PS_AWAKE 0x0a -+ -+/** Event ID: PS_SLEEP */ -+#define EVENT_PS_SLEEP 0x0b -+ -+/** PS_STATE */ -+typedef enum _PS_STATE -+{ -+ PS_STATE_AWAKE, -+ PS_STATE_PRE_SLEEP, -+ PS_STATE_SLEEP -+} PS_STATE; -+ -+/** TLV type: AP Sleep param */ -+#define TLV_TYPE_AP_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 106) -+/** TLV type: AP Inactivity Sleep param */ -+#define TLV_TYPE_AP_INACT_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 107) -+ -+/** MrvlIEtypes_sleep_param_t */ -+typedef struct _MrvlIEtypes_sleep_param_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t header; -+ /** control bitmap */ -+ u32 ctrl_bitmap; -+ /** min_sleep */ -+ u32 min_sleep; -+ /** max_sleep */ -+ u32 max_sleep; -+} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t; -+ -+/** MrvlIEtypes_inact_sleep_param_t */ -+typedef struct _MrvlIEtypes_inact_sleep_param_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t header; -+ /** inactivity timeout */ -+ u32 inactivity_to; -+ /** min_awake */ -+ u32 min_awake; -+ /** max_awake */ -+ u32 max_awake; -+} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t; -+ -+/** AP_Event */ -+typedef struct _AP_Event -+{ -+ /** Event ID */ -+ u32 EventId; -+ /* -+ * Reserved for STA_ASSOCIATED event and contains -+ * status information for the MIC_COUNTERMEASURES event. -+ */ -+ /** Reserved/status */ -+ u16 status; -+ /** AP MAC address */ -+ u8 MacAddr[ETH_ALEN]; -+} __ATTRIB_PACK__ AP_Event; -+#endif /* _UAP_FW_H */ -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_headers.h linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_headers.h ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_headers.h 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_headers.h 2011-01-08 06:01:04.043835537 -0700 -@@ -0,0 +1,64 @@ -+/** @file uap_headers.h -+ * -+ * @brief This file contains all the necessary include file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifndef _UAP_HEADERS_H -+#define _UAP_HEADERS_H -+ -+/* Linux header files */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -+#include -+#else -+#include -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) -+#include -+#endif -+ -+/* Net header files */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "uap_drv.h" -+#include "uap_fw.h" -+ -+#include -+#include -+#include -+#include -+#include "uap_sdio_mmc.h" -+ -+#endif /* _UAP_HEADERS_H */ -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_main.c linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_main.c ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_main.c 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_main.c 2011-01-08 06:01:04.048835193 -0700 -@@ -0,0 +1,1830 @@ -+/** @file uap_main.c -+ * @brief This file contains the major functions in uAP -+ * driver. It includes init, exit etc.. -+ * This file also contains the initialization for SW, -+ * FW and HW -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/** -+ * @mainpage uAP Linux Driver -+ * -+ * @section overview_sec Overview -+ * -+ * This is Linux reference driver for Marvell uAP. -+ * -+ * @section copyright_sec Copyright -+ * -+ * Copyright (C) 2008, Marvell International Ltd. -+ * -+ */ -+ -+#include "uap_headers.h" -+ -+/** -+ * the global variable of a pointer to uap_private -+ * structure variable -+ */ -+uap_private *uappriv = NULL; -+#ifdef DEBUG_LEVEL1 -+#define DEFAULT_DEBUG_MASK (DBG_MSG | DBG_FATAL | DBG_ERROR) -+u32 drvdbg = DEFAULT_DEBUG_MASK; -+#endif -+/** Helper name */ -+char *helper_name = NULL; -+/** Firmware name */ -+char *fw_name = NULL; -+ -+/** Semaphore for add/remove card */ -+SEMAPHORE AddRemoveCardSem; -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief This function send sleep confirm command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+static int -+uap_dnld_sleep_confirm_cmd(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ PRINTM(CMND, "Sleep confirm\n"); -+ Adapter->cmd_pending = TRUE; -+ Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM; -+ ret = -+ sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep, -+ sizeof(PS_CMD_ConfirmSleep)); -+ if (ret != UAP_STATUS_SUCCESS) { -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->cmd_pending = FALSE; -+ Adapter->cmd_wait_option = FALSE; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function process sleep confirm resp from firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @param resp A pointer to resp buf -+ * @param resp_len resp buf len -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+int -+uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ HostCmd_DS_COMMAND *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ ENTER(); -+ PRINTM(CMND, "Sleep confirm resp\n"); -+ if (!resp_len) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) resp; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ } -+ done: -+ if (ret == UAP_STATUS_SUCCESS) -+ Adapter->ps_state = PS_STATE_SLEEP; -+ else -+ Adapter->ps_state = PS_STATE_AWAKE; -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks condition and prepares to -+ * send sleep confirm command to firmware if OK. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+static void -+uap_ps_cond_check(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ if (!priv->uap_dev.cmd_sent && -+ !Adapter->cmd_pending && !Adapter->IntCounter) { -+ uap_dnld_sleep_confirm_cmd(priv); -+ } else { -+ PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n", -+ (priv->uap_dev.cmd_sent) ? "D" : "", -+ (Adapter->cmd_pending) ? "C" : "", -+ (Adapter->IntCounter) ? "I" : ""); -+ } -+ LEAVE(); -+} -+ -+/** -+ * @brief This function add cmd to cmdQ and waiting for response -+ * -+ * @param priv A pointer to uap_private structure -+ * @param skb A pointer to the skb for process -+ * @param wait_option Wait option -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+static int -+uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ HostCmd_DS_COMMAND *cmd; -+ u8 *headptr; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "Hw not ready, uap_process_cmd\n"); -+ kfree(skb); -+ LEAVE(); -+ return -EFAULT; -+ } -+ skb->cb[0] = wait_option; -+ headptr = skb->data; -+ *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len); -+ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ Adapter->SeqNum++; -+ cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum); -+ PRINTM(CMND, "process_cmd: %x\n", cmd->Command); -+ DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size); -+ if (!wait_option) { -+ skb_queue_tail(&priv->adapter->cmd_queue, skb); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ LEAVE(); -+ return ret; -+ } -+ if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) { -+ PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n"); -+ kfree(skb); -+ LEAVE(); -+ return -EBUSY; -+ } -+ skb_queue_tail(&priv->adapter->cmd_queue, skb); -+ Adapter->CmdWaitQWoken = FALSE; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ /* Sleep until response is generated by FW */ -+ if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) { -+ if (!os_wait_interruptible_timeout -+ (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) { -+ PRINTM(ERROR, "Cmd timeout\n"); -+ Adapter->cmd_pending = FALSE; -+ ret = -EFAULT; -+ } -+ } else -+ wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken); -+ OS_REL_SEMAPHORE(&Adapter->CmdSem); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief Inspect the response buffer for pointers to expected TLVs -+ * -+ * -+ * @param pTlv Pointer to the start of the TLV buffer to parse -+ * @param tlvBufSize Size of the TLV buffer -+ * @param reqTlvType request tlv's tlvtype -+ * @param ppTlv Output parameter: Pointer to the request TLV if found -+ * -+ * @return void -+ */ -+static void -+uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize, -+ u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv) -+{ -+ MrvlIEtypes_Data_t *pCurrentTlv; -+ int tlvBufLeft; -+ u16 tlvType; -+ u16 tlvLen; -+ -+ ENTER(); -+ pCurrentTlv = pTlv; -+ tlvBufLeft = tlvBufSize; -+ *ppTlv = NULL; -+ PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize, -+ reqTlvType); -+ while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) { -+ tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type); -+ tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len); -+ if (reqTlvType == tlvType) -+ *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv; -+ if (*ppTlv) { -+ HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen); -+ break; -+ } -+ tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen); -+ pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen); -+ } /* while */ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function get mac -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_get_mac_address(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_COMMAND *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ MrvlIEtypes_MacAddr_t *pMacAddrTlv; -+ MrvlIEtypes_Data_t *pTlv; -+ u16 tlvBufSize; -+ ENTER(); -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = -+ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET); -+ pMacAddrTlv = -+ (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); -+ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ goto done; -+ } -+ pTlv = -+ (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG); -+ uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID, -+ (MrvlIEtypes_Data_t **) & pMacAddrTlv); -+ if (pMacAddrTlv) { -+ memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr, -+ ETH_ALEN); -+ HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN); -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks the conditions and sends packet to device -+ * -+ * @param priv A pointer to uap_private structure -+ * @param skb A pointer to the skb for process -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_process_tx(uap_private * priv, struct sk_buff *skb) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ TxPD *pLocalTxPD; -+ u8 *headptr; -+ struct sk_buff *newskb; -+ int newheadlen; -+ ENTER(); -+ ASSERT(skb); -+ if (!skb) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) { -+ newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT; -+ PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb)); -+ /* Insufficient skb headroom - allocate a new skb */ -+ newskb = skb_realloc_headroom(skb, newheadlen); -+ if (unlikely(newskb == NULL)) { -+ PRINTM(ERROR, "Tx: Cannot allocate skb\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ kfree_skb(skb); -+ skb = newskb; -+ PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb)); -+ } -+ /* headptr should be aligned */ -+ headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN; -+ headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1))); -+ -+ pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN); -+ memset(pLocalTxPD, 0, sizeof(TxPD)); -+ pLocalTxPD->BssType = PKT_TYPE_MICROAP; -+ pLocalTxPD->TxPktLength = skb->len; -+ /* offset of actual data */ -+ pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD; -+ endian_convert_TxPD(pLocalTxPD); -+ *(u16 *) & headptr[0] = -+ uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr)); -+ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT); -+ ret = -+ sbi_host_to_card(priv, headptr, -+ skb->len + ((long) skb->data - (long) headptr)); -+ if (ret) { -+ PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n", -+ ret); -+ Adapter->dbg.num_tx_host_to_card_failure++; -+ goto done; -+ } -+ PRINTM(DATA, "Data => FW\n"); -+ DBG_HEXDUMP(DAT_D, "Tx", headptr, -+ MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN)); -+ done: -+ /* Freed skb */ -+ kfree_skb(skb); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function initializes the adapter structure -+ * and set default value to the member of adapter. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_init_sw(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ -+ if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) { -+ PRINTM(INFO, "Failed to allocate command buffer!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ Adapter->cmd_pending = FALSE; -+ Adapter->CmdWaitQWoken = FALSE; -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->WakeupTries = 0; -+ -+ memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep)); -+ /** SDIO header */ -+ Adapter->PSConfirmSleep.SDLen = -+ uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep)); -+ Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD); -+ Adapter->PSConfirmSleep.SeqNum = 0; -+ Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM); -+ Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN)); -+ Adapter->PSConfirmSleep.Result = 0; -+ -+ init_waitqueue_head(&Adapter->cmdwait_q); -+ OS_INIT_SEMAPHORE(&Adapter->CmdSem); -+ -+ skb_queue_head_init(&Adapter->tx_queue); -+ skb_queue_head_init(&Adapter->cmd_queue); -+ -+ /* Status variable */ -+ Adapter->HardwareStatus = HWInitializing; -+ -+ /* PnP support */ -+ Adapter->SurpriseRemoved = FALSE; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) -+ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, -+ THIS_MODULE); -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, NULL, -+ THIS_MODULE); -+#else -+ Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, NULL, -+ THIS_MODULE); -+#endif -+#endif -+ if (!Adapter->nl_sk) { -+ PRINTM(ERROR, -+ "Could not initialize netlink event passing mechanism!\n"); -+ } -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function sends FUNC_INIT command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_func_init(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function sends FUNC_SHUTDOWN command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int __exit -+uap_func_shutdown(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function initializes firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_init_fw(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ sbi_disable_host_int(priv); -+ /* Check if firmware is already running */ -+ if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) { -+ PRINTM(MSG, "UAP FW already running! Skip FW download\n"); -+ } else { -+ if ((ret = request_firmware(&priv->fw_helper, helper_name, -+ priv->hotplug_device)) < 0) { -+ PRINTM(FATAL, -+ "request_firmware() failed (helper), error code = %#x\n", -+ ret); -+ goto done; -+ } -+ -+ /* Download the helper */ -+ ret = sbi_prog_helper(priv); -+ -+ if (ret) { -+ PRINTM(FATAL, -+ "Bootloader in invalid state! Helper download failed!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ if ((ret = request_firmware(&priv->firmware, fw_name, -+ priv->hotplug_device)) < 0) { -+ PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret); -+ goto done; -+ } -+ -+ /* Download the main firmware via the helper firmware */ -+ if (sbi_prog_fw_w_helper(priv)) { -+ PRINTM(FATAL, "UAP FW download failed!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ /* Check if the firmware is downloaded successfully or not */ -+ if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) == -+ UAP_STATUS_FAILURE) { -+ PRINTM(FATAL, "FW failed to be active in time!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(MSG, "UAP FW is active\n"); -+ } -+ sbi_enable_host_int(priv); -+ priv->adapter->HardwareStatus = HWReady; -+ if (uap_func_init(priv) != UAP_STATUS_SUCCESS) { -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ done: -+ if (priv->fw_helper) -+ release_firmware(priv->fw_helper); -+ if (priv->firmware) -+ release_firmware(priv->firmware); -+ LEAVE(); -+ return ret; -+ -+} -+ -+/** -+ * @brief This function frees the structure of adapter -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+static void -+uap_free_adapter(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ -+ if (Adapter) { -+ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { -+ sock_release((Adapter->nl_sk)->sk_socket); -+ Adapter->nl_sk = NULL; -+ } -+ if (Adapter->CmdBuf) -+ kfree(Adapter->CmdBuf); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ /* Free the adapter object itself */ -+ kfree(Adapter); -+ priv->adapter = NULL; -+ } -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function handles the major job in uap driver. -+ * it handles the event generated by firmware, rx data received -+ * from firmware and tx data sent from kernel. -+ * -+ * @param data A pointer to uap_thread structure -+ * @return BT_STATUS_SUCCESS -+ */ -+static int -+uap_service_main_thread(void *data) -+{ -+ uap_thread *thread = data; -+ uap_private *priv = thread->priv; -+ uap_adapter *Adapter = priv->adapter; -+ wait_queue_t wait; -+ u8 ireg = 0; -+ struct sk_buff *skb; -+ ENTER(); -+ uap_activate_thread(thread); -+ init_waitqueue_entry(&wait, current); -+ current->flags |= PF_NOFREEZE; -+ -+ for (;;) { -+ add_wait_queue(&thread->waitQ, &wait); -+ OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE); -+ if ((Adapter->WakeupTries) || -+ (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) || -+ (!priv->adapter->IntCounter -+ && (priv->uap_dev.data_sent || -+ skb_queue_empty(&priv->adapter->tx_queue)) -+ && (priv->uap_dev.cmd_sent || Adapter->cmd_pending || -+ skb_queue_empty(&priv->adapter->cmd_queue)) -+ )) { -+ PRINTM(INFO, "Main: Thread sleeping...\n"); -+ schedule(); -+ } -+ OS_SET_THREAD_STATE(TASK_RUNNING); -+ remove_wait_queue(&thread->waitQ, &wait); -+ if (kthread_should_stop() || Adapter->SurpriseRemoved) { -+ PRINTM(INFO, "main-thread: break from main thread: " -+ "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved); -+ /* Cancel pending command */ -+ if (Adapter->cmd_pending == TRUE) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } -+ break; -+ } -+ -+ PRINTM(INFO, "Main: Thread waking up...\n"); -+ if (priv->adapter->IntCounter) { -+ OS_INT_DISABLE; -+ Adapter->IntCounter = 0; -+ OS_INT_RESTORE; -+ sbi_get_int_status(priv, &ireg); -+ } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) && -+ (!skb_queue_empty(&priv->adapter->cmd_queue) || -+ !skb_queue_empty(&priv->adapter->tx_queue))) { -+ priv->adapter->WakeupTries++; -+ PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get()); -+ sbi_wakeup_firmware(priv); -+ continue; -+ } -+ if (Adapter->ps_state == PS_STATE_PRE_SLEEP) -+ uap_ps_cond_check(priv); -+ -+ /* The PS state is changed during processing of Sleep Request event -+ above */ -+ if ((Adapter->ps_state == PS_STATE_SLEEP) || -+ (Adapter->ps_state == PS_STATE_PRE_SLEEP)) -+ continue; -+ /* Execute the next command */ -+ if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending && -+ (Adapter->HardwareStatus == HWReady)) { -+ if (!skb_queue_empty(&priv->adapter->cmd_queue)) { -+ skb = skb_dequeue(&priv->adapter->cmd_queue); -+ if (skb) { -+ Adapter->CmdSize = 0; -+ Adapter->cmd_pending = TRUE; -+ Adapter->cmd_wait_option = skb->cb[0]; -+ if (sbi_host_to_card(priv, skb->data, skb->len)) { -+ PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n"); -+ Adapter->cmd_pending = FALSE; -+ Adapter->dbg.num_cmd_host_to_card_failure++; -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } else { -+ if (Adapter->cmd_wait_option == -+ HostCmd_OPTION_WAITFORSEND) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ Adapter->cmd_wait_option = FALSE; -+ } -+ } -+ kfree_skb(skb); -+ } -+ } -+ } -+ if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) { -+ if (!skb_queue_empty(&priv->adapter->tx_queue)) { -+ skb = skb_dequeue(&priv->adapter->tx_queue); -+ if (skb) { -+ if (uap_process_tx(priv, skb)) { -+ priv->stats.tx_dropped++; -+ priv->stats.tx_errors++; -+ os_start_queue(priv); -+ } else { -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+ } -+ -+ } -+ } -+ } -+ } -+ uap_deactivate_thread(thread); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief uap hostcmd ioctl handler -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @return UAP_STATUS_SUCCESS --success, otherwise fail -+ */ -+/********* format of ifr_data *************/ -+/* buf_len + Hostcmd_body */ -+/* buf_len: 4 bytes */ -+/* the length of the buf which */ -+/* can be used to return data */ -+/* to application */ -+/* Hostcmd_body */ -+/*******************************************/ -+static int -+uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req) -+{ -+ u32 buf_len; -+ HostCmd_HEADER head; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ struct sk_buff *skb; -+ -+ ENTER(); -+ -+ /* Sanity check */ -+ if (req->ifr_data == NULL) { -+ PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ memset(&head, 0, sizeof(HostCmd_HEADER)); -+ /* Get the command size from user space */ -+ if (copy_from_user -+ (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ head.Size = uap_le16_to_cpu(head.Size); -+ if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) { -+ PRINTM(ERROR, "CmdSize too big=%d\n", head.Size); -+ LEAVE(); -+ return -EFAULT; -+ } -+ PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command, -+ head.Size, buf_len); -+ skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ LEAVE(); -+ return -ENOMEM; -+ } -+ -+ /* Get the command from user space */ -+ if (copy_from_user -+ (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len), -+ head.Size)) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ skb_put(skb, head.Size + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { -+ PRINTM(ERROR, "Fail to process cmd\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (Adapter->CmdSize > buf_len) { -+ PRINTM(ERROR, "buf_len is too small\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ /* Copy to user */ -+ if (copy_to_user -+ (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) { -+ PRINTM(ERROR, "Copy to user failed!\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief uap power mode ioctl handler -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @return UAP_STATUS_SUCCESS --success, otherwise fail -+ */ -+static int -+uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req) -+{ -+ ps_mgmt pm_cfg; -+ int ret = UAP_STATUS_SUCCESS; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb = NULL; -+ HostCmd_DS_COMMAND *cmd; -+ u32 CmdSize; -+ u8 *tlv = NULL; -+ MrvlIEtypes_sleep_param_t *sleep_tlv = NULL; -+ MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL; -+ u16 tlv_buf_left = 0; -+ MrvlIEtypesHeader_t *tlvbuf = NULL; -+ u16 tlv_type = 0; -+ u16 tlv_len = 0; -+ -+ ENTER(); -+ -+ /* Sanity check */ -+ if (req->ifr_data == NULL) { -+ PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ -+ memset(&pm_cfg, 0, sizeof(ps_mgmt)); -+ if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ PRINTM(CMND, -+ "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d " -+ "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags, -+ (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap, -+ (int) pm_cfg.sleep_param.min_sleep, -+ (int) pm_cfg.sleep_param.max_sleep, -+ (int) pm_cfg.inact_param.inactivity_to, -+ (int) pm_cfg.inact_param.min_awake, -+ (int) pm_cfg.inact_param.max_awake); -+ -+ if (pm_cfg. -+ flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM | -+ PS_FLAG_INACT_SLEEP_PARAM)) { -+ PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags); -+ ret = -EINVAL; -+ goto done; -+ } -+ if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) { -+ PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags); -+ ret = -EINVAL; -+ goto done; -+ } -+ -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(INFO, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ -+ CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT); -+ -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT); -+ if (!pm_cfg.flags) { -+ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET); -+ } else { -+ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET); -+ cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode); -+ tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT); -+ -+ if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) { -+ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv; -+ sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM); -+ sleep_tlv->header.Len = -+ uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) - -+ sizeof(MrvlIEtypesHeader_t)); -+ sleep_tlv->ctrl_bitmap = -+ uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap); -+ sleep_tlv->min_sleep = -+ uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep); -+ sleep_tlv->max_sleep = -+ uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep); -+ CmdSize += sizeof(MrvlIEtypes_sleep_param_t); -+ tlv += sizeof(MrvlIEtypes_sleep_param_t); -+ } -+ if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) && -+ (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) { -+ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv; -+ inact_tlv->header.Type = -+ uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM); -+ inact_tlv->header.Len = -+ uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) - -+ sizeof(MrvlIEtypesHeader_t)); -+ inact_tlv->inactivity_to = -+ uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to); -+ inact_tlv->min_awake = -+ uap_cpu_to_le32(pm_cfg.inact_param.min_awake); -+ inact_tlv->max_awake = -+ uap_cpu_to_le32(pm_cfg.inact_param.max_awake); -+ CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t); -+ tlv += sizeof(MrvlIEtypes_inact_sleep_param_t); -+ } -+ } -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { -+ PRINTM(ERROR, "Fail to process cmd POWER_MODE\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (pm_cfg.flags) { -+ Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); -+ } else { -+ pm_cfg.flags = PS_FLAG_PS_MODE; -+ pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); -+ tlv_buf_left = -+ cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN); -+ tlvbuf = -+ (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg + -+ sizeof(HostCmd_DS_POWER_MGMT_EXT)); -+ while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) { -+ tlv_type = uap_le16_to_cpu(tlvbuf->Type); -+ tlv_len = uap_le16_to_cpu(tlvbuf->Len); -+ switch (tlv_type) { -+ case TLV_TYPE_AP_SLEEP_PARAM: -+ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf; -+ pm_cfg.flags |= PS_FLAG_SLEEP_PARAM; -+ pm_cfg.sleep_param.ctrl_bitmap = -+ uap_le32_to_cpu(sleep_tlv->ctrl_bitmap); -+ pm_cfg.sleep_param.min_sleep = -+ uap_le32_to_cpu(sleep_tlv->min_sleep); -+ pm_cfg.sleep_param.max_sleep = -+ uap_le32_to_cpu(sleep_tlv->max_sleep); -+ break; -+ case TLV_TYPE_AP_INACT_SLEEP_PARAM: -+ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf; -+ pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM; -+ pm_cfg.inact_param.inactivity_to = -+ uap_le32_to_cpu(inact_tlv->inactivity_to); -+ pm_cfg.inact_param.min_awake = -+ uap_le32_to_cpu(inact_tlv->min_awake); -+ pm_cfg.inact_param.max_awake = -+ uap_le32_to_cpu(inact_tlv->max_awake); -+ break; -+ } -+ tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t); -+ tlvbuf = -+ (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len + -+ sizeof(MrvlIEtypesHeader_t)); -+ } -+ /* Copy to user */ -+ if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) { -+ PRINTM(ERROR, "Copy to user failed!\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function send bss_stop command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_bss_stop(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "APCMD_BSS_STOP\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd BSS_STOP\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief This function send soft_reset command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+int -+uap_soft_reset(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ ret = uap_bss_stop(priv); -+ if (ret != UAP_STATUS_SUCCESS) -+ goto done; -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "APCMD_SOFT_RESET\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) { -+ PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ Adapter->SurpriseRemoved = TRUE; -+ /* delay to allow hardware complete reset */ -+ os_sched_timeout(5); -+ if (priv->MediaConnected == TRUE) { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ } -+ Adapter->CmdSize = 0; -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function processes received packet and forwards it -+ * to kernel/upper layer -+ * -+ * @param priv A pointer to uap_private -+ * @param skb A pointer to skb which includes the received packet -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_process_rx_packet(uap_private * priv, struct sk_buff *skb) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ RxPD *pRxPD; -+ ENTER(); -+ priv->adapter->ps_state = PS_STATE_AWAKE; -+ pRxPD = (RxPD *) skb->data; -+ endian_convert_RxPD(pRxPD); -+ DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); -+ skb_pull(skb, pRxPD->RxPktOffset); -+ priv->stats.rx_packets++; -+ priv->stats.rx_bytes += skb->len; -+ os_upload_rx_packet(priv, skb); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function opens the network device -+ * -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+uap_open(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ int i = 0; -+ -+ ENTER(); -+ -+ /* On some systems the device open handler will be called before HW ready. */ -+ /* Use the following flag check and wait function to work around the issue. */ -+ while ((Adapter->HardwareStatus != HWReady) && -+ (i < MAX_WAIT_DEVICE_READY_COUNT)) { -+ i++; -+ os_sched_timeout(100); -+ } -+ if (i >= MAX_WAIT_DEVICE_READY_COUNT) { -+ PRINTM(FATAL, "HW not ready, uap_open() return failure\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ priv->open = TRUE; -+ if (priv->MediaConnected == TRUE) { -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ } else { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ } -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function closes the network device -+ * -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+uap_close(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ ENTER(); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ -+ MODULE_PUT; -+ priv->open = FALSE; -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function returns the network statistics -+ * -+ * @param dev A pointer to uap_private structure -+ * @return A pointer to net_device_stats structure -+ */ -+static struct net_device_stats * -+uap_get_stats(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ return &priv->stats; -+} -+ -+/** -+ * @brief This function sets the MAC address to firmware. -+ * -+ * @param dev A pointer to uap_private structure -+ * @param addr MAC address to set -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_set_mac_address(struct net_device *dev, void *addr) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ struct sockaddr *pHwAddr = (struct sockaddr *) addr; -+ u32 CmdSize; -+ HostCmd_DS_COMMAND *cmd; -+ MrvlIEtypes_MacAddr_t *pMacAddrTlv; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ -+ ENTER(); -+ -+ /* Dump MAC address */ -+ DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN); -+ DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN); -+ if (priv->open && (priv->MediaConnected == TRUE)) { -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ LEAVE(); -+ return -ENOMEM; -+ } -+ CmdSize = -+ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET); -+ pMacAddrTlv = -+ (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); -+ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); -+ memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "set_mac_address\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to set mac address\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_cpu_to_le16(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result); -+ ret = -EFAULT; -+ } else -+ memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function sets multicast addresses to firmware -+ * -+ * @param dev A pointer to net_device structure -+ * @return n/a -+ */ -+static void -+uap_set_multicast_list(struct net_device *dev) -+{ -+ ENTER(); -+#warning uap_set_multicast_list not implemented. Expect problems with IPv6. -+ LEAVE(); -+} -+ -+/** -+ * @brief This function handles the timeout of packet -+ * transmission -+ * -+ * @param dev A pointer to net_device structure -+ * @return n/a -+ */ -+static void -+uap_tx_timeout(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ ENTER(); -+ -+ PRINTM(DATA, "Tx timeout\n"); -+ UpdateTransStart(dev); -+ priv->num_tx_timeout++; -+ priv->adapter->IntCounter++; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function handles packet transmission -+ * -+ * @param skb A pointer to sk_buff structure -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ PRINTM(DATA, "Data <= kernel\n"); -+ DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); -+ /* skb sanity check */ -+ if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) { -+ PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len, -+ MRVDRV_MAXIMUM_ETH_PACKET_SIZE); -+ priv->stats.tx_dropped++; -+ kfree(skb); -+ goto done; -+ } -+ skb_queue_tail(&priv->adapter->tx_queue, skb); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) { -+ UpdateTransStart(dev); -+ os_stop_queue(priv); -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief ioctl function - entry point -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @param cmd command -+ * @return UAP_STATUS_SUCCESS--success, otherwise fail -+ */ -+static int -+uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd); -+ -+ switch (cmd) { -+ case UAPHOSTCMD: -+ ret = uap_hostcmd_ioctl(dev, req); -+ break; -+ case UAP_POWER_MODE: -+ ret = uap_power_mode_ioctl(dev, req); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function handles events generated by firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @param payload A pointer to payload buffer -+ * @param len Length of the payload -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_process_event(uap_private * priv, u8 * payload, uint len) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb = NULL; -+ struct nlmsghdr *nlh = NULL; -+ struct sock *sk = Adapter->nl_sk; -+ AP_Event *pEvent; -+ -+ ENTER(); -+ Adapter->ps_state = PS_STATE_AWAKE; -+ if (len > NL_MAX_PAYLOAD) { -+ PRINTM(ERROR, "event size is too big!!! len=%d\n", len); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ pEvent = (AP_Event *) payload; -+ PRINTM(CMND, "Event: %d\n", pEvent->EventId); -+ switch (pEvent->EventId) { -+ case MICRO_AP_EV_ID_BSS_START: -+ memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN); -+ DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr, -+ ETH_ALEN); -+ break; -+ case MICRO_AP_EV_BSS_ACTIVE: -+ // carrier on -+ priv->MediaConnected = TRUE; -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ break; -+ case MICRO_AP_EV_BSS_IDLE: -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ break; -+ case EVENT_PS_AWAKE: -+ PRINTM(CMND, "UAP: PS_AWAKE\n"); -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->WakeupTries = 0; -+ break; -+ case EVENT_PS_SLEEP: -+ PRINTM(CMND, "UAP: PS_SLEEP\n"); -+ Adapter->ps_state = PS_STATE_PRE_SLEEP; -+ break; -+ default: -+ break; -+ } -+ if ((pEvent->EventId == EVENT_PS_AWAKE) || -+ (pEvent->EventId == EVENT_PS_SLEEP)) -+ goto done; -+ if (sk) { -+ /* Allocate skb */ -+ if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) { -+ PRINTM(ERROR, "Could not allocate skb for netlink.\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ nlh = (struct nlmsghdr *) skb->data; -+ nlh->nlmsg_len = NLMSG_SPACE(len); -+ -+ /* From kernel */ -+ nlh->nlmsg_pid = 0; -+ nlh->nlmsg_flags = 0; -+ -+ /* Data */ -+ skb_put(skb, nlh->nlmsg_len); -+ memcpy(NLMSG_DATA(nlh), payload, len); -+ -+ /* From Kernel */ -+ NETLINK_CB(skb).pid = 0; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ /* Multicast message */ -+ NETLINK_CB(skb).dst_pid = 0; -+#endif -+ -+ /* Multicast group number */ -+ NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP; -+ -+ /* Send message */ -+ netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL); -+ -+ ret = UAP_STATUS_SUCCESS; -+ } else { -+ PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function handles the interrupt. it will change PS -+ * state if applicable. it will wake up main_thread to handle -+ * the interrupt event as well. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+void -+uap_interrupt(uap_private * priv) -+{ -+ ENTER(); -+ priv->adapter->IntCounter++; -+ priv->adapter->WakeupTries = 0; -+ PRINTM(INFO, "*\n"); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ -+ LEAVE(); -+ -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) -+/** Network device handlers */ -+static const struct net_device_ops uap_netdev_ops = { -+ .ndo_open = uap_open, -+ .ndo_start_xmit = uap_hard_start_xmit, -+ .ndo_stop = uap_close, -+ .ndo_do_ioctl = uap_do_ioctl, -+ .ndo_set_mac_address = uap_set_mac_address, -+ .ndo_tx_timeout = uap_tx_timeout, -+ .ndo_get_stats = uap_get_stats, -+ .ndo_set_multicast_list = uap_set_multicast_list, -+}; -+#endif -+ -+/** -+ * @brief This function adds the card. it will probe the -+ * card, allocate the uap_priv and initialize the device. -+ * -+ * @param card A pointer to card -+ * @return A pointer to uap_private structure -+ */ -+uap_private * -+uap_add_card(void *card) -+{ -+ struct net_device *dev = NULL; -+ uap_private *priv = NULL; -+ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ /* Allocate an Ethernet device */ -+ if (!(dev = alloc_etherdev(sizeof(uap_private)))) { -+ PRINTM(FATAL, "Init ethernet device failed!\n"); -+ goto error; -+ } -+ priv = (uap_private *) netdev_priv(dev); -+ -+ /* Allocate name */ -+ if (dev_alloc_name(dev, "uap%d") < 0) { -+ PRINTM(ERROR, "Could not allocate device name!\n"); -+ goto error; -+ } -+ -+ /* Allocate buffer for uap_adapter */ -+ if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) { -+ PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n"); -+ goto error; -+ } -+ memset(priv->adapter, 0, sizeof(uap_adapter)); -+ -+ priv->uap_dev.netdev = dev; -+ priv->uap_dev.card = card; -+ priv->MediaConnected = FALSE; -+ uappriv = priv; -+ ((struct sdio_mmc_card *) card)->priv = priv; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ SET_MODULE_OWNER(dev); -+#endif -+ -+ /* Setup the OS Interface to our functions */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) -+ dev->open = uap_open; -+ dev->stop = uap_close; -+ dev->hard_start_xmit = uap_hard_start_xmit; -+ dev->tx_timeout = uap_tx_timeout; -+ dev->get_stats = uap_get_stats; -+ dev->do_ioctl = uap_do_ioctl; -+ dev->set_mac_address = uap_set_mac_address; -+ dev->set_multicast_list = uap_set_multicast_list; -+#else -+ dev->netdev_ops = &uap_netdev_ops; -+#endif -+ dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; -+ dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN; -+ dev->hard_header_len += HEADER_ALIGNMENT; -+#define NETIF_F_DYNALLOC 16 -+ dev->features |= NETIF_F_DYNALLOC; -+ dev->flags |= IFF_BROADCAST | IFF_MULTICAST; -+ -+ /* Init SW */ -+ if (uap_init_sw(priv)) { -+ PRINTM(FATAL, "Software Init Failed\n"); -+ goto error; -+ } -+ -+ PRINTM(INFO, "Starting kthread...\n"); -+ priv->MainThread.priv = priv; -+ spin_lock_init(&priv->driver_lock); -+ uap_create_thread(uap_service_main_thread, &priv->MainThread, -+ "uap_main_service"); -+ while (priv->MainThread.pid == 0) { -+ os_sched_timeout(2); -+ } -+ -+ /* Register the device */ -+ if (sbi_register_dev(priv) < 0) { -+ PRINTM(FATAL, "Failed to register uap device!\n"); -+ goto err_registerdev; -+ } -+#ifdef FW_DNLD_NEEDED -+ SET_NETDEV_DEV(dev, priv->hotplug_device); -+#endif -+ -+ /* Init FW and HW */ -+ if (uap_init_fw(priv)) { -+ PRINTM(FATAL, "Firmware Init Failed\n"); -+ goto err_init_fw; -+ } -+ -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ -+ /* Get mac address from firmware */ -+ if (uap_get_mac_address(priv)) { -+ PRINTM(FATAL, "Fail to get mac address\n"); -+ goto err_init_fw; -+ } -+ /* Register network device */ -+ if (register_netdev(dev)) { -+ printk(KERN_ERR "Cannot register network device!\n"); -+ goto err_init_fw; -+ } -+#ifdef CONFIG_PROC_FS -+ uap_proc_entry(priv, dev); -+ uap_debug_entry(priv, dev); -+#endif /* CPNFIG_PROC_FS */ -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ -+ LEAVE(); -+ return priv; -+ err_init_fw: -+ sbi_unregister_dev(priv); -+ err_registerdev: -+ ((struct sdio_mmc_card *) card)->priv = NULL; -+ /* Stop the thread servicing the interrupts */ -+ priv->adapter->SurpriseRemoved = TRUE; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ while (priv->MainThread.pid) { -+ os_sched_timeout(1); -+ } -+ error: -+ if (dev) { -+ if (dev->reg_state == NETREG_REGISTERED) -+ unregister_netdev(dev); -+ if (priv->adapter) -+ uap_free_adapter(priv); -+ free_netdev(dev); -+ uappriv = NULL; -+ } -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ LEAVE(); -+ return NULL; -+} -+ -+/** -+ * @brief This function removes the card. -+ * -+ * @param card A pointer to card -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+uap_remove_card(void *card) -+{ -+ uap_private *priv = uappriv; -+ uap_adapter *Adapter; -+ struct net_device *dev; -+ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ if (!priv || !(Adapter = priv->adapter)) { -+ goto exit_remove; -+ } -+ Adapter->SurpriseRemoved = TRUE; -+ if (Adapter->cmd_pending == TRUE) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } -+ dev = priv->uap_dev.netdev; -+ if (priv->MediaConnected == TRUE) { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ } -+ Adapter->CmdSize = 0; -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ -+ /* Disable interrupts on the card */ -+ sbi_disable_host_int(priv); -+ PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name, -+ (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style"); -+ unregister_netdev(dev); -+ PRINTM(INFO, "Unregister finish\n"); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ while (priv->MainThread.pid) { -+ os_sched_timeout(1); -+ } -+ -+ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { -+ sock_release((Adapter->nl_sk)->sk_socket); -+ Adapter->nl_sk = NULL; -+ } -+#ifdef CONFIG_PROC_FS -+ uap_debug_remove(priv); -+ uap_proc_remove(priv); -+#endif -+ sbi_unregister_dev(priv); -+ PRINTM(INFO, "Free Adapter\n"); -+ uap_free_adapter(priv); -+ priv->uap_dev.netdev = NULL; -+ free_netdev(dev); -+ uappriv = NULL; -+ -+ exit_remove: -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function initializes module. -+ * -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int __init -+uap_init_module(void) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ -+ OS_INIT_SEMAPHORE(&AddRemoveCardSem); -+ ret = sbi_register(); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function cleans module -+ * -+ * @return n/a -+ */ -+static void __exit -+uap_cleanup_module(void) -+{ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ if ((uappriv) && (uappriv->adapter)) { -+ uap_func_shutdown(uappriv); -+ } -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ sbi_unregister(); -+ LEAVE(); -+} -+ -+module_init(uap_init_module); -+module_exit(uap_cleanup_module); -+module_param(helper_name, charp, 0); -+MODULE_PARM_DESC(helper_name, "Helper name"); -+module_param(fw_name, charp, 0); -+MODULE_PARM_DESC(fw_name, "Firmware name"); -+ -+MODULE_DESCRIPTION("M-UAP Driver"); -+MODULE_AUTHOR("Marvell International Ltd."); -+MODULE_VERSION(DRIVER_VERSION); -+MODULE_LICENSE("GPL"); -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_proc.c linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_proc.c ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_proc.c 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_proc.c 2011-01-08 06:01:04.050835055 -0700 -@@ -0,0 +1,296 @@ -+/** @file uap_proc.c -+ * @brief This file contains functions for proc file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifdef CONFIG_PROC_FS -+#include "uap_headers.h" -+ -+/** /proc directory root */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+#define PROC_DIR NULL -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+#define PROC_DIR &proc_root -+#else -+#define PROC_DIR proc_net -+#endif -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+/******************************************************** -+ Global Variables -+********************************************************/ -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+ -+/** -+ * @brief proc read function -+ * -+ * @param page pointer to buffer -+ * @param start read data starting position -+ * @param offset offset -+ * @param count counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_proc_read(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ int i; -+ char *p = page; -+ struct net_device *netdev = data; -+ struct netdev_hw_addr *ha; -+ char fmt[64]; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ -+ if (offset != 0) { -+ *eof = 1; -+ goto exit; -+ } -+ -+ strcpy(fmt, DRIVER_VERSION); -+ -+ p += sprintf(p, "driver_name = " "\"uap\"\n"); -+ p += sprintf(p, "driver_version = %s-(FP%s)", fmt, FPNUM); -+ p += sprintf(p, "\nInterfaceName=\"%s\"\n", netdev->name); -+ p += sprintf(p, "State=\"%s\"\n", -+ ((priv->MediaConnected == -+ FALSE) ? "Disconnected" : "Connected")); -+ p += sprintf(p, "MACAddress=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", -+ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], -+ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); -+ i = 0; -+ netdev_for_each_mc_addr(ha, netdev) { -+ ++i; -+ } -+ p += sprintf(p, "MCCount=\"%d\"\n", i); -+ -+ /* -+ * Put out the multicast list -+ */ -+ i = 0; -+ netdev_for_each_mc_addr(ha, netdev) { -+ p += sprintf(p, -+ "MCAddr[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", -+ i++, -+ ha->addr[0], ha->addr[1], -+ ha->addr[2], ha->addr[3], -+ ha->addr[4], ha->addr[5]); -+ } -+ -+ p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); -+ p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); -+ p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets); -+ p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets); -+ p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); -+ p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); -+ p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); -+ p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); -+ p += sprintf(p, "num_tx_timeout = %u\n", priv->num_tx_timeout); -+ p += sprintf(p, "carrier %s\n", -+ ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off")); -+ p += sprintf(p, "tx queue %s\n", -+ ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" : -+ "started")); -+ -+ exit: -+ return (p - page); -+} -+ -+/** -+ * @brief hwstatus proc write function -+ * -+ * @param f file pointer -+ * @param buf pointer to data buffer -+ * @param cnt data number to write -+ * @param data data to write -+ * @return number of data -+ */ -+static int -+uap_hwstatus_write(struct file *f, const char *buf, unsigned long cnt, -+ void *data) -+{ -+ struct net_device *netdev = data; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ char databuf[10]; -+ int hwstatus; -+ MODULE_GET; -+ if (cnt > 10) { -+ MODULE_PUT; -+ return cnt; -+ } -+ if (copy_from_user(databuf, buf, cnt)) { -+ MODULE_PUT; -+ return 0; -+ } -+ hwstatus = string_to_number(databuf); -+ switch (hwstatus) { -+ case HWReset: -+ PRINTM(MSG, "reset hw\n"); -+ uap_soft_reset(priv); -+ priv->adapter->HardwareStatus = HWReset; -+ break; -+ default: -+ break; -+ } -+ MODULE_PUT; -+ return cnt; -+} -+ -+/** -+ * @brief hwstatus proc read function -+ * -+ * @param page pointer to buffer -+ * @param s read data starting position -+ * @param off offset -+ * @param cnt counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_hwstatus_read(char *page, char **s, off_t off, int cnt, int *eof, -+ void *data) -+{ -+ char *p = page; -+ struct net_device *netdev = data; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ MODULE_GET; -+ p += sprintf(p, "%d\n", priv->adapter->HardwareStatus); -+ MODULE_PUT; -+ return p - page; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief create uap proc file -+ * -+ * @param priv pointer uap_private -+ * @param dev pointer net_device -+ * @return N/A -+ */ -+void -+uap_proc_entry(uap_private * priv, struct net_device *dev) -+{ -+ struct proc_dir_entry *r = PROC_DIR; -+ -+ PRINTM(INFO, "Creating Proc Interface\n"); -+ /* Check if uap directory already exists */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) -+ for (r = r->subdir; r; r = r->next) { -+ if (r->namelen && !strcmp("uap", r->name)) { -+ /* Directory exists */ -+ PRINTM(WARN, "proc directory already exists!\n"); -+ priv->proc_uap = r; -+ break; -+ } -+ } -+#endif -+ if (!priv->proc_uap) { -+ priv->proc_uap = proc_mkdir("uap", PROC_DIR); -+ if (!priv->proc_uap) -+ return; -+ else -+ atomic_set(&priv->proc_uap->count, 1); -+ } else { -+ atomic_inc(&priv->proc_uap->count); -+ } -+ priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap); -+ -+ if (priv->proc_entry) { -+ r = create_proc_read_entry("info", 0, priv->proc_entry, uap_proc_read, -+ dev); -+ r = create_proc_entry("hwstatus", 0644, priv->proc_entry); -+ if (r) { -+ r->data = dev; -+ r->read_proc = uap_hwstatus_read; -+ r->write_proc = uap_hwstatus_write; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) -+ r->owner = THIS_MODULE; -+#endif -+ } else -+ PRINTM(MSG, "Fail to create proc hwstatus\n"); -+ } -+} -+ -+/** -+ * @brief remove proc file -+ * -+ * @param priv pointer uap_private -+ * @return N/A -+ */ -+void -+uap_proc_remove(uap_private * priv) -+{ -+ if (priv->proc_uap) { -+ if (priv->proc_entry) { -+ remove_proc_entry("info", priv->proc_entry); -+ remove_proc_entry("hwstatus", priv->proc_entry); -+ } -+ remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap); -+ atomic_dec(&priv->proc_uap->count); -+ if (atomic_read(&(priv->proc_uap->count)) == 0) -+ remove_proc_entry("uap", PROC_DIR); -+ } -+} -+ -+/** -+ * @brief convert string to number -+ * -+ * @param s pointer to numbered string -+ * @return converted number from string s -+ */ -+int -+string_to_number(char *s) -+{ -+ int r = 0; -+ int base = 0; -+ int pn = 1; -+ -+ if (strncmp(s, "-", 1) == 0) { -+ pn = -1; -+ s++; -+ } -+ if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) { -+ base = 16; -+ s += 2; -+ } else -+ base = 10; -+ -+ for (s = s; *s != 0; s++) { -+ if ((*s >= '0') && (*s <= '9')) -+ r = (r * base) + (*s - '0'); -+ else if ((*s >= 'A') && (*s <= 'F')) -+ r = (r * base) + (*s - 'A' + 10); -+ else if ((*s >= 'a') && (*s <= 'f')) -+ r = (r * base) + (*s - 'a' + 10); -+ else -+ break; -+ } -+ -+ return (r * pn); -+} -+ -+#endif -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 2011-01-08 06:01:04.055834709 -0700 -@@ -0,0 +1,1428 @@ -+/** @file uap_sdio_mmc.c -+ * @brief This file contains SDIO IF (interface) module -+ * related functions. -+ * -+ * Copyright (C) 2007-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/**************************************************** -+Change log: -+****************************************************/ -+ -+#include "uap_sdio_mmc.h" -+ -+#include -+ -+/** define SDIO block size */ -+/* We support up to 480-byte block size due to FW buffer limitation. */ -+#define SD_BLOCK_SIZE 256 -+ -+/** define allocated buffer size */ -+#define ALLOC_BUF_SIZE (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \ -+ MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \ -+ + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE) -+ -+/** Max retry number of CMD53 write */ -+#define MAX_WRITE_IOMEM_RETRY 2 -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+/** SDIO Rx unit */ -+static u8 sdio_rx_unit = 0; -+ -+/**Interrupt status */ -+static u8 sd_ireg = 0; -+/******************************************************** -+ Global Variables -+********************************************************/ -+extern u8 *helper_name; -+extern u8 *fw_name; -+/** Default helper name */ -+#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin" -+/** Default firmware name */ -+#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin" -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief This function reads the IO register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param reg register to be read -+ * @param dat A pointer to variable that keeps returned value -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat) -+{ -+ struct sdio_mmc_card *card; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ card = priv->uap_dev.card; -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ *dat = sdio_readb(card->func, reg, &ret); -+ if (ret) { -+ PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret); -+ goto done; -+ } -+ -+ PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, -+ card->func->num, reg, *dat); -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function writes the IO register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param reg register to be written -+ * @param dat the value to be written -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat) -+{ -+ struct sdio_mmc_card *card; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ card = priv->uap_dev.card; -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, -+ card->func->num, reg, dat); -+ -+ sdio_writeb(card->func, dat, reg, &ret); -+ if (ret) { -+ PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret); -+ goto done; -+ } -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function get rx_unit value -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_get_rx_unit(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 reg; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, ®); -+ if (ret == UAP_STATUS_SUCCESS) -+ sdio_rx_unit = reg; -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads rx length -+ * -+ * @param priv A pointer to uap_private structure -+ * @param dat A pointer to keep returned data -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_read_rx_len(uap_private * priv, u16 * dat) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 reg; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_RX_LEN_REG, ®); -+ if (ret == UAP_STATUS_SUCCESS) -+ *dat = (u16) reg << sdio_rx_unit; -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads fw status registers -+ * -+ * @param priv A pointer to uap_private structure -+ * @param dat A pointer to keep returned data -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_read_firmware_status(uap_private * priv, u16 * dat) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 fws0; -+ u8 fws1; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_FW_STATUS0_REG, &fws0); -+ if (ret < 0) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ ret = sbi_read_ioreg(priv, CARD_FW_STATUS1_REG, &fws1); -+ if (ret < 0) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ *dat = (((u16) fws1) << 8) | fws0; -+ -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function polls the card status register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param bits the bit mask -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+mv_sdio_poll_card_status(uap_private * priv, u8 bits) -+{ -+ int tries; -+ u8 cs; -+ -+ ENTER(); -+ -+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { -+ if (sbi_read_ioreg(priv, CARD_STATUS_REG, &cs) < 0) -+ break; -+ else if ((cs & bits) == bits) { -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+ } -+ udelay(10); -+ } -+ -+ PRINTM(WARN, "mv_sdio_poll_card_status failed, tries = %d\n", tries); -+ -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+} -+ -+/** -+ * @brief This function set the sdio bus width. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mode 1--1 bit mode, 4--4 bit mode -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+#if 0 -+static int -+sdio_set_bus_width(uap_private * priv, u8 mode) -+{ -+ ENTER(); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+#endif -+ -+/** -+ * @brief This function reads data from the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_card_to_host(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u16 buf_len = 0; -+ int buf_block_len; -+ int blksz; -+ struct sk_buff *skb = NULL; -+ u16 type; -+ u8 *payload = NULL; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ -+ /* Read the length of data to be transferred */ -+ ret = sd_read_rx_len(priv, &buf_len); -+ if (ret < 0) { -+ PRINTM(ERROR, "card_to_host, read scratch reg failed\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ -+ /* Allocate buffer */ -+ blksz = SD_BLOCK_SIZE; -+ buf_block_len = (buf_len + blksz - 1) / blksz; -+ if (buf_len <= INTF_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { -+ PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+#ifdef PXA3XX_DMA_ALIGN -+ skb = dev_alloc_skb(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT); -+#else -+ skb = dev_alloc_skb(buf_block_len * blksz); -+#endif -+ if (skb == NULL) { -+ PRINTM(WARN, "No free skb\n"); -+ goto exit; -+ } -+#ifdef PXA3XX_DMA_ALIGN -+ if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) { -+ skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); -+ skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); -+ } -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+ payload = skb->tail; -+ ret = sdio_readsb(card->func, payload, priv->uap_dev.ioport, -+ buf_block_len * blksz); -+ if (ret < 0) { -+ PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ HEXDUMP("SDIO Blk Rd", payload, blksz * buf_block_len); -+ /* -+ * This is SDIO specific header -+ * u16 length, -+ * u16 type (MV_TYPE_DAT = 0, MV_TYPE_CMD = 1, MV_TYPE_EVENT = 3) -+ */ -+ buf_len = uap_le16_to_cpu(*(u16 *) & payload[0]); -+ type = uap_le16_to_cpu(*(u16 *) & payload[2]); -+ switch (type) { -+ case MV_TYPE_EVENT: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ uap_process_event(priv, skb->data, skb->len); -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ case MV_TYPE_CMD: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ priv->adapter->cmd_pending = FALSE; -+ if (priv->adapter->cmd_wait_option == -+ HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM) { -+ priv->adapter->cmd_wait_option = FALSE; -+ uap_process_sleep_confirm_resp(priv, skb->data, skb->len); -+ } else if (priv->adapter->cmd_wait_option) { -+ memcpy(priv->adapter->CmdBuf, skb->data, skb->len); -+ priv->adapter->CmdSize = skb->len; -+ priv->adapter->cmd_wait_option = FALSE; -+ priv->adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&priv->adapter->cmdwait_q); -+ } -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ case MV_TYPE_DAT: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ uap_process_rx_packet(priv, skb); -+ break; -+ default: -+ priv->stats.rx_errors++; -+ priv->stats.rx_dropped++; -+ /* Driver specified event and command resp should be handle here */ -+ PRINTM(INFO, "Unknown PKT type:%d\n", type); -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ } -+ exit: -+ if (ret) { -+ if (skb) -+ kfree_skb(skb); -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function enables the host interrupts mask -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mask the interrupt mask -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+enable_host_int_mask(uap_private * priv, u8 mask) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ /* Simply write the mask to the register */ -+ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, mask); -+ -+ if (ret) { -+ PRINTM(WARN, "Unable to enable the host interrupt!\n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** @brief This function disables the host interrupts mask. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mask the interrupt mask -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+disable_host_int_mask(uap_private * priv, u8 mask) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 host_int_mask; -+ -+ ENTER(); -+ -+ /* Read back the host_int_mask register */ -+ ret = sbi_read_ioreg(priv, HOST_INT_MASK_REG, &host_int_mask); -+ if (ret) { -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ /* Update with the mask and write back to the register */ -+ host_int_mask &= ~mask; -+ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, host_int_mask); -+ if (ret < 0) { -+ PRINTM(WARN, "Unable to diable the host interrupt!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+ -+/** -+ * @brief This function handles the interrupt. -+ * -+ * @param func A pointer to sdio_func structure. -+ * @return n/a -+ */ -+static void -+sbi_interrupt(struct sdio_func *func) -+{ -+ struct sdio_mmc_card *card; -+ uap_private *priv; -+ u8 ireg = 0; -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ card = sdio_get_drvdata(func); -+ if (!card || !card->priv) { -+ PRINTM(MSG, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n", -+ __FUNCTION__, func, card); -+ LEAVE(); -+ return; -+ } -+ priv = card->priv; -+#ifdef FW_WAKEUP_TIME -+ if ((priv->adapter->wt_pwrup_sending != 0L) && -+ (priv->adapter->wt_int == 0L)) -+ priv->adapter->wt_int = get_utimeofday(); -+#endif -+ -+ ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); -+ if (ret) { -+ PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n"); -+ goto done; -+ } -+ if (ireg != 0) { -+ /* -+ * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS -+ * Clear the interrupt status register and re-enable the interrupt -+ */ -+ PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg); -+ sdio_writeb(card->func, -+ ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), -+ HOST_INTSTATUS_REG, &ret); -+ if (ret) { -+ PRINTM(WARN, -+ "sdio_write_ioreg: clear int status register failed\n"); -+ goto done; -+ } -+ } -+ OS_INT_DISABLE; -+ sd_ireg |= ireg; -+ OS_INT_RESTORE; -+ -+ uap_interrupt(priv); -+ done: -+ LEAVE(); -+} -+ -+/** -+ * @brief This function probe the card -+ * -+ * @param func A pointer to sdio_func structure -+ * @param id A pointer to structure sd_device_id -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ int ret = UAP_STATUS_FAILURE; -+ struct sdio_mmc_card *card = NULL; -+ -+ ENTER(); -+ -+ PRINTM(MSG, "%s: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", -+ __FUNCTION__, func->vendor, func->device, func->class, func->num); -+ -+ card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); -+ if (!card) { -+ ret = -ENOMEM; -+ goto done; -+ } -+ -+ card->func = func; -+ -+ if (!uap_add_card(card)) { -+ PRINTM(ERROR, "%s: uap_add_callback failed\n", __FUNCTION__); -+ kfree(card); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ ret = UAP_STATUS_SUCCESS; -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function removes the card -+ * -+ * @param func A pointer to sdio_func structure -+ * @return N/A -+ */ -+static void -+uap_remove(struct sdio_func *func) -+{ -+ struct sdio_mmc_card *card; -+ -+ ENTER(); -+ -+ if (func) { -+ card = sdio_get_drvdata(func); -+ if (card) { -+ uap_remove_card(card); -+ kfree(card); -+ } -+ } -+ -+ LEAVE(); -+} -+ -+#ifdef CONFIG_PM -+/** -+ * @brief This function handles client driver suspend -+ * -+ * @param func A pointer to sdio_func structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_suspend(struct sdio_func *func) -+{ -+ ENTER(); -+ LEAVE(); -+ return 0; -+} -+ -+/** -+ * @brief This function handles client driver resume -+ * -+ * @param func A pointer to sdio_func structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_resume(struct sdio_func *func) -+{ -+ ENTER(); -+ LEAVE(); -+ return 0; -+} -+#endif -+ -+/** Device ID for SD8688 */ -+#define SD_DEVICE_ID_8688_UAP 0x9104 -+/** UAP IDs */ -+static const struct sdio_device_id uap_ids[] = { -+ {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SD_DEVICE_ID_8688_UAP)}, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, uap_ids); -+ -+static struct sdio_driver uap_sdio = { -+ .name = "uap_sdio", -+ .id_table = uap_ids, -+ .probe = uap_probe, -+ .remove = uap_remove, -+#ifdef CONFIG_PM -+/* .suspend = uap_suspend, */ -+/* .resume = uap_resume, */ -+#endif -+ -+}; -+ -+/** -+ * @brief This function registers the IF module in bus driver. -+ * -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int __init -+sbi_register() -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ /* SDIO Driver Registration */ -+ if (sdio_register_driver(&uap_sdio) != 0) { -+ PRINTM(FATAL, "SDIO Driver Registration Failed \n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function de-registers the IF module in bus driver. -+ * -+ * @return n/a -+ */ -+void __exit -+sbi_unregister(void) -+{ -+ ENTER(); -+ -+ /* SDIO Driver Unregistration */ -+ sdio_unregister_driver(&uap_sdio); -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function checks the interrupt status and handle it accordingly. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param ireg A pointer to variable that keeps returned value -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_get_int_status(uap_private * priv, u8 * ireg) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 sdio_ireg = 0; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ *ireg = 0; -+ OS_INT_DISABLE; -+ sdio_ireg = sd_ireg; -+ sd_ireg = 0; -+ OS_INT_RESTORE; -+ -+ sdio_claim_host(card->func); -+ -+ if (sdio_ireg & DN_LD_HOST_INT_STATUS) { /* tx_done INT */ -+ if (!priv->uap_dev.cmd_sent) { /* tx_done already received */ -+ PRINTM(INFO, -+ "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n", -+ priv->uap_dev.cmd_sent, sdio_ireg); -+ } else { -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ if ( (priv->uap_dev.netdev->reg_state == NETREG_REGISTERED) && (skb_queue_len(&priv->adapter->tx_queue) < TX_LOW_WATERMARK)) { -+ os_start_queue(priv); -+ } -+ } -+ } -+ if (sdio_ireg & UP_LD_HOST_INT_STATUS) { -+ sd_card_to_host(priv); -+ } -+ -+ *ireg = sdio_ireg; -+ ret = UAP_STATUS_SUCCESS; -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function disables the host interrupts. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_disable_host_int(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ ret = disable_host_int_mask(priv, HIM_DISABLE); -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function enables the host interrupts. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+sbi_enable_host_int(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ ret = enable_host_int_mask(priv, HIM_ENABLE); -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function de-registers the device. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+sbi_unregister_dev(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "Error: card or function is NULL!\n"); -+ goto done; -+ } -+ -+ sdio_claim_host(card->func); -+ sdio_release_irq(card->func); -+ sdio_disable_func(card->func); -+ sdio_release_host(card->func); -+ -+ sdio_set_drvdata(card->func, NULL); -+ -+ done: -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function registers the device. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_register_dev(uap_private * priv) -+{ -+ int ret = UAP_STATUS_FAILURE; -+ u8 reg; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ struct sdio_func *func; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "Error: card or function is NULL!\n"); -+ goto done; -+ } -+ -+ func = card->func; -+ -+ /* Initialize the private structure */ -+ priv->uap_dev.ioport = 0; -+ -+ sdio_claim_host(func); -+ -+ ret = sdio_enable_func(func); -+ if (ret) { -+ PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret); -+ goto release_host; -+ } -+ -+ ret = sdio_claim_irq(func, sbi_interrupt); -+ if (ret) { -+ PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret); -+ goto disable_func; -+ } -+ -+ /* Read the IO port */ -+ ret = sbi_read_ioreg(priv, IO_PORT_0_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= reg; -+ -+ ret = sbi_read_ioreg(priv, IO_PORT_1_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= (reg << 8); -+ -+ ret = sbi_read_ioreg(priv, IO_PORT_2_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= (reg << 16); -+ -+ PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num, -+ priv->uap_dev.ioport); -+ -+ ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE); -+ if (ret) { -+ PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__); -+ ret = UAP_STATUS_FAILURE; -+ goto release_irq; -+ } -+ priv->hotplug_device = &func->dev; -+ -+ if (helper_name == NULL) { -+ helper_name = DEFAULT_HELPER_NAME; -+ } -+ if (fw_name == NULL) { -+ fw_name = DEFAULT_FW_NAME; -+ } -+ sdio_release_host(func); -+ -+ sdio_set_drvdata(func, card); -+ -+ ret = UAP_STATUS_SUCCESS; -+ goto done; -+ -+ release_irq: -+ sdio_release_irq(func); -+ disable_func: -+ sdio_disable_func(func); -+ release_host: -+ sdio_release_host(func); -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function sends data to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param payload A pointer to the data/cmd buffer -+ * @param nb the length of data/cmd -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ int buf_block_len; -+ int blksz; -+ int i = 0; -+ u8 *buf = NULL; -+#ifdef PXA3XX_DMA_ALIGN -+ void *tmpbuf = NULL; -+ int tmpbufsz; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ buf = payload; -+#ifdef PXA3XX_DMA_ALIGN -+ if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) { -+ tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT); -+ tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL); -+ memset(tmpbuf, 0, tmpbufsz); -+ /* Ensure 8-byte aligned CMD buffer */ -+ buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT); -+ memcpy(buf, payload, nb); -+ } -+#endif -+ /* Allocate buffer and copy payload */ -+ blksz = SD_BLOCK_SIZE; -+ buf_block_len = (nb + blksz - 1) / blksz; -+ sdio_claim_host(card->func); -+#define MAX_WRITE_IOMEM_RETRY 2 -+ priv->uap_dev.cmd_sent = TRUE; -+ priv->uap_dev.data_sent = TRUE; -+ do { -+ /* Transfer data to card */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf, -+ buf_block_len * blksz); -+ if (ret < 0) { -+ i++; -+ PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i, -+ ret); -+ ret = UAP_STATUS_FAILURE; -+ if (i > MAX_WRITE_IOMEM_RETRY) -+ goto exit; -+ } else { -+ HEXDUMP("SDIO Blk Wr", payload, nb); -+ } -+ } while (ret == UAP_STATUS_FAILURE); -+ exit: -+ sdio_release_host(card->func); -+#ifdef PXA3XX_DMA_ALIGN -+ if (tmpbuf) -+ kfree(tmpbuf); -+#endif -+ if (ret == UAP_STATUS_FAILURE) { -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads CIS information. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param cisinfo A pointer to CIS information output buffer -+ * @param cislen A pointer to length of CIS info output buffer -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+#if 0 -+static int -+sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen) -+{ -+#define CIS_PTR (0x8000) -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ unsigned int i, cis_ptr = CIS_PTR; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n"); -+ goto exit; -+ } -+#define MAX_SDIO_CIS_INFO_LEN (256) -+ if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) { -+ PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n"); -+ goto exit; -+ } -+ -+ *cislen = MAX_SDIO_CIS_INFO_LEN; -+ -+ sdio_claim_host(card->func); -+ -+ PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr); -+ -+ /* Read the Tuple Data */ -+ for (i = 0; i < *cislen; i++) { -+ ((unsigned char *) cisinfo)[i] = -+ sdio_readb(card->func, cis_ptr + i, &ret); -+ if (ret) { -+ PRINTM(WARN, "get_cis_info error: ret=%d\n", ret); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]); -+ } -+ -+ done: -+ sdio_release_host(card->func); -+ exit: -+ LEAVE(); -+ return ret; -+} -+#endif -+/** -+ * @brief This function downloads helper image to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_prog_helper(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ u8 *helper = NULL; -+ int helperlen; -+ int ret = UAP_STATUS_SUCCESS; -+ void *tmphlprbuf = NULL; -+ int tmphlprbufsz; -+ u8 *hlprbuf; -+ int hlprblknow; -+ u32 tx_len; -+#ifdef FW_DOWNLOAD_SPEED -+ u32 tv1, tv2; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ if (priv->fw_helper) { -+ helper = (u8 *) priv->fw_helper->data; -+ helperlen = priv->fw_helper->size; -+ } else { -+ PRINTM(MSG, "No helper image found! Terminating download.\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n", -+ helperlen, SD_BLOCK_SIZE); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv1 = get_utimeofday(); -+#endif -+ -+#ifdef PXA3XX_DMA_ALIGN -+ tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); -+#else /* !PXA3XX_DMA_ALIGN */ -+ tmphlprbufsz = UAP_UPLD_SIZE; -+#endif /* !PXA3XX_DMA_ALIGN */ -+ tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); -+ if (!tmphlprbuf) { -+ PRINTM(ERROR, -+ "Unable to allocate buffer for helper. Terminating download\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ memset(tmphlprbuf, 0, tmphlprbufsz); -+#ifdef PXA3XX_DMA_ALIGN -+ hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT); -+#else /* !PXA3XX_DMA_ALIGN */ -+ hlprbuf = (u8 *) tmphlprbuf; -+#endif /* !PXA3XX_DMA_ALIGN */ -+ -+ sdio_claim_host(card->func); -+ -+ /* Perform helper data transfer */ -+ tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN; -+ hlprblknow = 0; -+ do { -+ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ -+ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); -+ if (ret < 0) { -+ PRINTM(FATAL, "Helper download poll status timeout @ %d\n", -+ hlprblknow); -+ goto done; -+ } -+ -+ /* More data? */ -+ if (hlprblknow >= helperlen) -+ break; -+ -+ /* Set blocksize to transfer - checking for last block */ -+ if (helperlen - hlprblknow < tx_len) -+ tx_len = helperlen - hlprblknow; -+ -+ /* Set length to the 4-byte header */ -+ *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len); -+ -+ /* Copy payload to buffer */ -+ memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len); -+ -+ PRINTM(INFO, "."); -+ -+ /* Send data */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow); -+ goto done; -+ } -+ -+ hlprblknow += tx_len; -+ } while (TRUE); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv2 = get_utimeofday(); -+ PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000, -+ (tv1 % 1000000) / 1000, tv1 % 1000); -+ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000, -+ tv2 % 1000); -+ tv2 -= tv1; -+ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000, -+ tv2 % 1000); -+#endif -+ -+ /* Write last EOF data */ -+ PRINTM(INFO, "\nTransferring helper image EOF block\n"); -+ memset(hlprbuf, 0x0, SD_BLOCK_SIZE); -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ hlprbuf, SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(FATAL, "IO error in writing helper image EOF block\n"); -+ goto done; -+ } -+ -+ ret = UAP_STATUS_SUCCESS; -+ -+ done: -+ sdio_release_host(card->func); -+ if (tmphlprbuf) -+ kfree(tmphlprbuf); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function downloads firmware image to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_prog_fw_w_helper(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ u8 *firmware = NULL; -+ int firmwarelen; -+ u8 base0; -+ u8 base1; -+ int ret = UAP_STATUS_SUCCESS; -+ int offset; -+ void *tmpfwbuf = NULL; -+ int tmpfwbufsz; -+ u8 *fwbuf; -+ u16 len; -+ int txlen = 0; -+ int tx_blocks = 0; -+ int i = 0; -+ int tries = 0; -+#ifdef FW_DOWNLOAD_SPEED -+ u32 tv1, tv2; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ if (priv->firmware) { -+ firmware = (u8 *) priv->firmware->data; -+ firmwarelen = priv->firmware->size; -+ } else { -+ PRINTM(MSG, "No firmware image found! Terminating download.\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv1 = get_utimeofday(); -+#endif -+ -+#ifdef PXA3XX_DMA_ALIGN -+ tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); -+#else /* PXA3XX_DMA_ALIGN */ -+ tmpfwbufsz = UAP_UPLD_SIZE; -+#endif /* PXA3XX_DMA_ALIGN */ -+ tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); -+ if (!tmpfwbuf) { -+ PRINTM(ERROR, -+ "Unable to allocate buffer for firmware. Terminating download.\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ memset(tmpfwbuf, 0, tmpfwbufsz); -+#ifdef PXA3XX_DMA_ALIGN -+ /* Ensure 8-byte aligned firmware buffer */ -+ fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT); -+#else /* PXA3XX_DMA_ALIGN */ -+ fwbuf = (u8 *) tmpfwbuf; -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+ sdio_claim_host(card->func); -+ -+ /* Perform firmware data transfer */ -+ offset = 0; -+ do { -+ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ -+ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); -+ if (ret < 0) { -+ PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n", -+ offset); -+ goto done; -+ } -+ -+ /* More data? */ -+ if (offset >= firmwarelen) -+ break; -+ -+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { -+ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) { -+ PRINTM(WARN, "Dev BASE0 register read failed:" -+ " base0=0x%04X(%d). Terminating download.\n", base0, -+ base0); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) { -+ PRINTM(WARN, "Dev BASE1 register read failed:" -+ " base1=0x%04X(%d). Terminating download.\n", base1, -+ base1); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ len = (((u16) base1) << 8) | base0; -+ -+ /* For SD8688 wait until the length is not 0, 1 or 2 before -+ downloading the first FW block, since BOOT code writes the -+ register to indicate the helper/FW download winner, the value -+ could be 1 or 2 (Func1 or Func2). */ -+ if ((len && offset) || (len > 2)) -+ break; -+ udelay(10); -+ } -+ -+ if (len == 0) -+ break; -+ else if (len > UAP_UPLD_SIZE) { -+ PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n", -+ offset, len); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ txlen = len; -+ -+ if (len & BIT(0)) { -+ i++; -+ if (i > MAX_WRITE_IOMEM_RETRY) { -+ PRINTM(FATAL, -+ "FW download failure @ %d, over max retry count\n", -+ offset); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(ERROR, "FW CRC error indicated by the helper:" -+ " len = 0x%04X, txlen = %d\n", len, txlen); -+ len &= ~BIT(0); -+ /* Setting this to 0 to resend from same offset */ -+ txlen = 0; -+ } else { -+ i = 0; -+ -+ /* Set blocksize to transfer - checking for last block */ -+ if (firmwarelen - offset < txlen) { -+ txlen = firmwarelen - offset; -+ } -+ PRINTM(INFO, "."); -+ -+ tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE; -+ -+ /* Copy payload to buffer */ -+ memcpy(fwbuf, &firmware[offset], txlen); -+ } -+ -+ /* Send data */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ fwbuf, tx_blocks * SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i, -+ offset); -+ if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) { -+ PRINTM(ERROR, "write ioreg failed (CFG)\n"); -+ } -+ } -+ -+ offset += txlen; -+ } while (TRUE); -+ -+ PRINTM(INFO, "\nFW download over, size %d bytes\n", offset); -+ -+ ret = UAP_STATUS_SUCCESS; -+ done: -+#ifdef FW_DOWNLOAD_SPEED -+ tv2 = get_utimeofday(); -+ PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000, -+ (tv1 % 1000000) / 1000, tv1 % 1000); -+ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, -+ (tv2 % 1000000) / 1000, tv2 % 1000); -+ tv2 -= tv1; -+ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, -+ (tv2 % 1000000) / 1000, tv2 % 1000); -+#endif -+ sdio_release_host(card->func); -+ if (tmpfwbuf) -+ kfree(tmpfwbuf); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks if the firmware is ready to accept -+ * command or not. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param pollnum Poll number -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_check_fw_status(uap_private * priv, int pollnum) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ u16 firmwarestat; -+ int tries; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ -+ /* Wait for firmware initialization event */ -+ for (tries = 0; tries < pollnum; tries++) { -+ if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0) -+ continue; -+ if (firmwarestat == FIRMWARE_READY) { -+ ret = UAP_STATUS_SUCCESS; -+ break; -+ } else { -+ mdelay(10); -+ ret = UAP_STATUS_FAILURE; -+ } -+ } -+ -+ if (ret < 0) -+ goto done; -+ -+ ret = UAP_STATUS_SUCCESS; -+ sd_get_rx_unit(priv); -+ -+ done: -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function set bus clock on/off -+ * -+ * @param priv A pointer to uap_private structure -+ * @param option TRUE--on , FALSE--off -+ * @return UAP_STATUS_SUCCESS -+ */ -+#if 0 -+static int -+sbi_set_bus_clock(uap_private * priv, u8 option) -+{ -+ ENTER(); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+#endif -+ -+/** -+ * @brief This function wakeup firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_wakeup_firmware(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ sdio_claim_host(card->func); -+ sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret); -+ sdio_release_host(card->func); -+ LEAVE(); -+ return ret; -+} -diff -Naupr linux-2.6.37/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h ---- linux-2.6.37/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 1969-12-31 17:00:00.000000000 -0700 -+++ linux-2.6.37-new/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 2011-01-08 06:01:04.057834571 -0700 -@@ -0,0 +1,136 @@ -+/** @file uap_sdio_mmc.h -+ * @brief This file contains SDIO IF (interface) module -+ * related macros, enum, and structure. -+ * -+ * Copyright (C) 2007-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/**************************************************** -+Change log: -+ 10/10/07: initial version -+****************************************************/ -+ -+#ifndef _UAP_SDIO_MMC_H -+#define _UAP_SDIO_MMC_H -+ -+#include -+#include -+#include -+#include -+ -+#include "uap_headers.h" -+ -+/** The number of times to try when waiting for downloaded firmware to -+ become active. (polling the scratch register). */ -+#define MAX_FIRMWARE_POLL_TRIES 100 -+ -+/** Firmware ready */ -+#define FIRMWARE_READY 0xfedc -+ -+/** Number of firmware blocks to transfer */ -+#define FIRMWARE_TRANSFER_NBLOCK 2 -+ -+/* Host Control Registers */ -+/** Host Control Registers : I/O port 0 */ -+#define IO_PORT_0_REG 0x00 -+/** Host Control Registers : I/O port 1 */ -+#define IO_PORT_1_REG 0x01 -+/** Host Control Registers : I/O port 2 */ -+#define IO_PORT_2_REG 0x02 -+ -+/** Host Control Registers : Configuration */ -+#define CONFIGURATION_REG 0x03 -+/** Host Control Registers : Host without Command 53 finish host */ -+#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2) -+/** Host Control Registers : Host power up */ -+#define HOST_POWER_UP (0x1U << 1) -+/** Host Control Registers : Host power down */ -+#define HOST_POWER_DOWN (0x1U << 0) -+ -+/** Host Control Registers : Host interrupt mask */ -+#define HOST_INT_MASK_REG 0x04 -+/** Host Control Registers : Upload host interrupt mask */ -+#define UP_LD_HOST_INT_MASK (0x1U) -+/** Host Control Registers : Download host interrupt mask */ -+#define DN_LD_HOST_INT_MASK (0x2U) -+/** Enable Host interrupt mask */ -+#define HIM_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK) -+/** Disable Host interrupt mask */ -+#define HIM_DISABLE 0xff -+ -+/** Host Control Registers : Host interrupt status */ -+#define HOST_INTSTATUS_REG 0x05 -+/** Host Control Registers : Upload host interrupt status */ -+#define UP_LD_HOST_INT_STATUS (0x1U) -+/** Host Control Registers : Download host interrupt status */ -+#define DN_LD_HOST_INT_STATUS (0x2U) -+ -+/** Host F1 read base 0 */ -+#define HOST_F1_RD_BASE_0 0x10 -+/** Host F1 read base 1 */ -+#define HOST_F1_RD_BASE_1 0x11 -+ -+/** Card Control Registers : Card status register */ -+#define CARD_STATUS_REG 0x20 -+/** Card Control Registers : Card I/O ready */ -+#define CARD_IO_READY (0x1U << 3) -+/** Card Control Registers : CIS card ready */ -+#define CIS_CARD_RDY (0x1U << 2) -+/** Card Control Registers : Upload card ready */ -+#define UP_LD_CARD_RDY (0x1U << 1) -+/** Card Control Registers : Download card ready */ -+#define DN_LD_CARD_RDY (0x1U << 0) -+ -+/** Card Control Registers : Card OCR 0 register */ -+#define CARD_OCR_0_REG 0x34 -+/** Card Control Registers : Card OCR 1 register */ -+#define CARD_OCR_1_REG 0x35 -+ -+/** Firmware status 0 register */ -+#define CARD_FW_STATUS0_REG 0x40 -+/** Firmware status 1 register */ -+#define CARD_FW_STATUS1_REG 0x41 -+/** Rx length register */ -+#define CARD_RX_LEN_REG 0x42 -+/** Rx unit register */ -+#define CARD_RX_UNIT_REG 0x43 -+ -+/** Chip Id Register 0 */ -+#define CARD_CHIP_ID_0_REG 0x801c -+/** Chip Id Register 1 */ -+#define CARD_CHIP_ID_1_REG 0x801d -+ -+#ifdef PXA3XX_DMA_ALIGN -+/** DMA alignment value for PXA3XX platforms */ -+#define PXA3XX_DMA_ALIGNMENT 8 -+/** Macros for Data Alignment : size */ -+#define ALIGN_SZ(p, a) \ -+ (((p) + ((a) - 1)) & ~((a) - 1)) -+ -+/** Macros for Data Alignment : address */ -+#define ALIGN_ADDR(p, a) \ -+ ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1)) -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+struct sdio_mmc_card -+{ -+ /** sdio_func structure pointer */ -+ struct sdio_func *func; -+ /** uap_private structure pointer */ -+ uap_private *priv; -+}; -+ -+#endif /* _UAP_SDIO_MMC_H */ diff --git a/with-linux-3.4/linux-3.0.4-LIBERTAS-WEXT_PRIV.patch b/with-linux-3.4/linux-3.0.4-LIBERTAS-WEXT_PRIV.patch deleted file mode 100644 index 2c91ef1..0000000 --- a/with-linux-3.4/linux-3.0.4-LIBERTAS-WEXT_PRIV.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- ./drivers/net/wireless/libertas/Kconfig.orig 2011-08-29 14:56:30.000000000 -0600 -+++ ./drivers/net/wireless/libertas/Kconfig 2011-09-13 20:37:23.660904556 -0600 -@@ -3,6 +3,7 @@ config LIBERTAS - depends on CFG80211 - select WIRELESS_EXT - select WEXT_SPY -+ select WEXT_PRIV - select LIB80211 - select FW_LOADER - ---help--- diff --git a/with-linux-3.4/mvsdio-1-2.6.30.patch b/with-linux-3.4/mvsdio-1-2.6.30.patch deleted file mode 100644 index 63f0156..0000000 --- a/with-linux-3.4/mvsdio-1-2.6.30.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- ./drivers/mmc/host/mvsdio.c.orig 2009-06-09 21:05:27.000000000 -0600 -+++ ./drivers/mmc/host/mvsdio.c 2009-06-23 23:20:36.085662093 -0600 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -148,6 +149,7 @@ static void mvsd_request(struct mmc_host - - dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n", - cmd->opcode, mvsd_read(MVSD_HW_STATE)); -+ if (cmd->opcode == SD_SWITCH) mdelay(1); /* Voodoo */ - - cmdreg = MVSD_CMD_INDEX(cmd->opcode); - diff --git a/with-linux-3.4/mvsdio-2.patch b/with-linux-3.4/mvsdio-2.patch deleted file mode 100644 index 8d53f2a..0000000 --- a/with-linux-3.4/mvsdio-2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Nicolas Pitre -Date: Tue, 28 Apr 2009 02:38:12 +0000 (-0400) -Subject: [MMC] give Sandisk/Kingston SDHC cards some slack before the SWITCH command -X-Git-Url: http://git.marvell.com/?p=orion.git;a=commitdiff_plain;h=3ea638523747f6d312f11f643a3175c1a4661eec;hp=c0c3df02efed0e5dea9aa4d8313e06e1f68f2cb4 - -[MMC] give Sandisk/Kingston SDHC cards some slack before the SWITCH command - -Without this delay, those cards simply won't work in high speed mode -as the SWITCH command does not succeeds. - -Signed-off-by: Nicolas Pitre -Tested-by: Martin Michlmayr ---- - -diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c -index cd81c39..ba4c7ab 100644 ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -263,6 +263,15 @@ static int mmc_switch_hs(struct mmc_card *card) - return -ENOMEM; - } - -+ /* -+ * Some SDHC cards, notably those with a Sandisk SD controller -+ * (also found in Kingston products) need a bit of slack -+ * before successfully handling the SWITCH command. So far, -+ * cards identifying themselves as "SD04G" and "SD08G" are -+ * affected -+ */ -+ udelay(100); -+ - err = mmc_sd_switch(card, 1, 0, 1, status); - if (err) - goto out; - diff --git a/with-linux-3.4/mvsdio-3.patch b/with-linux-3.4/mvsdio-3.patch deleted file mode 100644 index 76e96ce..0000000 --- a/with-linux-3.4/mvsdio-3.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-3.4/drivers/mmc/core/core.c -=================================================================== ---- linux-3.4.orig/drivers/mmc/core/core.c 2012-05-27 15:26:08.394167850 -0300 -+++ linux-3.4/drivers/mmc/core/core.c 2012-05-27 15:26:38.085113097 -0300 -@@ -536,7 +536,7 @@ - */ - limit_us = 3000000; - else -- limit_us = 100000; -+ limit_us = 200000; - - /* - * SDHC cards always use these fixed values. diff --git a/with-linux-3.4/phys-virt.diff b/with-linux-3.4/phys-virt.diff deleted file mode 100644 index fc3d43e..0000000 --- a/with-linux-3.4/phys-virt.diff +++ /dev/null @@ -1,14 +0,0 @@ -Index: linux-3.4/arch/arm/Kconfig -=================================================================== ---- linux-3.4.orig/arch/arm/Kconfig 2012-05-27 17:00:06.244112647 -0300 -+++ linux-3.4/arch/arm/Kconfig 2012-05-27 17:01:06.456038133 -0300 -@@ -235,8 +235,7 @@ - - config PHYS_OFFSET - hex "Physical address of main memory" if MMU -- depends on !ARM_PATCH_PHYS_VIRT && !NEED_MACH_MEMORY_H -- default DRAM_BASE if !MMU -+ default 0x0 - help - Please provide the physical address corresponding to the - location of main memory in your system. diff --git a/with-linux-3.4/series b/with-linux-3.4/series deleted file mode 100644 index c143ea1..0000000 --- a/with-linux-3.4/series +++ /dev/null @@ -1,8 +0,0 @@ -dreamplug-3.4.0.patch -mvsdio-1-2.6.30.patch -mvsdio-2.patch -mvsdio-3.patch -linux-3.0-SDIO-micro-AP.patch -0002-Driver-for-Marvell-Libertas-8688-SDIO-micro-AP-suppo-3.2.patch -linux-3.0.4-LIBERTAS-WEXT_PRIV.patch -phys-virt.diff -- cgit v1.2.3