diff options
author | Luciano Coelho <coelho@ti.com> | 2012-06-07 16:39:28 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-06-08 02:14:08 -0400 |
commit | 640dfb9b85bc80c607c07531dc5428418ef39974 (patch) | |
tree | ad1e972d20e6127519efa3eac30c7ca6f3922147 /drivers/net/wireless | |
parent | 18b70ac9c7fd640cbd5921b5ca2705db0f8b9d83 (diff) |
wl18xx: read configuration structure from a binary file
Instead of using the hardcoded configuration structure, try to read it
from a "firmware" file called wl18xx-conf.bin. If the file doesn't
exist, fall back to the hardcoded version. If the file exists but is
illegal, bail out.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/main.c | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b6a80cd5e9ef..9cdf24f70964 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/ip.h> | 24 | #include <linux/ip.h> |
25 | #include <linux/firmware.h> | ||
25 | 26 | ||
26 | #include "../wlcore/wlcore.h" | 27 | #include "../wlcore/wlcore.h" |
27 | #include "../wlcore/debug.h" | 28 | #include "../wlcore/debug.h" |
@@ -1046,15 +1047,65 @@ static s8 wl18xx_get_pg_ver(struct wl1271 *wl) | |||
1046 | return (s8)fuse; | 1047 | return (s8)fuse; |
1047 | } | 1048 | } |
1048 | 1049 | ||
1049 | static void wl18xx_conf_init(struct wl1271 *wl) | 1050 | #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" |
1051 | static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) | ||
1050 | { | 1052 | { |
1051 | struct wl18xx_priv *priv = wl->priv; | 1053 | struct wl18xx_priv *priv = wl->priv; |
1054 | struct wlcore_conf_file *conf_file; | ||
1055 | const struct firmware *fw; | ||
1056 | int ret; | ||
1057 | |||
1058 | ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev); | ||
1059 | if (ret < 0) { | ||
1060 | wl1271_error("could not get configuration binary %s: %d", | ||
1061 | WL18XX_CONF_FILE_NAME, ret); | ||
1062 | goto out_fallback; | ||
1063 | } | ||
1064 | |||
1065 | if (fw->size != WL18XX_CONF_SIZE) { | ||
1066 | wl1271_error("configuration binary file size is wrong, " | ||
1067 | "expected %d got %d", WL18XX_CONF_SIZE, fw->size); | ||
1068 | ret = -EINVAL; | ||
1069 | goto out; | ||
1070 | } | ||
1071 | |||
1072 | conf_file = (struct wlcore_conf_file *) fw->data; | ||
1073 | |||
1074 | if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) { | ||
1075 | wl1271_error("configuration binary file magic number mismatch, " | ||
1076 | "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC, | ||
1077 | conf_file->header.magic); | ||
1078 | ret = -EINVAL; | ||
1079 | goto out; | ||
1080 | } | ||
1081 | |||
1082 | if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) { | ||
1083 | wl1271_error("configuration binary file version not supported, " | ||
1084 | "expected 0x%08x got 0x%08x", | ||
1085 | WL18XX_CONF_VERSION, conf_file->header.version); | ||
1086 | ret = -EINVAL; | ||
1087 | goto out; | ||
1088 | } | ||
1089 | |||
1090 | memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf)); | ||
1091 | memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf)); | ||
1092 | |||
1093 | goto out; | ||
1094 | |||
1095 | out_fallback: | ||
1096 | wl1271_warning("falling back to default config"); | ||
1052 | 1097 | ||
1053 | /* apply driver default configuration */ | 1098 | /* apply driver default configuration */ |
1054 | memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); | 1099 | memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); |
1055 | |||
1056 | /* apply default private configuration */ | 1100 | /* apply default private configuration */ |
1057 | memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); | 1101 | memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); |
1102 | |||
1103 | /* For now we just fallback */ | ||
1104 | return 0; | ||
1105 | |||
1106 | out: | ||
1107 | release_firmware(fw); | ||
1108 | return ret; | ||
1058 | } | 1109 | } |
1059 | 1110 | ||
1060 | static int wl18xx_plt_init(struct wl1271 *wl) | 1111 | static int wl18xx_plt_init(struct wl1271 *wl) |
@@ -1261,11 +1312,13 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1261 | struct wl1271 *wl; | 1312 | struct wl1271 *wl; |
1262 | struct ieee80211_hw *hw; | 1313 | struct ieee80211_hw *hw; |
1263 | struct wl18xx_priv *priv; | 1314 | struct wl18xx_priv *priv; |
1315 | int ret; | ||
1264 | 1316 | ||
1265 | hw = wlcore_alloc_hw(sizeof(*priv)); | 1317 | hw = wlcore_alloc_hw(sizeof(*priv)); |
1266 | if (IS_ERR(hw)) { | 1318 | if (IS_ERR(hw)) { |
1267 | wl1271_error("can't allocate hw"); | 1319 | wl1271_error("can't allocate hw"); |
1268 | return PTR_ERR(hw); | 1320 | ret = PTR_ERR(hw); |
1321 | goto out; | ||
1269 | } | 1322 | } |
1270 | 1323 | ||
1271 | wl = hw->priv; | 1324 | wl = hw->priv; |
@@ -1305,10 +1358,13 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1305 | sizeof(wl18xx_siso20_ht_cap)); | 1358 | sizeof(wl18xx_siso20_ht_cap)); |
1306 | } else { | 1359 | } else { |
1307 | wl1271_error("invalid ht_mode '%s'", ht_mode_param); | 1360 | wl1271_error("invalid ht_mode '%s'", ht_mode_param); |
1361 | ret = -EINVAL; | ||
1308 | goto out_free; | 1362 | goto out_free; |
1309 | } | 1363 | } |
1310 | 1364 | ||
1311 | wl18xx_conf_init(wl); | 1365 | ret = wl18xx_conf_init(wl, &pdev->dev); |
1366 | if (ret < 0) | ||
1367 | goto out_free; | ||
1312 | 1368 | ||
1313 | if (!strcmp(board_type_param, "fpga")) { | 1369 | if (!strcmp(board_type_param, "fpga")) { |
1314 | priv->board_type = BOARD_TYPE_FPGA_18XX; | 1370 | priv->board_type = BOARD_TYPE_FPGA_18XX; |
@@ -1326,6 +1382,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1326 | priv->conf.phy.low_band_component_type = 0x06; | 1382 | priv->conf.phy.low_band_component_type = 0x06; |
1327 | } else { | 1383 | } else { |
1328 | wl1271_error("invalid board type '%s'", board_type_param); | 1384 | wl1271_error("invalid board type '%s'", board_type_param); |
1385 | ret = -EINVAL; | ||
1329 | goto out_free; | 1386 | goto out_free; |
1330 | } | 1387 | } |
1331 | 1388 | ||
@@ -1373,7 +1430,8 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1373 | 1430 | ||
1374 | out_free: | 1431 | out_free: |
1375 | wlcore_free_hw(wl); | 1432 | wlcore_free_hw(wl); |
1376 | return -EINVAL; | 1433 | out: |
1434 | return ret; | ||
1377 | } | 1435 | } |
1378 | 1436 | ||
1379 | static const struct platform_device_id wl18xx_id_table[] __devinitconst = { | 1437 | static const struct platform_device_id wl18xx_id_table[] __devinitconst = { |