wl1251-modules: Add latest patch set and bump compat-wireless to 2010-03-10.
authorDavid-John Willis <John.Willis@Distant-earth.com>
Tue, 16 Mar 2010 10:57:17 +0000 (10:57 +0000)
committerDavid-John Willis <John.Willis@Distant-earth.com>
Tue, 16 Mar 2010 10:57:17 +0000 (10:57 +0000)
recipes/pandora-system/wl1251-modules.bb
recipes/pandora-system/wl1251-modules/0001-wl1251-make-local-symbols-static.patch [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/0002-wl1251-fix-ELP_CTRL-register-accesses-when-using-SDI.patch [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/0003-wl1251-reduce-eeprom-read-wait-time.patch [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/0004-wl1251-fix-potential-crash.patch [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/0005-pandora-hacks.patch [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/50-compat_firmware.rules [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/compat_firmware.sh [new file with mode: 0644]
recipes/pandora-system/wl1251-modules/rc.wl1251

index 43c7dfe..62679d1 100755 (executable)
@@ -1,22 +1,29 @@
 DESCRIPTION = "Kernel drivers for the TI WL1251 WiFi chip found on the Pandora - Connected via SDIO"
 LICENSE = "GPLv2"
 
 DESCRIPTION = "Kernel drivers for the TI WL1251 WiFi chip found on the Pandora - Connected via SDIO"
 LICENSE = "GPLv2"
 
-PR = "r1"
-
 SRC_URI += " \
 SRC_URI += " \
-       http://djwillis.openpandora.org/pandora/wifi/compat-wireless-2010-01-20.zip;name=compat-wireless \
+       http://www.orbit-lab.org/kernel/compat-wireless-2.6/compat-wireless-2010-03-10.tar.bz2;name=compat-wireless \
+       file://0001-wl1251-make-local-symbols-static.patch;patch=1 \
+       file://0002-wl1251-fix-ELP_CTRL-register-accesses-when-using-SDI.patch;patch=1 \
+       file://0003-wl1251-reduce-eeprom-read-wait-time.patch;patch=1 \
+       file://0004-wl1251-fix-potential-crash.patch;patch=1 \
+       file://0005-pandora-hacks.patch;patch=1 \
        file://rc.wl1251 \
        file://rc.wl1251 \
+       file://50-compat_firmware.rules \
+       file://compat_firmware.sh \
 "
 
 "
 
-SRC_URI[compat-wireless.md5sum] = "110a808b15384bff0809ae90017f85aa"
-SRC_URI[compat-wireless.sha256sum] = "0b6680956601b169d1e2d664f2b0ecfbff11746ca95effd324f7e29580286a68"
+RDEPENDS = "udev"
+
+SRC_URI[compat-wireless.md5sum] = "bd1875aebcc2a72f66529ba625751a8c"
+SRC_URI[compat-wireless.sha256sum] = "dd8d8bc79ccb24a1d043325979e337678991b79f2011df160c2d924f181a82c9"
 
 inherit update-rc.d
 
 INITSCRIPT_NAME = "wl1251-init"
 INITSCRIPT_PARAMS = "start 30 5 2 . stop 40 0 1 6 ."
 
 
 inherit update-rc.d
 
 INITSCRIPT_NAME = "wl1251-init"
 INITSCRIPT_PARAMS = "start 30 5 2 . stop 40 0 1 6 ."
 
-S = "${WORKDIR}/compat-wireless-2010-01-20"
+S = "${WORKDIR}/compat-wireless-2010-03-10"
 
 inherit module
 
 
 inherit module
 
@@ -47,6 +54,10 @@ do_install() {
           
           install -d ${D}${sysconfdir}/init.d/
           install -m 0755 ${WORKDIR}/rc.wl1251 ${D}${sysconfdir}/init.d/wl1251-init
           
           install -d ${D}${sysconfdir}/init.d/
           install -m 0755 ${WORKDIR}/rc.wl1251 ${D}${sysconfdir}/init.d/wl1251-init
+
+          install -d ${D}${sysconfdir}/udev/rules.d/
+          install -m 0644 ${WORKDIR}/50-compat_firmware.rules ${D}${sysconfdir}/udev/rules.d/
+          install -m 0755 ${WORKDIR}/compat_firmware.sh ${D}${sysconfdir}/udev/rules.d/          
 }
 
 FILES_${PN} += "/lib/modules/${KERNEL_VERSION}/updates/compat/*.ko.*"
 }
 
 FILES_${PN} += "/lib/modules/${KERNEL_VERSION}/updates/compat/*.ko.*"
diff --git a/recipes/pandora-system/wl1251-modules/0001-wl1251-make-local-symbols-static.patch b/recipes/pandora-system/wl1251-modules/0001-wl1251-make-local-symbols-static.patch
new file mode 100644 (file)
index 0000000..194e794
--- /dev/null
@@ -0,0 +1,95 @@
+From bd1e58fffa3e7be41926eac0377d3e726cd6048d Mon Sep 17 00:00:00 2001
+From: Grazvydas Ignotas <notasas@gmail.com>
+Date: Sat, 6 Mar 2010 22:22:32 +0200
+Subject: [PATCH 1/5] wl1251: make local symbols static
+
+Make local functions and data static, also constify
+some structures. While at it, clean up unneeded includes.
+
+Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
+Cc: Bob Copeland <me@bobcopeland.com>
+---
+ drivers/net/wireless/wl12xx/wl1251_sdio.c |   25 +++++++++----------------
+ 1 files changed, 9 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+index 9423f22..0aceb91 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
++++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+@@ -20,20 +20,10 @@
+  * 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 "wl1251_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
+@@ -65,7 +55,8 @@ static const struct sdio_device_id wl1251_devices[] = {
+ MODULE_DEVICE_TABLE(sdio, wl1251_devices);
+-void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
++static void wl1251_sdio_read(struct wl1251 *wl, int addr,
++                           void *buf, size_t len)
+ {
+       int ret;
+       struct sdio_func *func = wl_to_func(wl);
+@@ -77,7 +68,8 @@ void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+       sdio_release_host(func);
+ }
+-void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
++static void wl1251_sdio_write(struct wl1251 *wl, int addr,
++                            void *buf, size_t len)
+ {
+       int ret;
+       struct sdio_func *func = wl_to_func(wl);
+@@ -89,7 +81,7 @@ void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+       sdio_release_host(func);
+ }
+-void wl1251_sdio_reset(struct wl1251 *wl)
++static void wl1251_sdio_reset(struct wl1251 *wl)
+ {
+ }
+@@ -111,11 +103,11 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl)
+       sdio_release_host(func);
+ }
+-void wl1251_sdio_set_power(bool enable)
++static void wl1251_sdio_set_power(bool enable)
+ {
+ }
+-struct wl1251_if_operations wl1251_sdio_ops = {
++static const struct wl1251_if_operations wl1251_sdio_ops = {
+       .read = wl1251_sdio_read,
+       .write = wl1251_sdio_write,
+       .reset = wl1251_sdio_reset,
+@@ -123,7 +115,8 @@ struct wl1251_if_operations wl1251_sdio_ops = {
+       .disable_irq = wl1251_sdio_disable_irq,
+ };
+-int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
++static int wl1251_sdio_probe(struct sdio_func *func,
++                           const struct sdio_device_id *id)
+ {
+       int ret;
+       struct wl1251 *wl;
+-- 
+1.6.3.3
+
diff --git a/recipes/pandora-system/wl1251-modules/0002-wl1251-fix-ELP_CTRL-register-accesses-when-using-SDI.patch b/recipes/pandora-system/wl1251-modules/0002-wl1251-fix-ELP_CTRL-register-accesses-when-using-SDI.patch
new file mode 100644 (file)
index 0000000..6334b1f
--- /dev/null
@@ -0,0 +1,168 @@
+From 41489f2e50030ba25d07d918b61911ea0b0b81fa Mon Sep 17 00:00:00 2001
+From: Grazvydas Ignotas <notasas@gmail.com>
+Date: Mon, 8 Mar 2010 17:37:01 +0200
+Subject: [PATCH 2/5] wl1251: fix ELP_CTRL register accesses when using SDIO
+
+For some unknown reason ELP_CTRL can't be accesed using
+sdio_memcpy_* functions (any attemts to do so result in timeouts):
+
+ wl1251: ERROR sdio write failed (-110)
+ wl1251: ERROR sdio read failed (-110)
+ wl1251: WARNING WLAN not ready
+
+To fix this, add special IO functions for ELP_CTRL access that are
+using sdio_readb/sdio_writeb. Similar handling is done in TI
+reference driver from Android code drop.
+
+Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
+Cc: Bob Copeland <me@bobcopeland.com>
+---
+ drivers/net/wireless/wl12xx/wl1251.h      |    2 ++
+ drivers/net/wireless/wl12xx/wl1251_io.h   |   20 ++++++++++++++++++++
+ drivers/net/wireless/wl12xx/wl1251_main.c |    4 ++--
+ drivers/net/wireless/wl12xx/wl1251_ps.c   |    8 ++++----
+ drivers/net/wireless/wl12xx/wl1251_sdio.c |   28 ++++++++++++++++++++++++++++
+ 5 files changed, 56 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
+index 37c61c1..4f5f02a 100644
+--- a/drivers/net/wireless/wl12xx/wl1251.h
++++ b/drivers/net/wireless/wl12xx/wl1251.h
+@@ -256,6 +256,8 @@ struct wl1251_debugfs {
+ 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 (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
++      void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
+       void (*reset)(struct wl1251 *wl);
+       void (*enable_irq)(struct wl1251 *wl);
+       void (*disable_irq)(struct wl1251 *wl);
+diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
+index b89d2ac..c545e9d 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_io.h
++++ b/drivers/net/wireless/wl12xx/wl1251_io.h
+@@ -48,6 +48,26 @@ static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
+       wl->if_ops->write(wl, addr, &val, sizeof(u32));
+ }
++static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
++{
++      u32 response;
++
++      if (wl->if_ops->read_elp)
++              wl->if_ops->read_elp(wl, addr, &response);
++      else
++              wl->if_ops->read(wl, addr, &response, sizeof(u32));
++
++      return response;
++}
++
++static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
++{
++      if (wl->if_ops->write_elp)
++              wl->if_ops->write_elp(wl, addr, val);
++      else
++              wl->if_ops->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);
+diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
+index 0ef2d9c..7a8e489 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_main.c
++++ b/drivers/net/wireless/wl12xx/wl1251_main.c
+@@ -149,8 +149,8 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
+       u32 elp_reg;
+       elp_reg = ELPCTRL_WAKE_UP;
+-      wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+-      elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
++      wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
++      elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+       if (!(elp_reg & ELPCTRL_WLAN_READY))
+               wl1251_warning("WLAN not ready");
+diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
+index 851dfb6..b55cb2b 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
++++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
+@@ -45,7 +45,7 @@ void wl1251_elp_work(struct work_struct *work)
+               goto out;
+       wl1251_debug(DEBUG_PSM, "chip to elp");
+-      wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
++      wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+       wl->elp = true;
+ out:
+@@ -79,9 +79,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
+       start = jiffies;
+       timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
+-      wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
++      wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+-      elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
++      elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+       /*
+        * FIXME: we should wait for irq from chip but, as a temporary
+@@ -93,7 +93,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+-              elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
++              elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+       }
+       wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
+diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+index 0aceb91..4df1a20 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
++++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+@@ -81,6 +81,32 @@ static void wl1251_sdio_write(struct wl1251 *wl, int addr,
+       sdio_release_host(func);
+ }
++static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
++{
++      int ret = 0;
++      struct sdio_func *func = wl_to_func(wl);
++
++      sdio_claim_host(func);
++      *val = sdio_readb(func, addr, &ret);
++      sdio_release_host(func);
++
++      if (ret)
++              wl1251_error("sdio_readb failed (%d)", ret);
++}
++
++static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
++{
++      int ret = 0;
++      struct sdio_func *func = wl_to_func(wl);
++
++      sdio_claim_host(func);
++      sdio_writeb(func, val, addr, &ret);
++      sdio_release_host(func);
++
++      if (ret)
++              wl1251_error("sdio_writeb failed (%d)", ret);
++}
++
+ static void wl1251_sdio_reset(struct wl1251 *wl)
+ {
+ }
+@@ -110,6 +136,8 @@ static void wl1251_sdio_set_power(bool enable)
+ static const struct wl1251_if_operations wl1251_sdio_ops = {
+       .read = wl1251_sdio_read,
+       .write = wl1251_sdio_write,
++      .write_elp = wl1251_sdio_write_elp,
++      .read_elp = wl1251_sdio_read_elp,
+       .reset = wl1251_sdio_reset,
+       .enable_irq = wl1251_sdio_enable_irq,
+       .disable_irq = wl1251_sdio_disable_irq,
+-- 
+1.6.3.3
+
diff --git a/recipes/pandora-system/wl1251-modules/0003-wl1251-reduce-eeprom-read-wait-time.patch b/recipes/pandora-system/wl1251-modules/0003-wl1251-reduce-eeprom-read-wait-time.patch
new file mode 100644 (file)
index 0000000..fd2e8f2
--- /dev/null
@@ -0,0 +1,31 @@
+From 76c61286c4d8aa99a70f0e2d8858ff49d1ae5f94 Mon Sep 17 00:00:00 2001
+From: Grazvydas Ignotas <notasas@gmail.com>
+Date: Mon, 8 Mar 2010 19:12:25 +0200
+Subject: [PATCH 3/5] wl1251: reduce eeprom read wait time
+
+4sec wait is way too pessimistic, TI driver uses 40ms here,
+and testing shows that is ebough, so let's also use that.
+While at it, add useful sounding comment from the TI driver.
+
+Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
+---
+ drivers/net/wireless/wl12xx/wl1251_boot.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
+index 28a8086..acb3341 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
++++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
+@@ -496,7 +496,8 @@ int wl1251_boot(struct wl1251 *wl)
+       /* 2. start processing NVS file */
+       if (wl->use_eeprom) {
+               wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
+-              msleep(4000);
++              /* Wait for EEPROM NVS burst read to complete */
++              msleep(40);
+               wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
+       } else {
+               ret = wl1251_boot_upload_nvs(wl);
+-- 
+1.6.3.3
+
diff --git a/recipes/pandora-system/wl1251-modules/0004-wl1251-fix-potential-crash.patch b/recipes/pandora-system/wl1251-modules/0004-wl1251-fix-potential-crash.patch
new file mode 100644 (file)
index 0000000..450d29c
--- /dev/null
@@ -0,0 +1,47 @@
+From 4ce94ca87dfe4d0702cba031092443e3bb31686a Mon Sep 17 00:00:00 2001
+From: Grazvydas Ignotas <notasas@gmail.com>
+Date: Tue, 9 Mar 2010 22:34:10 +0200
+Subject: [PATCH 4/5] wl1251: fix potential crash
+
+In case debugfs does not init for some reason (or is disabled
+on older kernels) driver does not allocate stats.fw_stats
+structure, but tries to clear it later and trips on a NULL
+pointer:
+
+Unable to handle kernel NULL pointer dereference at virtual address
+00000000
+PC is at __memzero+0x24/0x80
+Backtrace:
+[<bf0ddb88>] (wl1251_debugfs_reset+0x0/0x30 [wl1251])
+[<bf0d6a2c>] (wl1251_op_stop+0x0/0x12c [wl1251])
+[<bf0bc228>] (ieee80211_stop_device+0x0/0x74 [mac80211])
+[<bf0b0d10>] (ieee80211_stop+0x0/0x4ac [mac80211])
+[<c02deeac>] (dev_close+0x0/0xb4)
+[<c02deac0>] (dev_change_flags+0x0/0x184)
+[<c031f478>] (devinet_ioctl+0x0/0x704)
+[<c0320720>] (inet_ioctl+0x0/0x100)
+
+Add a NULL pointer check to fix this.
+
+Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
+---
+ drivers/net/wireless/wl12xx/wl1251_debugfs.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+index 0ccba57..05e4d68 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
++++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+@@ -466,7 +466,8 @@ out:
+ void wl1251_debugfs_reset(struct wl1251 *wl)
+ {
+-      memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
++      if (wl->stats.fw_stats != NULL)
++              memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+       wl->stats.retry_count = 0;
+       wl->stats.excessive_retries = 0;
+ }
+-- 
+1.6.3.3
+
diff --git a/recipes/pandora-system/wl1251-modules/0005-pandora-hacks.patch b/recipes/pandora-system/wl1251-modules/0005-pandora-hacks.patch
new file mode 100644 (file)
index 0000000..c3a5700
--- /dev/null
@@ -0,0 +1,183 @@
+From 3d44ad6640036cc610db5a27ae2dbf35fadf29cd Mon Sep 17 00:00:00 2001
+From: Grazvydas Ignotas <notasas@gmail.com>
+Date: Thu, 11 Mar 2010 18:53:37 +0200
+Subject: [PATCH 5/5] pandora hacks
+
+---
+ drivers/net/wireless/wl12xx/wl1251_boot.c |    2 +-
+ drivers/net/wireless/wl12xx/wl1251_sdio.c |   78 +++++++++++++++++++++++++++++
+ 2 files changed, 79 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
+index acb3341..5cd3903 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
++++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
+@@ -494,7 +494,7 @@ int wl1251_boot(struct wl1251 *wl)
+               goto out;
+       /* 2. start processing NVS file */
+-      if (wl->use_eeprom) {
++      if (1) { //wl->use_eeprom) {
+               wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
+               /* Wait for EEPROM NVS burst read to complete */
+               msleep(40);
+diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+index 4df1a20..af7eadd 100644
+--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
++++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
+@@ -22,6 +22,7 @@
+ #include <linux/module.h>
+ #include <linux/mmc/sdio_func.h>
+ #include <linux/mmc/sdio_ids.h>
++#include <linux/irq.h>
+ #include "wl1251.h"
+@@ -33,11 +34,14 @@
+ #define SDIO_DEVICE_ID_TI_WL1251      0x9066
+ #endif
++#define USE_GPOIO_IRQ
++
+ static struct sdio_func *wl_to_func(struct wl1251 *wl)
+ {
+       return wl->if_priv;
+ }
++#ifndef USE_GPOIO_IRQ
+ static void wl1251_sdio_interrupt(struct sdio_func *func)
+ {
+       struct wl1251 *wl = sdio_get_drvdata(func);
+@@ -47,6 +51,20 @@ static void wl1251_sdio_interrupt(struct sdio_func *func)
+       /* FIXME should be synchronous for sdio */
+       ieee80211_queue_work(wl->hw, &wl->irq_work);
+ }
++#else
++static irqreturn_t wl1251_irq(int irq, void *cookie)
++{
++      struct wl1251 *wl;
++
++      wl1251_debug(DEBUG_IRQ, "r IRQ");
++
++      wl = cookie;
++
++      ieee80211_queue_work(wl->hw, &wl->irq_work);
++
++      return IRQ_HANDLED;
++}
++#endif
+ static const struct sdio_device_id wl1251_devices[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
+@@ -88,6 +106,7 @@ static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
+       sdio_claim_host(func);
+       *val = sdio_readb(func, addr, &ret);
++      //*val = sdio_readb_ext(func, addr, &ret, 1);
+       sdio_release_host(func);
+       if (ret)
+@@ -109,8 +128,23 @@ static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
+ static void wl1251_sdio_reset(struct wl1251 *wl)
+ {
++      extern int sdio_reset_comm(struct mmc_card *card);
++      struct sdio_func *func = wl_to_func(wl);
++      int ret;
++
++      sdio_claim_host(func);
++      sdio_reset_comm(func->card);
++      ret = sdio_enable_func(func);
++      if (ret)
++              goto release;
++
++      sdio_set_block_size(func, 512);
++
++release:
++      sdio_release_host(func);
+ }
++#ifndef USE_GPOIO_IRQ
+ static void wl1251_sdio_enable_irq(struct wl1251 *wl)
+ {
+       struct sdio_func *func = wl_to_func(wl);
+@@ -128,9 +162,31 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl)
+       sdio_release_irq(func);
+       sdio_release_host(func);
+ }
++#else
++static void wl1251_gpio_enable_irq(struct wl1251 *wl)
++{
++      return enable_irq(wl->irq);
++}
++
++static void wl1251_gpio_disable_irq(struct wl1251 *wl)
++{
++      return disable_irq(wl->irq);
++}
++#endif
++
++/* Pandora hacks */
++#include <linux/gpio.h>
++
++#define PANDORA_WIFI_IRQ OMAP_GPIO_IRQ(21)
++#define PANDORA_WIFI_GPIO 23
+ static void wl1251_sdio_set_power(bool enable)
+ {
++      gpio_set_value(PANDORA_WIFI_GPIO, enable ? 1 : 0);
++      wl1251_notice("nReset: %d", enable ? 1 : 0);
++
++      if (enable)
++              mdelay(30);
+ }
+ static const struct wl1251_if_operations wl1251_sdio_ops = {
+@@ -139,8 +195,13 @@ static const struct wl1251_if_operations wl1251_sdio_ops = {
+       .write_elp = wl1251_sdio_write_elp,
+       .read_elp = wl1251_sdio_read_elp,
+       .reset = wl1251_sdio_reset,
++#ifndef USE_GPOIO_IRQ
+       .enable_irq = wl1251_sdio_enable_irq,
+       .disable_irq = wl1251_sdio_disable_irq,
++#else
++      .enable_irq = wl1251_gpio_enable_irq,
++      .disable_irq = wl1251_gpio_disable_irq,
++#endif
+ };
+ static int wl1251_sdio_probe(struct sdio_func *func,
+@@ -168,6 +229,19 @@ static int wl1251_sdio_probe(struct sdio_func *func,
+       wl->if_ops = &wl1251_sdio_ops;
+       wl->set_power = wl1251_sdio_set_power;
++#ifdef USE_GPOIO_IRQ
++      wl->irq = PANDORA_WIFI_IRQ;
++      ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
++      if (ret < 0) {
++              wl1251_error("request_irq() failed: %d", ret);
++              goto disable;
++      }
++
++      set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
++
++      disable_irq(wl->irq);
++#endif
++
+       sdio_release_host(func);
+       ret = wl1251_init_ieee80211(wl);
+       if (ret)
+@@ -188,6 +262,10 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
+ {
+       struct wl1251 *wl = sdio_get_drvdata(func);
++#ifdef USE_GPOIO_IRQ
++      free_irq(wl->irq, wl);
++#endif
++
+       wl1251_free_hw(wl);
+       sdio_claim_host(func);
+-- 
+1.6.3.3
+
diff --git a/recipes/pandora-system/wl1251-modules/50-compat_firmware.rules b/recipes/pandora-system/wl1251-modules/50-compat_firmware.rules
new file mode 100644 (file)
index 0000000..780c74d
--- /dev/null
@@ -0,0 +1,4 @@
+# do not edit this file, it will be overwritten on update
+
+# compat_firmware-class requests, copies files into the kernel
+SUBSYSTEM=="compat_firmware", ACTION=="add", RUN+="/etc/udev/rules.d/compat_firmware.sh"
diff --git a/recipes/pandora-system/wl1251-modules/compat_firmware.sh b/recipes/pandora-system/wl1251-modules/compat_firmware.sh
new file mode 100644 (file)
index 0000000..ef609e7
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh -e
+
+# This is ported from Ubuntu but ubuntu uses these directories which
+# other distributions don't care about:
+# FIRMWARE_DIRS="/lib/firmware/updates/$(uname -r) /lib/firmware/updates \
+#               /lib/firmware/$(uname -r) /lib/firmware"
+# If your distribution looks for firmware in other directories
+# feel free to extend this and add your own directory here.
+#
+FIRMWARE_DIRS="/lib/firmware"
+
+err() {
+       echo "$@" >&2
+       logger -t "${0##*/}[$$]" "$@" 2>/dev/null || true
+}
+
+if [ ! -e /sys$DEVPATH/loading ]; then
+       err "udev firmware loader misses sysfs directory"
+       exit 1
+fi
+
+for DIR in $FIRMWARE_DIRS; do
+       [ -e "$DIR/$FIRMWARE" ] || continue
+       echo 1 > /sys$DEVPATH/loading
+       cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data
+       echo 0 > /sys$DEVPATH/loading
+       exit 0
+done
+
+echo -1 > /sys$DEVPATH/loading
+err "Cannot find  firmware file '$FIRMWARE'"
+mkdir -p /dev/.udev/firmware-missing
+file=$(echo "$FIRMWARE" | sed 's:/:\\x2f:g')
+ln -s -f "$DEVPATH" /dev/.udev/firmware-missing/$file
+exit 1
index 21b696d..30f8818 100755 (executable)
@@ -26,6 +26,7 @@ d_start() {
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "lib80211_crypt_ccmp.ko")
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "wl1251.ko")
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "wl1251_sdio.ko")
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "lib80211_crypt_ccmp.ko")
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "wl1251.ko")
        insmod $(busybox find /lib/modules/$(uname -r)/updates -name "wl1251_sdio.ko")
+       iwconfig wlan0 power off
 }
 
 case "$1" in
 }
 
 case "$1" in