From: Grazvydas Ignotas Date: Wed, 20 Mar 2013 23:41:09 +0000 (+0200) Subject: wl1251: NVS dump/load hacks X-Git-Tag: sz_154~3 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=8c38efd7a291f48b7b0241c859ee9b4d30af4ab1;ds=sidebyside wl1251: NVS dump/load hacks --- diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/wl1251/debugfs.c index 6c274007d200..66d75e363079 100644 --- a/drivers/net/wireless/wl1251/debugfs.c +++ b/drivers/net/wireless/wl1251/debugfs.c @@ -261,6 +261,42 @@ static const struct file_operations tx_queue_status_ops = { .llseek = generic_file_llseek, }; +static ssize_t dump_nvs_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1251 *wl = file->private_data; + + if (wl->eeprom_dump == NULL) + return -EINVAL; + + return simple_read_from_buffer(userbuf, count, ppos, + wl->eeprom_dump, 752); +} + +static ssize_t dump_full_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1251 *wl = file->private_data; + + if (wl->eeprom_dump == NULL) + return -EINVAL; + + return simple_read_from_buffer(userbuf, count, ppos, + wl->eeprom_dump, 1024); +} + +static const struct file_operations dump_nvs_ops = { + .read = dump_nvs_read, + .open = wl1251_open_file_generic, + .llseek = generic_file_llseek, +}; + +static const struct file_operations dump_full_ops = { + .read = dump_full_read, + .open = wl1251_open_file_generic, + .llseek = generic_file_llseek, +}; + static void wl1251_debugfs_delete_files(struct wl1251 *wl) { DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); @@ -358,6 +394,11 @@ static void wl1251_debugfs_delete_files(struct wl1251 *wl) DEBUGFS_DEL(tx_queue_status); DEBUGFS_DEL(retry_count); DEBUGFS_DEL(excessive_retries); + + if (wl->eeprom_dump != NULL) { + DEBUGFS_DEL(dump_nvs); + DEBUGFS_DEL(dump_full); + } } static int wl1251_debugfs_add_files(struct wl1251 *wl) @@ -460,6 +501,12 @@ static int wl1251_debugfs_add_files(struct wl1251 *wl) DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); + /* temporary (?) hack for EEPROM dumping */ + if (wl->eeprom_dump != NULL) { + DEBUGFS_ADD(dump_nvs, wl->debugfs.rootdir); + DEBUGFS_ADD(dump_full, wl->debugfs.rootdir); + } + out: if (ret < 0) wl1251_debugfs_delete_files(wl); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index cd487f6a3eae..0a27ae4b6050 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -1293,6 +1293,34 @@ static int wl1251_read_eeprom_mac(struct wl1251 *wl) return 0; } +/* temporary (?) hack for EEPROM dumping + * (it seems this can only be done before fw is running) */ +static int wl1251_dump_eeprom(struct wl1251 *wl) +{ + int ret; + + wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE); + + wl->eeprom_dump = kzalloc(1024, GFP_KERNEL); + if (wl->eeprom_dump == NULL) { + ret = -ENOMEM; + goto out; + } + + ret = wl1251_read_eeprom(wl, 0, wl->eeprom_dump, 1024); + if (ret != 0) { + wl1251_error("eeprom dump failed: %d", ret); + kfree(wl->eeprom_dump); + wl->eeprom_dump = NULL; + goto out; + } + + wl1251_info("eeprom dumped."); + +out: + return ret; +} + static int wl1251_register_hw(struct wl1251 *wl) { int ret; @@ -1342,6 +1370,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl) if (wl->use_eeprom) wl1251_read_eeprom_mac(wl); + if (wl->dump_eeprom) + wl1251_dump_eeprom(wl); ret = wl1251_register_hw(wl); if (ret) @@ -1450,6 +1480,9 @@ int wl1251_free_hw(struct wl1251 *wl) ieee80211_free_hw(wl->hw); + if (wl->eeprom_dump != NULL) + kfree(wl->eeprom_dump); + return 0; } EXPORT_SYMBOL_GPL(wl1251_free_hw); diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index e2750a12c6f1..cc34bea26ea6 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -31,6 +31,15 @@ #include "wl1251.h" +static bool force_nvs_file = false; +module_param(force_nvs_file, bool, 0644); +MODULE_PARM_DESC(force_nvs_file, "Force loading NVS data from file, " + "not EEPROM. Default: n/N/0"); +static bool dump_eeprom = false; +module_param(dump_eeprom, bool, 0644); +MODULE_PARM_DESC(dump_eeprom, "Dump EEPROM on module load and makes it " + "accessable through debugfs. Default: n/N/0"); + #ifndef SDIO_VENDOR_ID_TI #define SDIO_VENDOR_ID_TI 0x104c #endif @@ -259,6 +268,10 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl->use_eeprom = wl12xx_board_data->use_eeprom; } + if (force_nvs_file) + wl->use_eeprom = false; + wl->dump_eeprom = dump_eeprom; + if (wl->irq) { irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index c52136dfb0e1..5c1ec78e6f4d 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -255,6 +255,9 @@ struct wl1251_debugfs { struct dentry *retry_count; struct dentry *excessive_retries; + + struct dentry *dump_nvs; + struct dentry *dump_full; }; struct wl1251_if_operations { @@ -278,6 +281,7 @@ struct wl1251 { void (*set_power)(bool enable); int irq; bool use_eeprom; + bool dump_eeprom; spinlock_t wl_lock; @@ -391,6 +395,8 @@ struct wl1251 { /* Most recently reported noise in dBm */ s8 noise; + + void *eeprom_dump; }; int wl1251_plt_start(struct wl1251 *wl);