All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] ath6kl: query device tree for firmware board-id
@ 2011-09-12 11:12 Kalle Valo
  2011-09-12 11:12 ` [PATCH 2/9] ath6kl: separate firmware fetch from upload Kalle Valo
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

From: Sam Leffler <sleffler@chromium.org>

When no default board data file is present query the device tree for a
board-id setting to identify the board data to use.  If the FDT lacks the
necesary info fall back to the previous behaviour of using a compile-time
board filename.

Signed-off-by: Sam Leffler <sleffler@chromium.org>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/init.c |   64 ++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index eca34aa..9171670 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -15,6 +15,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/of.h>
 #include <linux/mmc/sdio_func.h>
 #include "core.h"
 #include "cfg80211.h"
@@ -680,6 +681,64 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
 	return ret;
 }
 
+#ifdef CONFIG_OF
+static const char *get_target_ver_dir(const struct ath6kl *ar)
+{
+	switch (ar->version.target_ver) {
+	case AR6003_REV1_VERSION:
+		return "ath6k/AR6003/hw1.0";
+	case AR6003_REV2_VERSION:
+		return "ath6k/AR6003/hw2.0";
+	case AR6003_REV3_VERSION:
+		return "ath6k/AR6003/hw2.1.1";
+	}
+	ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
+		    ar->version.target_ver);
+	return NULL;
+}
+
+/*
+ * Check the device tree for a board-id and use it to construct
+ * the pathname to the firmware file.  Used (for now) to find a
+ * fallback to the "bdata.bin" file--typically a symlink to the
+ * appropriate board-specific file.
+ */
+static bool check_device_tree(struct ath6kl *ar)
+{
+	static const char *board_id_prop = "atheros,board-id";
+	struct device_node *node;
+	char board_filename[64];
+	const char *board_id;
+	int ret;
+
+	for_each_compatible_node(node, NULL, "atheros,ath6kl") {
+		board_id = of_get_property(node, board_id_prop, NULL);
+		if (board_id == NULL) {
+			ath6kl_warn("No \"%s\" property on %s node.\n",
+				    board_id_prop, node->name);
+			continue;
+		}
+		snprintf(board_filename, sizeof(board_filename),
+			 "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id);
+
+		ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
+				    &ar->fw_board_len);
+		if (ret) {
+			ath6kl_err("Failed to get DT board file %s: %d\n",
+				   board_filename, ret);
+			continue;
+		}
+		return true;
+	}
+	return false;
+}
+#else
+static bool check_device_tree(struct ath6kl *ar)
+{
+	return false;
+}
+#endif /* CONFIG_OF */
+
 static int ath6kl_fetch_board_file(struct ath6kl *ar)
 {
 	const char *filename;
@@ -704,6 +763,11 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
 		return 0;
 	}
 
+	if (check_device_tree(ar)) {
+		/* got board file from device tree */
+		return 0;
+	}
+
 	/* there was no proper board file, try to use default instead */
 	ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
 		    filename, ret);


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/9] ath6kl: separate firmware fetch from upload
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:12 ` [PATCH 3/9] ath6kl: fix busy loop in ath6kl_bmi_get_rx_lkahd() Kalle Valo
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

In preparation for the new firmware image format.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/init.c |  249 ++++++++++++++++++++------------
 1 files changed, 153 insertions(+), 96 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 9171670..4055947 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -744,6 +744,9 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
 	const char *filename;
 	int ret;
 
+	if (ar->fw_board != NULL)
+		return 0;
+
 	switch (ar->version.target_ver) {
 	case AR6003_REV2_VERSION:
 		filename = AR6003_REV2_BOARD_DATA_FILE;
@@ -798,6 +801,144 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
 	return 0;
 }
 
+static int ath6kl_fetch_otp_file(struct ath6kl *ar)
+{
+	const char *filename;
+	int ret;
+
+	if (ar->fw_otp != NULL)
+		return 0;
+
+	switch (ar->version.target_ver) {
+	case AR6003_REV2_VERSION:
+		filename = AR6003_REV2_OTP_FILE;
+		break;
+	case AR6004_REV1_VERSION:
+		ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n");
+		return 0;
+		break;
+	default:
+		filename = AR6003_REV3_OTP_FILE;
+		break;
+	}
+
+	ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
+			    &ar->fw_otp_len);
+	if (ret) {
+		ath6kl_err("Failed to get OTP file %s: %d\n",
+			   filename, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath6kl_fetch_fw_file(struct ath6kl *ar)
+{
+	const char *filename;
+	int ret;
+
+	if (ar->fw != NULL)
+		return 0;
+
+	if (testmode) {
+		switch (ar->version.target_ver) {
+		case AR6003_REV2_VERSION:
+			filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
+			break;
+		case AR6003_REV3_VERSION:
+			filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
+			break;
+		case AR6004_REV1_VERSION:
+			ath6kl_warn("testmode not supported with ar6004\n");
+			return -EOPNOTSUPP;
+		default:
+			ath6kl_warn("unknown target version: 0x%x\n",
+				       ar->version.target_ver);
+			return -EINVAL;
+		}
+
+		set_bit(TESTMODE, &ar->flag);
+
+		goto get_fw;
+	}
+
+	switch (ar->version.target_ver) {
+	case AR6003_REV2_VERSION:
+		filename = AR6003_REV2_FIRMWARE_FILE;
+		break;
+	case AR6004_REV1_VERSION:
+		filename = AR6004_REV1_FIRMWARE_FILE;
+		break;
+	default:
+		filename = AR6003_REV3_FIRMWARE_FILE;
+		break;
+	}
+
+get_fw:
+	ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+	if (ret) {
+		ath6kl_err("Failed to get firmware file %s: %d\n",
+			   filename, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath6kl_fetch_patch_file(struct ath6kl *ar)
+{
+	const char *filename;
+	int ret;
+
+	switch (ar->version.target_ver) {
+	case AR6003_REV2_VERSION:
+		filename = AR6003_REV2_PATCH_FILE;
+		break;
+	case AR6004_REV1_VERSION:
+		/* FIXME: implement for AR6004 */
+		return 0;
+		break;
+	default:
+		filename = AR6003_REV3_PATCH_FILE;
+		break;
+	}
+
+	if (ar->fw_patch == NULL) {
+		ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
+				    &ar->fw_patch_len);
+		if (ret) {
+			ath6kl_err("Failed to get patch file %s: %d\n",
+				   filename, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ath6kl_fetch_firmwares(struct ath6kl *ar)
+{
+	int ret;
+
+	ret = ath6kl_fetch_board_file(ar);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_fetch_otp_file(ar);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_fetch_fw_file(ar);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_fetch_patch_file(ar);
+	if (ret)
+		return ret;
+
+	return 0;
+}
 
 static int ath6kl_upload_board_file(struct ath6kl *ar)
 {
@@ -805,11 +946,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
 	u32 board_data_size, board_ext_data_size;
 	int ret;
 
-	if (ar->fw_board == NULL) {
-		ret = ath6kl_fetch_board_file(ar);
-		if (ret)
-			return ret;
-	}
+	if (WARN_ON(ar->fw_board == NULL))
+		return -ENOENT;
 
 	/*
 	 * Determine where in Target RAM to write Board Data.
@@ -909,32 +1047,11 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
 
 static int ath6kl_upload_otp(struct ath6kl *ar)
 {
-	const char *filename;
 	u32 address, param;
 	int ret;
 
-	switch (ar->version.target_ver) {
-	case AR6003_REV2_VERSION:
-		filename = AR6003_REV2_OTP_FILE;
-		break;
-	case AR6004_REV1_VERSION:
-		ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n");
-		return 0;
-		break;
-	default:
-		filename = AR6003_REV3_OTP_FILE;
-		break;
-	}
-
-	if (ar->fw_otp == NULL) {
-		ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
-				    &ar->fw_otp_len);
-		if (ret) {
-			ath6kl_err("Failed to get OTP file %s: %d\n",
-				   filename, ret);
-			return ret;
-		}
-	}
+	if (WARN_ON(ar->fw_otp == NULL))
+		return -ENOENT;
 
 	address = ath6kl_get_load_address(ar->version.target_ver,
 					  APP_LOAD_ADDR);
@@ -957,54 +1074,11 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
 
 static int ath6kl_upload_firmware(struct ath6kl *ar)
 {
-	const char *filename;
 	u32 address;
 	int ret;
 
-	if (testmode) {
-		switch (ar->version.target_ver) {
-		case AR6003_REV2_VERSION:
-			filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
-			break;
-		case AR6003_REV3_VERSION:
-			filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
-			break;
-		case AR6004_REV1_VERSION:
-			ath6kl_warn("testmode not supported with ar6004\n");
-			return -EOPNOTSUPP;
-		default:
-			ath6kl_warn("unknown target version: 0x%x\n",
-				       ar->version.target_ver);
-			return -EINVAL;
-		}
-
-		set_bit(TESTMODE, &ar->flag);
-
-		goto get_fw;
-	}
-
-	switch (ar->version.target_ver) {
-	case AR6003_REV2_VERSION:
-		filename = AR6003_REV2_FIRMWARE_FILE;
-		break;
-	case AR6004_REV1_VERSION:
-		filename = AR6004_REV1_FIRMWARE_FILE;
-		break;
-	default:
-		filename = AR6003_REV3_FIRMWARE_FILE;
-		break;
-	}
-
-get_fw:
-
-	if (ar->fw == NULL) {
-		ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
-		if (ret) {
-			ath6kl_err("Failed to get firmware file %s: %d\n",
-				   filename, ret);
-			return ret;
-		}
-	}
+	if (WARN_ON(ar->fw == NULL))
+		return -ENOENT;
 
 	address = ath6kl_get_load_address(ar->version.target_ver,
 					  APP_LOAD_ADDR);
@@ -1030,32 +1104,11 @@ get_fw:
 
 static int ath6kl_upload_patch(struct ath6kl *ar)
 {
-	const char *filename;
 	u32 address, param;
 	int ret;
 
-	switch (ar->version.target_ver) {
-	case AR6003_REV2_VERSION:
-		filename = AR6003_REV2_PATCH_FILE;
-		break;
-	case AR6004_REV1_VERSION:
-		/* FIXME: implement for AR6004 */
-		return 0;
-		break;
-	default:
-		filename = AR6003_REV3_PATCH_FILE;
-		break;
-	}
-
-	if (ar->fw_patch == NULL) {
-		ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
-				    &ar->fw_patch_len);
-		if (ret) {
-			ath6kl_err("Failed to get patch file %s: %d\n",
-				   filename, ret);
-			return ret;
-		}
-	}
+	if (WARN_ON(ar->fw_patch == NULL))
+		return -ENOENT;
 
 	address = ath6kl_get_load_address(ar->version.target_ver,
 					  DATASET_PATCH_ADDR);
@@ -1362,6 +1415,10 @@ int ath6kl_core_init(struct ath6kl *ar)
 		goto err_htc_cleanup;
 	}
 
+	ret = ath6kl_fetch_firmwares(ar);
+	if (ret)
+		goto err_htc_cleanup;
+
 	ret = ath6kl_init_upload(ar);
 	if (ret)
 		goto err_htc_cleanup;


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/9] ath6kl: fix busy loop in ath6kl_bmi_get_rx_lkahd()
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
  2011-09-12 11:12 ` [PATCH 2/9] ath6kl: separate firmware fetch from upload Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:12 ` [PATCH 4/9] ath6kl: add support for firmware API 2 format Kalle Valo
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

Brent reported that ath6kl busy loops if firmware doesn't boot for some
reason (in this case he was using an older firmware which wasn't supported
by ath6kl).

Investigation revealed that this was even on purpose,
ath6kl_bmi_get_rx_lkahd() had a parameter to disable the timeout check,
which is extremely evil. I didn't find any reason why the timeout needs
to be disabled so I just removed the feature. The function already busyloops
a maximum of one second if it doesn't get an answer, even that's too long.
If something takes longer than that a more friendly approach is needed.

Reported-by: Brent Taylor <btaylor1@motorolasolutions.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/bmi.c |   23 ++++++++++-------------
 1 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index 8467669..c5d11cc 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
 	return 0;
 }
 
-static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout)
+static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
 {
 	unsigned long timeout;
 	u32 rx_word = 0;
 	int ret = 0;
 
 	timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
-	while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) {
+	while (time_before(jiffies, timeout) && !rx_word) {
 		ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
 					  (u8 *)&rx_word, sizeof(rx_word),
 					  HIF_RD_SYNC_BYTE_INC);
@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
 	return ret;
 }
 
-static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
-			u8 *buf, u32 len, bool want_timeout)
+static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
 {
 	int ret;
 	u32 addr;
@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
 	 * a function of Host processor speed.
 	 */
 	if (len >= 4) { /* NB: Currently, always true */
-		ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout);
+		ret = ath6kl_bmi_get_rx_lkahd(ar);
 		if (ret)
 			return ret;
 	}
@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
 	}
 
 	ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
-			sizeof(targ_info->version), true);
+				  sizeof(targ_info->version));
 	if (ret) {
 		ath6kl_err("Unable to recv target info: %d\n", ret);
 		return ret;
@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
 		/* Determine how many bytes are in the Target's targ_info */
 		ret = ath6kl_bmi_recv_buf(ar,
 				   (u8 *)&targ_info->byte_count,
-				   sizeof(targ_info->byte_count),
-				   true);
+				   sizeof(targ_info->byte_count));
 		if (ret) {
 			ath6kl_err("unable to read target info byte count: %d\n",
 				   ret);
@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
 				   ((u8 *)targ_info) +
 				   sizeof(targ_info->byte_count),
 				   sizeof(*targ_info) -
-				   sizeof(targ_info->byte_count),
-				   true);
+				   sizeof(targ_info->byte_count));
 
 		if (ret) {
 			ath6kl_err("Unable to read target info (%d bytes): %d\n",
@@ -311,7 +308,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
 				   ret);
 			return ret;
 		}
-		ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true);
+		ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len);
 		if (ret) {
 			ath6kl_err("Unable to read from the device: %d\n",
 				   ret);
@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
 		return ret;
 	}
 
-	ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false);
+	ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
 	if (ret) {
 		ath6kl_err("Unable to read from the device: %d\n", ret);
 		return ret;
@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
 		return ret;
 	}
 
-	ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true);
+	ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
 	if (ret) {
 		ath6kl_err("Unable to read from the device: %d\n", ret);
 		return ret;


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/9] ath6kl: add support for firmware API 2 format
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
  2011-09-12 11:12 ` [PATCH 2/9] ath6kl: separate firmware fetch from upload Kalle Valo
  2011-09-12 11:12 ` [PATCH 3/9] ath6kl: fix busy loop in ath6kl_bmi_get_rx_lkahd() Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:12 ` [PATCH 5/9] ath6kl: refactor firmware load address code Kalle Valo
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

In the new format all the format images are embedded into one file.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |   20 +++++
 drivers/net/wireless/ath/ath6kl/init.c |  136 +++++++++++++++++++++++++++++++-
 2 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c6ed1fc..761e550 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -58,6 +58,23 @@
 #define A_DEFAULT_LISTEN_INTERVAL         100
 #define A_MAX_WOW_LISTEN_INTERVAL         1000
 
+/* includes also the null byte */
+#define ATH6KL_FIRMWARE_MAGIC               "QCA-ATH6KL"
+
+enum ath6kl_fw_ie_type {
+	ATH6KL_FW_IE_FW_VERSION = 0,
+	ATH6KL_FW_IE_TIMESTAMP = 1,
+	ATH6KL_FW_IE_OTP_IMAGE = 2,
+	ATH6KL_FW_IE_FW_IMAGE = 3,
+	ATH6KL_FW_IE_PATCH_IMAGE = 4,
+};
+
+struct ath6kl_fw_ie {
+	__le32 id;
+	__le32 len;
+	u8 data[0];
+};
+
 /* AR6003 1.0 definitions */
 #define AR6003_REV1_VERSION                 0x300002ba
 
@@ -68,6 +85,7 @@
 #define AR6003_REV2_FIRMWARE_FILE           "ath6k/AR6003/hw2.0/athwlan.bin.z77"
 #define AR6003_REV2_TCMD_FIRMWARE_FILE      "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
 #define AR6003_REV2_PATCH_FILE              "ath6k/AR6003/hw2.0/data.patch.bin"
+#define AR6003_REV2_FIRMWARE_2_FILE         "ath6k/AR6003/hw2.0/fw-2.bin"
 #define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.bin"
 #define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
 
@@ -77,6 +95,7 @@
 #define AR6003_REV3_FIRMWARE_FILE           "ath6k/AR6003/hw2.1.1/athwlan.bin"
 #define AR6003_REV3_TCMD_FIRMWARE_FILE    "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
 #define AR6003_REV3_PATCH_FILE            "ath6k/AR6003/hw2.1.1/data.patch.bin"
+#define AR6003_REV3_FIRMWARE_2_FILE           "ath6k/AR6003/hw2.1.1/fw-2.bin"
 #define AR6003_REV3_BOARD_DATA_FILE       "ath6k/AR6003/hw2.1.1/bdata.bin"
 #define AR6003_REV3_DEFAULT_BOARD_DATA_FILE	\
 	"ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
@@ -84,6 +103,7 @@
 /* AR6004 1.0 definitions */
 #define AR6004_REV1_VERSION                 0x30000623
 #define AR6004_REV1_FIRMWARE_FILE           "ath6k/AR6004/hw6.1/fw.ram.bin"
+#define AR6004_REV1_FIRMWARE_2_FILE         "ath6k/AR6004/hw6.1/fw-2.bin"
 #define AR6004_REV1_BOARD_DATA_FILE         "ath6k/AR6004/hw6.1/bdata.bin"
 #define AR6004_REV1_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.DB132.bin"
 #define AR6004_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6004/hw6.1/endpointping.bin"
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 4055947..41f4e0d 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -917,14 +917,10 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar)
 	return 0;
 }
 
-static int ath6kl_fetch_firmwares(struct ath6kl *ar)
+static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
 {
 	int ret;
 
-	ret = ath6kl_fetch_board_file(ar);
-	if (ret)
-		return ret;
-
 	ret = ath6kl_fetch_otp_file(ar);
 	if (ret)
 		return ret;
@@ -940,6 +936,136 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar)
 	return 0;
 }
 
+static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
+{
+	size_t magic_len, len, ie_len;
+	const struct firmware *fw;
+	struct ath6kl_fw_ie *hdr;
+	const char *filename;
+	const u8 *data;
+	int ret, ie_id;
+
+	switch (ar->version.target_ver) {
+	case AR6003_REV2_VERSION:
+		filename = AR6003_REV2_FIRMWARE_2_FILE;
+		break;
+	case AR6003_REV3_VERSION:
+		filename = AR6003_REV3_FIRMWARE_2_FILE;
+		break;
+	case AR6004_REV1_VERSION:
+		filename = AR6004_REV1_FIRMWARE_2_FILE;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	ret = request_firmware(&fw, filename, ar->dev);
+	if (ret)
+		return ret;
+
+	data = fw->data;
+	len = fw->size;
+
+	/* magic also includes the null byte, check that as well */
+	magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
+
+	if (len < magic_len) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	len -= magic_len;
+	data += magic_len;
+
+	/* loop elements */
+	while (len > sizeof(struct ath6kl_fw_ie)) {
+		/* hdr is unaligned! */
+		hdr = (struct ath6kl_fw_ie *) data;
+
+		ie_id = le32_to_cpup(&hdr->id);
+		ie_len = le32_to_cpup(&hdr->len);
+
+		len -= sizeof(*hdr);
+		data += sizeof(*hdr);
+
+		if (len < ie_len) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		switch (ie_id) {
+		case ATH6KL_FW_IE_OTP_IMAGE:
+			ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
+
+			if (ar->fw_otp == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			ar->fw_otp_len = ie_len;
+			break;
+		case ATH6KL_FW_IE_FW_IMAGE:
+			ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
+
+			if (ar->fw == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			ar->fw_len = ie_len;
+			break;
+		case ATH6KL_FW_IE_PATCH_IMAGE:
+			ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
+
+			if (ar->fw_patch == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			ar->fw_patch_len = ie_len;
+			break;
+		default:
+			ath6kl_dbg(ATH6KL_DBG_TRC, "Unknown fw ie: %u\n",
+				   le32_to_cpup(&hdr->id));
+			break;
+		}
+
+		len -= ie_len;
+		data += ie_len;
+	};
+
+	ret = 0;
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static int ath6kl_fetch_firmwares(struct ath6kl *ar)
+{
+	int ret;
+
+	ret = ath6kl_fetch_board_file(ar);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_fetch_fw_api2(ar);
+	if (ret == 0)
+		/* fw api 2 found, use it */
+		return 0;
+
+	ret = ath6kl_fetch_fw_api1(ar);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int ath6kl_upload_board_file(struct ath6kl *ar)
 {
 	u32 board_address, board_ext_address, param;


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/9] ath6kl: refactor firmware load address code
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (2 preceding siblings ...)
  2011-09-12 11:12 ` [PATCH 4/9] ath6kl: add support for firmware API 2 format Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:12 ` [PATCH 6/9] ath6kl: refactor firmware ext data addr and reserved ram handling size Kalle Valo
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

Currently the load address was calculated everytime when it was needed,
and with a mess if clauses. Simplify this by adding a field to struct
ath6kl for each address and choose the address with simple switch
statements.

Also move the code just after target version is retrieved. That way it's
easier to override the values later in the boot process.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |    6 +++
 drivers/net/wireless/ath/ath6kl/init.c |   76 +++++++++++++++-----------------
 2 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 761e550..77783f8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -462,6 +462,12 @@ struct ath6kl {
 		size_t rx_report_len;
 	} tm;
 
+	struct {
+		u32 dataset_patch_addr;
+		u32 app_load_addr;
+		u32 app_start_override_addr;
+	} hw;
+
 	u16 conf_flags;
 	wait_queue_head_t event_wq;
 	struct ath6kl_mbox_info mbox_info;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 41f4e0d..f94c049 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -56,12 +56,6 @@ module_param(testmode, uint, 0644);
 
 #define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
 
-enum addr_type {
-	DATASET_PATCH_ADDR,
-	APP_LOAD_ADDR,
-	APP_START_OVERRIDE_ADDR,
-};
-
 #define ATH6KL_DATA_OFFSET    64
 struct sk_buff *ath6kl_buf_alloc(int size)
 {
@@ -636,30 +630,6 @@ int ath6kl_unavail_ev(struct ath6kl *ar)
 }
 
 /* firmware upload */
-static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
-{
-	WARN_ON(target_ver != AR6003_REV2_VERSION &&
-		target_ver != AR6003_REV3_VERSION &&
-		target_ver != AR6004_REV1_VERSION);
-
-	switch (type) {
-	case DATASET_PATCH_ADDR:
-		return (target_ver == AR6003_REV2_VERSION) ?
-			AR6003_REV2_DATASET_PATCH_ADDRESS :
-			AR6003_REV3_DATASET_PATCH_ADDRESS;
-	case APP_LOAD_ADDR:
-		return (target_ver == AR6003_REV2_VERSION) ?
-			AR6003_REV2_APP_LOAD_ADDRESS :
-			0x1234;
-	case APP_START_OVERRIDE_ADDR:
-		return (target_ver == AR6003_REV2_VERSION) ?
-			AR6003_REV2_APP_START_OVERRIDE :
-			AR6003_REV3_APP_START_OVERRIDE;
-	default:
-		return 0;
-	}
-}
-
 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
 			 u8 **fw, size_t *fw_len)
 {
@@ -1179,8 +1149,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
 	if (WARN_ON(ar->fw_otp == NULL))
 		return -ENOENT;
 
-	address = ath6kl_get_load_address(ar->version.target_ver,
-					  APP_LOAD_ADDR);
+	address = ar->hw.app_load_addr;
 
 	ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
 				       ar->fw_otp_len);
@@ -1191,8 +1160,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
 
 	/* execute the OTP code */
 	param = 0;
-	address = ath6kl_get_load_address(ar->version.target_ver,
-					  APP_START_OVERRIDE_ADDR);
+	address = ar->hw.app_start_override_addr;
 	ath6kl_bmi_execute(ar, address, &param);
 
 	return ret;
@@ -1206,8 +1174,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar)
 	if (WARN_ON(ar->fw == NULL))
 		return -ENOENT;
 
-	address = ath6kl_get_load_address(ar->version.target_ver,
-					  APP_LOAD_ADDR);
+	address = ar->hw.app_load_addr;
 
 	ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
 
@@ -1221,8 +1188,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar)
 	 * Don't need to setup app_start override addr on AR6004
 	 */
 	if (ar->target_type != TARGET_TYPE_AR6004) {
-		address = ath6kl_get_load_address(ar->version.target_ver,
-						  APP_START_OVERRIDE_ADDR);
+		address = ar->hw.app_start_override_addr;
 		ath6kl_bmi_set_app_start(ar, address);
 	}
 	return ret;
@@ -1236,8 +1202,7 @@ static int ath6kl_upload_patch(struct ath6kl *ar)
 	if (WARN_ON(ar->fw_patch == NULL))
 		return -ENOENT;
 
-	address = ath6kl_get_load_address(ar->version.target_ver,
-					  DATASET_PATCH_ADDR);
+	address = ar->hw.dataset_patch_addr;
 
 	ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
 	if (ret) {
@@ -1384,6 +1349,33 @@ static int ath6kl_init_upload(struct ath6kl *ar)
 	return status;
 }
 
+static int ath6kl_init_hw_params(struct ath6kl *ar)
+{
+	switch (ar->version.target_ver) {
+	case AR6003_REV2_VERSION:
+		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
+		ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS;
+		ar->hw.app_start_override_addr = AR6003_REV2_APP_START_OVERRIDE;
+		break;
+	case AR6003_REV3_VERSION:
+		ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS;
+		ar->hw.app_load_addr = 0x1234;
+		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
+		break;
+	case AR6004_REV1_VERSION:
+		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
+		ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS;
+		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
+		break;
+	default:
+		ath6kl_err("Unsupported hardware version: 0x%x\n",
+			   ar->version.target_ver);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int ath6kl_init(struct net_device *dev)
 {
 	struct ath6kl *ar = ath6kl_priv(dev);
@@ -1523,6 +1515,10 @@ int ath6kl_core_init(struct ath6kl *ar)
 	ar->target_type = le32_to_cpu(targ_info.type);
 	ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
 
+	ret = ath6kl_init_hw_params(ar);
+	if (ret)
+		goto err_bmi_cleanup;
+
 	ret = ath6kl_configure_target(ar);
 	if (ret)
 		goto err_bmi_cleanup;


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/9] ath6kl: refactor firmware ext data addr and reserved ram handling size
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (3 preceding siblings ...)
  2011-09-12 11:12 ` [PATCH 5/9] ath6kl: refactor firmware load address code Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:12 ` [PATCH 7/9] ath6kl: read firmware start address from hardware Kalle Valo
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

Less if clauses this way and again easier to override the values.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |    2 +
 drivers/net/wireless/ath/ath6kl/init.c |   46 ++++++++++++++------------------
 2 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 77783f8..3365dc8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -466,6 +466,8 @@ struct ath6kl {
 		u32 dataset_patch_addr;
 		u32 app_load_addr;
 		u32 app_start_override_addr;
+		u32 board_ext_data_addr;
+		u32 reserved_ram_size;
 	} hw;
 
 	u16 conf_flags;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index f94c049..bf0385e 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -527,33 +527,21 @@ int ath6kl_configure_target(struct ath6kl *ar)
 	 * but possible in theory.
 	 */
 
-	if (ar->target_type == TARGET_TYPE_AR6003 ||
-	    ar->target_type == TARGET_TYPE_AR6004) {
-		if (ar->version.target_ver == AR6003_REV2_VERSION) {
-			param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
-			ram_reserved_size =  AR6003_REV2_RAM_RESERVE_SIZE;
-		} else if (ar->version.target_ver == AR6004_REV1_VERSION) {
-			param = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
-			ram_reserved_size =  AR6004_REV1_RAM_RESERVE_SIZE;
-		} else {
-			param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
-			ram_reserved_size =  AR6003_REV3_RAM_RESERVE_SIZE;
-		}
+	param = ar->hw.board_ext_data_addr;
+	ram_reserved_size = ar->hw.reserved_ram_size;
 
-		if (ath6kl_bmi_write(ar,
-				     ath6kl_get_hi_item_addr(ar,
-				     HI_ITEM(hi_board_ext_data)),
-				     (u8 *)&param, 4) != 0) {
-			ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
-			return -EIO;
-		}
-		if (ath6kl_bmi_write(ar,
-				     ath6kl_get_hi_item_addr(ar,
-				     HI_ITEM(hi_end_ram_reserve_sz)),
-				     (u8 *)&ram_reserved_size, 4) != 0) {
-			ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
-			return -EIO;
-		}
+	if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
+					HI_ITEM(hi_board_ext_data)),
+			     (u8 *)&param, 4) != 0) {
+		ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
+		return -EIO;
+	}
+
+	if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
+					HI_ITEM(hi_end_ram_reserve_sz)),
+			     (u8 *)&ram_reserved_size, 4) != 0) {
+		ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
+		return -EIO;
 	}
 
 	/* set the block size for the target */
@@ -1356,16 +1344,22 @@ static int ath6kl_init_hw_params(struct ath6kl *ar)
 		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS;
 		ar->hw.app_start_override_addr = AR6003_REV2_APP_START_OVERRIDE;
+		ar->hw.board_ext_data_addr = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
+		ar->hw.reserved_ram_size = AR6003_REV2_RAM_RESERVE_SIZE;
 		break;
 	case AR6003_REV3_VERSION:
 		ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = 0x1234;
 		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
+		ar->hw.board_ext_data_addr = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
+		ar->hw.reserved_ram_size = AR6003_REV3_RAM_RESERVE_SIZE;
 		break;
 	case AR6004_REV1_VERSION:
 		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS;
 		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
+		ar->hw.board_ext_data_addr = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
+		ar->hw.reserved_ram_size = AR6004_REV1_RAM_RESERVE_SIZE;
 		break;
 	default:
 		ath6kl_err("Unsupported hardware version: 0x%x\n",


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/9] ath6kl: read firmware start address from hardware
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (4 preceding siblings ...)
  2011-09-12 11:12 ` [PATCH 6/9] ath6kl: refactor firmware ext data addr and reserved ram handling size Kalle Valo
@ 2011-09-12 11:12 ` Kalle Valo
  2011-09-12 11:13 ` [PATCH 8/9] ath6kl: read reserved ram size from firmware file Kalle Valo
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:12 UTC (permalink / raw)
  To: linux-wireless

It's actually possible to read the firmware start address from hardware,
that way there's no need to hardcore the address in hardware.

Thanks to Chilam Ng for the idea.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/init.c   |   17 +++++++++++++----
 drivers/net/wireless/ath/ath6kl/target.h |    2 --
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index bf0385e..5865466 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1146,9 +1146,21 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
 		return ret;
 	}
 
+	/* read firmware start address */
+	ret = ath6kl_bmi_read(ar,
+			      ath6kl_get_hi_item_addr(ar,
+						      HI_ITEM(hi_app_start)),
+			      (u8 *) &address, sizeof(address));
+
+	if (ret) {
+		ath6kl_err("Failed to read hi_app_start: %d\n", ret);
+		return ret;
+	}
+
+	ar->hw.app_start_override_addr = address;
+
 	/* execute the OTP code */
 	param = 0;
-	address = ar->hw.app_start_override_addr;
 	ath6kl_bmi_execute(ar, address, &param);
 
 	return ret;
@@ -1343,21 +1355,18 @@ static int ath6kl_init_hw_params(struct ath6kl *ar)
 	case AR6003_REV2_VERSION:
 		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS;
-		ar->hw.app_start_override_addr = AR6003_REV2_APP_START_OVERRIDE;
 		ar->hw.board_ext_data_addr = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
 		ar->hw.reserved_ram_size = AR6003_REV2_RAM_RESERVE_SIZE;
 		break;
 	case AR6003_REV3_VERSION:
 		ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = 0x1234;
-		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
 		ar->hw.board_ext_data_addr = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
 		ar->hw.reserved_ram_size = AR6003_REV3_RAM_RESERVE_SIZE;
 		break;
 	case AR6004_REV1_VERSION:
 		ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS;
 		ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS;
-		ar->hw.app_start_override_addr = AR6003_REV3_APP_START_OVERRIDE;
 		ar->hw.board_ext_data_addr = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
 		ar->hw.reserved_ram_size = AR6004_REV1_RAM_RESERVE_SIZE;
 		break;
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index 7db06a5..c9a7605 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -331,13 +331,11 @@ struct host_interest {
 	(((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \
 	(((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0))
 
-#define AR6003_REV2_APP_START_OVERRIDE          0x944C00
 #define AR6003_REV2_APP_LOAD_ADDRESS            0x543180
 #define AR6003_REV2_BOARD_EXT_DATA_ADDRESS      0x57E500
 #define AR6003_REV2_DATASET_PATCH_ADDRESS       0x57e884
 #define AR6003_REV2_RAM_RESERVE_SIZE            6912
 
-#define AR6003_REV3_APP_START_OVERRIDE          0x945d00
 #define AR6003_REV3_APP_LOAD_ADDRESS            0x545000
 #define AR6003_REV3_BOARD_EXT_DATA_ADDRESS      0x542330
 #define AR6003_REV3_DATASET_PATCH_ADDRESS       0x57FF74


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/9] ath6kl: read reserved ram size from firmware file
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (5 preceding siblings ...)
  2011-09-12 11:12 ` [PATCH 7/9] ath6kl: read firmware start address from hardware Kalle Valo
@ 2011-09-12 11:13 ` Kalle Valo
  2011-09-12 11:13 ` [PATCH 9/9] ath6kl: add firmware capabilities support Kalle Valo
  2011-09-15 13:37 ` [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:13 UTC (permalink / raw)
  To: linux-wireless

A new version of firmware needs different reserved ram size so read that
from the firmware image.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |    1 +
 drivers/net/wireless/ath/ath6kl/init.c |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 3365dc8..abb4aaf 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -67,6 +67,7 @@ enum ath6kl_fw_ie_type {
 	ATH6KL_FW_IE_OTP_IMAGE = 2,
 	ATH6KL_FW_IE_FW_IMAGE = 3,
 	ATH6KL_FW_IE_PATCH_IMAGE = 4,
+	ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
 };
 
 struct ath6kl_fw_ie {
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 5865466..e2a29b2 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -902,6 +902,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
 	const char *filename;
 	const u8 *data;
 	int ret, ie_id;
+	__le32 *val;
 
 	switch (ar->version.target_ver) {
 	case AR6003_REV2_VERSION:
@@ -987,6 +988,10 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
 
 			ar->fw_patch_len = ie_len;
 			break;
+		case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
+			val = (__le32 *) data;
+			ar->hw.reserved_ram_size = le32_to_cpup(val);
+			break;
 		default:
 			ath6kl_dbg(ATH6KL_DBG_TRC, "Unknown fw ie: %u\n",
 				   le32_to_cpup(&hdr->id));


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 9/9] ath6kl: add firmware capabilities support
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (6 preceding siblings ...)
  2011-09-12 11:13 ` [PATCH 8/9] ath6kl: read reserved ram size from firmware file Kalle Valo
@ 2011-09-12 11:13 ` Kalle Valo
  2011-09-15 13:37 ` [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-12 11:13 UTC (permalink / raw)
  To: linux-wireless

The new firmware format includes capability bits which make it
possible to check what features the firmware supports. Add infrastructure
to read the capabilities. For now it only provides
ATH6KL_FW_CAPABILITY_HOST_P2P which is not even used anywhere yet, but that
will be added later.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |   12 ++++++++++++
 drivers/net/wireless/ath/ath6kl/init.c |   11 ++++++++++-
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index abb4aaf..0fb82e9 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -68,8 +68,18 @@ enum ath6kl_fw_ie_type {
 	ATH6KL_FW_IE_FW_IMAGE = 3,
 	ATH6KL_FW_IE_PATCH_IMAGE = 4,
 	ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
+	ATH6KL_FW_IE_CAPABILITIES = 6,
 };
 
+enum ath6kl_fw_capability {
+	ATH6KL_FW_CAPABILITY_HOST_P2P = 0,
+
+	/* this needs to be last */
+	ATH6KL_FW_CAPABILITY_MAX,
+};
+
+#define ATH6KL_CAPABILITY_LEN (ALIGN(ATH6KL_FW_CAPABILITY_MAX, 32) / 32)
+
 struct ath6kl_fw_ie {
 	__le32 id;
 	__le32 len;
@@ -491,6 +501,8 @@ struct ath6kl {
 	u8 *fw_patch;
 	size_t fw_patch_len;
 
+	unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
+
 	struct workqueue_struct *ath6kl_wq;
 
 	struct ath6kl_node_table scan_table;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index e2a29b2..b9b13a0 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -901,7 +901,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
 	struct ath6kl_fw_ie *hdr;
 	const char *filename;
 	const u8 *data;
-	int ret, ie_id;
+	int ret, ie_id, i, index, bit;
 	__le32 *val;
 
 	switch (ar->version.target_ver) {
@@ -992,6 +992,15 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
 			val = (__le32 *) data;
 			ar->hw.reserved_ram_size = le32_to_cpup(val);
 			break;
+		case ATH6KL_FW_IE_CAPABILITIES:
+			for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
+				index = ALIGN(i, 8) / 8;
+				bit = i % 8;
+
+				if (data[index] & (1 << bit))
+					__set_bit(i, ar->fw_capabilities);
+			}
+			break;
 		default:
 			ath6kl_dbg(ATH6KL_DBG_TRC, "Unknown fw ie: %u\n",
 				   le32_to_cpup(&hdr->id));


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/9] ath6kl: query device tree for firmware board-id
  2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
                   ` (7 preceding siblings ...)
  2011-09-12 11:13 ` [PATCH 9/9] ath6kl: add firmware capabilities support Kalle Valo
@ 2011-09-15 13:37 ` Kalle Valo
  8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2011-09-15 13:37 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless

On 09/12/2011 02:12 PM, Kalle Valo wrote:
> From: Sam Leffler <sleffler@chromium.org>
> 
> When no default board data file is present query the device tree for a
> board-id setting to identify the board data to use.  If the FDT lacks the
> necesary info fall back to the previous behaviour of using a compile-time
> board filename.

All nine patches applied.

Kalle

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-09-15 13:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-12 11:12 [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo
2011-09-12 11:12 ` [PATCH 2/9] ath6kl: separate firmware fetch from upload Kalle Valo
2011-09-12 11:12 ` [PATCH 3/9] ath6kl: fix busy loop in ath6kl_bmi_get_rx_lkahd() Kalle Valo
2011-09-12 11:12 ` [PATCH 4/9] ath6kl: add support for firmware API 2 format Kalle Valo
2011-09-12 11:12 ` [PATCH 5/9] ath6kl: refactor firmware load address code Kalle Valo
2011-09-12 11:12 ` [PATCH 6/9] ath6kl: refactor firmware ext data addr and reserved ram handling size Kalle Valo
2011-09-12 11:12 ` [PATCH 7/9] ath6kl: read firmware start address from hardware Kalle Valo
2011-09-12 11:13 ` [PATCH 8/9] ath6kl: read reserved ram size from firmware file Kalle Valo
2011-09-12 11:13 ` [PATCH 9/9] ath6kl: add firmware capabilities support Kalle Valo
2011-09-15 13:37 ` [PATCH 1/9] ath6kl: query device tree for firmware board-id Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.