From 5aa42346bba2e385674eb1dd4019dfce4c2ef771 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Sun, 6 Mar 2011 16:32:07 +0200 Subject: wl12xx: 1281/1283 support - Add Definitions Definitions to support wl128x: - New FW file name - Chip ID - New PLL Configuration Algorithm macros that will be used at wl128x boot stage - Rename NVS macro name: wl127x and wl128x are using the same NVS file name. However, the ini parameters between them are different. The driver will validate the correct NVS size in wl1271_boot_upload_nvs(). [Cleaned up some of the definitions. -- Luca] Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index b1c7d031c391..1b6a1adb81af 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -343,4 +343,5 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); MODULE_FIRMWARE(WL1271_FW_NAME); +MODULE_FIRMWARE(WL128X_FW_NAME); MODULE_FIRMWARE(WL1271_AP_FW_NAME); -- cgit v1.2.3 From a81159edf8d64011933df177ec42f82d7896a0c7 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 14 Mar 2011 14:05:13 +0200 Subject: wl12xx: 1281/1283 support - add block size handling for sdio and spi Add the the set_block_size op in the SDIO and in the SPI modules. Since it is only used with SDIO, just explicitly set the op to NULL in spi.c Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 1b6a1adb81af..7491b3d8487a 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -51,6 +51,18 @@ static const struct sdio_device_id wl1271_devices[] = { }; MODULE_DEVICE_TABLE(sdio, wl1271_devices); +/* The max SDIO block size is 256 when working with tx padding to SDIO block */ +#define TX_PAD_SDIO_BLK_SIZE 256 + +static void wl1271_sdio_set_block_size(struct wl1271 *wl) +{ + wl->block_size = TX_PAD_SDIO_BLK_SIZE; + + sdio_claim_host(wl->if_priv); + sdio_set_block_size(wl->if_priv, TX_PAD_SDIO_BLK_SIZE); + sdio_release_host(wl->if_priv); +} + static inline struct sdio_func *wl_to_func(struct wl1271 *wl) { return wl->if_priv; @@ -166,6 +178,9 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) sdio_claim_host(func); sdio_enable_func(func); + /* Set the default block size in case it was modified */ + sdio_set_block_size(func, 0); + out: return ret; } @@ -203,7 +218,8 @@ static struct wl1271_if_operations sdio_ops = { .power = wl1271_sdio_set_power, .dev = wl1271_sdio_wl_to_dev, .enable_irq = wl1271_sdio_enable_interrupts, - .disable_irq = wl1271_sdio_disable_interrupts + .disable_irq = wl1271_sdio_disable_interrupts, + .set_block_size = wl1271_sdio_set_block_size, }; static int __devinit wl1271_probe(struct sdio_func *func, -- cgit v1.2.3 From 5ea417ae7749076ddaacb5b36487cae6ac920413 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Sun, 6 Mar 2011 16:32:11 +0200 Subject: wl12xx: 1281/1283 support - New boot sequence Boot sequence support FREF clock and TCXO clock. WL128x has two clocks input - TCXO and FREF. TCXO is the main clock of the device, while FREF is used to sync between the GPS and the cellular modem. Auto-detection checks where TCXO is 32.736MHz or 16.368MHz, in that case the FREF will be used as the WLAN/BT main clock. [Use clock enumeration as defined in linux/wl12xx.h; remove unnecessary else block in wl128x_switch_fref; remove unnecessary change in main.c; remove some unnecessary debug prints and comments; fix potential use of uninitialized value (pll_config) -- Luca] Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 7491b3d8487a..f6dd3dea4f30 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -255,6 +255,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, wl->irq = wlan_data->irq; wl->ref_clock = wlan_data->board_ref_clock; + wl->tcxo_clock = wlan_data->board_tcxo_clock; ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -- cgit v1.2.3 From 1aed55fd784d000fb6741cefb68712d64817bd68 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 6 Mar 2011 16:32:18 +0200 Subject: wl12xx: 1281/1283 support - Use different FW file for AP mode wl127x/wl128x chips Choose a different FW for AP-mode wl127x and wl128x chips, base on chip ID at boot time. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index f6dd3dea4f30..5a2951ed6eda 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -361,4 +361,5 @@ MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); MODULE_FIRMWARE(WL1271_FW_NAME); MODULE_FIRMWARE(WL128X_FW_NAME); -MODULE_FIRMWARE(WL1271_AP_FW_NAME); +MODULE_FIRMWARE(WL127X_AP_FW_NAME); +MODULE_FIRMWARE(WL128X_AP_FW_NAME); -- cgit v1.2.3 From 1d732e8cf3dcc09d7c862b6c12f876533529073d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 Mar 2011 14:49:57 +0200 Subject: wl12xx: Clamp byte mode transfers for 128x chips On wl128x based devices, when TX packets are aggregated, each packet size must be aligned to the SDIO block size, and sent using block mode transfers. The block size is set to 256 bytes, which is less than the maximum possible byte transfer. Thus, if two small packets (< 256 bytes) are aggregated, the aggregation buffer size would be 512, and will be sent using byte mode transfers. This can have undesired side effects. Fix this by setting the MMC_QUIRK_BLKSZ_FOR_BYTE_MODE mmc card quirk. For 127x chips this has no effect, as the block size is set to 512 bytes. Signed-off-by: Arik Nemtsov Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 5a2951ed6eda..2ade222f7cbb 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -246,6 +246,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, /* Grab access to FN0 for ELP reg. */ func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + /* Use block mode for transferring over one block size of data */ + func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; + wlan_data = wl12xx_get_platform_data(); if (IS_ERR(wlan_data)) { ret = PTR_ERR(wlan_data); -- cgit v1.2.3 From 0da13da767cd568c1fe2a7b5b936e86e521b5ae7 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 31 Mar 2011 10:06:58 +0200 Subject: wl12xx: Clean up the block size alignment code Simplify and clean up the block size alignment code: 1. Set the block size according to the padding field type, as it cannot exceed the maximum value this field can hold. 2. Move the alignment code into a function instead of duplicating it in multiple places. 3. In the current implementation, the block_size member can be misleading because a zero value actually means that there's no need to align. Declare a block size alignment quirk instead. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 2ade222f7cbb..8246e9de4306 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -51,15 +51,10 @@ static const struct sdio_device_id wl1271_devices[] = { }; MODULE_DEVICE_TABLE(sdio, wl1271_devices); -/* The max SDIO block size is 256 when working with tx padding to SDIO block */ -#define TX_PAD_SDIO_BLK_SIZE 256 - -static void wl1271_sdio_set_block_size(struct wl1271 *wl) +static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz) { - wl->block_size = TX_PAD_SDIO_BLK_SIZE; - sdio_claim_host(wl->if_priv); - sdio_set_block_size(wl->if_priv, TX_PAD_SDIO_BLK_SIZE); + sdio_set_block_size(wl->if_priv, blksz); sdio_release_host(wl->if_priv); } @@ -178,9 +173,6 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) sdio_claim_host(func); sdio_enable_func(func); - /* Set the default block size in case it was modified */ - sdio_set_block_size(func, 0); - out: return ret; } -- cgit v1.2.3 From 341b7cde6ccc60672fcd7fc84dd24a1b7c0b8d94 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 31 Mar 2011 10:07:01 +0200 Subject: wl12xx: Handle platforms without level trigger interrupts Some platforms are incapable of triggering on level interrupts. Add a platform quirks member in the platform data structure, as well as an edge interrupt quirk which can be set on such platforms. When the interrupt is requested with IRQF_TRIGGER_RISING, IRQF_ONESHOT cannot be used, as we might miss interrupts that occur after the FW status is cleared and before the threaded interrupt handler exits. Moreover, when IRQF_ONESHOT is not set, iterating more than once in the threaded interrupt handler introduces a few race conditions between this handler and the hardirq handler. Currently this is worked around by limiting the loop to one iteration only. This workaround has an impact on performance. To remove to this restriction, the race conditions will need to be addressed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/wl12xx/sdio.c') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 8246e9de4306..bcd4ad7ba90d 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -220,6 +220,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, struct ieee80211_hw *hw; const struct wl12xx_platform_data *wlan_data; struct wl1271 *wl; + unsigned long irqflags; int ret; /* We are only able to handle the wlan function */ @@ -251,9 +252,15 @@ static int __devinit wl1271_probe(struct sdio_func *func, wl->irq = wlan_data->irq; wl->ref_clock = wlan_data->board_ref_clock; wl->tcxo_clock = wlan_data->board_tcxo_clock; + wl->platform_quirks = wlan_data->platform_quirks; + + if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) + irqflags = IRQF_TRIGGER_RISING; + else + irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + irqflags, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); -- cgit v1.2.3