Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: any controller working in AP mode ?
From: Bob Copeland @ 2009-07-17 17:57 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: Ram kumar, Javier Cardona, andrey, linux-wireless
In-Reply-To: <1247843954.25608.62.camel@mj>

On Fri, Jul 17, 2009 at 11:19 AM, Pavel Roskin<proski@gnu.org> wrote:
> I did a quick test with rt73usb.  hostapd starts sucessfully, and a
> client using ath5k can connect and transmit data.  A client using ath9k
> can connect (wpa_supplicant enters state CONNECTED), but no data goes
> through.  The same client connects fine to a normal AP (D-Link DIR-615).

Sounds like the AP doesn't buffer frames properly -- ath9k does power
saving but ath5k does not, yet.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* [RFC PATCH v2 1/8] wl1251: remove fixed address support from spi commands
From: Kalle Valo @ 2009-07-17 18:47 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Kalle Valo <kalle.valo@nokia.com>

The fixed addresses are not used in wl1251, only in wl1271. So it can
be safely removed.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/wl1251_spi.c |   26 ++++++++------------------
 drivers/net/wireless/wl12xx/wl1251_spi.h |   18 ++++++------------
 2 files changed, 14 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index c5da79d..c2b813f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -255,8 +255,7 @@ int wl1251_set_partition(struct wl1251 *wl,
 	return 0;
 }
 
-void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
-		     size_t len, bool fixed)
+void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len)
 {
 	struct spi_transfer t[3];
 	struct spi_message m;
@@ -271,9 +270,6 @@ void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
 	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
 	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
 
-	if (fixed)
-		*cmd |= WSPI_CMD_FIXED;
-
 	spi_message_init(&m);
 	memset(t, 0, sizeof(t));
 
@@ -298,8 +294,7 @@ void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
 	wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
 }
 
-void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
-		      size_t len, bool fixed)
+void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len)
 {
 	struct spi_transfer t[2];
 	struct spi_message m;
@@ -312,9 +307,6 @@ void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
 	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
 	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
 
-	if (fixed)
-		*cmd |= WSPI_CMD_FIXED;
-
 	spi_message_init(&m);
 	memset(t, 0, sizeof(t));
 
@@ -339,7 +331,7 @@ void wl1251_spi_mem_read(struct wl1251 *wl, int addr, void *buf,
 
 	physical = wl1251_translate_mem_addr(wl, addr);
 
-	wl1251_spi_read(wl, physical, buf, len, false);
+	wl1251_spi_read(wl, physical, buf, len);
 }
 
 void wl1251_spi_mem_write(struct wl1251 *wl, int addr, void *buf,
@@ -349,27 +341,25 @@ void wl1251_spi_mem_write(struct wl1251 *wl, int addr, void *buf,
 
 	physical = wl1251_translate_mem_addr(wl, addr);
 
-	wl1251_spi_write(wl, physical, buf, len, false);
+	wl1251_spi_write(wl, physical, buf, len);
 }
 
-void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len,
-			 bool fixed)
+void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len)
 {
 	int physical;
 
 	physical = wl1251_translate_reg_addr(wl, addr);
 
-	wl1251_spi_read(wl, physical, buf, len, fixed);
+	wl1251_spi_read(wl, physical, buf, len);
 }
 
-void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len,
-			  bool fixed)
+void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len)
 {
 	int physical;
 
 	physical = wl1251_translate_reg_addr(wl, addr);
 
-	wl1251_spi_write(wl, physical, buf, len, fixed);
+	wl1251_spi_write(wl, physical, buf, len);
 }
 
 u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index 6e8daf4..7076352 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -71,10 +71,8 @@
 
 
 /* Raw target IO, address is not translated */
-void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
-		      size_t len, bool fixed);
-void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
-		     size_t len, bool fixed);
+void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len);
 
 /* Memory target IO, address is tranlated to partition 0 */
 void wl1251_spi_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
@@ -83,10 +81,8 @@ u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
 void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
 
 /* Registers IO */
-void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len,
-			 bool fixed);
-void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len,
-			  bool fixed);
+void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len);
 u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
 void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
 
@@ -99,8 +95,7 @@ int wl1251_set_partition(struct wl1251 *wl,
 
 static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
 {
-	wl1251_spi_read(wl, addr, &wl->buffer_32,
-			sizeof(wl->buffer_32), false);
+	wl1251_spi_read(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
 
 	return wl->buffer_32;
 }
@@ -108,8 +103,7 @@ static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
 static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
 {
 	wl->buffer_32 = val;
-	wl1251_spi_write(wl, addr, &wl->buffer_32,
-			 sizeof(wl->buffer_32), false);
+	wl1251_spi_write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
 }
 
 #endif /* __WL1251_SPI_H__ */


^ permalink raw reply related

* [RFC PATCH v2 8/8] wl1251: add sdio support
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

This adds the wl1251_sdio module, enabling the SDIO interface for
wl1251, as used by the Google G1 phone and others.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---

 drivers/net/wireless/wl12xx/Kconfig       |   11 ++
 drivers/net/wireless/wl12xx/Makefile      |    1 
 drivers/net/wireless/wl12xx/wl1251_sdio.c |  188 +++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_sdio.c

diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index e47d076..3c8b2cd 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -27,3 +27,14 @@ config WL1251_SPI
 
 	  If you choose to build a module, it'll be called wl1251_spi.
 	  Say N if unsure.
+
+config WL1251_SDIO
+	tristate "TI wl1251 SDIO support"
+	depends on WL1251 && MMC
+	---help---
+	  This module adds support for the SDIO interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SDIO bus.
+
+	  If you choose to build a module, it'll be called
+	  wl1251_sdio. Say N if unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index f92fe87..f3a7630 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -5,3 +5,4 @@ wl1251-objs		= wl1251_main.o wl1251_spi.o wl1251_event.o \
 
 obj-$(CONFIG_WL1251)	+= wl1251.o
 obj-$(CONFIG_WL1251_SPI)	+= wl1251_spi.o
+obj-$(CONFIG_WL1251_SDIO)	+= wl1251_sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
new file mode 100644
index 0000000..f1d9e76
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -0,0 +1,188 @@
+/*
+ * wl12xx SDIO routines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Copyright (C) 2005 Texas Instruments Incorporated
+ * Copyright (C) 2008 Google Inc
+ * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
+ */
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/mod_devicetable.h>
+#include <linux/irq.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/platform_device.h>
+
+#include "wl1251.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "wl1251_ps.h"
+#include "wl1251_io.h"
+#include "wl1251_tx.h"
+#include "wl1251_debugfs.h"
+
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI		0x104c
+#endif
+
+#ifndef SDIO_DEVICE_ID_TI_WL1251
+#define SDIO_DEVICE_ID_TI_WL1251	0x9066
+#endif
+
+static struct sdio_func *wl_to_func(struct wl1251 *wl)
+{
+	return wl->if_priv;
+}
+
+static void wl1251_sdio_interrupt(struct sdio_func *func)
+{
+	wl1251_irq(0, sdio_get_drvdata(func));
+}
+
+static const struct sdio_device_id wl1251_devices[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
+	{}
+};
+MODULE_DEVICE_TABLE(sdio, wl1251_devices);
+
+
+void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int ret;
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	ret = sdio_memcpy_fromio(func, buf, addr, len);
+	if (ret)
+		wl1251_error("sdio read failed (%d)", ret);
+	sdio_release_host(func);
+}
+
+void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int ret;
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	ret = sdio_memcpy_toio(func, addr, buf, len);
+	if (ret)
+		wl1251_error("sdio write failed (%d)", ret);
+	sdio_release_host(func);
+}
+
+void wl1251_sdio_reset(struct wl1251 *wl)
+{
+}
+
+void wl1251_sdio_set_power(bool enable)
+{
+}
+
+struct wl1251_if_operations wl1251_sdio_ops = {
+	.read = wl1251_sdio_read,
+	.write = wl1251_sdio_write,
+	.reset = wl1251_sdio_reset,
+};
+
+int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+	int ret;
+	struct wl1251 *wl;
+	struct ieee80211_hw *hw;
+
+	hw = wl1251_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	sdio_claim_host(func);
+	ret = sdio_enable_func(func);
+	if (ret)
+		goto release;
+
+	sdio_set_block_size(func, 512);
+
+	SET_IEEE80211_DEV(hw, &func->dev);
+	wl->if_priv = func;
+	wl->if_ops = &wl1251_sdio_ops;
+	wl->set_power = wl1251_sdio_set_power;
+
+	sdio_release_host(func);
+	ret = wl1251_init_ieee80211(wl);
+	sdio_claim_host(func);
+	if (ret)
+		goto disable;
+
+	ret = sdio_claim_irq(func, wl1251_sdio_interrupt);
+	if (ret)
+		goto no_irq;
+
+	sdio_release_host(func);
+	sdio_set_drvdata(func, wl);
+	return ret;
+
+no_irq:
+	wl1251_free_hw(wl);
+disable:
+	sdio_disable_func(func);
+release:
+	sdio_release_host(func);
+	return ret;
+}
+
+static void __devexit wl1251_sdio_remove(struct sdio_func *func)
+{
+	struct wl1251 *wl = sdio_get_drvdata(func);
+
+	wl1251_free_hw(wl);
+
+	sdio_claim_host(func);
+	sdio_release_irq(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+}
+
+static struct sdio_driver wl1251_sdio_driver = {
+	.name		= "wl1251_sdio",
+	.id_table	= wl1251_devices,
+	.probe		= wl1251_sdio_probe,
+	.remove		= __devexit_p(wl1251_sdio_remove),
+};
+
+static int __init wl1251_sdio_init(void)
+{
+	int err;
+
+	err = sdio_register_driver(&wl1251_sdio_driver);
+	if (err)
+		wl1251_error("failed to register sdio driver: %d", err);
+	return err;
+}
+
+static void __exit wl1251_sdio_exit(void)
+{
+	sdio_unregister_driver(&wl1251_sdio_driver);
+	wl1251_notice("unloaded");
+}
+
+module_init(wl1251_sdio_init);
+module_exit(wl1251_sdio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");


^ permalink raw reply related

* [RFC PATCH v2 5/8] wl1251: make wl1251_set_partition bus agnostic
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

The same partition setting code can be used for both SPI and SDIO
modes, if we remove the spi-specific commands and use the more
generic buffer write routines.  Do that and move it to io.c
since it deals with register/memory address offsets.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/wl1251_io.c  |   95 +++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_io.h  |   15 ++++
 drivers/net/wireless/wl12xx/wl1251_spi.c |  124 ------------------------------
 drivers/net/wireless/wl12xx/wl1251_spi.h |   15 ----
 4 files changed, 110 insertions(+), 139 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
index bc95785..db2cfbf 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -84,3 +84,98 @@ void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
 {
 	wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
 }
+
+/* Set the partitions to access the chip addresses.
+ *
+ * There are two VIRTUAL partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory.  This function also makes other checks to
+ * ensure that the partitions are not overlapping.  In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ *                               PHYSICAL address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem_start
+ *          VIRTUAL address     ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  part_size <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  part_size    |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg_start
+ *  reg_size              ...         |    |
+ *                           ...      |    | [PART_1]
+ *                              ...   |    |
+ *                                 ...+----+--> reg_start + reg_size
+ *                                    |    |
+ *
+ */
+void wl1251_set_partition(struct wl1251 *wl,
+			  u32 mem_start, u32 mem_size,
+			  u32 reg_start, u32 reg_size)
+{
+	struct wl1251_partition partition[2];
+
+	wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+		     mem_start, mem_size);
+	wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+		     reg_start, reg_size);
+
+	/* Make sure that the two partitions together don't exceed the
+	 * address range */
+	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+		wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+			     " address range.  Truncating partition[0].");
+		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	if ((mem_start < reg_start) &&
+	    ((mem_start + mem_size) > reg_start)) {
+		/* Guarantee that the memory partition doesn't overlap the
+		 * registers partition */
+		wl1251_debug(DEBUG_SPI, "End of partition[0] is "
+			     "overlapping partition[1].  Adjusted.");
+		mem_size = reg_start - mem_start;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	} else if ((reg_start < mem_start) &&
+		   ((reg_start + reg_size) > mem_start)) {
+		/* Guarantee that the register partition doesn't overlap the
+		 * memory partition */
+		wl1251_debug(DEBUG_SPI, "End of partition[1] is"
+			     " overlapping partition[0].  Adjusted.");
+		reg_size = mem_start - reg_start;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	partition[0].start = mem_start;
+	partition[0].size  = mem_size;
+	partition[1].start = reg_start;
+	partition[1].size  = reg_size;
+
+	wl->physical_mem_addr = mem_start;
+	wl->physical_reg_addr = reg_start;
+
+	wl->virtual_mem_addr = 0;
+	wl->virtual_reg_addr = mem_size;
+
+	wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
+		sizeof(partition));
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
index 1fa2ab1..b89d2ac 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -23,6 +23,17 @@
 
 #include "wl1251.h"
 
+#define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE             4
+
+#define HW_ACCESS_PRAM_MAX_RANGE		0x3c000
+
 static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
 {
 	u32 response;
@@ -46,4 +57,8 @@ void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
 u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
 void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
 
+void wl1251_set_partition(struct wl1251 *wl,
+			  u32 part_start, u32 part_size,
+			  u32 reg_start,  u32 reg_size);
+
 #endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 61a0852..ceb237b 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -115,130 +115,6 @@ static void wl1251_spi_reset_wake(struct wl1251 *wl)
 	wl1251_spi_init(wl);
 }
 
-
-/* Set the SPI partitions to access the chip addresses
- *
- * There are two VIRTUAL (SPI) partitions (the memory partition and the
- * registers partition), which are mapped to two different areas of the
- * PHYSICAL (hardware) memory.  This function also makes other checks to
- * ensure that the partitions are not overlapping.  In the diagram below, the
- * memory partition comes before the register partition, but the opposite is
- * also supported.
- *
- *                               PHYSICAL address
- *                                     space
- *
- *                                    |    |
- *                                 ...+----+--> mem_start
- *          VIRTUAL address     ...   |    |
- *               space       ...      |    | [PART_0]
- *                        ...         |    |
- * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
- *               |    |         ...   |    |
- *               |MEM |      ...      |    |
- *               |    |   ...         |    |
- *  part_size <--+----+...            |    | {unused area)
- *               |    |   ...         |    |
- *               |REG |      ...      |    |
- *  part_size    |    |         ...   |    |
- *      +     <--+----+...         ...+----+--> reg_start
- *  reg_size              ...         |    |
- *                           ...      |    | [PART_1]
- *                              ...   |    |
- *                                 ...+----+--> reg_start + reg_size
- *                                    |    |
- *
- */
-int wl1251_set_partition(struct wl1251 *wl,
-			  u32 mem_start, u32 mem_size,
-			  u32 reg_start, u32 reg_size)
-{
-	struct wl1251_partition *partition;
-	struct spi_transfer t;
-	struct spi_message m;
-	size_t len, cmd_len;
-	u32 *cmd;
-	int addr;
-
-	cmd_len = sizeof(u32) + 2 * sizeof(struct wl1251_partition);
-	cmd = kzalloc(cmd_len, GFP_KERNEL);
-	if (!cmd)
-		return -ENOMEM;
-
-	spi_message_init(&m);
-	memset(&t, 0, sizeof(t));
-
-	partition = (struct wl1251_partition *) (cmd + 1);
-	addr = HW_ACCESS_PART0_SIZE_ADDR;
-	len = 2 * sizeof(struct wl1251_partition);
-
-	*cmd |= WSPI_CMD_WRITE;
-	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-	wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-		     mem_start, mem_size);
-	wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-		     reg_start, reg_size);
-
-	/* Make sure that the two partitions together don't exceed the
-	 * address range */
-	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
-		wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
-			     " address range.  Truncating partition[0].");
-		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
-		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
-
-	if ((mem_start < reg_start) &&
-	    ((mem_start + mem_size) > reg_start)) {
-		/* Guarantee that the memory partition doesn't overlap the
-		 * registers partition */
-		wl1251_debug(DEBUG_SPI, "End of partition[0] is "
-			     "overlapping partition[1].  Adjusted.");
-		mem_size = reg_start - mem_start;
-		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	} else if ((reg_start < mem_start) &&
-		   ((reg_start + reg_size) > mem_start)) {
-		/* Guarantee that the register partition doesn't overlap the
-		 * memory partition */
-		wl1251_debug(DEBUG_SPI, "End of partition[1] is"
-			     " overlapping partition[0].  Adjusted.");
-		reg_size = mem_start - reg_start;
-		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
-
-	partition[0].start = mem_start;
-	partition[0].size  = mem_size;
-	partition[1].start = reg_start;
-	partition[1].size  = reg_size;
-
-	wl->physical_mem_addr = mem_start;
-	wl->physical_reg_addr = reg_start;
-
-	wl->virtual_mem_addr = 0;
-	wl->virtual_reg_addr = mem_size;
-
-	t.tx_buf = cmd;
-	t.len = cmd_len;
-	spi_message_add_tail(&t, &m);
-
-	spi_sync(wl->spi, &m);
-
-	kfree(cmd);
-
-	return 0;
-}
-
 static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
 			    size_t len)
 {
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index 7c6da21..cb0c228 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -29,17 +29,6 @@
 #include "wl1251_acx.h"
 #include "reg.h"
 
-#define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
-
-#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
-#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
-#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
-#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
-
-#define HW_ACCESS_REGISTER_SIZE             4
-
-#define HW_ACCESS_PRAM_MAX_RANGE		0x3c000
-
 #define WSPI_CMD_READ                 0x40000000
 #define WSPI_CMD_WRITE                0x00000000
 #define WSPI_CMD_FIXED                0x20000000
@@ -69,8 +58,4 @@
 		((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
 #define HW_ACCESS_WSPI_INIT_CMD_MASK  0
 
-int wl1251_set_partition(struct wl1251 *wl,
-			 u32 part_start, u32 part_size,
-			 u32 reg_start,  u32 reg_size);
-
 #endif /* __WL1251_SPI_H__ */


^ permalink raw reply related

* [RFC PATCH v2 3/8] wl1251: use wiphy_dev instead of wl->spi->dev
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

Remove a dependency on the bus-specific struct device by using wiphy_dev
when requesting firmware.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/wl1251_main.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 2967e19..d9c5d8a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -75,9 +75,10 @@ static irqreturn_t wl1251_irq(int irq, void *cookie)
 static int wl1251_fetch_firmware(struct wl1251 *wl)
 {
 	const struct firmware *fw;
+	struct device *dev = wiphy_dev(wl->hw->wiphy);
 	int ret;
 
-	ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
+	ret = request_firmware(&fw, wl->chip.fw_filename, dev);
 
 	if (ret < 0) {
 		wl1251_error("could not get firmware: %d", ret);
@@ -113,9 +114,10 @@ out:
 static int wl1251_fetch_nvs(struct wl1251 *wl)
 {
 	const struct firmware *fw;
+	struct device *dev = wiphy_dev(wl->hw->wiphy);
 	int ret;
 
-	ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
+	ret = request_firmware(&fw, wl->chip.nvs_filename, dev);
 
 	if (ret < 0) {
 		wl1251_error("could not get nvs file: %d", ret);


^ permalink raw reply related

* [RFC PATCH v2 6/8] wl1251: move module probe methods into spi.c
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

This change moves all of the spi specific code from main.c into
spi.c.  The module initialization code also moves, but common
code for initializing mac80211 etc. stays in main.c, as this will
eventually form a common library module also used by wl1251_sdio.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/wl1251.h      |    7 +
 drivers/net/wireless/wl12xx/wl1251_acx.c  |    1 
 drivers/net/wireless/wl12xx/wl1251_cmd.c  |    1 
 drivers/net/wireless/wl12xx/wl1251_main.c |  148 ++++-------------------------
 drivers/net/wireless/wl12xx/wl1251_spi.c  |  125 ++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_tx.c   |    1 
 6 files changed, 151 insertions(+), 132 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 284bb50..df4c06d 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -292,7 +292,7 @@ struct wl1251 {
 	bool mac80211_registered;
 
 	struct spi_device *spi;
-	struct wl1251_if_operations *if_ops;
+	const struct wl1251_if_operations *if_ops;
 
 	void (*set_power)(bool enable);
 	int irq;
@@ -404,6 +404,11 @@ struct wl1251 {
 int wl1251_plt_start(struct wl1251 *wl);
 int wl1251_plt_stop(struct wl1251 *wl);
 
+irqreturn_t wl1251_irq(int irq, void *cookie);
+struct ieee80211_hw *wl1251_alloc_hw(void);
+int wl1251_free_hw(struct wl1251 *wl);
+int wl1251_init_ieee80211(struct wl1251 *wl);
+
 #define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
 #define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
 #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index b89fa23..b07747d 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/crc7.h>
-#include <linux/spi/spi.h>
 
 #include "wl1251.h"
 #include "reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index 2c30c70..dfbf681 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/crc7.h>
-#include <linux/spi/spi.h>
 
 #include "wl1251.h"
 #include "reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 238b4a8..62b84fc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -26,17 +26,15 @@
 #include <linux/firmware.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <linux/spi/spi.h>
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
-#include <linux/spi/wl12xx.h>
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
 #include "reg.h"
 #include "wl1251_ops.h"
 #include "wl1251_io.h"
-#include "wl1251_spi.h"
+#include "wl1251_cmd.h"
 #include "wl1251_event.h"
 #include "wl1251_tx.h"
 #include "wl1251_rx.h"
@@ -59,7 +57,7 @@ static void wl1251_power_on(struct wl1251 *wl)
 	wl->set_power(true);
 }
 
-static irqreturn_t wl1251_irq(int irq, void *cookie)
+irqreturn_t wl1251_irq(int irq, void *cookie)
 {
 	struct wl1251 *wl;
 
@@ -1224,8 +1222,10 @@ static int wl1251_register_hw(struct wl1251 *wl)
 	return 0;
 }
 
-static int wl1251_init_ieee80211(struct wl1251 *wl)
+int wl1251_init_ieee80211(struct wl1251 *wl)
 {
+	int ret;
+
 	/* The tx descriptor buffer and the TKIP space */
 	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
 		+ WL1251_TKIP_IV_SPACE;
@@ -1241,41 +1241,37 @@ static int wl1251_init_ieee80211(struct wl1251 *wl)
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
 
-	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+	ret = wl1251_register_hw(wl);
+	if (ret)
+		goto out;
 
-	return 0;
-}
+	wl1251_debugfs_init(wl);
+	wl1251_notice("initialized");
 
-extern struct wl1251_if_operations wl1251_spi_ops;
+	ret = 0;
+
+out:
+	return ret;
+}
 
 #define WL1251_DEFAULT_CHANNEL 1
-static int __devinit wl1251_probe(struct spi_device *spi)
+struct ieee80211_hw *wl1251_alloc_hw(void)
 {
-	struct wl12xx_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
-	int ret, i;
+	int i;
 	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
 
-	pdata = spi->dev.platform_data;
-	if (!pdata) {
-		wl1251_error("no platform data");
-		return -ENODEV;
-	}
-
 	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
 	if (!hw) {
 		wl1251_error("could not alloc ieee80211_hw");
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	wl = hw->priv;
 	memset(wl, 0, sizeof(*wl));
 
 	wl->hw = hw;
-	dev_set_drvdata(&spi->dev, wl);
-	wl->spi = spi;
-	wl->if_ops = &wl1251_spi_ops;
 
 	wl->data_in_count = 0;
 
@@ -1323,74 +1319,15 @@ static int __devinit wl1251_probe(struct spi_device *spi)
 	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
 	if (!wl->rx_descriptor) {
 		wl1251_error("could not allocate memory for rx descriptor");
-		ret = -ENOMEM;
-		goto out_free;
+		ieee80211_free_hw(hw);
+		return ERR_PTR(-ENOMEM);
 	}
 
-	/* This is the only SPI value that we need to set here, the rest
-	 * comes from the board-peripherals file */
-	spi->bits_per_word = 32;
-
-	ret = spi_setup(spi);
-	if (ret < 0) {
-		wl1251_error("spi_setup failed");
-		goto out_free;
-	}
-
-	wl->set_power = pdata->set_power;
-	if (!wl->set_power) {
-		wl1251_error("set power function missing in platform data");
-		ret = -ENODEV;
-		goto out_free;
-	}
-
-	wl->irq = spi->irq;
-	if (wl->irq < 0) {
-		wl1251_error("irq missing in platform data");
-		ret = -ENODEV;
-		goto out_free;
-	}
-
-	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
-	if (ret < 0) {
-		wl1251_error("request_irq() failed: %d", ret);
-		goto out_free;
-	}
-
-	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
-	disable_irq(wl->irq);
-
-	ret = wl1251_init_ieee80211(wl);
-	if (ret)
-		goto out_irq;
-
-	ret = wl1251_register_hw(wl);
-	if (ret)
-		goto out_irq;
-
-	wl1251_debugfs_init(wl);
-
-	wl1251_notice("initialized");
-
-	return 0;
-
- out_irq:
-	free_irq(wl->irq, wl);
-
- out_free:
-	kfree(wl->rx_descriptor);
-	wl->rx_descriptor = NULL;
-
-	ieee80211_free_hw(hw);
-
-	return ret;
+	return hw;
 }
 
-static int __devexit wl1251_remove(struct spi_device *spi)
+int wl1251_free_hw(struct wl1251 *wl)
 {
-	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
-
 	ieee80211_unregister_hw(wl->hw);
 
 	wl1251_debugfs_exit(wl);
@@ -1410,44 +1347,3 @@ static int __devexit wl1251_remove(struct spi_device *spi)
 
 	return 0;
 }
-
-
-static struct spi_driver wl1251_spi_driver = {
-	.driver = {
-		/* FIXME: use wl12xx name to not break the user space */
-		.name		= "wl12xx",
-		.bus		= &spi_bus_type,
-		.owner		= THIS_MODULE,
-	},
-
-	.probe		= wl1251_probe,
-	.remove		= __devexit_p(wl1251_remove),
-};
-
-static int __init wl1251_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&wl1251_spi_driver);
-	if (ret < 0) {
-		wl1251_error("failed to register spi driver: %d", ret);
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void __exit wl1251_exit(void)
-{
-	spi_unregister_driver(&wl1251_spi_driver);
-
-	wl1251_notice("unloaded");
-}
-
-module_init(wl1251_init);
-module_exit(wl1251_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
-		"Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index ceb237b..13e7a72 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -21,9 +21,11 @@
  *
  */
 
+#include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/wl12xx.h>
 
 #include "wl1251.h"
 #include "reg.h"
@@ -55,7 +57,7 @@ static void wl1251_spi_reset(struct wl1251 *wl)
 	wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
 }
 
-static void wl1251_spi_init(struct wl1251 *wl)
+static void wl1251_spi_wake(struct wl1251 *wl)
 {
 	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
 	struct spi_transfer t;
@@ -112,7 +114,7 @@ static void wl1251_spi_init(struct wl1251 *wl)
 static void wl1251_spi_reset_wake(struct wl1251 *wl)
 {
 	wl1251_spi_reset(wl);
-	wl1251_spi_init(wl);
+	wl1251_spi_wake(wl);
 }
 
 static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
@@ -191,3 +193,122 @@ const struct wl1251_if_operations wl1251_spi_ops = {
 	.write = wl1251_spi_write,
 	.reset = wl1251_spi_reset_wake,
 };
+
+static int __devinit wl1251_spi_probe(struct spi_device *spi)
+{
+	struct wl12xx_platform_data *pdata;
+	struct ieee80211_hw *hw;
+	struct wl1251 *wl;
+	int ret;
+
+	pdata = spi->dev.platform_data;
+	if (!pdata) {
+		wl1251_error("no platform data");
+		return -ENODEV;
+	}
+
+	hw = wl1251_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	SET_IEEE80211_DEV(hw, &spi->dev);
+	dev_set_drvdata(&spi->dev, wl);
+	wl->spi = spi;
+	wl->if_ops = &wl1251_spi_ops;
+
+	/* This is the only SPI value that we need to set here, the rest
+	 * comes from the board-peripherals file */
+	spi->bits_per_word = 32;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		wl1251_error("spi_setup failed");
+		goto out_free;
+	}
+
+	wl->set_power = pdata->set_power;
+	if (!wl->set_power) {
+		wl1251_error("set power function missing in platform data");
+		return -ENODEV;
+	}
+
+	wl->irq = spi->irq;
+	if (wl->irq < 0) {
+		wl1251_error("irq missing in platform data");
+		return -ENODEV;
+	}
+
+	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+	if (ret < 0) {
+		wl1251_error("request_irq() failed: %d", ret);
+		goto out_free;
+	}
+
+	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(wl->irq);
+
+	ret = wl1251_init_ieee80211(wl);
+	if (ret)
+		goto out_irq;
+
+	return 0;
+
+ out_irq:
+	free_irq(wl->irq, wl);
+
+ out_free:
+	ieee80211_free_hw(hw);
+
+	return ret;
+}
+
+static int __devexit wl1251_spi_remove(struct spi_device *spi)
+{
+	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
+
+	wl1251_free_hw(wl);
+
+	return 0;
+}
+
+static struct spi_driver wl1251_spi_driver = {
+	.driver = {
+		.name		= "wl12xx",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= wl1251_spi_probe,
+	.remove		= __devexit_p(wl1251_spi_remove),
+};
+
+static int __init wl1251_spi_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&wl1251_spi_driver);
+	if (ret < 0) {
+		wl1251_error("failed to register spi driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit wl1251_spi_exit(void)
+{
+	spi_unregister_driver(&wl1251_spi_driver);
+
+	wl1251_notice("unloaded");
+}
+
+module_init(wl1251_spi_init);
+module_exit(wl1251_spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index 7ddc9a3..f20bab6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -27,7 +27,6 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
 #include "wl1251_tx.h"
 #include "wl1251_ps.h"
 #include "wl1251_io.h"


^ permalink raw reply related

* [RFC PATCH v2 7/8] wl1251: split spi interface into separate module
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

This creates a module called wl1251_spi.ko which contains just the
SPI-specific code.  The core remains in the module wl1251.ko.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/Kconfig       |   17 ++++++++++++++---
 drivers/net/wireless/wl12xx/Makefile      |    2 ++
 drivers/net/wireless/wl12xx/wl1251.h      |    2 +-
 drivers/net/wireless/wl12xx/wl1251_main.c |    9 +++++++++
 drivers/net/wireless/wl12xx/wl1251_spi.c  |   15 ++++++++++-----
 5 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 82a0f97..e47d076 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -7,12 +7,23 @@ menuconfig WL12XX
 
 config WL1251
 	tristate "TI wl1251 support"
-	depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS
+	depends on WL12XX && GENERIC_HARDIRQS
 	select FW_LOADER
 	select CRC7
 	---help---
 	  This module adds support for wireless adapters based on
 	  TI wl1251 chipset.
 
-	  If you choose to build a module, it'll be called wl1251. Say N if
-	  unsure.
+	  If you choose to build a module, it'll be called wl1251. Say
+	  N if unsure.
+
+config WL1251_SPI
+	tristate "TI wl1251 SPI support"
+	depends on WL1251 && SPI_MASTER
+	---help---
+	  This module adds support for the SPI interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SPI bus.
+
+	  If you choose to build a module, it'll be called wl1251_spi.
+	  Say N if unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index a978567..f92fe87 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -2,4 +2,6 @@ wl1251-objs		= wl1251_main.o wl1251_spi.o wl1251_event.o \
 			  wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
 			  wl1251_acx.o wl1251_boot.o wl1251_init.o \
 			  wl1251_ops.o wl1251_debugfs.o wl1251_io.o
+
 obj-$(CONFIG_WL1251)	+= wl1251.o
+obj-$(CONFIG_WL1251_SPI)	+= wl1251_spi.o
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index df4c06d..ebe2c70 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -291,7 +291,7 @@ struct wl1251 {
 	struct ieee80211_hw *hw;
 	bool mac80211_registered;
 
-	struct spi_device *spi;
+	void *if_priv;
 	const struct wl1251_if_operations *if_ops;
 
 	void (*set_power)(bool enable);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 62b84fc..c5c94b2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -69,6 +69,7 @@ irqreturn_t wl1251_irq(int irq, void *cookie)
 
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL_GPL(wl1251_irq);
 
 static int wl1251_fetch_firmware(struct wl1251 *wl)
 {
@@ -1253,6 +1254,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
 
 #define WL1251_DEFAULT_CHANNEL 1
 struct ieee80211_hw *wl1251_alloc_hw(void)
@@ -1325,6 +1327,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
 
 	return hw;
 }
+EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
 
 int wl1251_free_hw(struct wl1251 *wl)
 {
@@ -1347,3 +1350,9 @@ int wl1251_free_hw(struct wl1251 *wl)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(wl1251_free_hw);
+
+MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 13e7a72..464b802 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -31,6 +31,11 @@
 #include "reg.h"
 #include "wl1251_spi.h"
 
+static struct spi_device *wl_to_spi(struct wl1251 *wl)
+{
+	return wl->if_priv;
+}
+
 static void wl1251_spi_reset(struct wl1251 *wl)
 {
 	u8 *cmd;
@@ -52,7 +57,7 @@ static void wl1251_spi_reset(struct wl1251 *wl)
 	t.len = WSPI_INIT_CMD_LEN;
 	spi_message_add_tail(&t, &m);
 
-	spi_sync(wl->spi, &m);
+	spi_sync(wl_to_spi(wl), &m);
 
 	wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
 }
@@ -106,7 +111,7 @@ static void wl1251_spi_wake(struct wl1251 *wl)
 	t.len = WSPI_INIT_CMD_LEN;
 	spi_message_add_tail(&t, &m);
 
-	spi_sync(wl->spi, &m);
+	spi_sync(wl_to_spi(wl), &m);
 
 	wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
 }
@@ -149,7 +154,7 @@ static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
 	t[2].len = len;
 	spi_message_add_tail(&t[2], &m);
 
-	spi_sync(wl->spi, &m);
+	spi_sync(wl_to_spi(wl), &m);
 
 	/* FIXME: check busy words */
 
@@ -182,7 +187,7 @@ static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
 
-	spi_sync(wl->spi, &m);
+	spi_sync(wl_to_spi(wl), &m);
 
 	wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
 	wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
@@ -215,7 +220,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
 
 	SET_IEEE80211_DEV(hw, &spi->dev);
 	dev_set_drvdata(&spi->dev, wl);
-	wl->spi = spi;
+	wl->if_priv = spi;
 	wl->if_ops = &wl1251_spi_ops;
 
 	/* This is the only SPI value that we need to set here, the rest


^ permalink raw reply related

* [RFC PATCH v2 0/8] wl1251 sdio interface
From: Kalle Valo @ 2009-07-17 18:47 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless

Here is v2 of Bob's wl1251 sdio patches. I have now rebased them on
top of wl1251/wl1271 split patches. Only compile-tested because I
don't have working test setup right now (neither spi or sdio), but I
should have access to one in two weeks.

We should get the patches into wireless-testing soon because there is
quite a lot of interest for wl1251 sdio support, sdio is more widely
used than spi. I would like to get the patches into 2.6.32 if at all
possible.

v2:
o rebase to current wireless-testing (after wl1251/wl1271 split)

---

Bob Copeland (7):
      wl1251: add sdio support
      wl1251: split spi interface into separate module
      wl1251: move module probe methods into spi.c
      wl1251: make wl1251_set_partition bus agnostic
      wl1251: introduce wl1251_if_operations struct
      wl1251: use wiphy_dev instead of wl->spi->dev
      wl1251: separate bus i/o code into io.c

Kalle Valo (1):
      wl1251: remove fixed address support from spi commands


 drivers/net/wireless/wl12xx/Kconfig        |   28 ++-
 drivers/net/wireless/wl12xx/Makefile       |    5 
 drivers/net/wireless/wl12xx/wl1251.h       |   14 +
 drivers/net/wireless/wl12xx/wl1251_acx.c   |    3 
 drivers/net/wireless/wl12xx/wl1251_boot.c  |    1 
 drivers/net/wireless/wl12xx/wl1251_cmd.c   |   11 -
 drivers/net/wireless/wl12xx/wl1251_event.c |    4 
 drivers/net/wireless/wl12xx/wl1251_io.c    |  181 ++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_io.h    |   64 ++++++
 drivers/net/wireless/wl12xx/wl1251_main.c  |  162 +++------------
 drivers/net/wireless/wl12xx/wl1251_ops.c   |    5 
 drivers/net/wireless/wl12xx/wl1251_ps.c    |    3 
 drivers/net/wireless/wl12xx/wl1251_rx.c    |    7 -
 drivers/net/wireless/wl12xx/wl1251_sdio.c  |  188 +++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_spi.c   |  310 +++++++++++-----------------
 drivers/net/wireless/wl12xx/wl1251_spi.h   |   54 -----
 drivers/net/wireless/wl12xx/wl1251_tx.c    |   62 +++---
 17 files changed, 678 insertions(+), 424 deletions(-)
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.h
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_sdio.c


^ permalink raw reply

* [RFC PATCH v2 4/8] wl1251: introduce wl1251_if_operations struct
From: Kalle Valo @ 2009-07-17 18:48 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

Introduce an ops struct with read, write, and reset functions to
abstract away the details of the wl1251 bus interface.  Doing this
will allow SDIO to coexist with SPI by supplying its own I/O
routines.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/wl1251.h      |    7 +++++++
 drivers/net/wireless/wl12xx/wl1251_boot.c |    1 +
 drivers/net/wireless/wl12xx/wl1251_io.c   |    4 ++--
 drivers/net/wireless/wl12xx/wl1251_io.h   |    9 ++-------
 drivers/net/wireless/wl12xx/wl1251_main.c |    6 ++++--
 drivers/net/wireless/wl12xx/wl1251_ops.c  |    1 +
 drivers/net/wireless/wl12xx/wl1251_spi.c  |   23 +++++++++++++++++++----
 drivers/net/wireless/wl12xx/wl1251_spi.h  |    3 ---
 8 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 665aca0..284bb50 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -281,11 +281,18 @@ struct wl1251_debugfs {
 	struct dentry *excessive_retries;
 };
 
+struct wl1251_if_operations {
+	void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
+	void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
+	void (*reset)(struct wl1251 *wl);
+};
+
 struct wl1251 {
 	struct ieee80211_hw *hw;
 	bool mac80211_registered;
 
 	struct spi_device *spi;
+	struct wl1251_if_operations *if_ops;
 
 	void (*set_power)(bool enable);
 	int irq;
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 5702398..5c6f327 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -26,6 +26,7 @@
 #include "reg.h"
 #include "wl1251_boot.h"
 #include "wl1251_io.h"
+#include "wl1251_spi.h"
 #include "wl1251_event.h"
 
 static void wl1251_boot_enable_interrupts(struct wl1251 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
index 1fa2674..bc95785 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -53,7 +53,7 @@ void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
 
 	physical = wl1251_translate_mem_addr(wl, addr);
 
-	wl1251_spi_read(wl, physical, buf, len);
+	wl->if_ops->read(wl, physical, buf, len);
 }
 
 void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
@@ -62,7 +62,7 @@ void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
 
 	physical = wl1251_translate_mem_addr(wl, addr);
 
-	wl1251_spi_write(wl, physical, buf, len);
+	wl->if_ops->write(wl, physical, buf, len);
 }
 
 u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
index e2bb954..1fa2ab1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -22,24 +22,19 @@
 #define __WL1251_IO_H__
 
 #include "wl1251.h"
-#include "wl1251_spi.h"
-
-/* Raw target IO, address is not translated */
-void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len);
 
 static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
 {
 	u32 response;
 
-	wl1251_spi_read(wl, addr, &response, sizeof(u32));
+	wl->if_ops->read(wl, addr, &response, sizeof(u32));
 
 	return response;
 }
 
 static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
 {
-	wl1251_spi_write(wl, addr, &val, sizeof(u32));
+	wl->if_ops->write(wl, addr, &val, sizeof(u32));
 }
 
 /* Memory target IO, address is translated to partition 0 */
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index d9c5d8a..238b4a8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -168,8 +168,7 @@ static int wl1251_chip_wakeup(struct wl1251 *wl)
 
 	wl1251_power_on(wl);
 	msleep(wl->chip.power_on_sleep);
-	wl1251_spi_reset(wl);
-	wl1251_spi_init(wl);
+	wl->if_ops->reset(wl);
 
 	/* We don't need a real memory partition here, because we only want
 	 * to use the registers at this point. */
@@ -1247,6 +1246,8 @@ static int wl1251_init_ieee80211(struct wl1251 *wl)
 	return 0;
 }
 
+extern struct wl1251_if_operations wl1251_spi_ops;
+
 #define WL1251_DEFAULT_CHANNEL 1
 static int __devinit wl1251_probe(struct spi_device *spi)
 {
@@ -1274,6 +1275,7 @@ static int __devinit wl1251_probe(struct spi_device *spi)
 	wl->hw = hw;
 	dev_set_drvdata(&spi->dev, wl);
 	wl->spi = spi;
+	wl->if_ops = &wl1251_spi_ops;
 
 	wl->data_in_count = 0;
 
diff --git a/drivers/net/wireless/wl12xx/wl1251_ops.c b/drivers/net/wireless/wl12xx/wl1251_ops.c
index 0c169ec..966c919 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ops.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ops.c
@@ -27,6 +27,7 @@
 #include "wl1251_ops.h"
 #include "reg.h"
 #include "wl1251_io.h"
+#include "wl1251_spi.h"
 #include "wl1251_boot.h"
 #include "wl1251_event.h"
 #include "wl1251_acx.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 031a3ba..61a0852 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -29,7 +29,7 @@
 #include "reg.h"
 #include "wl1251_spi.h"
 
-void wl1251_spi_reset(struct wl1251 *wl)
+static void wl1251_spi_reset(struct wl1251 *wl)
 {
 	u8 *cmd;
 	struct spi_transfer t;
@@ -55,7 +55,7 @@ void wl1251_spi_reset(struct wl1251 *wl)
 	wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
 }
 
-void wl1251_spi_init(struct wl1251 *wl)
+static void wl1251_spi_init(struct wl1251 *wl)
 {
 	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
 	struct spi_transfer t;
@@ -109,6 +109,13 @@ void wl1251_spi_init(struct wl1251 *wl)
 	wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
 }
 
+static void wl1251_spi_reset_wake(struct wl1251 *wl)
+{
+	wl1251_spi_reset(wl);
+	wl1251_spi_init(wl);
+}
+
+
 /* Set the SPI partitions to access the chip addresses
  *
  * There are two VIRTUAL (SPI) partitions (the memory partition and the
@@ -232,7 +239,8 @@ int wl1251_set_partition(struct wl1251 *wl,
 	return 0;
 }
 
-void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
+			    size_t len)
 {
 	struct spi_transfer t[3];
 	struct spi_message m;
@@ -271,7 +279,8 @@ void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len)
 	wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
 }
 
-void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
+			     size_t len)
 {
 	struct spi_transfer t[2];
 	struct spi_message m;
@@ -300,3 +309,9 @@ void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len)
 	wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
 	wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
 }
+
+const struct wl1251_if_operations wl1251_spi_ops = {
+	.read = wl1251_spi_read,
+	.write = wl1251_spi_write,
+	.reset = wl1251_spi_reset_wake,
+};
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index ca9a851..7c6da21 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -69,9 +69,6 @@
 		((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
 #define HW_ACCESS_WSPI_INIT_CMD_MASK  0
 
-/* INIT and RESET words */
-void wl1251_spi_reset(struct wl1251 *wl);
-void wl1251_spi_init(struct wl1251 *wl);
 int wl1251_set_partition(struct wl1251 *wl,
 			 u32 part_start, u32 part_size,
 			 u32 reg_start,  u32 reg_size);


^ permalink raw reply related

* [RFC PATCH v2 2/8] wl1251: separate bus i/o code into io.c
From: Kalle Valo @ 2009-07-17 18:47 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

From: Bob Copeland <me@bobcopeland.com>

In order to eventually support wl1251 spi and sdio interfaces, move
the register and memory transfer functions to a common file.  Also
rename wl1251_spi_mem_{read,write} to indicate its common usage.
We still use spi_read internally until SDIO interface is introduced
so nothing functional should change here.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---

 drivers/net/wireless/wl12xx/Makefile       |    2 -
 drivers/net/wireless/wl12xx/wl1251_acx.c   |    2 -
 drivers/net/wireless/wl12xx/wl1251_boot.c  |    2 -
 drivers/net/wireless/wl12xx/wl1251_cmd.c   |   10 ++-
 drivers/net/wireless/wl12xx/wl1251_event.c |    4 +
 drivers/net/wireless/wl12xx/wl1251_io.c    |   86 ++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_io.h    |   54 ++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_main.c  |    3 +
 drivers/net/wireless/wl12xx/wl1251_ops.c   |    6 +-
 drivers/net/wireless/wl12xx/wl1251_ps.c    |    3 +
 drivers/net/wireless/wl12xx/wl1251_rx.c    |    7 +-
 drivers/net/wireless/wl12xx/wl1251_spi.c   |   81 --------------------------
 drivers/net/wireless/wl12xx/wl1251_spi.h   |   30 ----------
 drivers/net/wireless/wl12xx/wl1251_tx.c    |   61 ++++++++++----------
 14 files changed, 192 insertions(+), 159 deletions(-)
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1251_io.h

diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index d5595a8..a978567 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,5 +1,5 @@
 wl1251-objs		= wl1251_main.o wl1251_spi.o wl1251_event.o \
 			  wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
 			  wl1251_acx.o wl1251_boot.o wl1251_init.o \
-			  wl1251_ops.o wl1251_debugfs.o
+			  wl1251_ops.o wl1251_debugfs.o wl1251_io.o
 obj-$(CONFIG_WL1251)	+= wl1251.o
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index 5a8d21c..b89fa23 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -6,7 +6,7 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
+#include "wl1251_cmd.h"
 #include "wl1251_ps.h"
 
 int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index d8a155d..5702398 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -25,7 +25,7 @@
 
 #include "reg.h"
 #include "wl1251_boot.h"
-#include "wl1251_spi.h"
+#include "wl1251_io.h"
 #include "wl1251_event.h"
 
 static void wl1251_boot_enable_interrupts(struct wl1251 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index dc04d1f..2c30c70 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -6,7 +6,7 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
+#include "wl1251_io.h"
 #include "wl1251_ps.h"
 #include "wl1251_acx.h"
 
@@ -31,7 +31,7 @@ int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len)
 
 	WARN_ON(len % 4 != 0);
 
-	wl1251_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
+	wl1251_mem_write(wl, wl->cmd_box_addr, buf, len);
 
 	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
 
@@ -86,7 +86,7 @@ int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer)
 		 * The answer would be a wl1251_command, where the
 		 * parameter array contains the actual answer.
 		 */
-		wl1251_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+		wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
 
 		cmd_answer = buf;
 
@@ -125,7 +125,7 @@ int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len)
 	}
 
 	/* the interrogate command got in, we can read the answer */
-	wl1251_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
+	wl1251_mem_read(wl, wl->cmd_box_addr, buf, len);
 
 	acx = buf;
 	if (acx->cmd.status != CMD_STATUS_SUCCESS)
@@ -379,7 +379,7 @@ int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
 	}
 
 	/* the read command got in, we can now read the answer */
-	wl1251_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+	wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
 
 	if (cmd->header.status != CMD_STATUS_SUCCESS)
 		wl1251_error("error in read command result: %d",
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c
index 1a0a0bc..1b4f8d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ b/drivers/net/wireless/wl12xx/wl1251_event.c
@@ -24,7 +24,7 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
+#include "wl1251_io.h"
 #include "wl1251_event.h"
 #include "wl1251_ps.h"
 
@@ -112,7 +112,7 @@ int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
 		return -EINVAL;
 
 	/* first we read the mbox descriptor */
-	wl1251_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+	wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
 			    sizeof(struct event_mailbox));
 
 	/* process the descriptor */
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
new file mode 100644
index 0000000..1fa2674
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -0,0 +1,86 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl1251.h"
+#include "reg.h"
+#include "wl1251_io.h"
+
+static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
+{
+	/* If the address is lower than REGISTERS_BASE, it means that this is
+	 * a chip-specific register address, so look it up in the registers
+	 * table */
+	if (addr < REGISTERS_BASE) {
+		/* Make sure we don't go over the table */
+		if (addr >= ACX_REG_TABLE_LEN) {
+			wl1251_error("address out of range (%d)", addr);
+			return -EINVAL;
+		}
+		addr = wl->chip.acx_reg_table[addr];
+	}
+
+	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
+{
+	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int physical;
+
+	physical = wl1251_translate_mem_addr(wl, addr);
+
+	wl1251_spi_read(wl, physical, buf, len);
+}
+
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int physical;
+
+	physical = wl1251_translate_mem_addr(wl, addr);
+
+	wl1251_spi_write(wl, physical, buf, len);
+}
+
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
+{
+	return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
+}
+
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
+{
+	return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
+}
+
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
new file mode 100644
index 0000000..e2bb954
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __WL1251_IO_H__
+#define __WL1251_IO_H__
+
+#include "wl1251.h"
+#include "wl1251_spi.h"
+
+/* Raw target IO, address is not translated */
+void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len);
+
+static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
+{
+	u32 response;
+
+	wl1251_spi_read(wl, addr, &response, sizeof(u32));
+
+	return response;
+}
+
+static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl1251_spi_write(wl, addr, &val, sizeof(u32));
+}
+
+/* Memory target IO, address is translated to partition 0 */
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
+/* Registers IO */
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index cf5e054..2967e19 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -35,6 +35,7 @@
 #include "wl12xx_80211.h"
 #include "reg.h"
 #include "wl1251_ops.h"
+#include "wl1251_io.h"
 #include "wl1251_spi.h"
 #include "wl1251_event.h"
 #include "wl1251_tx.h"
@@ -932,7 +933,7 @@ static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
 	if (ret < 0)
 		wl1251_error("SCAN failed");
 
-	wl1251_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+	wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
 
 	if (params->header.status != CMD_STATUS_SUCCESS) {
 		wl1251_error("TEST command answer error: %d",
diff --git a/drivers/net/wireless/wl12xx/wl1251_ops.c b/drivers/net/wireless/wl12xx/wl1251_ops.c
index 96a45f5..0c169ec 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ops.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ops.c
@@ -26,7 +26,7 @@
 
 #include "wl1251_ops.h"
 #include "reg.h"
-#include "wl1251_spi.h"
+#include "wl1251_io.h"
 #include "wl1251_boot.h"
 #include "wl1251_event.h"
 #include "wl1251_acx.h"
@@ -130,7 +130,7 @@ static int wl1251_upload_firmware(struct wl1251 *wl)
 		p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
 		wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
 			     p, addr);
-		wl1251_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+		wl1251_mem_write(wl, addr, p, CHUNK_SIZE);
 
 		chunk_num++;
 	}
@@ -140,7 +140,7 @@ static int wl1251_upload_firmware(struct wl1251 *wl)
 	p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
 	wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
 		     fw_data_len % CHUNK_SIZE, p, addr);
-	wl1251_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+	wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 68ff7f1..0581677 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -23,7 +23,8 @@
 
 #include "reg.h"
 #include "wl1251_ps.h"
-#include "wl1251_spi.h"
+#include "wl1251_cmd.h"
+#include "wl1251_io.h"
 
 #define WL1251_WAKEUP_TIMEOUT 2000
 
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index 0dbb483..af81879 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -27,8 +27,9 @@
 
 #include "wl1251.h"
 #include "reg.h"
-#include "wl1251_spi.h"
+#include "wl1251_io.h"
 #include "wl1251_rx.h"
+#include "wl1251_cmd.h"
 #include "wl1251_acx.h"
 
 static void wl1251_rx_header(struct wl1251 *wl,
@@ -40,7 +41,7 @@ static void wl1251_rx_header(struct wl1251 *wl,
 	if (wl->rx_current_buffer)
 		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
 
-	wl1251_spi_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
+	wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
 }
 
 static void wl1251_rx_status(struct wl1251 *wl,
@@ -136,7 +137,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
 	}
 
 	rx_buffer = skb_put(skb, length);
-	wl1251_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+	wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
 
 	/* The actual lenght doesn't include the target's alignment */
 	skb->len = desc->length  - PLCP_HEADER_LENGTH;
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index c2b813f..031a3ba 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -29,29 +29,6 @@
 #include "reg.h"
 #include "wl1251_spi.h"
 
-static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
-{
-	/* If the address is lower than REGISTERS_BASE, it means that this is
-	 * a chip-specific register address, so look it up in the registers
-	 * table */
-	if (addr < REGISTERS_BASE) {
-		/* Make sure we don't go over the table */
-		if (addr >= ACX_REG_TABLE_LEN) {
-			wl1251_error("address out of range (%d)", addr);
-			return -EINVAL;
-		}
-		addr = wl->chip.acx_reg_table[addr];
-	}
-
-	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
-{
-	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
-}
-
-
 void wl1251_spi_reset(struct wl1251 *wl)
 {
 	u8 *cmd;
@@ -323,61 +300,3 @@ void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len)
 	wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
 	wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
 }
-
-void wl1251_spi_mem_read(struct wl1251 *wl, int addr, void *buf,
-			 size_t len)
-{
-	int physical;
-
-	physical = wl1251_translate_mem_addr(wl, addr);
-
-	wl1251_spi_read(wl, physical, buf, len);
-}
-
-void wl1251_spi_mem_write(struct wl1251 *wl, int addr, void *buf,
-			  size_t len)
-{
-	int physical;
-
-	physical = wl1251_translate_mem_addr(wl, addr);
-
-	wl1251_spi_write(wl, physical, buf, len);
-}
-
-void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
-	int physical;
-
-	physical = wl1251_translate_reg_addr(wl, addr);
-
-	wl1251_spi_read(wl, physical, buf, len);
-}
-
-void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
-	int physical;
-
-	physical = wl1251_translate_reg_addr(wl, addr);
-
-	wl1251_spi_write(wl, physical, buf, len);
-}
-
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
-{
-	return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
-}
-
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
-{
-	wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
-}
-
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
-{
-	return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
-}
-
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
-{
-	wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index 7076352..ca9a851 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -69,23 +69,6 @@
 		((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
 #define HW_ACCESS_WSPI_INIT_CMD_MASK  0
 
-
-/* Raw target IO, address is not translated */
-void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-
-/* Memory target IO, address is tranlated to partition 0 */
-void wl1251_spi_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_spi_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
-
-/* Registers IO */
-void wl1251_spi_reg_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_spi_reg_write(struct wl1251 *wl, int addr, void *buf, size_t len);
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
-
 /* INIT and RESET words */
 void wl1251_spi_reset(struct wl1251 *wl);
 void wl1251_spi_init(struct wl1251 *wl);
@@ -93,17 +76,4 @@ int wl1251_set_partition(struct wl1251 *wl,
 			 u32 part_start, u32 part_size,
 			 u32 reg_start,  u32 reg_size);
 
-static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
-{
-	wl1251_spi_read(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
-
-	return wl->buffer_32;
-}
-
-static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
-{
-	wl->buffer_32 = val;
-	wl1251_spi_write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
-}
-
 #endif /* __WL1251_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index 2652a22..7ddc9a3 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -30,6 +30,7 @@
 #include "wl1251_spi.h"
 #include "wl1251_tx.h"
 #include "wl1251_ps.h"
+#include "wl1251_io.h"
 
 static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
 {
@@ -235,7 +236,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
 	else
 		addr = wl->data_path->tx_packet_ring_addr;
 
-	wl1251_spi_mem_write(wl, addr, skb->data, len);
+	wl1251_mem_write(wl, addr, skb->data, len);
 
 	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
 		     tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
@@ -451,7 +452,7 @@ void wl1251_tx_complete(struct wl1251 *wl)
 		return;
 
 	/* First we read the result */
-	wl1251_spi_mem_read(wl, wl->data_path->tx_complete_addr,
+	wl1251_mem_read(wl, wl->data_path->tx_complete_addr,
 			    result, sizeof(result));
 
 	result_index = wl->next_tx_complete;
@@ -482,41 +483,41 @@ void wl1251_tx_complete(struct wl1251 *wl)
 		 */
 		if (result_index > wl->next_tx_complete) {
 			/* Only 1 write is needed */
-			wl1251_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr +
-					     (wl->next_tx_complete *
-					      sizeof(struct tx_result)),
-					     &result[wl->next_tx_complete],
-					     num_complete *
-					     sizeof(struct tx_result));
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr +
+					 (wl->next_tx_complete *
+					  sizeof(struct tx_result)),
+					 &result[wl->next_tx_complete],
+					 num_complete *
+					 sizeof(struct tx_result));
 
 
 		} else if (result_index < wl->next_tx_complete) {
 			/* 2 writes are needed */
-			wl1251_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr +
-					     (wl->next_tx_complete *
-					      sizeof(struct tx_result)),
-					     &result[wl->next_tx_complete],
-					     (FW_TX_CMPLT_BLOCK_SIZE -
-					      wl->next_tx_complete) *
-					     sizeof(struct tx_result));
-
-			wl1251_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr,
-					     result,
-					     (num_complete -
-					      FW_TX_CMPLT_BLOCK_SIZE +
-					      wl->next_tx_complete) *
-					     sizeof(struct tx_result));
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr +
+					 (wl->next_tx_complete *
+					  sizeof(struct tx_result)),
+					 &result[wl->next_tx_complete],
+					 (FW_TX_CMPLT_BLOCK_SIZE -
+					  wl->next_tx_complete) *
+					 sizeof(struct tx_result));
+
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr,
+					 result,
+					 (num_complete -
+					  FW_TX_CMPLT_BLOCK_SIZE +
+					  wl->next_tx_complete) *
+					 sizeof(struct tx_result));
 
 		} else {
 			/* We have to write the whole array */
-			wl1251_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr,
-					     result,
-					     FW_TX_CMPLT_BLOCK_SIZE *
-					     sizeof(struct tx_result));
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr,
+					 result,
+					 FW_TX_CMPLT_BLOCK_SIZE *
+					 sizeof(struct tx_result));
 		}
 
 	}


^ permalink raw reply related

* Re: [RFC PATCH v2 0/8] wl1251 sdio interface
From: Kalle Valo @ 2009-07-17 19:04 UTC (permalink / raw)
  To: Bob Copeland; +Cc: linux-wireless
In-Reply-To: <20090717184643.25883.95065.stgit@tikku>

Kalle Valo <kalle.valo@iki.fi> writes:

> Here is v2 of Bob's wl1251 sdio patches. I have now rebased them on
> top of wl1251/wl1271 split patches. Only compile-tested because I
> don't have working test setup right now (neither spi or sdio), but I
> should have access to one in two weeks.

I forgot to mention that wl1251 most probably is still broken regards to
bssid handling. I will fix this after my (current) vacation, unless
someone else is faster. To get wl1251 temporarily working, this patch
must be reverted:

    commit cc3ec8cb518534c1c593e5f2682710d33c903627
    Author: Johannes Berg <johannes@sipsolutions.net>
    Date:   Thu May 14 13:10:14 2009 +0200

    mac80211: fix managed mode BSSID handling
    
    Currently, we will ask the driver to configure right away
    when somebody changes the desired BSSID. That's totally
    strange because then we will configure the driver without
    even knowing whether the BSS exists. Change this to only
    configure the BSSID when associated, and configure a zero
    BSSID when not associated.

Oddly enough I can't find this patch anymore in wireless-testing, I
could only find a revert. I don't know what happened to it.

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC PATCH v2 0/8] wl1251 sdio interface
From: Bob Copeland @ 2009-07-17 19:20 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless
In-Reply-To: <87r5wfp1v4.fsf@litku.valot.fi>

On Fri, 17 Jul 2009 22:04:47 +0300, Kalle Valo wrote
> Kalle Valo <kalle.valo@iki.fi> writes:
> I forgot to mention that wl1251 most probably is still broken regards to
> bssid handling. I will fix this after my (current) vacation, unless
> someone else is faster. To get wl1251 temporarily working, this patch
> must be reverted:

Thanks Kalle, 

I'll take a look at doing this conversion too.

-- 
Bob Copeland %% www.bobcopeland.com



^ permalink raw reply

* [PATCH] rt2x00: Comment spellchecking
From: Ivo van Doorn @ 2009-07-17 19:39 UTC (permalink / raw)
  To: John Linville, linux-wireless, users

From: Luis Correia <luis.f.correia@gmail.com>

Fix a bunch of spelling errors in the rt2x00 drivers

Signed-off-by: Luis Correia <luis.f.correia@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index ec3b004..ccd6441 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -928,7 +928,7 @@
 #define RXD_W7_RESERVED			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  * NOTE: Logics in rt2400pci for txpower are reversed
  * compared to the other rt2x00 drivers. A higher txpower
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index ce2f065..54d3795 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1218,7 +1218,7 @@
 #define RXD_W10_DROP			FIELD32(0x00000001)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 5bc46fe..b01edca 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -831,7 +831,7 @@
 #define RXD_W3_EIV			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index a204e66..d356de4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1910,7 +1910,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 		/*
 		 * Before the radio can be enabled, the device first has
 		 * to be woken up. After that it needs a bit of time
-		 * to be fully awake and the radio can be enabled.
+		 * to be fully awake and then the radio can be enabled.
 		 */
 		rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
 		msleep(1);
@@ -1918,7 +1918,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 		break;
 	case STATE_RADIO_OFF:
 		/*
-		 * After the radio has been disablee, the device should
+		 * After the radio has been disabled, the device should
 		 * be put to sleep for powersaving.
 		 */
 		rt2800usb_disable_radio(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 61a8be6..2d9dc37 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -1921,7 +1921,7 @@ struct mac_iveiv_entry {
 #define RXWI_W3_SNR1			FIELD32(0x0000ff00)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_G_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index de3f13a..2abb085 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -251,7 +251,7 @@ struct link_ant {
 	struct antenna_setup active;
 
 	/*
-	 * RSSI information for the different antenna's.
+	 * RSSI information for the different antennas.
 	 * These statistics are used to determine when
 	 * to switch antenna when using software diversity.
 	 *
@@ -640,7 +640,7 @@ struct rt2x00_dev {
 	 * The structure stored in here depends on the
 	 * system bus (PCI or USB).
 	 * When accessing this variable, the rt2x00dev_{pci,usb}
-	 * macro's should be used for correct typecasting.
+	 * macros should be used for correct typecasting.
 	 */
 	struct device *dev;
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 3e019a1..c6e0bcf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -132,7 +132,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Failsafe: Make sure we are not sending the
 	 * ANTENNA_SW_DIVERSITY state to the driver.
-	 * If that happes fallback to hardware default,
+	 * If that happens, fallback to hardware defaults,
 	 * or our own default.
 	 * The calls to rt2x00lib_config_antenna_check()
 	 * might have caused that we restore back to the already
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index c54eda3..30fbd3b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -129,7 +129,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
 	/* Pull buffer to correct size */
 	skb_pull(skb, txdesc->iv_len);
 
-	/* IV/EIV data has officially be stripped */
+	/* IV/EIV data has officially been stripped */
 	skbdesc->flags |= SKBDESC_IV_STRIPPED;
 }
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index eb9b981..3257075 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -158,7 +158,7 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
 
 	/*
 	 * During the last period we have sampled the RSSI
-	 * from both antenna's. It now is time to determine
+	 * from both antennas. It now is time to determine
 	 * which antenna demonstrated the best performance.
 	 * When we are already on the antenna with the best
 	 * performance, then there really is nothing for us
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b7e0ddd..54fd2e8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -341,7 +341,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 	int status;
 
 	/*
-	 * Mac80211 might be calling this function while we are trying
+	 * mac80211 might be calling this function while we are trying
 	 * to remove the device or perhaps suspending it.
 	 */
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
@@ -577,7 +577,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 	int update_bssid = 0;
 
 	/*
-	 * Mac80211 might be calling this function while we are trying
+	 * mac80211 might be calling this function while we are trying
 	 * to remove the device or perhaps suspending it.
 	 */
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index b5e0634..47d175a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -29,7 +29,7 @@
 #include <linux/prefetch.h>
 
 /**
- * DOC: Entrie frame size
+ * DOC: Entry frame size
  *
  * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes,
  * for USB devices this restriction does not apply, but the value of
@@ -45,13 +45,13 @@
 /**
  * DOC: Number of entries per queue
  *
- * Under normal load without fragmentation 12 entries are sufficient
+ * Under normal load without fragmentation, 12 entries are sufficient
  * without the queue being filled up to the maximum. When using fragmentation
- * and the queue threshold code we need to add some additional margins to
+ * and the queue threshold code, we need to add some additional margins to
  * make sure the queue will never (or only under extreme load) fill up
  * completely.
- * Since we don't use preallocated DMA having a large number of queue entries
- * will have only minimal impact on the memory requirements for the queue.
+ * Since we don't use preallocated DMA, having a large number of queue entries
+ * will have minimal impact on the memory requirements for the queue.
  */
 #define RX_ENTRIES	24
 #define TX_ENTRIES	24
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 861322d..983e52e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -176,8 +176,8 @@ struct rt2x00_field32 {
 #define is_valid_mask(x)	is_power_of_two(1LU + (x) + low_bit_mask(x))
 
 /*
- * Macro's to find first set bit in a variable.
- * These macro's behaves the same as the __ffs() function with
+ * Macros to find first set bit in a variable.
+ * These macros behave the same as the __ffs() functions but
  * the most important difference that this is done during
  * compile-time rather then run-time.
  */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 8a49d99..4bbbd13 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2312,7 +2312,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	}
 
 	/*
-	 * Determine number of antenna's.
+	 * Determine number of antennas.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
 		__set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6c71f77..93eb699 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1476,7 +1476,7 @@ struct hw_pairwise_ta_entry {
 #define RXD_W15_RESERVED		FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index c8016f6..81fe0be 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -809,7 +809,7 @@ struct hw_pairwise_ta_entry {
 
 /*
  * EEPROM antenna.
- * ANTENNA_NUM: Number of antenna's.
+ * ANTENNA_NUM: Number of antennas.
  * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
  * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
  * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only.
@@ -1058,7 +1058,7 @@ struct hw_pairwise_ta_entry {
 #define RXD_W5_RESERVED			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0

^ permalink raw reply related

* Setting rfkill from user space
From: Tim Gardner @ 2009-07-17 20:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org

Johannes,

Because the rfkill sysfs info moved around, I've been working on a
program for the Debian acpi-support package that can be used to perform
2 operations; 1) discover if there are any wireless devices powered on,
and 2) toggle the states of all wireless devices (at the same time).

git://kernel.ubuntu.com/rtg/rfkill

I'm a bit confused about what idx is in the event structure. Other then
ascending (though not monotonically), idx appears to have no real value
to user space. I see in the rfkill driver where its being assigned, and
it appears to be an rfkill instance number that describes a relationship
to a device. For example:

Here is the output before toggling and right after a boot:

rtg@xps1330:~$ ./rfkill
bluetooth 0 UNBLOCKED soft:0 hard:0
wlan 1 UNBLOCKED soft:0 hard:0
bluetooth 2 UNBLOCKED soft:0 hard:0
wlan 3 UNBLOCKED soft:0 hard:0
UNBLOCKED

After toggling to BLOCKED:

rtg@xps1330:~$ sudo ./rfkill 1
[sudo] password for rtg:
rtg@xps1330:~$ ./rfkill
wlan 1 SOFT_BLOCKED soft:1 hard:0
bluetooth 2 SOFT_BLOCKED soft:1 hard:0
wlan 3 HARD_BLOCKED soft:1 hard:1
BLOCKED

After toggling to UNBLOCKED:

rtg@xps1330:~$ sudo ./rfkill 0
rtg@xps1330:~$ ./rfkill
wlan 1 HARD_BLOCKED soft:0 hard:1
bluetooth 2 HARD_BLOCKED soft:0 hard:1
wlan 3 UNBLOCKED soft:0 hard:0
bluetooth 4 UNBLOCKED soft:0 hard:0
UNBLOCKED

This laptop only has one wlan and one bluetooth device. Why the extra
index values?

rtg
-- 
Tim Gardner tim.gardner@canonical.com

^ permalink raw reply

* Re: SDIO Stack and Device Support
From: Robert Emanuele @ 2009-07-17 23:20 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-kernel, linux-wireless
In-Reply-To: <4A604246.5060204@gmail.com>

This support for these wireless chips in the mainline kernel is great.
 Originally I was looking at wireless SDIO cards from Spectec and
Silex.  What manufacturers use the libertas/Marvell chipsets in SDIO
Cards?  (or are they only available as modules?)

Thank you,

Rob

On Fri, Jul 17, 2009 at 2:20 AM, Jonathan
Cameron<Jonathan.Cameron@gmail.com> wrote:
> Robert Emanuele wrote:
>> Greetings all,
>>
>> I'm trying to find out more information about the status of an SDIO
>> stack and SDIO devices in the kernel.  I see under drivers/mmc/ some
>> SDIO support.
>>
>> I'm evaluating the potential of getting a Wireless SDIO card to work
>> with the 2.6 kernel.  So far all I see in the kernel is support for an
>> SDIO UART.  There is a patch on sourceforge for an SDIO stack and
>> drivers from Atheros but that is for 2.6.18.  Is there current support
>> for other SDIO wireless devices in the kernel?
>>
> There is pretty good support for the Marvell chips (sd8686 etc) in the
> mainline
> kernel. Take a look under drivers/net/wireless/libertas/
>
> I've also copied in the linux-wireless list.
>
>
>
>
>
>

^ permalink raw reply

* Using compat-wireless w/ 2.6.27.26
From: Philip A. Prindeville @ 2009-07-18  1:27 UTC (permalink / raw)
  To: linux-wireless

I'm the lead developer on the Astlinux project, which I might have
mentioned in a previous posting.  This means that I have my hands in
many pots, so I'm not an expert in the latest Linux kernel changes... be
patient with me.  Hard to keep track of 200+ individual projects.

I'm building 2.6.26.27 as I said for (amongst other things) an Alix 2D3
(GeodeLX) with EMP-8602 (AR-5413) as a test platform.

My kernel gets built with:

#
# Wireless
#
CONFIG_CFG80211=m
CONFIG_NL80211=y
CONFIG_WIRELESS_EXT=y
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_MAC80211=m

#
# Rate control algorithm selection
#
CONFIG_MAC80211_RC_PID=y
CONFIG_MAC80211_RC_DEFAULT_PID=y
CONFIG_MAC80211_RC_DEFAULT="pid"
# CONFIG_MAC80211_MESH is not set
CONFIG_MAC80211_LEDS=y
# CONFIG_MAC80211_DEBUG_MENU is not set
# CONFIG_IEEE80211 is not set
CONFIG_RFKILL=m
CONFIG_RFKILL_INPUT=m
CONFIG_RFKILL_LEDS=y
# CONFIG_NET_9P is not set


I build compat-wireless-2.6.30 into /lib/modules/2.6.27.26-astlinux/kernel/... as a Kbuild.

The system also has iw-0.9.15 and hostapd-0.6.9.

All of this is fairly straightforward.

On boot, our /etc/init.d scripts do the following:

+ modprobe ath5k
ath5k phy0: Atheros AR5413 chip found (MAC: 0xa4, PHY: 0x61)

+ iw dev wlan0 interface add ap0 type managed
+ ip link set ap0 up
+ iw dev ap0 connect xxxx
command failed: Operation not supported (-95)



So doing some sanity checks by hand I get:

pbx ~ # lsmod | head
Module                  Size  Used by
ath5k                 104772  0 
mac80211              153304  1 ath5k
cfg80211               54584  2 ath5k,mac80211
binfmt_misc             7112  1 
aes_i586                7456  0 
aes_generic            28968  1 aes_i586
lm90                   11944  0 
hwmon                   2324  1 lm90
scx200_acb              4356  0 
pbx ~ # iw dev ap0 info
Interface ap0
	ifindex 9
	type managed
pbx ~ # iw phy phy0 info
command failed: No buffer space available (-105)
pbx ~ # 


Not sure why the "phy ... info" command fails.

pbx ~ # hostapd -v
hostapd v0.6.9
User space daemon for IEEE 802.11 AP management,
IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> and contributors
pbx ~ # cat /etc/hostapd.conf
# automatically generated. do not edit!

logger_syslog=-1
logger_syslog_level=2
logger_stdout=--1
logger_stdout_level=2

debug=0

ctrl_interface_group=0

# should this be per-ssid?
macaddr_acl=0

dump_file=/tmp/hostapd.dump

# should this be an option?
hw_mode=b

bridge=br1
interface=ap0
driver=nl80211
ssid=xxxxx
channel=0

auth_algs=1

wpa_passphrase=yyyyy
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

ignore_broadcast_ssid=1

wpa_strict_rekey=1
wpa_group_rekey=600
wpa_gmk_rekey=14400

pbx ~ # ip link show ap0
9: ap0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
    link/ether 00:02:6f:5a:d2:2b brd ff:ff:ff:ff:ff:ff
pbx ~ # brctl show
bridge name	bridge id		STP enabled	interfaces
br1		8000.00026f5ad22b	no		ap0
							eth0
pbx ~ # 
pbx ~ # hostapd -dddd -P /var/run/hostapd.pid /etc/hostapd.conf
Configuration file: /etc/hostapd.conf
Line 8: DEPRECATED: 'debug' configuration variable is not used anymore
ctrl_interface_group=0
Failed to set interface ap0 to master mode.
nl80211 driver initialization failed.
ap0: Unable to setup interface.
ELOOP: remaining socket: sock=5 eloop_data=0x8098028 user_data=(nil) handler=0x806f503
pbx ~ # 
pbx ~ # ldd /usr/bin/hostapd
	libnl.so.1 => /usr/lib/libnl.so.1 (0xb7f04000)
	libcrypto.so.0.9.8 => /lib/libcrypto.so.0.9.8 (0xb7df8000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7def000)
	libc.so.0 => /lib/libc.so.0 (0xb7da5000)
	libm.so.0 => /lib/libm.so.0 (0xb7d97000)
	libdl.so.0 => /lib/libdl.so.0 (0xb7d94000)
	ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0xb7f3d000)
pbx ~ # 


And on the host that this was cross-compiled:

[philipp@builder ~/kernel]$ cat build_i586/hostapd-0.6.9/hostapd/.config 
CFLAGS+=-Os -Wall -Os -pipe -fomit-frame-pointer -march=k6-2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels 
CFLAGS+= -DUSE_KERNEL_HEADERS -I/home/philipp/kernel/build_i586/linux-2.6.27.26-astlinux/include
CONFIG_IEEE80211N=y
CONFIG_DRIVER_NL80211=y
CFLAGS+=-I/home/philipp/kernel/build_i586/staging_dir/usr/include
LIBS+=-L/home/philipp/kernel/build_i586/root/usr/lib
CONFIG_DRIVER_NONE=y
CONFIG_DRIVER_WIRED=y
CONFIG_IAPP=y
CONFIG_RSN_PREAUTH=y
CONFIG_PEERKEY=y
CONFIG_EAP=y
CONFIG_EAP_MD5=y
CONFIG_EAP_MSCHAPV2=y
CONFIG_EAP_GTC=y
CONFIG_EAP_SIM=y
CONFIG_EAP_AKA=y
CONFIG_EAP_AKA_PRIME=y
CONFIG_EAP_PAX=y
CONFIG_EAP_PSK=y
CONFIG_EAP_SAKE=y
CONFIG_EAP_GPSK=y
CONFIG_EAP_GPSK_SHA256=y
CONFIG_EAP_IKEV2=y
CONFIG_PKCS12=y
CONFIG_IPV6=y
CONFIG_IEEE80211R=y
CONFIG_IEEE80211N=y
[philipp@builder ~/kernel]$ 



What am I missing?

How should I go about debugging this?

Thanks,

-Philip



^ permalink raw reply

* Re: [RFC PATCH v2 0/8] wl1251 sdio interface
From: Bob Copeland @ 2009-07-18  5:32 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless
In-Reply-To: <87r5wfp1v4.fsf@litku.valot.fi>

On Fri, Jul 17, 2009 at 10:04:47PM +0300, Kalle Valo wrote:
> Kalle Valo <kalle.valo@iki.fi> writes:
> 
> > Here is v2 of Bob's wl1251 sdio patches. I have now rebased them on
> > top of wl1251/wl1271 split patches. Only compile-tested because I
> > don't have working test setup right now (neither spi or sdio), but I
> > should have access to one in two weeks.

Ok, my first tests with this have mixed results -- wpa_supplicant
didn't associate, but I could do a scan.  There were a few sdio
transfer errors.  So I'll try going back to the earlier version and see
how they compare.

Meanwhile, this patch (or something like it) would be good:

>From 742f257a955fa9e637f7bcb62a73a110718fb247 Mon Sep 17 00:00:00 2001
From: Bob Copeland <me@bobcopeland.com>
Date: Fri, 17 Jul 2009 23:53:15 -0400
Subject: [PATCH] wl12xx: make irq handling interface specific

Due to the differences in interrupt handling between SPI and SDIO, the
relevant code needs to be interface specific.  This patch pushes
the irq code down into _spi.c and _sdio.c, and adds enable/disable
callbacks (no-ops for the SDIO case, but not needed there).

This fixes the following warning:

[  566.343887] ------------[ cut here ]------------
[  566.349105] WARNING: at kernel/irq/manage.c:222 __enable_irq+0x3c/0x6c()
[  566.356735] Unbalanced enable for IRQ 0
[  566.361099] Modules linked in: msm_wifi wl12xx_sdio wl12xx mac80211 cfg80211 rfkill_backport lib80211_crypt_ccmp lib80211_crypt_wep lib80211_crypt_tkip lib80211
[  566.381240] [<c025acec>] (dump_stack+0x0/0x14) from [<c004b610>] (warn_slowpath+0x70/0x8c)
[  566.391860] [<c004b5a0>] (warn_slowpath+0x0/0x8c) from [<c0077c10>] (__enable_irq+0x3c/0x6c)
[  566.402572]  r3:00000000 r2:c02cad13
[  566.407516]  r7:00001002 r6:00000000 r5:c0310be4 r4:c0310be4
[  566.415786] [<c0077bd4>] (__enable_irq+0x0/0x6c) from [<c0077fd0>] (enable_irq+0x38/0x64)
[  566.425826]  r5:c0310be4 r4:a0000013
[  566.430709] [<c0077f98>] (enable_irq+0x0/0x64) from [<bf0dfa78>] (wl12xx_boot_run_firmware+0xfc/0x170 [wl12xx])
[  566.442947]  r7:00001002 r6:c440a9fc r5:00000072 r4:c440a9e0
[  566.450851] [<bf0df97c>] (wl12xx_boot_run_firmware+0x0/0x170 [wl12xx]) from [<bf0e05f0>] (wl1251_boot+0xd4/0x108 [wl12xx])
[  566.464492]  r5:00000000 r4:c440a9e0
[  566.469466] [<bf0e051c>] (wl1251_boot+0x0/0x108 [wl12xx]) from [<bf0dd27c>] (wl12xx_op_start+0x54/0xb8 [wl12xx])
[  566.482162]  r5:00000000 r4:c440a9e0
[  566.487472] [<bf0dd228>] (wl12xx_op_start+0x0/0xb8 [wl12xx]) from [<bf0b96dc>] (ieee80211_open+0x2dc/0x720 [mac80211])
[  566.500594]  r7:00001002 r6:c4950800 r5:c440a220 r4:00000000
[  566.508865] [<bf0b9400>] (ieee80211_open+0x0/0x720 [mac80211]) from [<c01f1edc>] (dev_open+0x9c/0xfc)
[  566.520705] [<c01f1e40>] (dev_open+0x0/0xfc) from [<c01f17dc>] (dev_change_flags+0x98/0x170)
[  566.531417]  r5:00000041 r4:c4950800
[  566.536330] [<c01f1744>] (dev_change_flags+0x0/0x170) from [<c023041c>] (devinet_ioctl+0x3a8/0x784)
[  566.547683]  r7:c128e380 r6:00000001 r5:00008914 r4:00000000
[  566.555587] [<c0230074>] (devinet_ioctl+0x0/0x784) from [<c02318cc>] (inet_ioctl+0xdc/0x114)
[  566.566299] [<c02317f0>] (inet_ioctl+0x0/0x114) from [<c01e1a60>] (sock_ioctl+0x1f0/0x248)
[  566.576827]  r5:00008914 r4:c572c1a0
[  566.581771] [<c01e1870>] (sock_ioctl+0x0/0x248) from [<c00b23a0>] (vfs_ioctl+0x34/0x94)
[  566.592086]  r7:c572c1a0 r6:bee497e8 r5:00008914 r4:c572c1a0
[  566.599990] [<c00b236c>] (vfs_ioctl+0x0/0x94) from [<c00b2a28>] (do_vfs_ioctl+0x52c/0x584)
[  566.610549]  r7:c572c1a0 r6:00008914 r5:c572c1a0 r4:c3201228
[  566.618453] [<c00b24fc>] (do_vfs_ioctl+0x0/0x584) from [<c00b2ac0>] (sys_ioctl+0x40/0x64)
[  566.628890] [<c00b2a80>] (sys_ioctl+0x0/0x64) from [<c0021da0>] (ret_fast_syscall+0x0/0x2c)
[  566.639541]  r7:00000036 r6:00000000 r5:00000004 r4:001a11f3
[  566.647445] ---[ end trace 15c26ef7dd5e7b03 ]---

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 drivers/net/wireless/wl12xx/wl1251.h      |    5 ++++-
 drivers/net/wireless/wl12xx/wl1251_boot.c |    7 +------
 drivers/net/wireless/wl12xx/wl1251_main.c |   26 +++++++++-----------------
 drivers/net/wireless/wl12xx/wl1251_sdio.c |    7 ++++++-
 drivers/net/wireless/wl12xx/wl1251_spi.c  |   17 +++++++++++++++++
 5 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index ebe2c70..20d77fe 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -295,6 +295,8 @@ struct wl1251 {
 	const struct wl1251_if_operations *if_ops;
 
 	void (*set_power)(bool enable);
+	void (*enable_irq)(int irq);
+	void (*disable_irq)(int irq);
 	int irq;
 
 	enum wl1251_state state;
@@ -404,10 +406,11 @@ struct wl1251 {
 int wl1251_plt_start(struct wl1251 *wl);
 int wl1251_plt_stop(struct wl1251 *wl);
 
-irqreturn_t wl1251_irq(int irq, void *cookie);
 struct ieee80211_hw *wl1251_alloc_hw(void);
 int wl1251_free_hw(struct wl1251 *wl);
 int wl1251_init_ieee80211(struct wl1251 *wl);
+void wl1251_enable_interrupts(struct wl1251 *wl);
+void wl1251_disable_interrupts(struct wl1251 *wl);
 
 #define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
 #define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 5c6f327..8b50d44 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -29,11 +29,6 @@
 #include "wl1251_spi.h"
 #include "wl1251_event.h"
 
-static void wl1251_boot_enable_interrupts(struct wl1251 *wl)
-{
-	enable_irq(wl->irq);
-}
-
 void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
 {
 	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
@@ -278,7 +273,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
 	 */
 
 	/* enable gpio interrupts */
-	wl1251_boot_enable_interrupts(wl);
+	wl1251_enable_interrupts(wl);
 
 	wl->chip.op_target_enable_interrupts(wl);
 
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index c5c94b2..094247c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -42,9 +42,16 @@
 #include "wl1251_init.h"
 #include "wl1251_debugfs.h"
 
-static void wl1251_disable_interrupts(struct wl1251 *wl)
+void wl1251_enable_interrupts(struct wl1251 *wl)
 {
-	disable_irq(wl->irq);
+	if (wl->enable_irq)
+		wl->enable_irq(wl->irq);
+}
+
+void wl1251_disable_interrupts(struct wl1251 *wl)
+{
+	if (wl->disable_irq)
+		wl->disable_irq(wl->irq);
 }
 
 static void wl1251_power_off(struct wl1251 *wl)
@@ -57,20 +64,6 @@ static void wl1251_power_on(struct wl1251 *wl)
 	wl->set_power(true);
 }
 
-irqreturn_t wl1251_irq(int irq, void *cookie)
-{
-	struct wl1251 *wl;
-
-	wl1251_debug(DEBUG_IRQ, "IRQ");
-
-	wl = cookie;
-
-	schedule_work(&wl->irq_work);
-
-	return IRQ_HANDLED;
-}
-EXPORT_SYMBOL_GPL(wl1251_irq);
-
 static int wl1251_fetch_firmware(struct wl1251 *wl)
 {
 	const struct firmware *fw;
@@ -1335,7 +1328,6 @@ int wl1251_free_hw(struct wl1251 *wl)
 
 	wl1251_debugfs_exit(wl);
 
-	free_irq(wl->irq, wl);
 	kfree(wl->target_mem_map);
 	kfree(wl->data_path);
 	kfree(wl->fw);
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index f1d9e76..66961e3 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -50,7 +50,12 @@ static struct sdio_func *wl_to_func(struct wl1251 *wl)
 
 static void wl1251_sdio_interrupt(struct sdio_func *func)
 {
-	wl1251_irq(0, sdio_get_drvdata(func));
+	struct wl1251 *wl = sdio_get_drvdata(func);
+
+	wl1251_debug(DEBUG_IRQ, "IRQ");
+
+	/* FIXME should be synchronous for sdio */
+	schedule_work(&wl->irq_work);
 }
 
 static const struct sdio_device_id wl1251_devices[] = {
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 464b802..a835d56 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -31,6 +31,19 @@
 #include "reg.h"
 #include "wl1251_spi.h"
 
+static irqreturn_t wl1251_irq(int irq, void *cookie)
+{
+	struct wl1251 *wl;
+
+	wl1251_debug(DEBUG_IRQ, "IRQ");
+
+	wl = cookie;
+
+	schedule_work(&wl->irq_work);
+
+	return IRQ_HANDLED;
+}
+
 static struct spi_device *wl_to_spi(struct wl1251 *wl)
 {
 	return wl->if_priv;
@@ -255,6 +268,9 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
 
 	disable_irq(wl->irq);
 
+	wl->enable_irq = enable_irq;
+	wl->disable_irq = disable_irq;
+
 	ret = wl1251_init_ieee80211(wl);
 	if (ret)
 		goto out_irq;
@@ -274,6 +290,7 @@ static int __devexit wl1251_spi_remove(struct spi_device *spi)
 {
 	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
 
+	free_irq(wl->irq, wl);
 	wl1251_free_hw(wl);
 
 	return 0;
-- 
1.6.2.5


-- 
Bob Copeland %% www.bobcopeland.com


^ permalink raw reply related

* Re: Setting rfkill from user space
From: Johannes Berg @ 2009-07-18  9:57 UTC (permalink / raw)
  To: tim.gardner; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <4A60E5EC.1080700@canonical.com>

[-- Attachment #1: Type: text/plain, Size: 2713 bytes --]

On Fri, 2009-07-17 at 14:58 -0600, Tim Gardner wrote:
> Johannes,
> 
> Because the rfkill sysfs info moved around, I've been working on a
> program for the Debian acpi-support package that can be used to perform
> 2 operations; 1) discover if there are any wireless devices powered on,
> and 2) toggle the states of all wireless devices (at the same time).
> 
> git://kernel.ubuntu.com/rtg/rfkill

Oh, I'm sorry, we already had http://git.sipsolutions.net/rfkill.git/, I
really should have publicised that more (and wasn't around when you
asked the question yesterday).

> I'm a bit confused about what idx is in the event structure. Other then
> ascending (though not monotonically), idx appears to have no real value
> to user space. I see in the rfkill driver where its being assigned, and
> it appears to be an rfkill instance number that describes a relationship
> to a device. For example:

Well, the index is just a unique identifier for each rfkill instance,
like the network interface index for instance. Yes, it doesn't really
have any value, but if you hot-plug rfkill instances (e.g. with a USB
wireless device) then you may want to know it's now a new instance.

> Here is the output before toggling and right after a boot:
> 
> rtg@xps1330:~$ ./rfkill
> bluetooth 0 UNBLOCKED soft:0 hard:0
> wlan 1 UNBLOCKED soft:0 hard:0
> bluetooth 2 UNBLOCKED soft:0 hard:0
> wlan 3 UNBLOCKED soft:0 hard:0
> UNBLOCKED
> 
> After toggling to BLOCKED:
> 
> rtg@xps1330:~$ sudo ./rfkill 1
> [sudo] password for rtg:
> rtg@xps1330:~$ ./rfkill
> wlan 1 SOFT_BLOCKED soft:1 hard:0
> bluetooth 2 SOFT_BLOCKED soft:1 hard:0
> wlan 3 HARD_BLOCKED soft:1 hard:1
> BLOCKED
> 
> After toggling to UNBLOCKED:
> 
> rtg@xps1330:~$ sudo ./rfkill 0
> rtg@xps1330:~$ ./rfkill
> wlan 1 HARD_BLOCKED soft:0 hard:1
> bluetooth 2 HARD_BLOCKED soft:0 hard:1
> wlan 3 UNBLOCKED soft:0 hard:0
> bluetooth 4 UNBLOCKED soft:0 hard:0
> UNBLOCKED
> 
> This laptop only has one wlan and one bluetooth device. Why the extra
> index values?

You mean, why the extra wlan? Well, if you poke sysfs (which our tool
does) you'll notice that you have different instances, in my case (no
laptop wireless button):

# ./rfkill list
11: hci0: Bluetooth
	Soft blocked: no
	Hard blocked: no
12: phy3: Wireless LAN
	Soft blocked: no
	Hard blocked: no

So I have 'hci0' and 'phy3', which is a cfg80211 device. You will,
additionally, have something like 'acer-wireless' or 'hp-wireless' or
whatever, which is the platform's rfkill.

That's also why you see 'hard blocked' in your case, because your
platform's soft-block is wired up to your wireless card's hard block.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Setting rfkill from user space
From: Marcel Holtmann @ 2009-07-18 10:11 UTC (permalink / raw)
  To: Johannes Berg; +Cc: tim.gardner, linux-wireless@vger.kernel.org
In-Reply-To: <1247911044.1055.22.camel@johannes.local>

Hi Johannes,

> > Because the rfkill sysfs info moved around, I've been working on a
> > program for the Debian acpi-support package that can be used to perform
> > 2 operations; 1) discover if there are any wireless devices powered on,
> > and 2) toggle the states of all wireless devices (at the same time).
> > 
> > git://kernel.ubuntu.com/rtg/rfkill
> 
> Oh, I'm sorry, we already had http://git.sipsolutions.net/rfkill.git/, I
> really should have publicised that more (and wasn't around when you
> asked the question yesterday).

I saw this post yesterday, but didn't realize they wrote their own tool.

Regards

Marcel



^ permalink raw reply

* Re: Generic events for wake up from S1-S4
From: Pavel Machek @ 2009-07-18 10:37 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Rafael J. Wysocki, linux-kernel, Johannes Berg, John W. Linville,
	Jouni Malinen, linux-wireless, Stephen Chen
In-Reply-To: <43e72e890907151100j37feb30av7281d09960ca5db2@mail.gmail.com>

On Wed 2009-07-15 11:00:07, Luis R. Rodriguez wrote:
> On Wed, Jul 15, 2009 at 8:51 AM, Luis R. Rodriguez<mcgrof@gmail.com> wrote:
> > On Tue, Jul 14, 2009 at 4:53 PM, Pavel Machek<pavel@ucw.cz> wrote:
> >> On Tue 2009-07-14 15:11:45, Luis R. Rodriguez wrote:
> >>> I'm working on Wake-on-Wireless support for wireless right now [1].
> >>> Upon wake up I wanted to inform the kernel of the event which caused
> >>> the wake up but am not clear if there is a generic API for this. Mind
> >>> you, for WoW we'll need at least some AC power to the card so we'll
> >>> need to at least be in S3-Hot so we'll only need events for that for
> >>> now.
> >>>
> >>> Do we have some generic infrastructure to gather reasons for wake up
> >>> from S1-S4 and pass this to userspace yet?
> >>
> >> I do not think generic api exists...
> 
> Going back to this topic -- any suggestions? Will a generic netlink
> family be OK? Or perhaps easier a udev event for some suitable
> existing parent ?

Is "who woke me" information even relevant? Yes, it may be interesting
enough for printk, but... What will userspace do with that information?

Imagine WoW packet comes, 5msec later WoL packet comes, 5msec later
user opens the lid. You report WoW as wakeup reason, but it is
inherently "racy".

What about simply reporting "wake event happened on this device" and
doing that for all the devices?


									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [PATCH] cfg80211: don't optimise wext calls too much
From: Marcel Holtmann @ 2009-07-18 12:00 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <1247737144.24433.11.camel@johannes.local>

Hi Johannes,

> In the wext code I tried to not reconnect all the time
> when the user wasn't really sure what they were doing,
> like setting the BSSID back to the same value it was.
> However, this optimisation should only be done while
> associated so that setting the BSSID back to the same
> value that it was actually triggers a new association
> if not currently associated. To achieve, that, put the
> relevant code into the !IDLE case instead.

this patch fixes my problems with wireless-testing.git

> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

Tested-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: WARN_ON at minstrel_get_rate (include/net/mac80211.h:2111) with p54usb
From: Larry Finger @ 2009-07-18 15:03 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: Johannes Berg, wireless
In-Reply-To: <200907181433.47985.chunkeey@web.de>

Christian Lamparter wrote:
> On Saturday 18 July 2009 03:05:04 Larry Finger wrote:
>> Johannes and Christian,
>>
>> I am getting a WARN_ON from mac80211 in the location stated in the
>> subject. I put in some test prints and got the following:
>>
>> sband->n_bitrates 8, Band 1, supp_rates 0x0
> hmm, so something decides to talk to a 5GHz network here?
> But the AP doesn't have any available rates in that band!?

Ah, band 1 is 5GHz, not 2.4. There are no 802.11a AP's in my neighborhood.

> If my memory serves my right some people have triggered the same WARN_ON
> with the ath5k driver as well...
> unfortunately, I didn't follow the thread and now I can't find it anymore.
>  
> (btw: is your b43 11a capable as well?)

Yes it is, but that section is software crippled.

Thanks for the patch. I'll let you know what happens.

Larry

^ permalink raw reply

* Re: Rfkill rewrite
From: Alan Jenkins @ 2009-07-18 15:46 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org

On 4/18/09, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Sat, 2009-04-18 at 14:29 +0100, Alan Jenkins wrote:
>
>> API nit:
>> 
>>  * This function tells the rfkill core that the device is capable of
>>  * remembering soft blocks (which it is notified of via the set_block
>>  * method) -- this means that the driver may ignore the return value
>>  * from rfkill_set_hw_state().
>> 
>> Doesn't this conflict with the declaration of rfkill_set_hw_state() as
>> __must_check?
>
> Yeah, in a way it does, but I figure it's rare enough that those who
> really can ignore it can write
> 	(void) rfkill_set_hw_state(...)
>
> Don't really have a strong opinion, it just seemed the mistake in the
> other direction would be more common.

It seems my GCC has a stronger definition of "must" than you do :-).  I can't get rid of the warning by casting it to void.  So I'm not sure __must_check is really appropriate here.

drivers/platform/x86/hp-wmi.c: In function ‘hp_wmi_bios_setup’:
drivers/platform/x86/hp-wmi.c:467: warning: ignoring return value of ‘rfkill_set_hw_state’, declared with attribute warn_unused_result

$ grep -n rfkill_set_hw_state drivers/platform/x86/hp-wmi.c
467:            (void) rfkill_set_hw_state(wifi_rfkill,

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)


Thanks
Alan

^ permalink raw reply

* Re: WARN_ON at minstrel_get_rate (include/net/mac80211.h:2111)
From: Christian Lamparter @ 2009-07-18 16:08 UTC (permalink / raw)
  To: Larry Finger; +Cc: Johannes Berg, wireless
In-Reply-To: <4A61E436.9060808@lwfinger.net>

On Saturday 18 July 2009 17:03:18 Larry Finger wrote:
> Christian Lamparter wrote:
> > If my memory serves my right some people have triggered the same WARN_ON
> > with the ath5k driver as well...
> > unfortunately, I didn't follow the thread and now I can't find it anymore.
anyone? Bob, Nick?

> Thanks for the patch. I'll let you know what happens.
I have my doubts. Do you still have the WARN_ON dump?
or at least which of the two functions are listed in the dump?
- rate_control_get_rate 
- rate_control_rate_init <- unlikely/really surprising

Regards,
	Chr

^ permalink raw reply

* Re: Rfkill rewrite
From: Johannes Berg @ 2009-07-18 17:40 UTC (permalink / raw)
  To: Alan Jenkins; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <4A61EE43.4060003@tuffmail.co.uk>

[-- Attachment #1: Type: text/plain, Size: 343 bytes --]

On Sat, 2009-07-18 at 16:46 +0100, Alan Jenkins wrote:

> It seems my GCC has a stronger definition of "must" than you do :-).
> I can't get rid of the warning by casting it to void.  So I'm not sure
> __must_check is really appropriate here.

Heh, my gcc agrees with you :)
I'm happy to remove it -- want to send a patch?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox