mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-22 10:53:45 +07:00
iwlagn: dynamically allocate & reflect calibration data
This makes handling the calibration data more generic and no longer requires updating IWL_CALIB_MAX when a new uCode comes with more calibration packets. Since we just copy the data back, there's also no need for understanding which calibration we received -- we can just reflect it back to the runtime uCode. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
93b64105e5
commit
f02c2fd383
@ -88,19 +88,18 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
|||||||
.id = REPLY_PHY_CALIBRATION_CMD,
|
.id = REPLY_PHY_CALIBRATION_CMD,
|
||||||
.flags = CMD_SYNC,
|
.flags = CMD_SYNC,
|
||||||
};
|
};
|
||||||
int i = 0;
|
struct iwl_calib_result *res;
|
||||||
|
|
||||||
for (i = 0; i < IWL_CALIB_MAX; i++) {
|
list_for_each_entry(res, &priv->calib_results, list) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!priv->calib_results[i].buf)
|
hcmd.len[0] = res->cmd_len;
|
||||||
continue;
|
hcmd.data[0] = &res->hdr;
|
||||||
hcmd.len[0] = priv->calib_results[i].buf_len;
|
|
||||||
hcmd.data[0] = priv->calib_results[i].buf;
|
|
||||||
hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
|
hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
|
||||||
ret = iwl_trans_send_cmd(trans(priv), &hcmd);
|
ret = iwl_trans_send_cmd(trans(priv), &hcmd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
|
IWL_ERR(priv, "Error %d on calib cmd %d\n",
|
||||||
|
ret, res->hdr.op_code);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,28 +107,39 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
|
int iwl_calib_set(struct iwl_priv *priv,
|
||||||
|
const struct iwl_calib_hdr *cmd, int len)
|
||||||
{
|
{
|
||||||
if (res->buf_len != len) {
|
struct iwl_calib_result *res, *tmp;
|
||||||
kfree(res->buf);
|
|
||||||
res->buf = kzalloc(len, GFP_ATOMIC);
|
res = kmalloc(sizeof(*res) + len - sizeof(struct iwl_calib_hdr),
|
||||||
}
|
GFP_ATOMIC);
|
||||||
if (unlikely(res->buf == NULL))
|
if (!res)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
memcpy(&res->hdr, cmd, len);
|
||||||
|
res->cmd_len = len;
|
||||||
|
|
||||||
|
list_for_each_entry(tmp, &priv->calib_results, list) {
|
||||||
|
if (tmp->hdr.op_code == res->hdr.op_code) {
|
||||||
|
list_replace(&tmp->list, &res->list);
|
||||||
|
kfree(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wasn't in list already */
|
||||||
|
list_add_tail(&res->list, &priv->calib_results);
|
||||||
|
|
||||||
res->buf_len = len;
|
|
||||||
memcpy(res->buf, buf, len);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_calib_free_results(struct iwl_priv *priv)
|
void iwl_calib_free_results(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
int i;
|
struct iwl_calib_result *res, *tmp;
|
||||||
|
|
||||||
for (i = 0; i < IWL_CALIB_MAX; i++) {
|
list_for_each_entry_safe(res, tmp, &priv->calib_results, list) {
|
||||||
kfree(priv->calib_results[i].buf);
|
list_del(&res->list);
|
||||||
priv->calib_results[i].buf = NULL;
|
kfree(res);
|
||||||
priv->calib_results[i].buf_len = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,8 @@ void iwl_init_sensitivity(struct iwl_priv *priv);
|
|||||||
void iwl_reset_run_time_calib(struct iwl_priv *priv);
|
void iwl_reset_run_time_calib(struct iwl_priv *priv);
|
||||||
|
|
||||||
int iwl_send_calib_results(struct iwl_priv *priv);
|
int iwl_send_calib_results(struct iwl_priv *priv);
|
||||||
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
|
int iwl_calib_set(struct iwl_priv *priv,
|
||||||
|
const struct iwl_calib_hdr *cmd, int len);
|
||||||
void iwl_calib_free_results(struct iwl_priv *priv);
|
void iwl_calib_free_results(struct iwl_priv *priv);
|
||||||
|
|
||||||
#endif /* __iwl_calib_h__ */
|
#endif /* __iwl_calib_h__ */
|
||||||
|
@ -222,8 +222,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
|
|||||||
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
|
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
|
||||||
cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
|
cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
|
||||||
cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
|
cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
|
||||||
return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
|
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||||
(u8 *)&cmd, sizeof(cmd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
|
static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
|
||||||
@ -240,8 +239,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
|
|||||||
|
|
||||||
IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
|
IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
|
||||||
le16_to_cpu(cmd.radio_sensor_offset));
|
le16_to_cpu(cmd.radio_sensor_offset));
|
||||||
return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
|
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||||
(u8 *)&cmd, sizeof(cmd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv)
|
static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv)
|
||||||
@ -276,8 +274,7 @@ static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv)
|
|||||||
IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
|
IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
|
||||||
le16_to_cpu(cmd.burntVoltageRef));
|
le16_to_cpu(cmd.burntVoltageRef));
|
||||||
|
|
||||||
return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
|
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||||
(u8 *)&cmd, sizeof(cmd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
|
static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
|
||||||
@ -306,37 +303,14 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv,
|
|||||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
|
struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
|
||||||
int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
||||||
int index;
|
|
||||||
|
|
||||||
/* reduce the size of the length field itself */
|
/* reduce the size of the length field itself */
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
|
||||||
/* Define the order in which the results will be sent to the runtime
|
if (iwl_calib_set(priv, hdr, len))
|
||||||
* uCode. iwl_send_calib_results sends them in a row according to
|
IWL_ERR(priv, "Failed to record calibration data %d\n",
|
||||||
* their index. We sort them here
|
hdr->op_code);
|
||||||
*/
|
|
||||||
switch (hdr->op_code) {
|
|
||||||
case IWL_PHY_CALIBRATE_DC_CMD:
|
|
||||||
index = IWL_CALIB_DC;
|
|
||||||
break;
|
|
||||||
case IWL_PHY_CALIBRATE_LO_CMD:
|
|
||||||
index = IWL_CALIB_LO;
|
|
||||||
break;
|
|
||||||
case IWL_PHY_CALIBRATE_TX_IQ_CMD:
|
|
||||||
index = IWL_CALIB_TX_IQ;
|
|
||||||
break;
|
|
||||||
case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
|
|
||||||
index = IWL_CALIB_TX_IQ_PERD;
|
|
||||||
break;
|
|
||||||
case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
|
|
||||||
index = IWL_CALIB_BASE_BAND;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
IWL_ERR(priv, "Unknown calibration notification %d\n",
|
|
||||||
hdr->op_code);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1575,6 +1575,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
|
|||||||
|
|
||||||
mutex_init(&priv->shrd->mutex);
|
mutex_init(&priv->shrd->mutex);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&priv->calib_results);
|
||||||
|
|
||||||
priv->ieee_channels = NULL;
|
priv->ieee_channels = NULL;
|
||||||
priv->ieee_rates = NULL;
|
priv->ieee_rates = NULL;
|
||||||
priv->band = IEEE80211_BAND_2GHZ;
|
priv->band = IEEE80211_BAND_2GHZ;
|
||||||
|
@ -442,26 +442,12 @@ enum iwlagn_chain_noise_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* enum iwl_calib
|
|
||||||
* defines the order in which results of initial calibrations
|
|
||||||
* should be sent to the runtime uCode
|
|
||||||
*/
|
|
||||||
enum iwl_calib {
|
|
||||||
IWL_CALIB_XTAL,
|
|
||||||
IWL_CALIB_DC,
|
|
||||||
IWL_CALIB_LO,
|
|
||||||
IWL_CALIB_TX_IQ,
|
|
||||||
IWL_CALIB_TX_IQ_PERD,
|
|
||||||
IWL_CALIB_BASE_BAND,
|
|
||||||
IWL_CALIB_TEMP_OFFSET,
|
|
||||||
IWL_CALIB_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Opaque calibration results */
|
/* Opaque calibration results */
|
||||||
struct iwl_calib_result {
|
struct iwl_calib_result {
|
||||||
void *buf;
|
struct list_head list;
|
||||||
size_t buf_len;
|
size_t cmd_len;
|
||||||
|
struct iwl_calib_hdr hdr;
|
||||||
|
/* data follows */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sensitivity calib data */
|
/* Sensitivity calib data */
|
||||||
@ -869,7 +855,7 @@ struct iwl_priv {
|
|||||||
s32 last_temperature;
|
s32 last_temperature;
|
||||||
|
|
||||||
/* init calibration results */
|
/* init calibration results */
|
||||||
struct iwl_calib_result calib_results[IWL_CALIB_MAX];
|
struct list_head calib_results;
|
||||||
|
|
||||||
struct iwl_wipan_noa_data __rcu *noa_data;
|
struct iwl_wipan_noa_data __rcu *noa_data;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user