diff options
author | Luciano Coelho <coelho@ti.com> | 2012-05-10 05:14:10 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-06-05 08:58:20 -0400 |
commit | 7140df6e51ecca70e8963f18e9836e62090221c2 (patch) | |
tree | 1ca50fe5978940f0fce150c71ece37cc7e0fa4f5 /drivers | |
parent | 8c0ea1021c38cfd2f0ba5d8fdd48a9e9827bbc03 (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.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/boot.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/hw_ops.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore.h | 6 |
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 | ||
48 | static int wlcore_parse_fw_ver(struct wl1271 *wl) | 48 | static 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 | 74 | out: | |
67 | return 0; | 75 | return ret; |
68 | } | 76 | } |
69 | 77 | ||
70 | static int wlcore_boot_fw_version(struct wl1271 *wl) | 78 | static 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; | 100 | out_free: |
101 | kfree(static_data); | ||
102 | out: | ||
103 | return ret; | ||
97 | } | 104 | } |
98 | 105 | ||
99 | static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, | 106 | static 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 | ||
161 | static inline int | ||
162 | wlcore_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 | ||
77 | enum wlcore_partitions { | 80 | enum 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 | }; |