* [PATCH 07/16] wl1271: Add top-register access functions
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Add top register access function.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_boot.c | 27 ++---------------
drivers/net/wireless/wl12xx/wl1271_boot.h | 15 +---------
drivers/net/wireless/wl12xx/wl1271_spi.c | 46 +++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/wl1271_spi.h | 16 ++++++++++
4 files changed, 66 insertions(+), 38 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 2eb7836..1a3084c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -419,34 +419,13 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
{
- u32 polarity, status, i;
+ u32 polarity;
- wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
- wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
-
- /* Wait until the command is complete (ie. bit 18 is set) */
- for (i = 0; i < OCP_CMD_LOOP; i++) {
- polarity = wl1271_reg_read32(wl, OCP_DATA_READ);
- if (polarity & OCP_READY_MASK)
- break;
- }
- if (i == OCP_CMD_LOOP) {
- wl1271_error("OCP command timeout!");
- return -EIO;
- }
-
- status = polarity & OCP_STATUS_MASK;
- if (status != OCP_STATUS_OK) {
- wl1271_error("OCP command failed (%d)", status);
- return -EIO;
- }
+ polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
/* We use HIGH polarity, so unset the LOW bit */
polarity &= ~POLARITY_LOW;
-
- wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
- wl1271_reg_write32(wl, OCP_DATA_WRITE, polarity);
- wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
+ wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
return 0;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index b0d8fb4..4501653 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -50,20 +50,7 @@ struct wl1271_static_data {
#define WU_COUNTER_PAUSE_VAL 0x3FF
#define WELP_ARM_COMMAND_VAL 0x4
-#define OCP_CMD_LOOP 32
-
-#define OCP_CMD_WRITE 0x1
-#define OCP_CMD_READ 0x2
-
-#define OCP_READY_MASK BIT(18)
-#define OCP_STATUS_MASK (BIT(16) | BIT(17))
-
-#define OCP_STATUS_NO_RESP 0x00000
-#define OCP_STATUS_OK 0x10000
-#define OCP_STATUS_REQ_FAILED 0x20000
-#define OCP_STATUS_RESP_ERROR 0x30000
-
-#define OCP_REG_POLARITY 0x30032
+#define OCP_REG_POLARITY 0x0064
#define CMD_MBOX_ADDRESS 0x407B4
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 367f2d3..7a7890b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -395,3 +395,49 @@ void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
{
wl1271_write32(wl, wl1271_translate_addr(wl, addr), val);
}
+
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
+{
+ /* write address >> 1 + 0x30000 to OCP_POR_CTR */
+ addr = (addr >> 1) + 0x30000;
+ wl1271_reg_write32(wl, OCP_POR_CTR, addr);
+
+ /* write value to OCP_POR_WDATA */
+ wl1271_reg_write32(wl, OCP_DATA_WRITE, val);
+
+ /* write 1 to OCP_CMD */
+ wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
+}
+
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
+{
+ u32 val;
+ int timeout = OCP_CMD_LOOP;
+
+ /* write address >> 1 + 0x30000 to OCP_POR_CTR */
+ addr = (addr >> 1) + 0x30000;
+ wl1271_reg_write32(wl, OCP_POR_CTR, addr);
+
+ /* write 2 to OCP_CMD */
+ wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
+
+ /* poll for data ready */
+ do {
+ val = wl1271_reg_read32(wl, OCP_DATA_READ);
+ timeout--;
+ } while (!(val & OCP_READY_MASK) && timeout);
+
+ if (!timeout) {
+ wl1271_warning("Top register access timed out.");
+ return 0xffff;
+ }
+
+ /* check data status and return if OK */
+ if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
+ return val & 0xffff;
+ else {
+ wl1271_warning("Top register access returned error.");
+ return 0xffff;
+ }
+}
+
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
index c58e027..4f1608e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -71,6 +71,18 @@
((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
+#define OCP_CMD_LOOP 32
+
+#define OCP_CMD_WRITE 0x1
+#define OCP_CMD_READ 0x2
+
+#define OCP_READY_MASK BIT(18)
+#define OCP_STATUS_MASK (BIT(16) | BIT(17))
+
+#define OCP_STATUS_NO_RESP 0x00000
+#define OCP_STATUS_OK 0x10000
+#define OCP_STATUS_REQ_FAILED 0x20000
+#define OCP_STATUS_RESP_ERROR 0x30000
/* Raw target IO, address is not translated */
void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
@@ -92,6 +104,10 @@ void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
u32 wl1271_reg_read32(struct wl1271 *wl, int addr);
void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
+/* Top Register IO */
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
+
/* INIT and RESET words */
void wl1271_spi_reset(struct wl1271 *wl);
void wl1271_spi_init(struct wl1271 *wl);
--
1.5.6.5
^ permalink raw reply related
* [PATCH 04/16] wl1271: enable HW_AVAILABLE interrupt to fix ELP
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
We need to listen to HW_AVAILABLE interrupts when using ELP with firmware
revision 6.1.0.0.241. Add WL1271_ACX_INTR_HW_AVAILABLE to the interrupts that
are enabled by default.
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Reviewed-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_acx.h | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 0c2a107..07256d2 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -61,8 +61,9 @@
WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
-#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \
- WL1271_ACX_INTR_EVENT_B | \
+#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \
+ WL1271_ACX_INTR_EVENT_B | \
+ WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
/* Target's information element */
--
1.5.6.5
^ permalink raw reply related
* [PATCH 00/16] Second batch of patches for wl1271
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Hi,
Here is the second batch of patches to be included in wireless-testing. I got
a few comments from Johannes about the first batch and those issues will be
fixed after I send the 3rd and final batch.
Cheers,
Luca.
Juuso Oikarinen (10):
wl1271: Update memory mapping for firmware revision 6.1.0.0.241
wl1271: Remove RX workaround
wl1271: Add top-register access functions
wl1271: RefClk configuration
wl1271: Update interrupt handling by removing an extra SPI read
wl1271: Enable ELP
wl1271: Enable smart reflex
wl1271: Update TX path block calucation algo
wl1271: Remove outdated SPI functions
wl1271: Update boot time configuration for the new firmware
Luciano Coelho (6):
wl1271: implement cmd_disconnect
wl1271: workaround to send a disconnect before rejoining
wl1271: add workaround to avoid distortion due to excessive tx power
wl1271: enable HW_AVAILABLE interrupt to fix ELP
wl1271: use acx_rx_config instead of join when updating filters
wl1271: remove unnecessary joins and join only when the bssid changes
drivers/net/wireless/wl12xx/wl1271.h | 14 +-
drivers/net/wireless/wl12xx/wl1271_acx.c | 79 +++++++++-
drivers/net/wireless/wl12xx/wl1271_acx.h | 28 +++-
drivers/net/wireless/wl12xx/wl1271_boot.c | 177 ++++++++++----------
drivers/net/wireless/wl12xx/wl1271_boot.h | 22 +--
drivers/net/wireless/wl12xx/wl1271_cmd.c | 68 +++++++--
drivers/net/wireless/wl12xx/wl1271_cmd.h | 27 +++
drivers/net/wireless/wl12xx/wl1271_event.c | 8 +-
drivers/net/wireless/wl12xx/wl1271_init.c | 7 +-
drivers/net/wireless/wl12xx/wl1271_main.c | 160 ++++++++----------
drivers/net/wireless/wl12xx/wl1271_ps.c | 11 +-
drivers/net/wireless/wl12xx/wl1271_reg.h | 3 +-
drivers/net/wireless/wl12xx/wl1271_rx.c | 14 +-
drivers/net/wireless/wl12xx/wl1271_spi.c | 251 ++++++++++++----------------
drivers/net/wireless/wl12xx/wl1271_spi.h | 65 +++++---
drivers/net/wireless/wl12xx/wl1271_tx.c | 14 +-
16 files changed, 531 insertions(+), 417 deletions(-)
^ permalink raw reply
* [PATCH 15/16] wl1271: use acx_rx_config instead of join when updating filters
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
We shouldn't use a join command to change the filter settings while
associated. The right way to do it is to use ACX_RX_CFG.
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Reviewed-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_main.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 5ef0bd5..fc0d03f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -422,7 +422,7 @@ static void wl1271_filter_work(struct work_struct *work)
goto out;
/* apply configured filters */
- ret = wl1271_cmd_join(wl);
+ ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
if (ret < 0)
goto out_sleep;
@@ -869,6 +869,8 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
wl1271_warning("Unknown mc address length.");
}
+ /* FIXME: We still need to set our filters properly */
+
spin_lock_irqsave(&wl->wl_lock, flags);
kfree(wl->filter_params);
wl->filter_params = fp;
--
1.5.6.5
^ permalink raw reply related
* [PATCH 12/16] wl1271: Update TX path block calucation algo
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Update the TX path block calculation algorithm based on TI reference.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_tx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 5d3aa4b..56a7f36 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -57,8 +57,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
/* approximate the number of blocks required for this packet
in the firmware */
/* FIXME: try to figure out what is done here and make it cleaner */
- total_blocks = (total_len) >> TX_HW_BLOCK_SHIFT_DIV;
- excluded = (total_blocks << 2) + (skb->len & 0xff) + 34;
+ total_blocks = (total_len + 20) >> TX_HW_BLOCK_SHIFT_DIV;
+ excluded = (total_blocks << 2) + ((total_len + 20) & 0xff) + 34;
total_blocks += (excluded > 252) ? 2 : 1;
total_blocks += TX_HW_BLOCK_SPARE;
--
1.5.6.5
^ permalink raw reply related
* [PATCH 06/16] wl1271: Remove RX workaround
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Remove RX workaround which is not needed with newer firmware revisions. This
will reduce one SPI register transaction per RX packet.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_reg.h | 1 -
drivers/net/wireless/wl12xx/wl1271_rx.c | 4 ----
2 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h
index f8ed4a4..bd12615 100644
--- a/drivers/net/wireless/wl12xx/wl1271_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1271_reg.h
@@ -213,7 +213,6 @@
==============================================*/
#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0)
-#define RX_DRIVER_DUMMY_WRITE_ADDRESS (REGISTERS_BASE + 0x0534)
#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538)
/* Device Configuration registers*/
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 5d8d401..1d98653 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -187,8 +187,4 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
}
wl1271_reg_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
-
- /* This is a workaround for some problems in the chip */
- wl1271_reg_write32(wl, RX_DRIVER_DUMMY_WRITE_ADDRESS, 0x1);
-
}
--
1.5.6.5
^ permalink raw reply related
* [PATCH 08/16] wl1271: RefClk configuration
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Updated RefClk configuration based on reference sources. Apparently this
change will improve RF performance.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_boot.c | 20 ++++++++++++++++++--
drivers/net/wireless/wl12xx/wl1271_boot.h | 9 ++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 1a3084c..b586577 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -435,13 +435,29 @@ int wl1271_boot(struct wl1271 *wl)
int ret = 0;
u32 tmp, clk, pause;
- if (REF_CLOCK == 0 || REF_CLOCK == 2)
- /* ref clk: 19.2/38.4 */
+ if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
+ /* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
else if (REF_CLOCK == 1 || REF_CLOCK == 3)
/* ref clk: 26/52 */
clk = 0x5;
+ if (REF_CLOCK != 0) {
+ u16 val;
+ /* Set clock type */
+ val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
+ val &= FREF_CLK_TYPE_BITS;
+ val |= CLK_REQ_PRCM;
+ wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
+ } else {
+ u16 val;
+ /* Set clock polarity */
+ val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
+ val &= FREF_CLK_POLARITY_BITS;
+ val |= CLK_REQ_OUTN_SEL;
+ wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
+ }
+
wl1271_reg_write32(wl, PLL_PARAMETERS, clk);
pause = wl1271_reg_read32(wl, PLL_PARAMETERS);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index 4501653..412443e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -50,10 +50,17 @@ struct wl1271_static_data {
#define WU_COUNTER_PAUSE_VAL 0x3FF
#define WELP_ARM_COMMAND_VAL 0x4
-#define OCP_REG_POLARITY 0x0064
+#define OCP_REG_POLARITY 0x0064
+#define OCP_REG_CLK_TYPE 0x0448
+#define OCP_REG_CLK_POLARITY 0x0cb2
#define CMD_MBOX_ADDRESS 0x407B4
#define POLARITY_LOW BIT(1)
+#define FREF_CLK_TYPE_BITS 0xfffffe7f
+#define CLK_REQ_PRCM 0x100
+#define FREF_CLK_POLARITY_BITS 0xfffff8ff
+#define CLK_REQ_OUTN_SEL 0x700
+
#endif
--
1.5.6.5
^ permalink raw reply related
* [PATCH 05/16] wl1271: Update memory mapping for firmware revision 6.1.0.0.241
From: Luciano Coelho @ 2009-10-12 12:08 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1255349337-9776-1-git-send-email-luciano.coelho@nokia.com>
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Update the memory regions and memory mapping to support firmware revision
6.1.0.0.241.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271.h | 7 +-
drivers/net/wireless/wl12xx/wl1271_boot.c | 67 ++++++-----
drivers/net/wireless/wl12xx/wl1271_main.c | 10 +-
drivers/net/wireless/wl12xx/wl1271_spi.c | 178 ++++++++++------------------
drivers/net/wireless/wl12xx/wl1271_spi.h | 15 ++-
5 files changed, 116 insertions(+), 161 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 858bf6b..b2bc7b5 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -148,6 +148,8 @@ struct wl1271_partition {
struct wl1271_partition_set {
struct wl1271_partition mem;
struct wl1271_partition reg;
+ struct wl1271_partition mem2;
+ struct wl1271_partition mem3;
};
struct wl1271;
@@ -302,10 +304,7 @@ struct wl1271 {
enum wl1271_state state;
struct mutex mutex;
- int physical_mem_addr;
- int physical_reg_addr;
- int virtual_mem_addr;
- int virtual_reg_addr;
+ struct wl1271_partition_set part;
struct wl1271_chip chip;
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 140e943..2eb7836 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -39,6 +39,14 @@ static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
.start = REGISTERS_BASE,
.size = 0x00008800
},
+ .mem2 = {
+ .start = 0x00000000,
+ .size = 0x00000000
+ },
+ .mem3 = {
+ .start = 0x00000000,
+ .size = 0x00000000
+ },
},
[PART_WORK] = {
@@ -48,7 +56,15 @@ static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
},
.reg = {
.start = REGISTERS_BASE,
- .size = 0x0000b000
+ .size = 0x0000a000
+ },
+ .mem2 = {
+ .start = 0x003004f8,
+ .size = 0x00000004
+ },
+ .mem3 = {
+ .start = 0x00040404,
+ .size = 0x00000000
},
},
@@ -60,6 +76,14 @@ static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
.reg = {
.start = DRPW_BASE,
.size = 0x00006000
+ },
+ .mem2 = {
+ .start = 0x00000000,
+ .size = 0x00000000
+ },
+ .mem3 = {
+ .start = 0x00000000,
+ .size = 0x00000000
}
}
};
@@ -93,6 +117,7 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
size_t fw_data_len, u32 dest)
{
+ struct wl1271_partition_set partition;
int addr, chunk_num, partition_limit;
u8 *p, *chunk;
@@ -114,10 +139,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
return -ENOMEM;
}
- wl1271_set_partition(wl, dest,
- part_table[PART_DOWN].mem.size,
- part_table[PART_DOWN].reg.start,
- part_table[PART_DOWN].reg.size);
+ memcpy(&partition, &part_table[PART_DOWN], sizeof(partition));
+ partition.mem.start = dest;
+ wl1271_set_partition(wl, &partition);
/* 10.1 set partition limit and chunk num */
chunk_num = 0;
@@ -130,13 +154,8 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
addr = dest + chunk_num * CHUNK_SIZE;
partition_limit = chunk_num * CHUNK_SIZE +
part_table[PART_DOWN].mem.size;
-
- /* FIXME: Over 80 chars! */
- wl1271_set_partition(wl,
- addr,
- part_table[PART_DOWN].mem.size,
- part_table[PART_DOWN].reg.start,
- part_table[PART_DOWN].reg.size);
+ partition.mem.start = addr;
+ wl1271_set_partition(wl, &partition);
}
/* 10.3 upload the chunk */
@@ -261,11 +280,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
/* FIXME: The driver sets the partition here, but this is not needed,
since it sets to the same one as currently in use */
/* Now we must set the partition correctly */
- wl1271_set_partition(wl,
- part_table[PART_WORK].mem.start,
- part_table[PART_WORK].mem.size,
- part_table[PART_WORK].reg.start,
- part_table[PART_WORK].reg.size);
+ wl1271_set_partition(wl, &part_table[PART_WORK]);
/* Copy the NVS tables to a new block to ensure alignment */
nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
@@ -371,11 +386,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl->event_box_addr = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
/* set the working partition to its "running" mode offset */
- wl1271_set_partition(wl,
- part_table[PART_WORK].mem.start,
- part_table[PART_WORK].mem.size,
- part_table[PART_WORK].reg.start,
- part_table[PART_WORK].reg.size);
+ wl1271_set_partition(wl, &part_table[PART_WORK]);
wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
wl->cmd_box_addr, wl->event_box_addr);
@@ -469,11 +480,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_reg_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
udelay(500);
- wl1271_set_partition(wl,
- part_table[PART_DRPW].mem.start,
- part_table[PART_DRPW].mem.size,
- part_table[PART_DRPW].reg.start,
- part_table[PART_DRPW].reg.size);
+ wl1271_set_partition(wl, &part_table[PART_DRPW]);
/* Read-modify-write DRPW_SCRATCH_START register (see next state)
to be used by DRPw FW. The RTRIM value will be added by the FW
@@ -488,11 +495,7 @@ int wl1271_boot(struct wl1271 *wl)
clk |= (REF_CLOCK << 1) << 4;
wl1271_reg_write32(wl, DRPW_SCRATCH_START, clk);
- wl1271_set_partition(wl,
- part_table[PART_WORK].mem.start,
- part_table[PART_WORK].mem.size,
- part_table[PART_WORK].reg.start,
- part_table[PART_WORK].reg.size);
+ wl1271_set_partition(wl, &part_table[PART_WORK]);
/* Disable interrupts */
wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index b9f2091..22d44ba 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -315,6 +315,7 @@ static int wl1271_setup(struct wl1271 *wl)
static int wl1271_chip_wakeup(struct wl1271 *wl)
{
+ struct wl1271_partition_set partition;
int ret = 0;
wl1271_power_on(wl);
@@ -324,11 +325,10 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
/* We don't need a real memory partition here, because we only want
* to use the registers at this point. */
- wl1271_set_partition(wl,
- 0x00000000,
- 0x00000000,
- REGISTERS_BASE,
- REGISTERS_DOWN_SIZE);
+ memset(&partition, 0, sizeof(partition));
+ partition.reg.start = REGISTERS_BASE;
+ partition.reg.size = REGISTERS_DOWN_SIZE;
+ wl1271_set_partition(wl, &partition);
/* ELP module wake up */
wl1271_fw_wakeup(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 504991a..367f2d3 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -30,17 +30,29 @@
#include "wl12xx_80211.h"
#include "wl1271_spi.h"
-static int wl1271_translate_reg_addr(struct wl1271 *wl, int addr)
+static int wl1271_translate_addr(struct wl1271 *wl, int addr)
{
- return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl1271_translate_mem_addr(struct wl1271 *wl, int addr)
-{
- return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+ /*
+ * To translate, first check to which window of addresses the
+ * particular address belongs. Then subtract the starting address
+ * of that window from the address. Then, add offset of the
+ * translated region.
+ *
+ * The translated regions occur next to each other in physical device
+ * memory, so just add the sizes of the preceeding address regions to
+ * get the offset to the new region.
+ *
+ * Currently, only the two first regions are addressed, and the
+ * assumption is that all addresses will fall into either of those
+ * two.
+ */
+ if ((addr >= wl->part.reg.start) &&
+ (addr < wl->part.reg.start + wl->part.reg.size))
+ return addr - wl->part.reg.start + wl->part.mem.size;
+ else
+ return addr - wl->part.mem.start;
}
-
void wl1271_spi_reset(struct wl1271 *wl)
{
u8 *cmd;
@@ -123,123 +135,61 @@ void wl1271_spi_init(struct wl1271 *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.
+ * To simplify driver code, a fixed (virtual) memory map is defined for
+ * register and memory addresses. Because in the chipset, in different stages
+ * of operation, those addresses will move around, an address translation
+ * mechanism is required.
*
- * PHYSICAL address
+ * There are four partitions (three memory and one register partition),
+ * which are mapped to two different areas of the hardware memory.
+ *
+ * Virtual address
* space
*
* | |
- * ...+----+--> mem_start
- * VIRTUAL address ... | |
+ * ...+----+--> mem.start
+ * Physical address ... | |
* space ... | | [PART_0]
* ... | |
- * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
+ * 00000000 <--+----+... ...+----+--> mem.start + mem.size
* | | ... | |
* |MEM | ... | |
* | | ... | |
- * part_size <--+----+... | | {unused area)
+ * mem.size <--+----+... | | {unused area)
* | | ... | |
* |REG | ... | |
- * part_size | | ... | |
- * + <--+----+... ...+----+--> reg_start
- * reg_size ... | |
- * ... | | [PART_1]
- * ... | |
- * ...+----+--> reg_start + reg_size
+ * mem.size | | ... | |
+ * + <--+----+... ...+----+--> reg.start
+ * reg.size | | ... | |
+ * |MEM2| ... | | [PART_1]
+ * | | ... | |
+ * ...+----+--> reg.start + reg.size
* | |
*
*/
int wl1271_set_partition(struct wl1271 *wl,
- u32 mem_start, u32 mem_size,
- u32 reg_start, u32 reg_size)
+ struct wl1271_partition_set *p)
{
- struct wl1271_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 wl1271_partition);
- cmd = kzalloc(cmd_len, GFP_KERNEL);
- if (!cmd)
- return -ENOMEM;
-
- spi_message_init(&m);
- memset(&t, 0, sizeof(t));
-
- partition = (struct wl1271_partition *) (cmd + 1);
- addr = HW_ACCESS_PART0_SIZE_ADDR;
- len = 2 * sizeof(struct wl1271_partition);
-
- *cmd |= WSPI_CMD_WRITE;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+ /* copy partition info */
+ memcpy(&wl->part, p, sizeof(*p));
wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
+ p->mem.start, p->mem.size);
wl1271_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) {
- wl1271_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
- " address range. Truncating partition[0].");
- mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
- wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1271_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 */
- wl1271_debug(DEBUG_SPI, "End of partition[0] is "
- "overlapping partition[1]. Adjusted.");
- mem_size = reg_start - mem_start;
- wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1271_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 */
- wl1271_debug(DEBUG_SPI, "End of partition[1] is"
- " overlapping partition[0]. Adjusted.");
- reg_size = mem_start - reg_start;
- wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1271_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);
+ p->reg.start, p->reg.size);
+ wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
+ p->mem2.start, p->mem2.size);
+ wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
+ p->mem3.start, p->mem3.size);
+
+ /* write partition info to the chipset */
+ wl1271_write32(wl, HW_PART0_START_ADDR, p->mem.start);
+ wl1271_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
+ wl1271_write32(wl, HW_PART1_START_ADDR, p->reg.start);
+ wl1271_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
+ wl1271_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
+ wl1271_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
+ wl1271_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
return 0;
}
@@ -391,7 +341,7 @@ void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf,
{
int physical;
- physical = wl1271_translate_mem_addr(wl, addr);
+ physical = wl1271_translate_addr(wl, addr);
wl1271_spi_read(wl, physical, buf, len, false);
}
@@ -401,7 +351,7 @@ void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf,
{
int physical;
- physical = wl1271_translate_mem_addr(wl, addr);
+ physical = wl1271_translate_addr(wl, addr);
wl1271_spi_write(wl, physical, buf, len, false);
}
@@ -411,7 +361,7 @@ void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
{
int physical;
- physical = wl1271_translate_reg_addr(wl, addr);
+ physical = wl1271_translate_addr(wl, addr);
wl1271_spi_read(wl, physical, buf, len, fixed);
}
@@ -421,27 +371,27 @@ void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
{
int physical;
- physical = wl1271_translate_reg_addr(wl, addr);
+ physical = wl1271_translate_addr(wl, addr);
wl1271_spi_write(wl, physical, buf, len, fixed);
}
u32 wl1271_mem_read32(struct wl1271 *wl, int addr)
{
- return wl1271_read32(wl, wl1271_translate_mem_addr(wl, addr));
+ return wl1271_read32(wl, wl1271_translate_addr(wl, addr));
}
void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val)
{
- wl1271_write32(wl, wl1271_translate_mem_addr(wl, addr), val);
+ wl1271_write32(wl, wl1271_translate_addr(wl, addr), val);
}
u32 wl1271_reg_read32(struct wl1271 *wl, int addr)
{
- return wl1271_read32(wl, wl1271_translate_reg_addr(wl, addr));
+ return wl1271_read32(wl, wl1271_translate_addr(wl, addr));
}
void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
{
- wl1271_write32(wl, wl1271_translate_reg_addr(wl, addr), val);
+ wl1271_write32(wl, wl1271_translate_addr(wl, addr), val);
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
index 2c99684..c58e027 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -29,10 +29,14 @@
#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_PARTITION_REGISTERS_ADDR 0x1ffc0
+#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
+#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
+#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
+#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
+#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
+#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
+#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
#define HW_ACCESS_REGISTER_SIZE 4
@@ -92,8 +96,7 @@ void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
void wl1271_spi_reset(struct wl1271 *wl);
void wl1271_spi_init(struct wl1271 *wl);
int wl1271_set_partition(struct wl1271 *wl,
- u32 part_start, u32 part_size,
- u32 reg_start, u32 reg_size);
+ struct wl1271_partition_set *p);
static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
{
--
1.5.6.5
^ permalink raw reply related
* WARNING: slow-path
From: Holger Schurig @ 2009-10-12 11:35 UTC (permalink / raw)
To: linux-wireless
I'm getting a "slow-path" warning that I don't really comprehend:
[ 33.357576] libertas leave: lbs_cfg_scan_worker()
[ 33.368197] libertas enter: lbs_cfg_auth()
[ 33.368356] libertas leave: lbs_cfg_auth(), ret 0
[ 33.368554] libertas enter: lbs_cfg_ret_auth()
[ 33.368746] libertas leave: lbs_cfg_ret_auth()
Next comes the .assoc function. This isn't yet coded so I return -ENOTSUPP
[ 33.368832] libertas enter: lbs_cfg_assoc()
[ 33.368902] libertas leave: lbs_cfg_assoc(-ENOTSUPP)
... with makes mlme.c call my .deauth function:
[ 33.368970] libertas enter: lbs_cfg_deauth()
[ 33.369768] libertas enter: lbs_cfg_ret_deauth()
[ 33.369838] ------------[ cut here ]------------
[ 33.369923] WARNING: at net/wireless/mlme.c:135 __cfg80211_send_deauth+0x3f/0x1e1 [cfg80211]()
[ 33.370028] Hardware name: Amilo M1425
[ 33.370096] Modules linked in: libertas_cs libertas cfg80211 lib80211 psmouse uhci_hcd [last unloaded: cfg80211]
[ 33.370461] Pid: 1700, comm: lbs_main Not tainted 2.6.32-rc3-wl #21
[ 33.370532] Call Trace:
[ 33.370604] [<c012395a>] warn_slowpath_common+0x60/0x77
[ 33.370676] [<c012397e>] warn_slowpath_null+0xd/0x10
[ 33.370754] [<f91205c0>] __cfg80211_send_deauth+0x3f/0x1e1 [cfg80211]
[ 33.370834] [<f9120c85>] cfg80211_send_deauth+0x33/0x5a [cfg80211]
[ 33.370916] [<f93324cc>] lbs_cfg_ret_deauth+0x9d/0xe7 [libertas]
[ 33.370993] [<f933242f>] ? lbs_cfg_ret_deauth+0x0/0xe7 [libertas]
[ 33.371071] [<f93380bc>] lbs_process_command_response+0x538/0xa96 [libertas]
[ 33.371147] [<c0399f7a>] ? _spin_unlock_irq+0x22/0x3b
[ 33.371225] [<f933ca77>] lbs_thread+0x358/0x747 [libertas]
[ 33.371300] [<c011ebbc>] ? default_wake_function+0x0/0xd
[ 33.371377] [<f933c71f>] ? lbs_thread+0x0/0x747 [libertas]
[ 33.371450] [<c0133c9c>] kthread+0x61/0x69
[ 33.371520] [<c0133c3b>] ? kthread+0x0/0x69
[ 33.371591] [<c010334b>] kernel_thread_helper+0x7/0x10
[ 33.371661] ---[ end trace f5da223917368c61 ]---
[ 33.371756] libertas leave: lbs_cfg_ret_deauth()
Bellow is lbs_cfg_deauth. I know from friday's debugging, that
__lbs_cmd_async also does a preempt (CONFIG_PREEMPT). That
might have something do to with it.
static int lbs_cfg_deauth(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_deauth_request *req,
void *cookie)
{
struct lbs_private *priv = wiphy_priv(wiphy);
struct cmd_ds_802_11_deauthenticate cmd;
lbs_deb_enter(LBS_DEB_CFG80211);
memset(&cmd, 0, sizeof(cmd));
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
memcpy(cmd.macaddr, &req->bss->bssid, ETH_ALEN);
cmd.reasoncode = cpu_to_le16(req->reason_code);
__lbs_cmd_async(priv, CMD_802_11_DEAUTHENTICATE,
&cmd.hdr, sizeof(cmd),
lbs_cfg_ret_deauth, (unsigned long) cookie);
return 0;
}
lbs_cfg_ret_deauth() get's called as soon as the
firmware sends me back some response.
static int lbs_cfg_ret_deauth(struct lbs_private *priv, unsigned long dummy,
struct cmd_header *resp)
{
struct cmd_ds_802_11_deauthenticate *deauth_resp = (void *)resp;
struct ieee80211_mgmt mgmt;
lbs_deb_enter(LBS_DEB_CFG80211);
/* Fake a management frame */
memset(&mgmt, 0, sizeof(mgmt));
memcpy(mgmt.bssid, deauth_resp->macaddr, ETH_ALEN);
memcpy(mgmt.sa, deauth_resp->macaddr, ETH_ALEN);
memcpy(mgmt.da, priv->current_addr, ETH_ALEN);
cfg80211_send_deauth(priv->dev, (u8 *)&mgmt, sizeof(mgmt),
(void *)dummy);
lbs_deb_leave(LBS_DEB_CFG80211);
return 0;
}
Any idea on how to fix that?
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: NOHZ: local_softirq_pending 08
From: Tilman Schmidt @ 2009-10-12 11:25 UTC (permalink / raw)
To: David Miller
Cc: tilman, johannes, hidave.darkstar, linux-kernel, tglx,
linux-wireless, linux-ppp, netdev, paulus
In-Reply-To: <20091012.033246.56701176.davem@davemloft.net>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Mon, 12 Oct 2009 03:32:46 -0700 (PDT), David Miller wrote:
> The PPP receive paths in ppp_generic.c do a local_bh_disable()/
> local_bh_enable() around packet receiving (via ppp_recv_lock()/
> ppp_recv_unlock() in ppp_do_recv).
>
> So at least that part is perfectly fine.
>
> ppp_input(), as called from ppp_sync_process(), also disables BH's
> around ppp_do_recv() calls (via read_lock_bh()/read_unlock_bh()).
>
> So that's fine too.
>
> Do you have a bug report or are you just scanning around looking
> for trouble? :-)
I have encountered the message in the subject during a test of
the Gigaset CAPI driver, and would like to determine whether
it's a bug in the driver, a bug somewhere else, or no bug at
all. The test scenario was PPP over ISDN with pppd+capiplugin.
In an alternative scenario, also PPP over ISDN but with
smpppd+capidrv, the message did not occur.
Johannes' answer pointed me to the netif_rx() function.
The Gigaset driver itself doesn't call that function at all.
In the scenario where I saw the message, it was the SYNC_PPP
line discipline that did. But from your explanation I gather
that the cause cannot lie there.
So now I'm looking for other possible causes of that message.
- --
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFK0xITQ3+did9BuFsRAmXGAKCIiqJffUnuKw9rPjxHwbj9AnXOigCdGgS9
MpxRNGs0A4GTydYJaylbjyo=
=LFxi
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: Bleeding Edge does not compile (was Re: Bleeding Edge b43 dated since 30 of september no longer working & today does not even compile.)
From: Florian Fainelli @ 2009-10-12 11:09 UTC (permalink / raw)
To: Riffer; +Cc: John W. Linville, linux-wireless
In-Reply-To: <4ACCDF24.7050002@penny.prima.de>
Hi,
On Wednesday 07 October 2009 20:34:12 Riffer wrote:
> Hello!
>
> Thanks for your reply!
>
> Besides the other failure mentioned after patching the version of 06th
> there is a new problem with the one from today (7th of oct):
>
> ----
> /home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/a
>th5k/base.c: In Funktion »ath5k_pci_suspend_compat«:
> /home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/a
>th5k/base.c:206: Fehler: Inkompatibler Typ für Argument 1 von
> »ath5k_pci_suspend«
> /home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/a
>th5k/base.c: In Funktion »ath5k_pci_resume_compat«:
> /home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/a
>th5k/base.c:224: Fehler: Inkompatibler Typ für Argument 1 von
> »ath5k_pci_resume«
> make[5]: ***
> [/home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/
>ath5k/base.o] Fehler 1
> make[4]: ***
> [/home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath/
>ath5k] Fehler 2
> make[3]: ***
> [/home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless/ath]
> Fehler 2
> make[2]: ***
> [/home/riffer/bleeding/compat-wireless-2009-10-07/drivers/net/wireless]
> Fehler 2
> make[1]: *** [_module_/home/riffer/bleeding/compat-wireless-2009-10-07]
> Fehler 2
> make[1]: Verlasse Verzeichnis
> '/usr/src/linux-headers-2.6.30-02063006-generic'
> make: *** [modules] Fehler 2
I got the same compilation failure here, the code in ath5k/base.c looks
perfectly fine though.
^ permalink raw reply
* Re: NOHZ: local_softirq_pending 08
From: David Miller @ 2009-10-12 10:32 UTC (permalink / raw)
To: tilman
Cc: johannes, hidave.darkstar, linux-kernel, tglx, linux-wireless,
linux-ppp, netdev, paulus
In-Reply-To: <4AD2E8C8.4060205@imap.cc>
From: Tilman Schmidt <tilman@imap.cc>
Date: Mon, 12 Oct 2009 10:28:56 +0200
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> [CCing PPP people]
>
> Am 11.10.2009 13:40 schrieb Johannes Berg:
>> On Sun, 2009-10-11 at 13:18 +0200, Tilman Schmidt wrote:
>>
>>> Can you explain a bit more what that message is about?
>>> I am encountering it in a completely different context
>>> (PPP over ISDN) [...]
>>
>> Basically, calling netif_rx() with softirqs enabled.
>
> AFAICS that would have to be the netif_rx() call in
> ppp_receive_nonmp_frame() [drivers/net/ppp_generic.c#L1791],
> called (via others) from the tasklet work function
> ppp_sync_process() [drivers/net/ppp_synctty.c#L545].
> Should that be changed to the
> "if (in_interrupt()) netif_rx(skb) else netif_rx_ni(skb)"
> stanza from the linux.kernel.wireless.general thread then?
The PPP receive paths in ppp_generic.c do a local_bh_disable()/
local_bh_enable() around packet receiving (via ppp_recv_lock()/
ppp_recv_unlock() in ppp_do_recv).
So at least that part is perfectly fine.
ppp_input(), as called from ppp_sync_process(), also disables BH's
around ppp_do_recv() calls (via read_lock_bh()/read_unlock_bh()).
So that's fine too.
Do you have a bug report or are you just scanning around looking
for trouble? :-)
^ permalink raw reply
* ar9170 network interface initialization failure
From: oshi @ 2009-10-12 10:05 UTC (permalink / raw)
To: linux-wireless
Hello,
I am trying to enable a Ubiquity SR71 device on x86 - ubuntu 9.04 (kernel
headers 2.6.28-15).
I built and installed compat-wireless-2009-10-09 on my machine.
ar9170 module is loaded and a network interface is created.
However when I try to bring up the interface, an error occurs:
ifconfig wlan3 up
SIOCSIFFLAGS: Operation not permitted
I managed to trace down the error to a failure in usb_submit_urb() called from
ar9170_init_mac().
[70247.612064] usb 2-1: new high speed USB device using ehci_hcd and address 10
[70247.779863] usb 2-1: config 1 interface 0 altsetting 0 bulk endpoint 0x4 has
invalid maxpacket 64
[70247.792411] usb 2-1: configuration #1 chosen from 1 choice
[70247.910900] usb 2-1: reset high speed USB device using ehci_hcd and address 10
[70249.084059] usb 2-1: firmware: requesting ar9170.fw
[70249.096406] usb 2-1: ar9170.fw firmware file not found, trying old firmware...
[70249.096416] usb 2-1: firmware: requesting ar9170-1.fw
[70249.138585] usb 2-1: firmware: requesting ar9170-2.fw
[70249.568392] ath: EEPROM regdomain: 0x0
[70249.568397] ath: EEPROM indicates default country code should be used
[70249.568402] ath: doing EEPROM country->regdmn map search
[70249.568408] ath: country maps to regdmn code: 0x3a
[70249.568413] ath: Country alpha2 being used: US
[70249.568418] ath: Regpair used: 0x3a
[70249.568792] phy2: Selected rate control algorithm 'minstrel'
[70249.572212] ar9170_usb_exec_cmd line 399
[70249.572488] ar9170_usb_exec_cmd line 399
[70249.572820] Registered led device: ar9170-phy2::tx
[70249.572883] Registered led device: ar9170-phy2::assoc
[70249.572890] usb 2-1: Atheros AR9170 is registered as 'phy2'
[70249.588769] udev: renamed network interface wlan0 to wlan3
[70254.388224] ar9170_op_start 1259
[70254.388231] ar9170_init_mac 147
[70254.388257] ar9170_usb_exec_cmd usb_submit_urb err -1
[70254.391839] ar9170_usb_exec_cmd usb_submit_urb err -1
[70254.391846] usb 2-1: USB setup failed (-1).
[70262.056330] ar9170_usb_exec_cmd usb_submit_urb err -1
[70262.056338] usb 2-1: USB setup failed (-1).
The problem occurs also when using the single firmware file.
All the process was performed as root.
Am I missing any configuration phase?
Are there any usb patches i am missing?
Any suggestion will be appreciated.
Thanks,
Oshi
^ permalink raw reply
* 802.11: Throughput optimization beyond rate selection
From: Joerg Pommnitz @ 2009-10-12 9:28 UTC (permalink / raw)
To: linux-wireless
Hello all,
the throughput achieved over a wireless 802.11 network depends on more than the
rate selection. Other parameters are fragmentation threshold, RTS threshold
and the retry limits. Are you aware of a "unified throughput optimization" algorithm
that tries to optimize the whole parameter set instead of just the data rate?
--
Regards
Joerg
^ permalink raw reply
* Re: [RFC] p54pci: skb_over_panic, soft lockup, stall under flood
From: Christian Lamparter @ 2009-10-12 8:57 UTC (permalink / raw)
To: Quintin Pitts; +Cc: Larry Finger, linux-wireless
In-Reply-To: <4AD273B2.5000607@gmail.com>
[-- Attachment #1: Type: Text/Plain, Size: 1358 bytes --]
On Monday 12 October 2009 02:09:22 Quintin Pitts wrote:
> On Sun Oct 11 2009 10:31:42 GMT-0500 (CDT), Larry Finger wrote:
> > On 10/11/2009 09:28 AM, Quintin Pitts wrote:
> > As I understand it, this patch is to fix the driver to work around
> > firmware errors. If that is correct, please state that clearly. If
> > only partially correct, then indicate which parts are to fix firmware
> > errors, and which are to fix driver errors. Has your analysis included
> > thinking about where the driver might delay to avoid firmware problems.
>
> I think Christian has hit the nail on the head.
> Mostly flaky hardware or implementation (it8152 pci bridge) when pushed.
hmm, flaky hardware or simply incomplete linux support.
you've said that it works with win ce,
so I suppose the code is missing some important bits.
e.g.:
00:06.0 Network controller: Intersil Corporation ISL3886 [Prism Javelin/Prism Xbow] (rev 01)
Subsystem: Intersil Corporation Device 0000
Flags: bus master, medium devsel, latency 56, IRQ 217
by the looks of it, something could wrong with the latency timer value.
(what's lspci -vvnnxxx output for the card?)
I've attached a minimal patch which c&p some latency-timer related logic
from the original prism54 driver code to p54pci.
Can you please give this a try?
I don't have a p54pci available for testing right now.
Regards,
Chr
[-- Attachment #2: p54-latency.diff --]
[-- Type: text/x-patch, Size: 865 bytes --]
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index d348c26..c1b1bee 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -473,6 +473,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
struct ieee80211_hw *dev;
unsigned long mem_addr, mem_len;
int err;
+ u8 latency;
err = pci_enable_device(pdev);
if (err) {
@@ -493,6 +494,12 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
goto err_disable_dev;
}
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
+ if (latency < 64) {
+ dev_info(&pdev->dev, "set latency timer\n");
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 80);
+ }
+
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
dev_err(&pdev->dev, "No suitable DMA available\n");
^ permalink raw reply related
* Re: NOHZ: local_softirq_pending 08
From: Tilman Schmidt @ 2009-10-12 8:28 UTC (permalink / raw)
To: Johannes Berg
Cc: Dave Young, linux-kernel, tglx, linux-wireless, David S. Miller,
linux-ppp, netdev, Paul Mackerras
In-Reply-To: <1255261251.4095.143.camel@johannes.local>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[CCing PPP people]
Am 11.10.2009 13:40 schrieb Johannes Berg:
> On Sun, 2009-10-11 at 13:18 +0200, Tilman Schmidt wrote:
>
>> Can you explain a bit more what that message is about?
>> I am encountering it in a completely different context
>> (PPP over ISDN) [...]
>
> Basically, calling netif_rx() with softirqs enabled.
AFAICS that would have to be the netif_rx() call in
ppp_receive_nonmp_frame() [drivers/net/ppp_generic.c#L1791],
called (via others) from the tasklet work function
ppp_sync_process() [drivers/net/ppp_synctty.c#L545].
Should that be changed to the
"if (in_interrupt()) netif_rx(skb) else netif_rx_ni(skb)"
stanza from the linux.kernel.wireless.general thread then?
Thanks,
Tilman
- --
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFK0ujIQ3+did9BuFsRAtGBAJ9rj2pyQZ75ZKTipLhpICqA3ZvTdQCdHQs/
RmdeOT3TuPZykXJxcHLJCzU=
=87DI
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: ath5k AP kernel panic when client uses SCP
From: Tomasz Chmielewski @ 2009-10-12 8:13 UTC (permalink / raw)
To: Bob Copeland; +Cc: linux-wireless, linux-mips, linux-net
In-Reply-To: <b6c5339f0910111547w33a88f7dtd9d16cd3380877cd@mail.gmail.com>
Bob Copeland wrote:
> On Sun, Oct 11, 2009 at 1:49 PM, Tomasz Chmielewski <mangoo@wpkg.org> wrote:
>> The AP is Asus WL-500gP, it's a MIPS platform, running 2.6.31.1 kernel,
>> hostapd v0.6.9.
>>
>> I can reproduce the issue reliably.
>>
>> Let me know if you need more info here.
>
> Yes, please -- it would really be helpful if instead of just the addresses
> we have all the function names in the stack trace. Or at least what is
> at 8006f058 and 80276190. We've had a couple of reports of unaligned
> accesses but I haven't yet seen a useful stack trace.
OK, will try to send it later today.
>> [67359.700000] ------------[ cut here ]------------
>> [67359.710000] WARNING: at net/core/dev.c:1566 0x80280890()
>> [67359.710000] b44: caps=(0x0, 0x0) len=80 data_len=0 ip_summed=1
>> [67359.720000] Modules linked in: tun sch_sfq cls_fw sch_htb ipt_MASQUERADE
>> iptable_nat nf_nat xt_MARK iptable_mangle ipt_ULOG xt_recent
>> nf_conntrack_ipv4 nf_defrag1
>
> Did you replace the wireless device? I don't see ath5k in the
> above list; IIRC that AP is originally some broadcom chipset.
The AP device comes with a broadcom wireless card, which doesn't work well.
So I replaced broadcom with an ath5k card.
ath5k and other modules were probably "eaten" by the terminal/minicom/konsole/whatever.
This is the list of modules which should be loaded when the panic occurs:
# lsmod
Module Size Used by
tun 12160 2
sch_sfq 4496 1
cls_fw 3216 1
sch_htb 12480 1
ipt_MASQUERADE 976 1
iptable_nat 2800 1
nf_nat 12496 2 ipt_MASQUERADE,iptable_nat
xt_MARK 912 1
iptable_mangle 1008 1
ipt_ULOG 4144 1
xt_recent 5408 9
nf_conntrack_ipv4 4560 7 iptable_nat,nf_nat
nf_defrag_ipv4 624 1 nf_conntrack_ipv4
xt_state 784 4
nf_conntrack 46640 5 ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state
xt_tcpudp 1888 5
iptable_filter 768 1
ip_tables 8848 3 iptable_nat,iptable_mangle,iptable_filter
x_tables 9648 8 ipt_MASQUERADE,iptable_nat,xt_MARK,ipt_ULOG,xt_recent,xt_state,xt_tcpudp,ip_tables
ath5k 131616 0
mac80211 130208 1 ath5k
ath 6256 1 ath5k
ohci_hcd 17344 0
uhci_hcd 18048 0
cfg80211 72000 3 ath5k,mac80211,ath
>> [67360.080000] Disabling lock debugging due to kernel taint
>> [67360.560000] Kernel panic - not syncing: Fatal exception in interrupt
>
> Why's it tainted? I can't remember and can't check right now if
> TAINT_WARN counts.
Yes, WARN taints the kernel.
--
Tomasz Chmielewski
http://wpkg.org
^ permalink raw reply
* Re: ath5k AP kernel panic when client uses SCP
From: Tomasz Chmielewski @ 2009-10-12 8:13 UTC (permalink / raw)
To: Bob Copeland; +Cc: linux-wireless, linux-mips
In-Reply-To: <b6c5339f0910111547w33a88f7dtd9d16cd3380877cd@mail.gmail.com>
Bob Copeland wrote:
> On Sun, Oct 11, 2009 at 1:49 PM, Tomasz Chmielewski <mangoo@wpkg.org> wrote:
>> The AP is Asus WL-500gP, it's a MIPS platform, running 2.6.31.1 kernel,
>> hostapd v0.6.9.
>>
>> I can reproduce the issue reliably.
>>
>> Let me know if you need more info here.
>
> Yes, please -- it would really be helpful if instead of just the addresses
> we have all the function names in the stack trace. Or at least what is
> at 8006f058 and 80276190. We've had a couple of reports of unaligned
> accesses but I haven't yet seen a useful stack trace.
OK, will try to send it later today.
>> [67359.700000] ------------[ cut here ]------------
>> [67359.710000] WARNING: at net/core/dev.c:1566 0x80280890()
>> [67359.710000] b44: caps=(0x0, 0x0) len=80 data_len=0 ip_summed=1
>> [67359.720000] Modules linked in: tun sch_sfq cls_fw sch_htb ipt_MASQUERADE
>> iptable_nat nf_nat xt_MARK iptable_mangle ipt_ULOG xt_recent
>> nf_conntrack_ipv4 nf_defrag1
>
> Did you replace the wireless device? I don't see ath5k in the
> above list; IIRC that AP is originally some broadcom chipset.
The AP device comes with a broadcom wireless card, which doesn't work well.
So I replaced broadcom with an ath5k card.
ath5k and other modules were probably "eaten" by the terminal/minicom/konsole/whatever.
This is the list of modules which should be loaded when the panic occurs:
# lsmod
Module Size Used by
tun 12160 2
sch_sfq 4496 1
cls_fw 3216 1
sch_htb 12480 1
ipt_MASQUERADE 976 1
iptable_nat 2800 1
nf_nat 12496 2 ipt_MASQUERADE,iptable_nat
xt_MARK 912 1
iptable_mangle 1008 1
ipt_ULOG 4144 1
xt_recent 5408 9
nf_conntrack_ipv4 4560 7 iptable_nat,nf_nat
nf_defrag_ipv4 624 1 nf_conntrack_ipv4
xt_state 784 4
nf_conntrack 46640 5 ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state
xt_tcpudp 1888 5
iptable_filter 768 1
ip_tables 8848 3 iptable_nat,iptable_mangle,iptable_filter
x_tables 9648 8 ipt_MASQUERADE,iptable_nat,xt_MARK,ipt_ULOG,xt_recent,xt_state,xt_tcpudp,ip_tables
ath5k 131616 0
mac80211 130208 1 ath5k
ath 6256 1 ath5k
ohci_hcd 17344 0
uhci_hcd 18048 0
cfg80211 72000 3 ath5k,mac80211,ath
>> [67360.080000] Disabling lock debugging due to kernel taint
>> [67360.560000] Kernel panic - not syncing: Fatal exception in interrupt
>
> Why's it tainted? I can't remember and can't check right now if
> TAINT_WARN counts.
Yes, WARN taints the kernel.
--
Tomasz Chmielewski
http://wpkg.org
^ permalink raw reply
* Re: [PATCH] b43: fix ieee80211_rx() context
From: Kalle Valo @ 2009-10-12 7:49 UTC (permalink / raw)
To: David Miller
Cc: johannes, linville, hidave.darkstar, linux-wireless,
luciano.coelho
In-Reply-To: <20091011.200857.141215452.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
>>> I really don't see the point, since it's just three lines of code, but I
>>> wouldn't mind all that much either.
>>
>> My worry are the developers who even don't know what is a bottom half
>> and might get it all wrong. (Yes, there really are such people.)
>
> And the difference between this and knowing you need to call the
> ieee80211_rx_ni() thing is?
>
> You have to know what the heck a bottom half is to even know that you
> would need to call the ieee80211_rx_ni() thing.
>
> And that's the same amount of knowledge necessary to simply wrap the
> thing in a BH disable/enable sequence.
I was thinking that it's possible to document it something like this:
o in irq context use ieee80211_rx_irqsafe()
o in a tasklet use ieee80211_rx()
o in process context use ieee80211_rx_ni()
Also in the future it might be easier to optimise something based on
these functions. Maybe.
But as Johannes didn't like the idea, and neither do you, I'm going to
drop the idea. I'll add the BH disable/enable to wl1251 instead and
hopefully Luciano does the same to wl1271.
--
Kalle Valo
^ permalink raw reply
* Re: deauthentication and disassociation nl80211 commands
From: Holger Schurig @ 2009-10-12 7:44 UTC (permalink / raw)
To: hostap; +Cc: Maxim Levitsky, linux-wireless
In-Reply-To: <1255146340.3542.10.camel@maxim-laptop>
> Nobody uses driver_nl80211 but me?
And me :-) But still not in production.
Consider us two early-adaptors :-)
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: [PATCH] b43: fix ieee80211_rx() context
From: Holger Schurig @ 2009-10-12 7:27 UTC (permalink / raw)
To: Johannes Berg
Cc: Michael Buesch, John Linville, David Miller, Kalle Valo,
Dave Young, linux-wireless
In-Reply-To: <1255257066.4095.66.camel@johannes.local>
> As far as I know, it is an accurate account of what happened in the
> other thread, and as such is not slander.
It might not be slander, but it's still not polite.
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: [PATCH -next] libertas: depends on CFG80211
From: Holger Schurig @ 2009-10-12 7:18 UTC (permalink / raw)
To: Randy Dunlap
Cc: Stephen Rothwell, linux-wireless, Dan Williams, linux-next,
libertas-dev
In-Reply-To: <20091009161730.6ae5fe59.randy.dunlap@oracle.com>
Oh, and I sent in the same patch:
http://marc.info/?l=linux-wireless&m=125507252131925&w=4
I don't care which one get's applied.
--
http://www.holgerschurig.de
^ permalink raw reply
* Re: BUG? I can reproduce "Association request to the driver failed" at will
From: Jouni Malinen @ 2009-10-12 7:15 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-wireless, hostap
In-Reply-To: <200909211309.40476.hs4233@mail.mn-solutions.de>
On Mon, Sep 21, 2009 at 01:09:40PM +0200, Holger Schurig wrote:
> The following is an indication about yet another MLME problem:
>
> Two APs, both set to the MNHS/WPA.
>
> Let wpa_supplicant associate. Turn one AP off. wpa_supplicant
> automatically associates to the second.
Though, even in this case, there is actually a bug somewhere (in
mac80211, I would assume).. The authentication attempt with the second
AP times out because mac80211 ends up sending the direct probes to the
MAC address of the old AP (which is now turned off). When wpa_supplicant
tries to authenticate again, the direct probes are going to the correct
destination and connection can be established.
> Now turn the first AP on again. Issue a manual scan command:
..
> 1253527140.953161: nl80211: Event message available
> 1253527140.953200: nl80211: MLME event 37
> 1253527140.953216: SME: Authentication response: peer=00:13:19:80:da:30 auth_type=0 status_code=0
> 1253527140.953243: Trying to associate with 00:13:19:80:da:30 (SSID='MNWPA' freq=2412 MHz)
> 1253527140.953257: State: AUTHENTICATING -> ASSOCIATING
> 1253527140.953270: wpa_driver_nl80211_set_operstate: operstate 1->0 (DORMANT)
> 1253527140.953284: nl80211: Operstate: linkmode=-1, operstate=5
> 1253527140.953901: nl80211: Associate (ifindex=34)
> 1253527140.953919: * bssid=00:13:19:80:da:30
> 1253527140.953934: * freq=2412
> 1253527140.953945: * SSID - hexdump_ascii(len=5):
> 4d 4e 57 50 41 MNWPA
> 1253527140.953977: * IEs - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 01 00 00 50 f2 02
> 1253527140.954064: nl80211: MLME command failed: ret=-114 (Operation already in progress)
> 1253527140.954086: Association request to the driver failed
I can reproduce this with the current wpa_supplicant (that has a
workaround for this EALREADY for authentication case, but not for
assoc) and the current wireless-testing. Roaming will get mac80211 into
very odd state..
Not only is this association failing (after the authentication with the
same AP actually worked), but the scanning state will also get quite
confused.. The next scan trigger after this is never completed (iw scan
gets stuck). Or well, actually, once I wait long enough for the AP to
deauthenticate the client, it looks like mac80211 can recover. The scan
command returned after five minutes of waiting.. ;-)
> The "Association request to the driver failed" will
> be shown even without "-d". Also note that the association
> seems to actually work, e.g. I can ping throught the
> connection.
mac80211 remains associated with the old AP (I think) and somehow
remains in the state between authentication and association (with the
new AP) which will block scans.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [PATCH -next] libertas: depends on CFG80211
From: Holger Schurig @ 2009-10-12 7:11 UTC (permalink / raw)
To: Randy Dunlap
Cc: Stephen Rothwell, linux-wireless, Dan Williams, linux-next,
libertas-dev
In-Reply-To: <20091009161730.6ae5fe59.randy.dunlap@oracle.com>
> libertas uses CFG80211 functions so it should depend on that
symbol.
Ack.
Sigh, I should concentrate more on getting clean patches on the
first iteration.
^ permalink raw reply
* Re: deauthentication and disassociation nl80211 commands
From: Jouni Malinen @ 2009-10-12 6:55 UTC (permalink / raw)
To: Johannes Berg; +Cc: Maxim Levitsky, hostap@lists.shmoo.com, linux-wireless
In-Reply-To: <1255191866.4095.32.camel@johannes.local>
On Sat, Oct 10, 2009 at 06:24:26PM +0200, Johannes Berg wrote:
> On the other hand, I think Jouni's argument is that you should be able
> to authenticate (force an auth frame exchange) even while authenticated.
> I don't really disagree with that all that much, but I'm not sure how to
> cleanly fit it in. mac80211 would have to reset the auth state without
> sending a deauth.
Yes, this is exactly what I would like to see happening when using
mac80211. For now, I think we can work around the issue in
wpa_supplicant, but eventually, this change in mac80211 would allow the
code in wpa_supplicant to be cleaned up and the need for an extra
deauthentication frame could be removed.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox