1 /******************************************************************************
3 * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
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"
21 #if HALMAC_88XX_SUPPORT
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
31 enum halmac_ret_status
32 start_iqk_88xx(struct halmac_adapter *adapter, struct halmac_iqk_para *param)
34 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 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;
40 proc_status = &adapter->halmac_state.iqk_state.proc_status;
42 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
43 return HALMAC_RET_NO_DLFW;
45 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
47 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
48 PLTFM_MSG_TRACE("[TRACE]Wait event(iqk)\n");
49 return HALMAC_RET_BUSY_STATE;
52 *proc_status = HALMAC_CMD_PROCESS_SENDING;
54 IQK_SET_CLEAR(h2c_buf, param->clear);
55 IQK_SET_SEGMENT_IQK(h2c_buf, param->segment_iqk);
57 hdr_info.sub_cmd_id = SUB_CMD_ID_IQK;
58 hdr_info.content_size = 1;
60 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
62 adapter->halmac_state.iqk_state.seq_num = seq_num;
64 status = send_h2c_pkt_88xx(adapter, h2c_buf);
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);
72 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
74 return HALMAC_RET_SUCCESS;
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
85 enum halmac_ret_status
86 ctrl_pwr_tracking_88xx(struct halmac_adapter *adapter,
87 struct halmac_pwr_tracking_option *opt)
89 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 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;
96 proc_status = &adapter->halmac_state.pwr_trk_state.proc_status;
98 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
99 return HALMAC_RET_NO_DLFW;
101 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
103 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
104 PLTFM_MSG_TRACE("[TRACE]Wait event(pwr tracking)...\n");
105 return HALMAC_RET_BUSY_STATE;
108 *proc_status = HALMAC_CMD_PROCESS_SENDING;
110 PWR_TRK_SET_TYPE(h2c_buf, opt->type);
111 PWR_TRK_SET_BBSWING_INDEX(h2c_buf, opt->bbswing_index);
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);
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);
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);
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);
137 hdr_info.sub_cmd_id = SUB_CMD_ID_PWR_TRK;
138 hdr_info.content_size = 20;
140 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
142 adapter->halmac_state.pwr_trk_state.seq_num = seq_num;
144 status = send_h2c_pkt_88xx(adapter, h2c_buf);
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);
152 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
154 return HALMAC_RET_SUCCESS;
157 enum halmac_ret_status
158 get_iqk_status_88xx(struct halmac_adapter *adapter,
159 enum halmac_cmd_process_status *proc_status)
161 *proc_status = adapter->halmac_state.iqk_state.proc_status;
163 return HALMAC_RET_SUCCESS;
166 enum halmac_ret_status
167 get_pwr_trk_status_88xx(struct halmac_adapter *adapter,
168 enum halmac_cmd_process_status *proc_status)
170 *proc_status = adapter->halmac_state.pwr_trk_state.proc_status;
172 return HALMAC_RET_SUCCESS;
175 enum halmac_ret_status
176 get_psd_status_88xx(struct halmac_adapter *adapter,
177 enum halmac_cmd_process_status *proc_status, u8 *data,
180 struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
182 *proc_status = state->proc_status;
185 return HALMAC_RET_NULL_POINTER;
188 return HALMAC_RET_NULL_POINTER;
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;
196 *size = state->data_size;
197 PLTFM_MEMCPY(data, state->data, *size);
200 return HALMAC_RET_SUCCESS;
204 * psd_88xx() - trigger fw psd
205 * @adapter : the adapter of halmac
206 * @start_psd : start 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
212 enum halmac_ret_status
213 psd_88xx(struct halmac_adapter *adapter, u16 start_psd, u16 end_psd)
215 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 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;
221 proc_status = &adapter->halmac_state.psd_state.proc_status;
223 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
224 return HALMAC_RET_NO_DLFW;
226 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
228 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
229 PLTFM_MSG_TRACE("[TRACE]Wait event(psd)\n");
230 return HALMAC_RET_BUSY_STATE;
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;
239 adapter->halmac_state.psd_state.data_size = 0;
240 adapter->halmac_state.psd_state.seg_size = 0;
242 *proc_status = HALMAC_CMD_PROCESS_SENDING;
244 PSD_SET_START_PSD(h2c_buf, start_psd);
245 PSD_SET_END_PSD(h2c_buf, end_psd);
247 hdr_info.sub_cmd_id = SUB_CMD_ID_PSD;
248 hdr_info.content_size = 4;
250 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
252 status = send_h2c_pkt_88xx(adapter, h2c_buf);
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);
260 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
262 return HALMAC_RET_SUCCESS;
265 enum halmac_ret_status
266 get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
270 struct halmac_iqk_state *state = &adapter->halmac_state.iqk_state;
271 enum halmac_cmd_process_status proc_status;
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;
282 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
283 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
284 return HALMAC_RET_SUCCESS;
287 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
288 state->fw_rc = fw_rc;
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);
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);
300 return HALMAC_RET_SUCCESS;
303 enum halmac_ret_status
304 get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
308 struct halmac_pwr_tracking_state *state;
309 enum halmac_cmd_process_status proc_status;
311 state = &adapter->halmac_state.pwr_trk_state;
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;
322 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
323 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
324 return HALMAC_RET_SUCCESS;
327 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
328 state->fw_rc = fw_rc;
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,
336 proc_status = HALMAC_CMD_PROCESS_ERROR;
337 state->proc_status = proc_status;
338 PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
342 return HALMAC_RET_SUCCESS;
345 enum halmac_ret_status
346 get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
352 enum halmac_cmd_process_status proc_status;
353 struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
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;
364 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
365 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
366 return HALMAC_RET_SUCCESS;
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;
375 state->data = (u8 *)PLTFM_MALLOC(state->data_size);
378 state->seg_size = seg_size;
380 PLTFM_MEMCPY(state->data + seg_id * state->seg_size,
381 buf + C2H_DATA_OFFSET_88XX, seg_size);
383 if (PSD_DATA_GET_END_SEGMENT(buf) == 0)
384 return HALMAC_RET_SUCCESS;
386 proc_status = HALMAC_CMD_PROCESS_DONE;
387 state->proc_status = proc_status;
389 PLTFM_EVENT_SIG(HALMAC_FEATURE_PSD, proc_status, state->data,
392 return HALMAC_RET_SUCCESS;
395 #endif /* HALMAC_88XX_SUPPORT */