aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2012-05-10 05:14:10 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-05 08:58:20 -0400
commit7140df6e51ecca70e8963f18e9836e62090221c2 (patch)
tree1ca50fe5978940f0fce150c71ece37cc7e0fa4f5 /drivers
parent8c0ea1021c38cfd2f0ba5d8fdd48a9e9827bbc03 (diff)
wlcore: create private static_data area and add operation to parse it
The wl18xx firmware has more information in the static_data than wl12xx. To be able to parse that in an abstracted way, this patch adds a priv area to the static data struct and an operation that allows the lower driver to parse it if necessary. Signed-off-by: Luciano Coelho <coelho@ti.com> Signed-off-by: Arik Nemtsov <arik@wizery.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c53
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.h1
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h6
4 files changed, 46 insertions, 23 deletions
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
index 9b98230f84ce..ed718f7ddcce 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -45,10 +45,17 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
45 wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); 45 wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl);
46} 46}
47 47
48static int wlcore_parse_fw_ver(struct wl1271 *wl) 48static int wlcore_boot_parse_fw_ver(struct wl1271 *wl,
49 struct wl1271_static_data *static_data)
49{ 50{
50 int ret; 51 int ret;
51 52
53 strncpy(wl->chip.fw_ver_str, static_data->fw_version,
54 sizeof(wl->chip.fw_ver_str));
55
56 /* make sure the string is NULL-terminated */
57 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
58
52 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u", 59 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
53 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1], 60 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
54 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3], 61 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
@@ -57,43 +64,43 @@ static int wlcore_parse_fw_ver(struct wl1271 *wl)
57 if (ret != 5) { 64 if (ret != 5) {
58 wl1271_warning("fw version incorrect value"); 65 wl1271_warning("fw version incorrect value");
59 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); 66 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
60 return -EINVAL; 67 ret = -EINVAL;
68 goto out;
61 } 69 }
62 70
63 ret = wlcore_identify_fw(wl); 71 ret = wlcore_identify_fw(wl);
64 if (ret < 0) 72 if (ret < 0)
65 return ret; 73 goto out;
66 74out:
67 return 0; 75 return ret;
68} 76}
69 77
70static int wlcore_boot_fw_version(struct wl1271 *wl) 78static int wlcore_boot_static_data(struct wl1271 *wl)
71{ 79{
72 struct wl1271_static_data *static_data; 80 struct wl1271_static_data *static_data;
81 size_t len = sizeof(*static_data) + wl->static_data_priv_len;
73 int ret; 82 int ret;
74 83
75 static_data = kmalloc(sizeof(*static_data), GFP_KERNEL | GFP_DMA); 84 static_data = kmalloc(len, GFP_KERNEL);
76 if (!static_data) { 85 if (!static_data) {
77 wl1271_error("Couldn't allocate memory for static data!"); 86 ret = -ENOMEM;
78 return -ENOMEM; 87 goto out;
79 } 88 }
80 89
81 wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data), 90 wl1271_read(wl, wl->cmd_box_addr, static_data, len, false);
82 false);
83 91
84 strncpy(wl->chip.fw_ver_str, static_data->fw_version, 92 ret = wlcore_boot_parse_fw_ver(wl, static_data);
85 sizeof(wl->chip.fw_ver_str)); 93 if (ret < 0)
86 94 goto out_free;
87 kfree(static_data);
88
89 /* make sure the string is NULL-terminated */
90 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
91 95
92 ret = wlcore_parse_fw_ver(wl); 96 ret = wlcore_handle_static_data(wl, static_data);
93 if (ret < 0) 97 if (ret < 0)
94 return ret; 98 goto out_free;
95 99
96 return 0; 100out_free:
101 kfree(static_data);
102out:
103 return ret;
97} 104}
98 105
99static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, 106static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
@@ -400,9 +407,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
400 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", 407 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x",
401 wl->mbox_ptr[0], wl->mbox_ptr[1]); 408 wl->mbox_ptr[0], wl->mbox_ptr[1]);
402 409
403 ret = wlcore_boot_fw_version(wl); 410 ret = wlcore_boot_static_data(wl);
404 if (ret < 0) { 411 if (ret < 0) {
405 wl1271_error("couldn't boot firmware"); 412 wl1271_error("error getting static data");
406 return ret; 413 return ret;
407 } 414 }
408 415
diff --git a/drivers/net/wireless/ti/wlcore/boot.h b/drivers/net/wireless/ti/wlcore/boot.h
index 094981dd2227..a525225f990c 100644
--- a/drivers/net/wireless/ti/wlcore/boot.h
+++ b/drivers/net/wireless/ti/wlcore/boot.h
@@ -40,6 +40,7 @@ struct wl1271_static_data {
40 u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; 40 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
41 u32 hw_version; 41 u32 hw_version;
42 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; 42 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
43 u8 priv[0];
43}; 44};
44 45
45/* number of times we try to read the INIT interrupt */ 46/* number of times we try to read the INIT interrupt */
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 1555c3e12c1b..c590b6f529d1 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -158,4 +158,13 @@ wlcore_debugfs_init(struct wl1271 *wl, struct dentry *rootdir)
158 return 0; 158 return 0;
159} 159}
160 160
161static inline int
162wlcore_handle_static_data(struct wl1271 *wl, void *static_data)
163{
164 if (wl->ops->handle_static_data)
165 return wl->ops->handle_static_data(wl, static_data);
166
167 return 0;
168}
169
161#endif 170#endif
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 85fd3d9a5471..19678738a069 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -26,6 +26,7 @@
26 26
27#include "wlcore_i.h" 27#include "wlcore_i.h"
28#include "event.h" 28#include "event.h"
29#include "boot.h"
29 30
30/* The maximum number of Tx descriptors in all chip families */ 31/* The maximum number of Tx descriptors in all chip families */
31#define WLCORE_MAX_TX_DESCRIPTORS 32 32#define WLCORE_MAX_TX_DESCRIPTORS 32
@@ -72,6 +73,8 @@ struct wlcore_ops {
72 u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, 73 u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl,
73 struct wl12xx_vif *wlvif); 74 struct wl12xx_vif *wlvif);
74 int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); 75 int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir);
76 int (*handle_static_data)(struct wl1271 *wl,
77 struct wl1271_static_data *static_data);
75}; 78};
76 79
77enum wlcore_partitions { 80enum wlcore_partitions {
@@ -373,6 +376,9 @@ struct wl1271 {
373 /* RX Data filter rule state - enabled/disabled */ 376 /* RX Data filter rule state - enabled/disabled */
374 bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; 377 bool rx_filter_enabled[WL1271_MAX_RX_FILTERS];
375 378
379 /* size of the private static data */
380 size_t static_data_priv_len;
381
376 /* the current channel type */ 382 /* the current channel type */
377 enum nl80211_channel_type channel_type; 383 enum nl80211_channel_type channel_type;
378}; 384};