diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-calib.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 72 |
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 | ||
85 | int iwl_send_calib_results(struct iwl_priv *priv) | 85 | int 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 | ||
113 | int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) | 110 | int 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 | ||
127 | void iwl_calib_free_results(struct iwl_priv *priv) | 136 | void 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 | ||