1 /* 2 * This file is part of wl12xx 3 * 4 * Copyright (C) 2009-2010 Nokia Corporation 5 * Copyright (C) 2011 Texas Instruments Inc. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * version 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19 * 02110-1301 USA 20 * 21 */ 22 23 #include "../wlcore/cmd.h" 24 #include "../wlcore/debug.h" 25 26 #include "wl12xx.h" 27 #include "cmd.h" 28 29 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) 30 { 31 struct wl1271_ext_radio_parms_cmd *ext_radio_parms; 32 struct wl12xx_priv *priv = wl->priv; 33 struct wl12xx_conf_rf *rf = &priv->conf.rf; 34 int ret; 35 36 if (!wl->nvs) 37 return -ENODEV; 38 39 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); 40 if (!ext_radio_parms) 41 return -ENOMEM; 42 43 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; 44 45 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, 46 rf->tx_per_channel_power_compensation_2, 47 CONF_TX_PWR_COMPENSATION_LEN_2); 48 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, 49 rf->tx_per_channel_power_compensation_5, 50 CONF_TX_PWR_COMPENSATION_LEN_5); 51 52 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", 53 ext_radio_parms, sizeof(*ext_radio_parms)); 54 55 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); 56 if (ret < 0) 57 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); 58 59 kfree(ext_radio_parms); 60 return ret; 61 } 62 63 int wl1271_cmd_general_parms(struct wl1271 *wl) 64 { 65 struct wl1271_general_parms_cmd *gen_parms; 66 struct wl1271_ini_general_params *gp = 67 &((struct wl1271_nvs_file *)wl->nvs)->general_params; 68 bool answer = false; 69 int ret; 70 71 if (!wl->nvs) 72 return -ENODEV; 73 74 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 75 wl1271_warning("FEM index from INI out of bounds"); 76 return -EINVAL; 77 } 78 79 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); 80 if (!gen_parms) 81 return -ENOMEM; 82 83 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 84 85 memcpy(&gen_parms->general_params, gp, sizeof(*gp)); 86 87 if (gp->tx_bip_fem_auto_detect) 88 answer = true; 89 90 /* Override the REF CLK from the NVS with the one from platform data */ 91 gen_parms->general_params.ref_clock = wl->ref_clock; 92 93 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 94 if (ret < 0) { 95 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 96 goto out; 97 } 98 99 gp->tx_bip_fem_manufacturer = 100 gen_parms->general_params.tx_bip_fem_manufacturer; 101 102 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 103 wl1271_warning("FEM index from FW out of bounds"); 104 ret = -EINVAL; 105 goto out; 106 } 107 108 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", 109 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); 110 111 out: 112 kfree(gen_parms); 113 return ret; 114 } 115 116 int wl128x_cmd_general_parms(struct wl1271 *wl) 117 { 118 struct wl128x_general_parms_cmd *gen_parms; 119 struct wl128x_ini_general_params *gp = 120 &((struct wl128x_nvs_file *)wl->nvs)->general_params; 121 bool answer = false; 122 int ret; 123 124 if (!wl->nvs) 125 return -ENODEV; 126 127 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 128 wl1271_warning("FEM index from ini out of bounds"); 129 return -EINVAL; 130 } 131 132 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); 133 if (!gen_parms) 134 return -ENOMEM; 135 136 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 137 138 memcpy(&gen_parms->general_params, gp, sizeof(*gp)); 139 140 if (gp->tx_bip_fem_auto_detect) 141 answer = true; 142 143 /* Replace REF and TCXO CLKs with the ones from platform data */ 144 gen_parms->general_params.ref_clock = wl->ref_clock; 145 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock; 146 147 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 148 if (ret < 0) { 149 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 150 goto out; 151 } 152 153 gp->tx_bip_fem_manufacturer = 154 gen_parms->general_params.tx_bip_fem_manufacturer; 155 156 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 157 wl1271_warning("FEM index from FW out of bounds"); 158 ret = -EINVAL; 159 goto out; 160 } 161 162 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", 163 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); 164 165 out: 166 kfree(gen_parms); 167 return ret; 168 } 169 170 int wl1271_cmd_radio_parms(struct wl1271 *wl) 171 { 172 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs; 173 struct wl1271_radio_parms_cmd *radio_parms; 174 struct wl1271_ini_general_params *gp = &nvs->general_params; 175 int ret; 176 177 if (!wl->nvs) 178 return -ENODEV; 179 180 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); 181 if (!radio_parms) 182 return -ENOMEM; 183 184 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 185 186 /* 2.4GHz parameters */ 187 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, 188 sizeof(struct wl1271_ini_band_params_2)); 189 memcpy(&radio_parms->dyn_params_2, 190 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, 191 sizeof(struct wl1271_ini_fem_params_2)); 192 193 /* 5GHz parameters */ 194 memcpy(&radio_parms->static_params_5, 195 &nvs->stat_radio_params_5, 196 sizeof(struct wl1271_ini_band_params_5)); 197 memcpy(&radio_parms->dyn_params_5, 198 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, 199 sizeof(struct wl1271_ini_fem_params_5)); 200 201 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 202 radio_parms, sizeof(*radio_parms)); 203 204 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); 205 if (ret < 0) 206 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); 207 208 kfree(radio_parms); 209 return ret; 210 } 211 212 int wl128x_cmd_radio_parms(struct wl1271 *wl) 213 { 214 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; 215 struct wl128x_radio_parms_cmd *radio_parms; 216 struct wl128x_ini_general_params *gp = &nvs->general_params; 217 int ret; 218 219 if (!wl->nvs) 220 return -ENODEV; 221 222 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); 223 if (!radio_parms) 224 return -ENOMEM; 225 226 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 227 228 /* 2.4GHz parameters */ 229 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, 230 sizeof(struct wl128x_ini_band_params_2)); 231 memcpy(&radio_parms->dyn_params_2, 232 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, 233 sizeof(struct wl128x_ini_fem_params_2)); 234 235 /* 5GHz parameters */ 236 memcpy(&radio_parms->static_params_5, 237 &nvs->stat_radio_params_5, 238 sizeof(struct wl128x_ini_band_params_5)); 239 memcpy(&radio_parms->dyn_params_5, 240 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, 241 sizeof(struct wl128x_ini_fem_params_5)); 242 243 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options; 244 245 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 246 radio_parms, sizeof(*radio_parms)); 247 248 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); 249 if (ret < 0) 250 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); 251 252 kfree(radio_parms); 253 return ret; 254 } 255