cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cmd.c (8474B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * This file is part of wl12xx
      4 *
      5 * Copyright (C) 2009-2010 Nokia Corporation
      6 * Copyright (C) 2011 Texas Instruments Inc.
      7 */
      8
      9#include "../wlcore/cmd.h"
     10#include "../wlcore/debug.h"
     11
     12#include "wl12xx.h"
     13#include "cmd.h"
     14
     15int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
     16{
     17	struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
     18	struct wl12xx_priv *priv = wl->priv;
     19	struct wl12xx_conf_rf *rf = &priv->conf.rf;
     20	int ret;
     21
     22	if (!wl->nvs)
     23		return -ENODEV;
     24
     25	ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
     26	if (!ext_radio_parms)
     27		return -ENOMEM;
     28
     29	ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
     30
     31	memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
     32	       rf->tx_per_channel_power_compensation_2,
     33	       CONF_TX_PWR_COMPENSATION_LEN_2);
     34	memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
     35	       rf->tx_per_channel_power_compensation_5,
     36	       CONF_TX_PWR_COMPENSATION_LEN_5);
     37
     38	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
     39		    ext_radio_parms, sizeof(*ext_radio_parms));
     40
     41	ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
     42	if (ret < 0)
     43		wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
     44
     45	kfree(ext_radio_parms);
     46	return ret;
     47}
     48
     49int wl1271_cmd_general_parms(struct wl1271 *wl)
     50{
     51	struct wl1271_general_parms_cmd *gen_parms;
     52	struct wl1271_ini_general_params *gp =
     53		&((struct wl1271_nvs_file *)wl->nvs)->general_params;
     54	struct wl12xx_priv *priv = wl->priv;
     55	bool answer = false;
     56	int ret;
     57
     58	if (!wl->nvs)
     59		return -ENODEV;
     60
     61	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
     62		wl1271_warning("FEM index from INI out of bounds");
     63		return -EINVAL;
     64	}
     65
     66	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
     67	if (!gen_parms)
     68		return -ENOMEM;
     69
     70	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
     71
     72	memcpy(&gen_parms->general_params, gp, sizeof(*gp));
     73
     74	/* If we started in PLT FEM_DETECT mode, force auto detect */
     75	if (wl->plt_mode == PLT_FEM_DETECT)
     76		gen_parms->general_params.tx_bip_fem_auto_detect = true;
     77
     78	if (gen_parms->general_params.tx_bip_fem_auto_detect)
     79		answer = true;
     80
     81	/* Override the REF CLK from the NVS with the one from platform data */
     82	gen_parms->general_params.ref_clock = priv->ref_clock;
     83
     84	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
     85	if (ret < 0) {
     86		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
     87		goto out;
     88	}
     89
     90	gp->tx_bip_fem_manufacturer =
     91		gen_parms->general_params.tx_bip_fem_manufacturer;
     92
     93	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
     94		wl1271_warning("FEM index from FW out of bounds");
     95		ret = -EINVAL;
     96		goto out;
     97	}
     98
     99	/* If we are in calibrator based fem auto detect - save fem nr */
    100	if (wl->plt_mode == PLT_FEM_DETECT)
    101		wl->fem_manuf = gp->tx_bip_fem_manufacturer;
    102
    103	wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
    104		answer == false ?
    105			"manual" :
    106		wl->plt_mode == PLT_FEM_DETECT ?
    107			"calibrator_fem_detect" :
    108			"auto",
    109		gp->tx_bip_fem_manufacturer);
    110
    111out:
    112	kfree(gen_parms);
    113	return ret;
    114}
    115
    116int 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	struct wl12xx_priv *priv = wl->priv;
    122	bool answer = false;
    123	int ret;
    124
    125	if (!wl->nvs)
    126		return -ENODEV;
    127
    128	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
    129		wl1271_warning("FEM index from ini out of bounds");
    130		return -EINVAL;
    131	}
    132
    133	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
    134	if (!gen_parms)
    135		return -ENOMEM;
    136
    137	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
    138
    139	memcpy(&gen_parms->general_params, gp, sizeof(*gp));
    140
    141	/* If we started in PLT FEM_DETECT mode, force auto detect */
    142	if (wl->plt_mode == PLT_FEM_DETECT)
    143		gen_parms->general_params.tx_bip_fem_auto_detect = true;
    144
    145	if (gen_parms->general_params.tx_bip_fem_auto_detect)
    146		answer = true;
    147
    148	/* Replace REF and TCXO CLKs with the ones from platform data */
    149	gen_parms->general_params.ref_clock = priv->ref_clock;
    150	gen_parms->general_params.tcxo_ref_clock = priv->tcxo_clock;
    151
    152	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
    153	if (ret < 0) {
    154		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
    155		goto out;
    156	}
    157
    158	gp->tx_bip_fem_manufacturer =
    159		gen_parms->general_params.tx_bip_fem_manufacturer;
    160
    161	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
    162		wl1271_warning("FEM index from FW out of bounds");
    163		ret = -EINVAL;
    164		goto out;
    165	}
    166
    167	/* If we are in calibrator based fem auto detect - save fem nr */
    168	if (wl->plt_mode == PLT_FEM_DETECT)
    169		wl->fem_manuf = gp->tx_bip_fem_manufacturer;
    170
    171	wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
    172		answer == false ?
    173			"manual" :
    174		wl->plt_mode == PLT_FEM_DETECT ?
    175			"calibrator_fem_detect" :
    176			"auto",
    177		gp->tx_bip_fem_manufacturer);
    178
    179out:
    180	kfree(gen_parms);
    181	return ret;
    182}
    183
    184int wl1271_cmd_radio_parms(struct wl1271 *wl)
    185{
    186	struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
    187	struct wl1271_radio_parms_cmd *radio_parms;
    188	struct wl1271_ini_general_params *gp = &nvs->general_params;
    189	int ret, fem_idx;
    190
    191	if (!wl->nvs)
    192		return -ENODEV;
    193
    194	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
    195	if (!radio_parms)
    196		return -ENOMEM;
    197
    198	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
    199
    200	fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);
    201
    202	/* 2.4GHz parameters */
    203	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
    204	       sizeof(struct wl1271_ini_band_params_2));
    205	memcpy(&radio_parms->dyn_params_2,
    206	       &nvs->dyn_radio_params_2[fem_idx].params,
    207	       sizeof(struct wl1271_ini_fem_params_2));
    208
    209	/* 5GHz parameters */
    210	memcpy(&radio_parms->static_params_5,
    211	       &nvs->stat_radio_params_5,
    212	       sizeof(struct wl1271_ini_band_params_5));
    213	memcpy(&radio_parms->dyn_params_5,
    214	       &nvs->dyn_radio_params_5[fem_idx].params,
    215	       sizeof(struct wl1271_ini_fem_params_5));
    216
    217	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
    218		    radio_parms, sizeof(*radio_parms));
    219
    220	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
    221	if (ret < 0)
    222		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
    223
    224	kfree(radio_parms);
    225	return ret;
    226}
    227
    228int wl128x_cmd_radio_parms(struct wl1271 *wl)
    229{
    230	struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
    231	struct wl128x_radio_parms_cmd *radio_parms;
    232	struct wl128x_ini_general_params *gp = &nvs->general_params;
    233	int ret, fem_idx;
    234
    235	if (!wl->nvs)
    236		return -ENODEV;
    237
    238	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
    239	if (!radio_parms)
    240		return -ENOMEM;
    241
    242	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
    243
    244	fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);
    245
    246	/* 2.4GHz parameters */
    247	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
    248	       sizeof(struct wl128x_ini_band_params_2));
    249	memcpy(&radio_parms->dyn_params_2,
    250	       &nvs->dyn_radio_params_2[fem_idx].params,
    251	       sizeof(struct wl128x_ini_fem_params_2));
    252
    253	/* 5GHz parameters */
    254	memcpy(&radio_parms->static_params_5,
    255	       &nvs->stat_radio_params_5,
    256	       sizeof(struct wl128x_ini_band_params_5));
    257	memcpy(&radio_parms->dyn_params_5,
    258	       &nvs->dyn_radio_params_5[fem_idx].params,
    259	       sizeof(struct wl128x_ini_fem_params_5));
    260
    261	radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
    262
    263	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
    264		    radio_parms, sizeof(*radio_parms));
    265
    266	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
    267	if (ret < 0)
    268		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
    269
    270	kfree(radio_parms);
    271	return ret;
    272}
    273
    274int wl12xx_cmd_channel_switch(struct wl1271 *wl,
    275			      struct wl12xx_vif *wlvif,
    276			      struct ieee80211_channel_switch *ch_switch)
    277{
    278	struct wl12xx_cmd_channel_switch *cmd;
    279	int ret;
    280
    281	wl1271_debug(DEBUG_ACX, "cmd channel switch");
    282
    283	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
    284	if (!cmd) {
    285		ret = -ENOMEM;
    286		goto out;
    287	}
    288
    289	cmd->role_id = wlvif->role_id;
    290	cmd->channel = ch_switch->chandef.chan->hw_value;
    291	cmd->switch_time = ch_switch->count;
    292	cmd->stop_tx = ch_switch->block_tx;
    293
    294	/* FIXME: control from mac80211 in the future */
    295	/* Enable TX on the target channel */
    296	cmd->post_switch_tx_disable = 0;
    297
    298	ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
    299	if (ret < 0) {
    300		wl1271_error("failed to send channel switch command");
    301		goto out_free;
    302	}
    303
    304out_free:
    305	kfree(cmd);
    306
    307out:
    308	return ret;
    309}