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 "cmd.h" 27 28 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) 29 { 30 struct wl1271_ext_radio_parms_cmd *ext_radio_parms; 31 struct conf_rf_settings *rf = &wl->conf.rf; 32 int ret; 33 34 if (!wl->nvs) 35 return -ENODEV; 36 37 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); 38 if (!ext_radio_parms) 39 return -ENOMEM; 40 41 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; 42 43 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, 44 rf->tx_per_channel_power_compensation_2, 45 CONF_TX_PWR_COMPENSATION_LEN_2); 46 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, 47 rf->tx_per_channel_power_compensation_5, 48 CONF_TX_PWR_COMPENSATION_LEN_5); 49 50 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", 51 ext_radio_parms, sizeof(*ext_radio_parms)); 52 53 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); 54 if (ret < 0) 55 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); 56 57 kfree(ext_radio_parms); 58 return ret; 59 } 60 61 int wl1271_cmd_general_parms(struct wl1271 *wl) 62 { 63 struct wl1271_general_parms_cmd *gen_parms; 64 struct wl1271_ini_general_params *gp = 65 &((struct wl1271_nvs_file *)wl->nvs)->general_params; 66 bool answer = false; 67 int ret; 68 69 if (!wl->nvs) 70 return -ENODEV; 71 72 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 73 wl1271_warning("FEM index from INI out of bounds"); 74 return -EINVAL; 75 } 76 77 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); 78 if (!gen_parms) 79 return -ENOMEM; 80 81 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 82 83 memcpy(&gen_parms->general_params, gp, sizeof(*gp)); 84 85 if (gp->tx_bip_fem_auto_detect) 86 answer = true; 87 88 /* Override the REF CLK from the NVS with the one from platform data */ 89 gen_parms->general_params.ref_clock = wl->ref_clock; 90 91 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 92 if (ret < 0) { 93 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 94 goto out; 95 } 96 97 gp->tx_bip_fem_manufacturer = 98 gen_parms->general_params.tx_bip_fem_manufacturer; 99 100 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 101 wl1271_warning("FEM index from FW out of bounds"); 102 ret = -EINVAL; 103 goto out; 104 } 105 106 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", 107 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); 108 109 out: 110 kfree(gen_parms); 111 return ret; 112 } 113 114 int wl128x_cmd_general_parms(struct wl1271 *wl) 115 { 116 struct wl128x_general_parms_cmd *gen_parms; 117 struct wl128x_ini_general_params *gp = 118 &((struct wl128x_nvs_file *)wl->nvs)->general_params; 119 bool answer = false; 120 int ret; 121 122 if (!wl->nvs) 123 return -ENODEV; 124 125 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 126 wl1271_warning("FEM index from ini out of bounds"); 127 return -EINVAL; 128 } 129 130 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); 131 if (!gen_parms) 132 return -ENOMEM; 133 134 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 135 136 memcpy(&gen_parms->general_params, gp, sizeof(*gp)); 137 138 if (gp->tx_bip_fem_auto_detect) 139 answer = true; 140 141 /* Replace REF and TCXO CLKs with the ones from platform data */ 142 gen_parms->general_params.ref_clock = wl->ref_clock; 143 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock; 144 145 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 146 if (ret < 0) { 147 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 148 goto out; 149 } 150 151 gp->tx_bip_fem_manufacturer = 152 gen_parms->general_params.tx_bip_fem_manufacturer; 153 154 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) { 155 wl1271_warning("FEM index from FW out of bounds"); 156 ret = -EINVAL; 157 goto out; 158 } 159 160 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", 161 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); 162 163 out: 164 kfree(gen_parms); 165 return ret; 166 } 167 168 int wl1271_cmd_radio_parms(struct wl1271 *wl) 169 { 170 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs; 171 struct wl1271_radio_parms_cmd *radio_parms; 172 struct wl1271_ini_general_params *gp = &nvs->general_params; 173 int ret; 174 175 if (!wl->nvs) 176 return -ENODEV; 177 178 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); 179 if (!radio_parms) 180 return -ENOMEM; 181 182 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 183 184 /* 2.4GHz parameters */ 185 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, 186 sizeof(struct wl1271_ini_band_params_2)); 187 memcpy(&radio_parms->dyn_params_2, 188 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, 189 sizeof(struct wl1271_ini_fem_params_2)); 190 191 /* 5GHz parameters */ 192 memcpy(&radio_parms->static_params_5, 193 &nvs->stat_radio_params_5, 194 sizeof(struct wl1271_ini_band_params_5)); 195 memcpy(&radio_parms->dyn_params_5, 196 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, 197 sizeof(struct wl1271_ini_fem_params_5)); 198 199 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 200 radio_parms, sizeof(*radio_parms)); 201 202 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); 203 if (ret < 0) 204 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); 205 206 kfree(radio_parms); 207 return ret; 208 } 209 210 int wl128x_cmd_radio_parms(struct wl1271 *wl) 211 { 212 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; 213 struct wl128x_radio_parms_cmd *radio_parms; 214 struct wl128x_ini_general_params *gp = &nvs->general_params; 215 int ret; 216 217 if (!wl->nvs) 218 return -ENODEV; 219 220 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); 221 if (!radio_parms) 222 return -ENOMEM; 223 224 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 225 226 /* 2.4GHz parameters */ 227 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, 228 sizeof(struct wl128x_ini_band_params_2)); 229 memcpy(&radio_parms->dyn_params_2, 230 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, 231 sizeof(struct wl128x_ini_fem_params_2)); 232 233 /* 5GHz parameters */ 234 memcpy(&radio_parms->static_params_5, 235 &nvs->stat_radio_params_5, 236 sizeof(struct wl128x_ini_band_params_5)); 237 memcpy(&radio_parms->dyn_params_5, 238 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, 239 sizeof(struct wl128x_ini_fem_params_5)); 240 241 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options; 242 243 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 244 radio_parms, sizeof(*radio_parms)); 245 246 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); 247 if (ret < 0) 248 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); 249 250 kfree(radio_parms); 251 return ret; 252 } 253