aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-calib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 03bac48558b2..16971a020297 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -82,56 +82,64 @@ struct statistics_general_data {
82 u32 beacon_energy_c; 82 u32 beacon_energy_c;
83}; 83};
84 84
85int iwl_send_calib_results(struct iwl_priv *priv) 85int iwl_send_calib_results(struct iwl_trans *trans)
86{ 86{
87 int ret = 0;
88 int i = 0;
89
90 struct iwl_host_cmd hcmd = { 87 struct iwl_host_cmd hcmd = {
91 .id = REPLY_PHY_CALIBRATION_CMD, 88 .id = REPLY_PHY_CALIBRATION_CMD,
92 .flags = CMD_SYNC, 89 .flags = CMD_SYNC,
93 }; 90 };
94 91 struct iwl_calib_result *res;
95 for (i = 0; i < IWL_CALIB_MAX; i++) { 92
96 if ((BIT(i) & hw_params(priv).calib_init_cfg) && 93 list_for_each_entry(res, &trans->calib_results, list) {
97 priv->calib_results[i].buf) { 94 int ret;
98 hcmd.len[0] = priv->calib_results[i].buf_len; 95
99 hcmd.data[0] = priv->calib_results[i].buf; 96 hcmd.len[0] = res->cmd_len;
100 hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; 97 hcmd.data[0] = &res->hdr;
101 ret = iwl_trans_send_cmd(trans(priv), &hcmd); 98 hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
102 if (ret) { 99 ret = iwl_trans_send_cmd(trans, &hcmd);
103 IWL_ERR(priv, "Error %d iteration %d\n", 100 if (ret) {
104 ret, i); 101 IWL_ERR(trans, "Error %d on calib cmd %d\n",
105 break; 102 ret, res->hdr.op_code);
106 } 103 return ret;
107 } 104 }
108 } 105 }
109 106
110 return ret; 107 return 0;
111} 108}
112 109
113int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) 110int iwl_calib_set(struct iwl_trans *trans,
111 const struct iwl_calib_hdr *cmd, int len)
114{ 112{
115 if (res->buf_len != len) { 113 struct iwl_calib_result *res, *tmp;
116 kfree(res->buf); 114
117 res->buf = kzalloc(len, GFP_ATOMIC); 115 res = kmalloc(sizeof(*res) + len - sizeof(struct iwl_calib_hdr),
118 } 116 GFP_ATOMIC);
119 if (unlikely(res->buf == NULL)) 117 if (!res)
120 return -ENOMEM; 118 return -ENOMEM;
119 memcpy(&res->hdr, cmd, len);
120 res->cmd_len = len;
121
122 list_for_each_entry(tmp, &trans->calib_results, list) {
123 if (tmp->hdr.op_code == res->hdr.op_code) {
124 list_replace(&tmp->list, &res->list);
125 kfree(tmp);
126 return 0;
127 }
128 }
129
130 /* wasn't in list already */
131 list_add_tail(&res->list, &trans->calib_results);
121 132
122 res->buf_len = len;
123 memcpy(res->buf, buf, len);
124 return 0; 133 return 0;
125} 134}
126 135
127void iwl_calib_free_results(struct iwl_priv *priv) 136void iwl_calib_free_results(struct iwl_trans *trans)
128{ 137{
129 int i; 138 struct iwl_calib_result *res, *tmp;
130 139
131 for (i = 0; i < IWL_CALIB_MAX; i++) { 140 list_for_each_entry_safe(res, tmp, &trans->calib_results, list) {
132 kfree(priv->calib_results[i].buf); 141 list_del(&res->list);
133 priv->calib_results[i].buf = NULL; 142 kfree(res);
134 priv->calib_results[i].buf_len = 0;
135 } 143 }
136} 144}
137 145