From c50a282515dc7092f7318708a0f3ae7ca7342b9f Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 22 Nov 2012 18:06:19 +0200 Subject: wlcore: update events enum/struct to new fw api The event mailbox in wl18xx has a different (non-compatible) structure. Create common functions in wlcore to handle the events, and call them from the chip-specific event mailbox parsers. This way, each driver (wl12xx/wl18xx) extracts the event mailbox by itself according to its own structure, and then calls the common wlcore functions to handle it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/boot.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers/net/wireless/ti/wlcore/boot.c') diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 375ea574eafb..230c765ab401 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -491,7 +491,7 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) if (ret < 0) return ret; - wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); + wl->mbox_ptr[1] = wl->mbox_ptr[0] + wl->mbox_size; wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", wl->mbox_ptr[0], wl->mbox_ptr[1]); @@ -508,23 +508,6 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) */ /* unmask required mbox events */ - wl->event_mask = BSS_LOSE_EVENT_ID | - REGAINED_BSS_EVENT_ID | - SCAN_COMPLETE_EVENT_ID | - ROLE_STOP_COMPLETE_EVENT_ID | - RSSI_SNR_TRIGGER_0_EVENT_ID | - PSPOLL_DELIVERY_FAILURE_EVENT_ID | - SOFT_GEMINI_SENSE_EVENT_ID | - PERIODIC_SCAN_REPORT_EVENT_ID | - PERIODIC_SCAN_COMPLETE_EVENT_ID | - DUMMY_PACKET_EVENT_ID | - PEER_REMOVE_COMPLETE_EVENT_ID | - BA_SESSION_RX_CONSTRAINT_EVENT_ID | - REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | - INACTIVE_STA_EVENT_ID | - MAX_TX_RETRY_EVENT_ID | - CHANNEL_SWITCH_COMPLETE_EVENT_ID; - ret = wl1271_event_unmask(wl); if (ret < 0) { wl1271_error("EVENT mask setting failed"); -- cgit v1.2.3 From af4e94c56581b446b2010854a983ef722ad9ed1f Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 27 Nov 2012 15:51:58 +0200 Subject: wlcore: change way of checking the firmware version The firmwares version string contain 5 integers. We used to consider all the digits (except for the first one, which indicates the chip) as linearly increasing version numbers. This is not correct, because some of the integers indicate type of firmware (eg. single-role vs. multi-role) or the internal project it was created for. Besides, this varies a bit from chip to chip, so we need to make the firmware version checks more flexible (eg. allow the lower driver to ignore some of the integers). Additionally, we need to change the code so that we only check for a linearly increasing number on the fields where this actually makes sense. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/boot.c | 55 +++++++++++++++++++-------------- drivers/net/wireless/ti/wlcore/wlcore.h | 3 ++ 2 files changed, 35 insertions(+), 23 deletions(-) (limited to 'drivers/net/wireless/ti/wlcore/boot.c') diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 230c765ab401..2c57246b6a85 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -85,46 +85,55 @@ static int wlcore_validate_fw_ver(struct wl1271 *wl) { unsigned int *fw_ver = wl->chip.fw_ver; unsigned int *min_ver = wl->min_fw_ver; + char min_fw_str[32] = ""; + int i; /* the chip must be exactly equal */ - if (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP]) + if ((min_ver[FW_VER_CHIP] != WLCORE_FW_VER_IGNORE) && + (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP])) goto fail; - /* always check the next digit if all previous ones are equal */ - - if (min_ver[FW_VER_IF_TYPE] < fw_ver[FW_VER_IF_TYPE]) - goto out; - else if (min_ver[FW_VER_IF_TYPE] > fw_ver[FW_VER_IF_TYPE]) + /* the firmware type must be equal */ + if ((min_ver[FW_VER_IF_TYPE] != WLCORE_FW_VER_IGNORE) && + (min_ver[FW_VER_IF_TYPE] != fw_ver[FW_VER_IF_TYPE])) goto fail; - if (min_ver[FW_VER_MAJOR] < fw_ver[FW_VER_MAJOR]) - goto out; - else if (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR]) + /* the project number must be equal */ + if ((min_ver[FW_VER_SUBTYPE] != WLCORE_FW_VER_IGNORE) && + (min_ver[FW_VER_SUBTYPE] != fw_ver[FW_VER_SUBTYPE])) goto fail; - if (min_ver[FW_VER_SUBTYPE] < fw_ver[FW_VER_SUBTYPE]) - goto out; - else if (min_ver[FW_VER_SUBTYPE] > fw_ver[FW_VER_SUBTYPE]) + /* the API version must be greater or equal */ + if ((min_ver[FW_VER_MAJOR] != WLCORE_FW_VER_IGNORE) && + (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR])) goto fail; - if (min_ver[FW_VER_MINOR] < fw_ver[FW_VER_MINOR]) - goto out; - else if (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR]) + /* if the API version is equal... */ + if (((min_ver[FW_VER_MAJOR] == WLCORE_FW_VER_IGNORE) || + (min_ver[FW_VER_MAJOR] == fw_ver[FW_VER_MAJOR])) && + /* ...the minor must be greater or equal */ + ((min_ver[FW_VER_MINOR] != WLCORE_FW_VER_IGNORE) && + (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR]))) goto fail; -out: return 0; fail: - wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is outdated.\n" - "Please use at least FW %u.%u.%u.%u.%u.\n" - "You can get more information at:\n" - "http://wireless.kernel.org/en/users/Drivers/wl12xx", + for (i = 0; i < NUM_FW_VER; i++) + if (min_ver[i] == WLCORE_FW_VER_IGNORE) + snprintf(min_fw_str, sizeof(min_fw_str), + "%s*.", min_fw_str); + else + snprintf(min_fw_str, sizeof(min_fw_str), + "%s%u.", min_fw_str, min_ver[i]); + + wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n" + "Please use at least FW %s\n" + "You can get the latest firmwares at:\n" + "git://github.com/TI-OpenLink/firmwares.git", fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE], fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE], - fw_ver[FW_VER_MINOR], min_ver[FW_VER_CHIP], - min_ver[FW_VER_IF_TYPE], min_ver[FW_VER_MAJOR], - min_ver[FW_VER_SUBTYPE], min_ver[FW_VER_MINOR]); + fw_ver[FW_VER_MINOR], min_fw_str); return -EINVAL; } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index c28e89190ac6..66b8306883d2 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -466,6 +466,9 @@ wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); } +/* Tell wlcore not to care about this element when checking the version */ +#define WLCORE_FW_VER_IGNORE -1 + static inline void wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, unsigned int iftype, unsigned int major, -- cgit v1.2.3 From 8675f9abdf5b67a3f621fa99e1f0e0c8d8ae2531 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 27 Nov 2012 15:52:00 +0200 Subject: wlcore/wl12xx/wl18xx: verify multi-role and single-role fw versions Previously we were only checking the single-role firmware version. Now add code to check for the firmware versions separately for each firmware type. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 24 +++++++++++++++--------- drivers/net/wireless/ti/wl12xx/wl12xx.h | 32 ++++++++++++++++++++++---------- drivers/net/wireless/ti/wl18xx/main.c | 8 +++++--- drivers/net/wireless/ti/wlcore/boot.c | 3 ++- drivers/net/wireless/ti/wlcore/wlcore.h | 29 ++++++++++++++++++++--------- 5 files changed, 64 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/ti/wlcore/boot.c') diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 07f7f76a0783..37e577ff17cb 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -653,9 +653,11 @@ static int wl12xx_identify_chip(struct wl1271 *wl) /* read data preparation is only needed by wl127x */ wl->ops->prepare_read = wl127x_prepare_read; - wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER, - WL127X_MAJOR_VER, WL127X_SUBTYPE_VER, - WL127X_MINOR_VER); + wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, + WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER, + WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER, + WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER, + WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER); break; case CHIP_ID_127X_PG20: @@ -675,9 +677,11 @@ static int wl12xx_identify_chip(struct wl1271 *wl) /* read data preparation is only needed by wl127x */ wl->ops->prepare_read = wl127x_prepare_read; - wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER, - WL127X_MAJOR_VER, WL127X_SUBTYPE_VER, - WL127X_MINOR_VER); + wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, + WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER, + WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER, + WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER, + WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER); break; case CHIP_ID_128X_PG20: @@ -693,9 +697,11 @@ static int wl12xx_identify_chip(struct wl1271 *wl) 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, - WL128X_MINOR_VER); + wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, + WL128X_IFTYPE_SR_VER, WL128X_MAJOR_SR_VER, + WL128X_SUBTYPE_SR_VER, WL128X_MINOR_SR_VER, + WL128X_IFTYPE_MR_VER, WL128X_MAJOR_MR_VER, + WL128X_SUBTYPE_MR_VER, WL128X_MINOR_MR_VER); break; case CHIP_ID_128X_PG10: default: diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 310df5200c26..a07be5e022fb 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h @@ -30,19 +30,31 @@ #define CHIP_ID_128X_PG10 (0x05030101) #define CHIP_ID_128X_PG20 (0x05030111) -/* minimum FW required for driver for wl127x */ +/* FW chip version for wl127x */ #define WL127X_CHIP_VER 6 -#define WL127X_IFTYPE_VER WLCORE_FW_VER_IGNORE -#define WL127X_MAJOR_VER 10 -#define WL127X_SUBTYPE_VER WLCORE_FW_VER_IGNORE -#define WL127X_MINOR_VER 115 +/* minimum single-role FW version for wl127x */ +#define WL127X_IFTYPE_SR_VER 3 +#define WL127X_MAJOR_SR_VER 10 +#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE +#define WL127X_MINOR_SR_VER 115 +/* minimum multi-role FW version for wl127x */ +#define WL127X_IFTYPE_MR_VER 5 +#define WL127X_MAJOR_MR_VER 7 +#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE +#define WL127X_MINOR_MR_VER 115 -/* minimum FW required for driver for wl128x */ +/* FW chip version for wl128x */ #define WL128X_CHIP_VER 7 -#define WL128X_IFTYPE_VER WLCORE_FW_VER_IGNORE -#define WL128X_MAJOR_VER 10 -#define WL128X_SUBTYPE_VER WLCORE_FW_VER_IGNORE -#define WL128X_MINOR_VER 115 +/* minimum single-role FW version for wl128x */ +#define WL128X_IFTYPE_SR_VER 3 +#define WL128X_MAJOR_SR_VER 10 +#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE +#define WL128X_MINOR_SR_VER 115 +/* minimum multi-role FW version for wl128x */ +#define WL128X_IFTYPE_MR_VER 5 +#define WL128X_MAJOR_MR_VER 7 +#define WL128X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE +#define WL128X_MINOR_MR_VER 42 #define WL12XX_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 98d034b4530d..08c3a2fc427e 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -623,9 +623,11 @@ static int wl18xx_identify_chip(struct wl1271 *wl) WLCORE_QUIRK_REGDOMAIN_CONF | WLCORE_QUIRK_DUAL_PROBE_TMPL; - wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, WL18XX_IFTYPE_VER, - WL18XX_MAJOR_VER, WL18XX_SUBTYPE_VER, - WL18XX_MINOR_VER); + wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, + WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER, + WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER, + /* there's no separate multi-role FW */ + 0, 0, 0, 0); break; case CHIP_ID_185x_PG10: wl1271_warning("chip id 0x%x (185x PG10) is deprecated", diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 2c57246b6a85..b58ae5fc1487 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -84,7 +84,8 @@ out: static int wlcore_validate_fw_ver(struct wl1271 *wl) { unsigned int *fw_ver = wl->chip.fw_ver; - unsigned int *min_ver = wl->min_fw_ver; + unsigned int *min_ver = (wl->fw_type == WL12XX_FW_TYPE_NORMAL) ? + wl->min_sr_fw_ver : wl->min_mr_fw_ver; char min_fw_str[32] = ""; int i; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 66b8306883d2..32987d0a5f73 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -439,8 +439,11 @@ struct wl1271 { /* the number of allocated MAC addresses in this chip */ int num_mac_addr; - /* the minimum FW version required for the driver to work */ - unsigned int min_fw_ver[NUM_FW_VER]; + /* minimum FW version required for the driver to work in single-role */ + unsigned int min_sr_fw_ver[NUM_FW_VER]; + + /* minimum FW version required for the driver to work in multi-role */ + unsigned int min_mr_fw_ver[NUM_FW_VER]; struct completion nvs_loading_complete; @@ -471,14 +474,22 @@ wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, static inline void wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, - unsigned int iftype, unsigned int major, - unsigned int subtype, unsigned int minor) + unsigned int iftype_sr, unsigned int major_sr, + unsigned int subtype_sr, unsigned int minor_sr, + unsigned int iftype_mr, unsigned int major_mr, + unsigned int subtype_mr, unsigned int minor_mr) { - wl->min_fw_ver[FW_VER_CHIP] = chip; - wl->min_fw_ver[FW_VER_IF_TYPE] = iftype; - wl->min_fw_ver[FW_VER_MAJOR] = major; - wl->min_fw_ver[FW_VER_SUBTYPE] = subtype; - wl->min_fw_ver[FW_VER_MINOR] = minor; + wl->min_sr_fw_ver[FW_VER_CHIP] = chip; + wl->min_sr_fw_ver[FW_VER_IF_TYPE] = iftype_sr; + wl->min_sr_fw_ver[FW_VER_MAJOR] = major_sr; + wl->min_sr_fw_ver[FW_VER_SUBTYPE] = subtype_sr; + wl->min_sr_fw_ver[FW_VER_MINOR] = minor_sr; + + wl->min_mr_fw_ver[FW_VER_CHIP] = chip; + wl->min_mr_fw_ver[FW_VER_IF_TYPE] = iftype_mr; + wl->min_mr_fw_ver[FW_VER_MAJOR] = major_mr; + wl->min_mr_fw_ver[FW_VER_SUBTYPE] = subtype_mr; + wl->min_mr_fw_ver[FW_VER_MINOR] = minor_mr; } /* Firmware image load chunk size */ -- cgit v1.2.3 From 9646b1346760a0af1035f0c59ba727fca1f5824d Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 12 Dec 2012 10:14:22 +0200 Subject: wlcore: use single-role version when verifying the PLT firmware The PLT firmware used by wl12xx for calibration always has the same version number as the single-role firmware. Currntly the driver rejects the PLT firmware since anything that is not single-role uses the multi-role version. Fix this by using the single-role version for everything except multi-role. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/boot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ti/wlcore/boot.c') diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index b58ae5fc1487..77752b03f189 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -84,8 +84,8 @@ out: static int wlcore_validate_fw_ver(struct wl1271 *wl) { unsigned int *fw_ver = wl->chip.fw_ver; - unsigned int *min_ver = (wl->fw_type == WL12XX_FW_TYPE_NORMAL) ? - wl->min_sr_fw_ver : wl->min_mr_fw_ver; + unsigned int *min_ver = (wl->fw_type == WL12XX_FW_TYPE_MULTI) ? + wl->min_mr_fw_ver : wl->min_sr_fw_ver; char min_fw_str[32] = ""; int i; -- cgit v1.2.3