2012-05-08 11:07:28

by Yoni Divinsky

[permalink] [raw]
Subject: [PATCH 1/4] wlcore: use psd_type indexing according to spec

In ieee80211.h the uapsd bit mask is defined such that
VO=BIT(0), VI=BIT(1), BK=BIT(2), BE=BIT(3).
The firmware uses the indexing as defined in the ieee80211
spec, meaning that VO=3, VI=2, BK=1, BE=0.

In AP mode when adding peer wlcore needs to convert
the indexing accordingly.

Signed-off-by: Yoni Divinsky <[email protected]>
---
drivers/net/wireless/ti/wlcore/cmd.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 5b128a9..576c5bc 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1346,9 +1346,12 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,

for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
if (sta->wme && (sta->uapsd_queues & BIT(i)))
- cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER;
+ cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] =
+ WL1271_PSD_UPSD_TRIGGER;
else
- cmd->psd_type[i] = WL1271_PSD_LEGACY;
+ cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] =
+ WL1271_PSD_LEGACY;
+

sta_rates = sta->supp_rates[wlvif->band];
if (sta->ht_cap.ht_supported)
--
1.7.0.4



2012-05-08 11:07:30

by Yoni Divinsky

[permalink] [raw]
Subject: [PATCH 3/4] wlcore: do not send stop fwlog cmd if fw is hanged

If the driver received a watchdog interrupt then the
assumption is that the fw is hanged. Avoid sending
the stop fwlog command in case of a watchdog recovey
to avoid waiting for the 2 seconds timeout of the command.

Signed-off-by: Yoni Divinsky <[email protected]>
---
drivers/net/wireless/ti/wlcore/main.c | 9 +++++++--
drivers/net/wireless/ti/wlcore/wlcore.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 45fe911..b8dcef3 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -582,6 +582,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
wl1271_error("watchdog interrupt received! "
"starting recovery.");
+ wl->watchdog_recovery = true;
wl12xx_queue_recovery_work(wl);

/* restarting the chip. ignore any other interrupt. */
@@ -820,10 +821,12 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)

/*
* Make sure the chip is awake and the logger isn't active.
- * This might fail if the firmware hanged.
+ * Do not send a stop fwlog command if the fw is hanged.
*/
- if (!wl1271_ps_elp_wakeup(wl))
+ if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery)
wl12xx_cmd_stop_fwlog(wl);
+ else
+ goto out;

/* Read the first memory block address */
wl12xx_fw_status(wl, wl->fw_status);
@@ -926,6 +929,7 @@ static void wl1271_recovery_work(struct work_struct *work)
* to restart the HW.
*/
ieee80211_wake_queues(wl->hw);
+ wl->watchdog_recovery = false;
return;
out_unlock:
mutex_unlock(&wl->mutex);
@@ -1049,6 +1053,7 @@ int wl1271_plt_start(struct wl1271 *wl)

wl->plt = true;
wl->state = WL1271_STATE_ON;
+ wl->watchdog_recovery = false;
wl1271_notice("firmware booted in PLT mode (%s)",
wl->chip.fw_ver_str);

diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0b3f0b5..d6a8ad4 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -228,6 +228,7 @@ struct wl1271 {

/* Hardware recovery work */
struct work_struct recovery_work;
+ bool watchdog_recovery;

/* Pointer that holds DMA-friendly block for the mailbox */
struct event_mailbox *mbox;
--
1.7.0.4


2012-05-11 07:46:27

by Arik Nemtsov

[permalink] [raw]
Subject: Re: [PATCH 3/4] wlcore: do not send stop fwlog cmd if fw is hanged

On Tue, May 8, 2012 at 2:02 PM, Yoni Divinsky <[email protected]> wrote:
> If the driver received a watchdog interrupt then the
> assumption is that the fw is hanged. Avoid sending
> the stop fwlog command in case of a watchdog recovey
> to avoid waiting for the 2 seconds timeout of the command.
>
> Signed-off-by: Yoni Divinsky <[email protected]>
> ---
> ?drivers/net/wireless/ti/wlcore/main.c ? | ? ?9 +++++++--
> ?drivers/net/wireless/ti/wlcore/wlcore.h | ? ?1 +
> ?2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
> index 45fe911..b8dcef3 100644
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -582,6 +582,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
> ? ? ? ? ? ? ? ?if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
> ? ? ? ? ? ? ? ? ? ? ? ?wl1271_error("watchdog interrupt received! "
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "starting recovery.");
> + ? ? ? ? ? ? ? ? ? ? ? wl->watchdog_recovery = true;
> ? ? ? ? ? ? ? ? ? ? ? ?wl12xx_queue_recovery_work(wl);
>
> ? ? ? ? ? ? ? ? ? ? ? ?/* restarting the chip. ignore any other interrupt. */
> @@ -820,10 +821,12 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
>
> ? ? ? ?/*
> ? ? ? ? * Make sure the chip is awake and the logger isn't active.
> - ? ? ? ?* This might fail if the firmware hanged.
> + ? ? ? ?* Do not send a stop fwlog command if the fw is hanged.
> ? ? ? ? */
> - ? ? ? if (!wl1271_ps_elp_wakeup(wl))
> + ? ? ? if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery)
> ? ? ? ? ? ? ? ?wl12xx_cmd_stop_fwlog(wl);
> + ? ? ? else
> + ? ? ? ? ? ? ? goto out;
>
> ? ? ? ?/* Read the first memory block address */
> ? ? ? ?wl12xx_fw_status(wl, wl->fw_status);
> @@ -926,6 +929,7 @@ static void wl1271_recovery_work(struct work_struct *work)
> ? ? ? ? * to restart the HW.
> ? ? ? ? */
> ? ? ? ?ieee80211_wake_queues(wl->hw);
> + ? ? ? wl->watchdog_recovery = false;
> ? ? ? ?return;

Please change watchdog_recovery only inside the wl->mutex.

> ?out_unlock:
> ? ? ? ?mutex_unlock(&wl->mutex);

Please change watchdog_recovery to false here as well.

> @@ -1049,6 +1053,7 @@ int wl1271_plt_start(struct wl1271 *wl)
>
> ? ? ? ? ? ? ? ?wl->plt = true;
> ? ? ? ? ? ? ? ?wl->state = WL1271_STATE_ON;
> + ? ? ? ? ? ? ? wl->watchdog_recovery = false;
> ? ? ? ? ? ? ? ?wl1271_notice("firmware booted in PLT mode (%s)",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?wl->chip.fw_ver_str);

This is not needed here once watchdog_recovery is always set to false
indie recovery_work().

Arik

2012-05-08 11:07:32

by Yoni Divinsky

[permalink] [raw]
Subject: [PATCH 4/4] wlcore: fix the CONF_TX_AC_ANY_TID to be 0xff

In the enum conf_tx_ac CONF_TX_AC_ANY_TID should
be 0xff to match the firmware's implementation.

Signed-off-by: Yoni Divinsky <[email protected]>
---
drivers/net/wireless/ti/wlcore/conf.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index fef0db4..dbea4db 100644
--- a/drivers/net/wireless/ti/wlcore/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -504,7 +504,7 @@ enum conf_tx_ac {
CONF_TX_AC_VI = 2, /* video */
CONF_TX_AC_VO = 3, /* voice */
CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */
- CONF_TX_AC_ANY_TID = 0x1f
+ CONF_TX_AC_ANY_TID = 0xff
};

struct conf_tx_ac_category {
--
1.7.0.4


2012-05-08 11:07:28

by Yoni Divinsky

[permalink] [raw]
Subject: [PATCH 2/4] wl12xx: set the irq polarity before loading the fw

The polarity should be set before the firmware is loaded
since the firmware touches the same register. Access
of the firmware and driver to the same register will
cause a collision since there is no exclusion scheme.

Signed-off-by: Yoni Divinsky <[email protected]>
---
drivers/net/wireless/ti/wl12xx/main.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index d7dd3de..d2ea424 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -989,7 +989,7 @@ out:

static void wl12xx_pre_upload(struct wl1271 *wl)
{
- u32 tmp;
+ u32 tmp, polarity;

/* write firmware's last address (ie. it's length) to
* ACX_EEPROMLESS_IND_REG */
@@ -1009,18 +1009,18 @@ static void wl12xx_pre_upload(struct wl1271 *wl)

if (wl->chip.id == CHIP_ID_1283_PG20)
wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
-}
-
-static void wl12xx_enable_interrupts(struct wl1271 *wl)
-{
- u32 polarity;

+ /* polarity must be set before the firmware is loaded */
polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);

/* We use HIGH polarity, so unset the LOW bit */
polarity &= ~POLARITY_LOW;
wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);

+}
+
+static void wl12xx_enable_interrupts(struct wl1271 *wl)
+{
wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR);

wlcore_enable_interrupts(wl);
--
1.7.0.4


2012-06-06 08:17:51

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 1/4] wlcore: use psd_type indexing according to spec

On Tue, 2012-05-08 at 14:02 +0300, Yoni Divinsky wrote:
> In ieee80211.h the uapsd bit mask is defined such that
> VO=BIT(0), VI=BIT(1), BK=BIT(2), BE=BIT(3).
> The firmware uses the indexing as defined in the ieee80211
> spec, meaning that VO=3, VI=2, BK=1, BE=0.
>
> In AP mode when adding peer wlcore needs to convert
> the indexing accordingly.
>
> Signed-off-by: Yoni Divinsky <[email protected]>
> ---

Applied and pushed this series, except for 3/4, which was sent as v2 in
a separate patchset.

--
Luca.