OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / hal / halmac / halmac_88xx / halmac_bb_rf_88xx.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15
16 #include "halmac_bb_rf_88xx.h"
17 #include "halmac_88xx_cfg.h"
18 #include "halmac_common_88xx.h"
19 #include "halmac_init_88xx.h"
20
21 #if HALMAC_88XX_SUPPORT
22
23 /**
24  * start_iqk_88xx() -trigger FW IQK
25  * @adapter : the adapter of halmac
26  * @param : IQK parameter
27  * Author : KaiYuan Chang/Ivan Lin
28  * Return : enum halmac_ret_status
29  * More details of status code can be found in prototype document
30  */
31 enum halmac_ret_status
32 start_iqk_88xx(struct halmac_adapter *adapter, struct halmac_iqk_para *param)
33 {
34         u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
35         u16 seq_num = 0;
36         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
37         struct halmac_h2c_header_info hdr_info;
38         enum halmac_cmd_process_status *proc_status;
39
40         proc_status = &adapter->halmac_state.iqk_state.proc_status;
41
42         if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
43                 return HALMAC_RET_NO_DLFW;
44
45         PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
46
47         if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
48                 PLTFM_MSG_TRACE("[TRACE]Wait event(iqk)\n");
49                 return HALMAC_RET_BUSY_STATE;
50         }
51
52         *proc_status = HALMAC_CMD_PROCESS_SENDING;
53
54         IQK_SET_CLEAR(h2c_buf, param->clear);
55         IQK_SET_SEGMENT_IQK(h2c_buf, param->segment_iqk);
56
57         hdr_info.sub_cmd_id = SUB_CMD_ID_IQK;
58         hdr_info.content_size = 1;
59         hdr_info.ack = 1;
60         set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
61
62         adapter->halmac_state.iqk_state.seq_num = seq_num;
63
64         status = send_h2c_pkt_88xx(adapter, h2c_buf);
65
66         if (status != HALMAC_RET_SUCCESS) {
67                 PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
68                 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_IQK);
69                 return status;
70         }
71
72         PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
73
74         return HALMAC_RET_SUCCESS;
75 }
76
77 /**
78  * ctrl_pwr_tracking_88xx() -trigger FW power tracking
79  * @adapter : the adapter of halmac
80  * @opt : power tracking option
81  * Author : KaiYuan Chang/Ivan Lin
82  * Return : enum halmac_ret_status
83  * More details of status code can be found in prototype document
84  */
85 enum halmac_ret_status
86 ctrl_pwr_tracking_88xx(struct halmac_adapter *adapter,
87                        struct halmac_pwr_tracking_option *opt)
88 {
89         u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
90         u16 seq_num = 0;
91         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
92         struct halmac_h2c_header_info hdr_info;
93         struct halmac_pwr_tracking_para *param;
94         enum halmac_cmd_process_status *proc_status;
95
96         proc_status = &adapter->halmac_state.pwr_trk_state.proc_status;
97
98         if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
99                 return HALMAC_RET_NO_DLFW;
100
101         PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
102
103         if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
104                 PLTFM_MSG_TRACE("[TRACE]Wait event(pwr tracking)...\n");
105                 return HALMAC_RET_BUSY_STATE;
106         }
107
108         *proc_status = HALMAC_CMD_PROCESS_SENDING;
109
110         PWR_TRK_SET_TYPE(h2c_buf, opt->type);
111         PWR_TRK_SET_BBSWING_INDEX(h2c_buf, opt->bbswing_index);
112
113         param = &opt->pwr_tracking_para[HALMAC_RF_PATH_A];
114         PWR_TRK_SET_ENABLE_A(h2c_buf, param->enable);
115         PWR_TRK_SET_TX_PWR_INDEX_A(h2c_buf, param->tx_pwr_index);
116         PWR_TRK_SET_TSSI_VALUE_A(h2c_buf, param->tssi_value);
117         PWR_TRK_SET_OFFSET_VALUE_A(h2c_buf, param->pwr_tracking_offset_value);
118
119         param = &opt->pwr_tracking_para[HALMAC_RF_PATH_B];
120         PWR_TRK_SET_ENABLE_B(h2c_buf, param->enable);
121         PWR_TRK_SET_TX_PWR_INDEX_B(h2c_buf, param->tx_pwr_index);
122         PWR_TRK_SET_TSSI_VALUE_B(h2c_buf, param->tssi_value);
123         PWR_TRK_SET_OFFSET_VALUE_B(h2c_buf, param->pwr_tracking_offset_value);
124
125         param = &opt->pwr_tracking_para[HALMAC_RF_PATH_C];
126         PWR_TRK_SET_ENABLE_C(h2c_buf, param->enable);
127         PWR_TRK_SET_TX_PWR_INDEX_C(h2c_buf, param->tx_pwr_index);
128         PWR_TRK_SET_TSSI_VALUE_C(h2c_buf, param->tssi_value);
129         PWR_TRK_SET_OFFSET_VALUE_C(h2c_buf, param->pwr_tracking_offset_value);
130
131         param = &opt->pwr_tracking_para[HALMAC_RF_PATH_D];
132         PWR_TRK_SET_ENABLE_D(h2c_buf, param->enable);
133         PWR_TRK_SET_TX_PWR_INDEX_D(h2c_buf, param->tx_pwr_index);
134         PWR_TRK_SET_TSSI_VALUE_D(h2c_buf, param->tssi_value);
135         PWR_TRK_SET_OFFSET_VALUE_D(h2c_buf, param->pwr_tracking_offset_value);
136
137         hdr_info.sub_cmd_id = SUB_CMD_ID_PWR_TRK;
138         hdr_info.content_size = 20;
139         hdr_info.ack = 1;
140         set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
141
142         adapter->halmac_state.pwr_trk_state.seq_num = seq_num;
143
144         status = send_h2c_pkt_88xx(adapter, h2c_buf);
145
146         if (status != HALMAC_RET_SUCCESS) {
147                 PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
148                 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_POWER_TRACKING);
149                 return status;
150         }
151
152         PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
153
154         return HALMAC_RET_SUCCESS;
155 }
156
157 enum halmac_ret_status
158 get_iqk_status_88xx(struct halmac_adapter *adapter,
159                     enum halmac_cmd_process_status *proc_status)
160 {
161         *proc_status = adapter->halmac_state.iqk_state.proc_status;
162
163         return HALMAC_RET_SUCCESS;
164 }
165
166 enum halmac_ret_status
167 get_pwr_trk_status_88xx(struct halmac_adapter *adapter,
168                         enum halmac_cmd_process_status *proc_status)
169 {
170         *proc_status = adapter->halmac_state.pwr_trk_state.proc_status;
171
172         return HALMAC_RET_SUCCESS;
173 }
174
175 enum halmac_ret_status
176 get_psd_status_88xx(struct halmac_adapter *adapter,
177                     enum halmac_cmd_process_status *proc_status, u8 *data,
178                     u32 *size)
179 {
180         struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
181
182         *proc_status = state->proc_status;
183
184         if (!data)
185                 return HALMAC_RET_NULL_POINTER;
186
187         if (!size)
188                 return HALMAC_RET_NULL_POINTER;
189
190         if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
191                 if (*size < state->data_size) {
192                         *size = state->data_size;
193                         return HALMAC_RET_BUFFER_TOO_SMALL;
194                 }
195
196                 *size = state->data_size;
197                 PLTFM_MEMCPY(data, state->data, *size);
198         }
199
200         return HALMAC_RET_SUCCESS;
201 }
202
203 /**
204  * psd_88xx() - trigger fw psd
205  * @adapter : the adapter of halmac
206  * @start_psd : start PSD
207  * @end_psd : end PSD
208  * Author : KaiYuan Chang/Ivan Lin
209  * Return : enum halmac_ret_status
210  * More details of status code can be found in prototype document
211  */
212 enum halmac_ret_status
213 psd_88xx(struct halmac_adapter *adapter, u16 start_psd, u16 end_psd)
214 {
215         u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
216         u16 seq_num = 0;
217         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
218         struct halmac_h2c_header_info hdr_info;
219         enum halmac_cmd_process_status *proc_status;
220
221         proc_status = &adapter->halmac_state.psd_state.proc_status;
222
223         if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
224                 return HALMAC_RET_NO_DLFW;
225
226         PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
227
228         if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
229                 PLTFM_MSG_TRACE("[TRACE]Wait event(psd)\n");
230                 return HALMAC_RET_BUSY_STATE;
231         }
232
233         if (adapter->halmac_state.psd_state.data) {
234                 PLTFM_FREE(adapter->halmac_state.psd_state.data,
235                            adapter->halmac_state.psd_state.data_size);
236                 adapter->halmac_state.psd_state.data = (u8 *)NULL;
237         }
238
239         adapter->halmac_state.psd_state.data_size = 0;
240         adapter->halmac_state.psd_state.seg_size = 0;
241
242         *proc_status = HALMAC_CMD_PROCESS_SENDING;
243
244         PSD_SET_START_PSD(h2c_buf, start_psd);
245         PSD_SET_END_PSD(h2c_buf, end_psd);
246
247         hdr_info.sub_cmd_id = SUB_CMD_ID_PSD;
248         hdr_info.content_size = 4;
249         hdr_info.ack = 1;
250         set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
251
252         status = send_h2c_pkt_88xx(adapter, h2c_buf);
253
254         if (status != HALMAC_RET_SUCCESS) {
255                 PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
256                 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_PSD);
257                 return status;
258         }
259
260         PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
261
262         return HALMAC_RET_SUCCESS;
263 }
264
265 enum halmac_ret_status
266 get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
267 {
268         u8 seq_num;
269         u8 fw_rc;
270         struct halmac_iqk_state *state = &adapter->halmac_state.iqk_state;
271         enum halmac_cmd_process_status proc_status;
272
273         seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
274         PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
275                         state->seq_num, seq_num);
276         if (seq_num != state->seq_num) {
277                 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
278                               state->seq_num, seq_num);
279                 return HALMAC_RET_SUCCESS;
280         }
281
282         if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
283                 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
284                 return HALMAC_RET_SUCCESS;
285         }
286
287         fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
288         state->fw_rc = fw_rc;
289
290         if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
291                 proc_status = HALMAC_CMD_PROCESS_DONE;
292                 state->proc_status = proc_status;
293                 PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, NULL, 0);
294         } else {
295                 proc_status = HALMAC_CMD_PROCESS_ERROR;
296                 state->proc_status = proc_status;
297                 PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, &fw_rc, 1);
298         }
299
300         return HALMAC_RET_SUCCESS;
301 }
302
303 enum halmac_ret_status
304 get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
305 {
306         u8 seq_num;
307         u8 fw_rc;
308         struct halmac_pwr_tracking_state *state;
309         enum halmac_cmd_process_status proc_status;
310
311         state = &adapter->halmac_state.pwr_trk_state;
312
313         seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
314         PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
315                         state->seq_num, seq_num);
316         if (seq_num != state->seq_num) {
317                 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
318                               state->seq_num, seq_num);
319                 return HALMAC_RET_SUCCESS;
320         }
321
322         if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
323                 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
324                 return HALMAC_RET_SUCCESS;
325         }
326
327         fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
328         state->fw_rc = fw_rc;
329
330         if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
331                 proc_status = HALMAC_CMD_PROCESS_DONE;
332                 state->proc_status = proc_status;
333                 PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
334                                 NULL, 0);
335         } else {
336                 proc_status = HALMAC_CMD_PROCESS_ERROR;
337                 state->proc_status = proc_status;
338                 PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
339                                 &fw_rc, 1);
340         }
341
342         return HALMAC_RET_SUCCESS;
343 }
344
345 enum halmac_ret_status
346 get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
347 {
348         u8 seg_id;
349         u8 seg_size;
350         u8 seq_num;
351         u16 total_size;
352         enum halmac_cmd_process_status proc_status;
353         struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
354
355         seq_num = (u8)PSD_DATA_GET_H2C_SEQ(buf);
356         PLTFM_MSG_TRACE("[TRACE]seq num : h2c->%d c2h->%d\n",
357                         state->seq_num, seq_num);
358         if (seq_num != state->seq_num) {
359                 PLTFM_MSG_ERR("[ERR]seq num mismatch : h2c->%d c2h->%d\n",
360                               state->seq_num, seq_num);
361                 return HALMAC_RET_SUCCESS;
362         }
363
364         if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
365                 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
366                 return HALMAC_RET_SUCCESS;
367         }
368
369         total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(buf);
370         seg_id = (u8)PSD_DATA_GET_SEGMENT_ID(buf);
371         seg_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(buf);
372         state->data_size = total_size;
373
374         if (!state->data)
375                 state->data = (u8 *)PLTFM_MALLOC(state->data_size);
376
377         if (seg_id == 0)
378                 state->seg_size = seg_size;
379
380         PLTFM_MEMCPY(state->data + seg_id * state->seg_size,
381                      buf + C2H_DATA_OFFSET_88XX, seg_size);
382
383         if (PSD_DATA_GET_END_SEGMENT(buf) == 0)
384                 return HALMAC_RET_SUCCESS;
385
386         proc_status = HALMAC_CMD_PROCESS_DONE;
387         state->proc_status = proc_status;
388
389         PLTFM_EVENT_SIG(HALMAC_FEATURE_PSD, proc_status, state->data,
390                         state->data_size);
391
392         return HALMAC_RET_SUCCESS;
393 }
394
395 #endif /* HALMAC_88XX_SUPPORT */