diff options
author | Bing Zhao <bzhao@marvell.com> | 2013-12-13 18:33:01 -0800 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-12-18 15:23:09 -0500 |
commit | 699b027b9cefbaf779ad8eaab5e9ea122620827c (patch) | |
tree | d9fd454ff2c6179102471a12274c27a6341ae905 /drivers/net/wireless/mwifiex | |
parent | d39fbc88956ef56a67b8030d53c7e8fa645a4e00 (diff) |
mwifiex: download cal-data from device-tree to firmware
Currently only conf file based cal-data downloading is supported.
On embedded platforms a better place to store the cal-data is in
device tree. Add cal-data downloading from device tree to firmware.
Both methods can co-exist.
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmd.c | 61 |
2 files changed, 58 insertions, 5 deletions
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index dc34457557f..2f5035492ef 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -32,6 +32,7 @@ #include <net/lib80211.h> #include <linux/firmware.h> #include <linux/ctype.h> +#include <linux/of.h> #include "decl.h" #include "ioctl.h" @@ -739,6 +740,7 @@ struct mwifiex_adapter { u8 scan_delay_cnt; u8 empty_tx_q_cnt; const struct firmware *cal_data; + struct device_node *dt_node; /* 11AC */ u32 is_hw_11ac_capable; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 2368c7f030b..6a9508695bb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1156,19 +1156,58 @@ static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst) return d - dst; } +static int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv, + struct device_node *node, const char *prefix) +{ +#ifdef CONFIG_OF + struct property *prop; + size_t len = strlen(prefix); + int ret; + + /* look for all matching property names */ + for_each_property_of_node(node, prop) { + if (len > strlen(prop->name) || + strncmp(prop->name, prefix, len)) + continue; + + /* property header is 6 bytes */ + if (prop && prop->value && prop->length > 6) { + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, + HostCmd_ACT_GEN_SET, 0, + prop); + if (ret) + return ret; + } + } +#endif + return 0; +} + /* This function prepares command of set_cfg_data. */ static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd) + struct host_cmd_ds_command *cmd, void *data_buf) { struct mwifiex_adapter *adapter = priv->adapter; + struct property *prop = data_buf; u32 len; u8 *data = (u8 *)cmd + S_DS_GEN; + int ret; - if ((adapter->cal_data->data) && (adapter->cal_data->size > 0)) + if (prop) { + len = prop->length; + ret = of_property_read_u8_array(adapter->dt_node, prop->name, + data, len); + if (ret) + return ret; + dev_dbg(adapter->dev, + "download cfg_data from device tree: %s\n", prop->name); + } else if (adapter->cal_data->data && adapter->cal_data->size > 0) { len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data, adapter->cal_data->size, data); - else + dev_dbg(adapter->dev, "download cfg_data from config file\n"); + } else { return -1; + } cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA); cmd->size = cpu_to_le16(S_DS_GEN + len); @@ -1259,7 +1298,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr); break; case HostCmd_CMD_CFG_DATA: - ret = mwifiex_cmd_cfg_data(priv, cmd_ptr); + ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, data_buf); break; case HostCmd_CMD_MAC_CONTROL: ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action, @@ -1519,7 +1558,19 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) return -1; - /* Download calibration data to firmware */ + /* Download calibration data to firmware. + * The cal-data can be read from device tree and/or + * a configuration file and downloaded to firmware. + */ + adapter->dt_node = + of_find_node_by_name(NULL, "marvell_cfgdata"); + if (adapter->dt_node) { + ret = mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node, + "marvell,caldata"); + if (ret) + return -1; + } + if (adapter->cal_data) { ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, HostCmd_ACT_GEN_SET, 0, NULL); |