From: David-John Willis Date: Tue, 16 Mar 2010 10:57:17 +0000 (+0000) Subject: wl1251-modules: Add latest patch set and bump compat-wireless to 2010-03-10. X-Git-Tag: Release-2010-05/1~99 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=openpandora.oe.git;a=commitdiff_plain;h=39f2fac9c365c1a0d3f1a8822d0b2ba784133f8f wl1251-modules: Add latest patch set and bump compat-wireless to 2010-03-10. --- diff --git a/recipes/pandora-system/wl1251-modules.bb b/recipes/pandora-system/wl1251-modules.bb index 43c7dfe..62679d1 100755 --- a/recipes/pandora-system/wl1251-modules.bb +++ b/recipes/pandora-system/wl1251-modules.bb @@ -1,22 +1,29 @@ DESCRIPTION = "Kernel drivers for the TI WL1251 WiFi chip found on the Pandora - Connected via SDIO" LICENSE = "GPLv2" -PR = "r1" - 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://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 ." -S = "${WORKDIR}/compat-wireless-2010-01-20" +S = "${WORKDIR}/compat-wireless-2010-03-10" 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}/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.*" 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 index 0000000..194e794 --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/0001-wl1251-make-local-symbols-static.patch @@ -0,0 +1,95 @@ +From bd1e58fffa3e7be41926eac0377d3e726cd6048d Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +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 +Cc: Bob Copeland +--- + 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 +-#include +-#include +-#include + #include + #include +-#include + + #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 index 0000000..6334b1f --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/0002-wl1251-fix-ELP_CTRL-register-accesses-when-using-SDI.patch @@ -0,0 +1,168 @@ +From 41489f2e50030ba25d07d918b61911ea0b0b81fa Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +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 +Cc: Bob Copeland +--- + 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 index 0000000..fd2e8f2 --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/0003-wl1251-reduce-eeprom-read-wait-time.patch @@ -0,0 +1,31 @@ +From 76c61286c4d8aa99a70f0e2d8858ff49d1ae5f94 Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +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 +--- + 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 index 0000000..450d29c --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/0004-wl1251-fix-potential-crash.patch @@ -0,0 +1,47 @@ +From 4ce94ca87dfe4d0702cba031092443e3bb31686a Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +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: +[] (wl1251_debugfs_reset+0x0/0x30 [wl1251]) +[] (wl1251_op_stop+0x0/0x12c [wl1251]) +[] (ieee80211_stop_device+0x0/0x74 [mac80211]) +[] (ieee80211_stop+0x0/0x4ac [mac80211]) +[] (dev_close+0x0/0xb4) +[] (dev_change_flags+0x0/0x184) +[] (devinet_ioctl+0x0/0x704) +[] (inet_ioctl+0x0/0x100) + +Add a NULL pointer check to fix this. + +Signed-off-by: Grazvydas Ignotas +--- + 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 index 0000000..c3a5700 --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/0005-pandora-hacks.patch @@ -0,0 +1,183 @@ +From 3d44ad6640036cc610db5a27ae2dbf35fadf29cd Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +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 + #include + #include ++#include + + #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 ++ ++#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 index 0000000..780c74d --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/50-compat_firmware.rules @@ -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 index 0000000..ef609e7 --- /dev/null +++ b/recipes/pandora-system/wl1251-modules/compat_firmware.sh @@ -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 diff --git a/recipes/pandora-system/wl1251-modules/rc.wl1251 b/recipes/pandora-system/wl1251-modules/rc.wl1251 index 21b696d..30f8818 100755 --- a/recipes/pandora-system/wl1251-modules/rc.wl1251 +++ b/recipes/pandora-system/wl1251-modules/rc.wl1251 @@ -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") + iwconfig wlan0 power off } case "$1" in