summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2012-11-20 13:20:02 +0200
committerLuciano Coelho <coelho@ti.com>2012-11-27 10:48:20 +0200
commit18eab430700dc877bae38cf04f0b0574b4724f0a (patch)
tree208748fe71b8fef0480d293fc359299990623439 /drivers
parent3230f35e09f386ee604f55450dcd26098a3c4bc3 (diff)
wlcore: workaround start_sta problem in wl12xx fw
for some reason, the wl12xx fw is not able to rx/tx on the first start_sta cmd. Workaround it by issuing a dummy start_sta + stop_sta before starting the sta for the final time. Signed-off-by: Eliad Peller <eliad@wizery.com> Reviewed-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c15
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h3
3 files changed, 23 insertions, 4 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index dadf1dbb002a..6c9fba486795 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -637,7 +637,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
WLCORE_QUIRK_DUAL_PROBE_TMPL |
- WLCORE_QUIRK_TKIP_HEADER_SPACE;
+ WLCORE_QUIRK_TKIP_HEADER_SPACE |
+ WLCORE_QUIRK_START_STA_FAILS;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
@@ -657,7 +658,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
WLCORE_QUIRK_DUAL_PROBE_TMPL |
- WLCORE_QUIRK_TKIP_HEADER_SPACE;
+ WLCORE_QUIRK_TKIP_HEADER_SPACE |
+ WLCORE_QUIRK_START_STA_FAILS;
wl->plt_fw_name = WL127X_PLT_FW_NAME;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
@@ -682,7 +684,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
/* wl128x requires TX blocksize alignment */
wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
WLCORE_QUIRK_DUAL_PROBE_TMPL |
- WLCORE_QUIRK_TKIP_HEADER_SPACE;
+ WLCORE_QUIRK_TKIP_HEADER_SPACE |
+ WLCORE_QUIRK_START_STA_FAILS;
wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, WL128X_IFTYPE_VER,
WL128X_MAJOR_VER, WL128X_SUBTYPE_VER,
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 63367c00d2fa..054daae9c2fe 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2490,8 +2490,21 @@ static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
if (is_ibss)
ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
- else
+ else {
+ if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) {
+ /*
+ * TODO: this is an ugly workaround for wl12xx fw
+ * bug - we are not able to tx/rx after the first
+ * start_sta, so make dummy start+stop calls,
+ * and then call start_sta again.
+ * this should be fixed in the fw.
+ */
+ wl12xx_cmd_role_start_sta(wl, wlvif);
+ wl12xx_cmd_role_stop_sta(wl, wlvif);
+ }
+
ret = wl12xx_cmd_role_start_sta(wl, wlvif);
+ }
return ret;
}
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 68584aa0f2b0..1030b6bffeec 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -450,6 +450,9 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
+/* the first start_role(sta) sometimes doesn't work on wl12xx */
+#define WLCORE_QUIRK_START_STA_FAILS BIT(1)
+
/* wl127x and SPI don't support SDIO block size alignment */
#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)