mirror of
https://github.com/RinCat/RTL88x2BU-Linux-Driver.git
synced 2024-11-14 03:02:50 +00:00
396 lines
11 KiB
C
396 lines
11 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "halmac_bb_rf_88xx.h"
|
|
#include "halmac_88xx_cfg.h"
|
|
#include "halmac_common_88xx.h"
|
|
#include "halmac_init_88xx.h"
|
|
|
|
#if HALMAC_88XX_SUPPORT
|
|
|
|
/**
|
|
* start_iqk_88xx() -trigger FW IQK
|
|
* @adapter : the adapter of halmac
|
|
* @param : IQK parameter
|
|
* Author : KaiYuan Chang/Ivan Lin
|
|
* Return : enum halmac_ret_status
|
|
* More details of status code can be found in prototype document
|
|
*/
|
|
enum halmac_ret_status
|
|
start_iqk_88xx(struct halmac_adapter *adapter, struct halmac_iqk_para *param)
|
|
{
|
|
u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
|
|
u16 seq_num = 0;
|
|
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
|
|
struct halmac_h2c_header_info hdr_info;
|
|
enum halmac_cmd_process_status *proc_status;
|
|
|
|
proc_status = &adapter->halmac_state.iqk_state.proc_status;
|
|
|
|
if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
|
|
return HALMAC_RET_NO_DLFW;
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
|
|
|
|
if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_TRACE("[TRACE]Wait event(iqk)\n");
|
|
return HALMAC_RET_BUSY_STATE;
|
|
}
|
|
|
|
*proc_status = HALMAC_CMD_PROCESS_SENDING;
|
|
|
|
IQK_SET_CLEAR(h2c_buf, param->clear);
|
|
IQK_SET_SEGMENT_IQK(h2c_buf, param->segment_iqk);
|
|
|
|
hdr_info.sub_cmd_id = SUB_CMD_ID_IQK;
|
|
hdr_info.content_size = 1;
|
|
hdr_info.ack = 1;
|
|
set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
|
|
|
|
adapter->halmac_state.iqk_state.seq_num = seq_num;
|
|
|
|
status = send_h2c_pkt_88xx(adapter, h2c_buf);
|
|
|
|
if (status != HALMAC_RET_SUCCESS) {
|
|
PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
|
|
reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_IQK);
|
|
return status;
|
|
}
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* ctrl_pwr_tracking_88xx() -trigger FW power tracking
|
|
* @adapter : the adapter of halmac
|
|
* @opt : power tracking option
|
|
* Author : KaiYuan Chang/Ivan Lin
|
|
* Return : enum halmac_ret_status
|
|
* More details of status code can be found in prototype document
|
|
*/
|
|
enum halmac_ret_status
|
|
ctrl_pwr_tracking_88xx(struct halmac_adapter *adapter,
|
|
struct halmac_pwr_tracking_option *opt)
|
|
{
|
|
u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
|
|
u16 seq_num = 0;
|
|
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
|
|
struct halmac_h2c_header_info hdr_info;
|
|
struct halmac_pwr_tracking_para *param;
|
|
enum halmac_cmd_process_status *proc_status;
|
|
|
|
proc_status = &adapter->halmac_state.pwr_trk_state.proc_status;
|
|
|
|
if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
|
|
return HALMAC_RET_NO_DLFW;
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
|
|
|
|
if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_TRACE("[TRACE]Wait event(pwr tracking)...\n");
|
|
return HALMAC_RET_BUSY_STATE;
|
|
}
|
|
|
|
*proc_status = HALMAC_CMD_PROCESS_SENDING;
|
|
|
|
PWR_TRK_SET_TYPE(h2c_buf, opt->type);
|
|
PWR_TRK_SET_BBSWING_INDEX(h2c_buf, opt->bbswing_index);
|
|
|
|
param = &opt->pwr_tracking_para[HALMAC_RF_PATH_A];
|
|
PWR_TRK_SET_ENABLE_A(h2c_buf, param->enable);
|
|
PWR_TRK_SET_TX_PWR_INDEX_A(h2c_buf, param->tx_pwr_index);
|
|
PWR_TRK_SET_TSSI_VALUE_A(h2c_buf, param->tssi_value);
|
|
PWR_TRK_SET_OFFSET_VALUE_A(h2c_buf, param->pwr_tracking_offset_value);
|
|
|
|
param = &opt->pwr_tracking_para[HALMAC_RF_PATH_B];
|
|
PWR_TRK_SET_ENABLE_B(h2c_buf, param->enable);
|
|
PWR_TRK_SET_TX_PWR_INDEX_B(h2c_buf, param->tx_pwr_index);
|
|
PWR_TRK_SET_TSSI_VALUE_B(h2c_buf, param->tssi_value);
|
|
PWR_TRK_SET_OFFSET_VALUE_B(h2c_buf, param->pwr_tracking_offset_value);
|
|
|
|
param = &opt->pwr_tracking_para[HALMAC_RF_PATH_C];
|
|
PWR_TRK_SET_ENABLE_C(h2c_buf, param->enable);
|
|
PWR_TRK_SET_TX_PWR_INDEX_C(h2c_buf, param->tx_pwr_index);
|
|
PWR_TRK_SET_TSSI_VALUE_C(h2c_buf, param->tssi_value);
|
|
PWR_TRK_SET_OFFSET_VALUE_C(h2c_buf, param->pwr_tracking_offset_value);
|
|
|
|
param = &opt->pwr_tracking_para[HALMAC_RF_PATH_D];
|
|
PWR_TRK_SET_ENABLE_D(h2c_buf, param->enable);
|
|
PWR_TRK_SET_TX_PWR_INDEX_D(h2c_buf, param->tx_pwr_index);
|
|
PWR_TRK_SET_TSSI_VALUE_D(h2c_buf, param->tssi_value);
|
|
PWR_TRK_SET_OFFSET_VALUE_D(h2c_buf, param->pwr_tracking_offset_value);
|
|
|
|
hdr_info.sub_cmd_id = SUB_CMD_ID_PWR_TRK;
|
|
hdr_info.content_size = 20;
|
|
hdr_info.ack = 1;
|
|
set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
|
|
|
|
adapter->halmac_state.pwr_trk_state.seq_num = seq_num;
|
|
|
|
status = send_h2c_pkt_88xx(adapter, h2c_buf);
|
|
|
|
if (status != HALMAC_RET_SUCCESS) {
|
|
PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
|
|
reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_POWER_TRACKING);
|
|
return status;
|
|
}
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_iqk_status_88xx(struct halmac_adapter *adapter,
|
|
enum halmac_cmd_process_status *proc_status)
|
|
{
|
|
*proc_status = adapter->halmac_state.iqk_state.proc_status;
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_pwr_trk_status_88xx(struct halmac_adapter *adapter,
|
|
enum halmac_cmd_process_status *proc_status)
|
|
{
|
|
*proc_status = adapter->halmac_state.pwr_trk_state.proc_status;
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_psd_status_88xx(struct halmac_adapter *adapter,
|
|
enum halmac_cmd_process_status *proc_status, u8 *data,
|
|
u32 *size)
|
|
{
|
|
struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
|
|
|
|
*proc_status = state->proc_status;
|
|
|
|
if (!data)
|
|
return HALMAC_RET_NULL_POINTER;
|
|
|
|
if (!size)
|
|
return HALMAC_RET_NULL_POINTER;
|
|
|
|
if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
|
|
if (*size < state->data_size) {
|
|
*size = state->data_size;
|
|
return HALMAC_RET_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
*size = state->data_size;
|
|
PLTFM_MEMCPY(data, state->data, *size);
|
|
}
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* psd_88xx() - trigger fw psd
|
|
* @adapter : the adapter of halmac
|
|
* @start_psd : start PSD
|
|
* @end_psd : end PSD
|
|
* Author : KaiYuan Chang/Ivan Lin
|
|
* Return : enum halmac_ret_status
|
|
* More details of status code can be found in prototype document
|
|
*/
|
|
enum halmac_ret_status
|
|
psd_88xx(struct halmac_adapter *adapter, u16 start_psd, u16 end_psd)
|
|
{
|
|
u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
|
|
u16 seq_num = 0;
|
|
enum halmac_ret_status status = HALMAC_RET_SUCCESS;
|
|
struct halmac_h2c_header_info hdr_info;
|
|
enum halmac_cmd_process_status *proc_status;
|
|
|
|
proc_status = &adapter->halmac_state.psd_state.proc_status;
|
|
|
|
if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
|
|
return HALMAC_RET_NO_DLFW;
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
|
|
|
|
if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_TRACE("[TRACE]Wait event(psd)\n");
|
|
return HALMAC_RET_BUSY_STATE;
|
|
}
|
|
|
|
if (adapter->halmac_state.psd_state.data) {
|
|
PLTFM_FREE(adapter->halmac_state.psd_state.data,
|
|
adapter->halmac_state.psd_state.data_size);
|
|
adapter->halmac_state.psd_state.data = (u8 *)NULL;
|
|
}
|
|
|
|
adapter->halmac_state.psd_state.data_size = 0;
|
|
adapter->halmac_state.psd_state.seg_size = 0;
|
|
|
|
*proc_status = HALMAC_CMD_PROCESS_SENDING;
|
|
|
|
PSD_SET_START_PSD(h2c_buf, start_psd);
|
|
PSD_SET_END_PSD(h2c_buf, end_psd);
|
|
|
|
hdr_info.sub_cmd_id = SUB_CMD_ID_PSD;
|
|
hdr_info.content_size = 4;
|
|
hdr_info.ack = 1;
|
|
set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
|
|
|
|
status = send_h2c_pkt_88xx(adapter, h2c_buf);
|
|
|
|
if (status != HALMAC_RET_SUCCESS) {
|
|
PLTFM_MSG_ERR("[ERR]send h2c pkt fail!!\n");
|
|
reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_PSD);
|
|
return status;
|
|
}
|
|
|
|
PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_h2c_ack_iqk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
|
|
{
|
|
u8 seq_num;
|
|
u8 fw_rc;
|
|
struct halmac_iqk_state *state = &adapter->halmac_state.iqk_state;
|
|
enum halmac_cmd_process_status proc_status;
|
|
|
|
seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
|
|
PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
if (seq_num != state->seq_num) {
|
|
PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_ERR("[ERR]not cmd sending\n");
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
|
|
state->fw_rc = fw_rc;
|
|
|
|
if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
|
|
proc_status = HALMAC_CMD_PROCESS_DONE;
|
|
state->proc_status = proc_status;
|
|
PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, NULL, 0);
|
|
} else {
|
|
proc_status = HALMAC_CMD_PROCESS_ERROR;
|
|
state->proc_status = proc_status;
|
|
PLTFM_EVENT_SIG(HALMAC_FEATURE_IQK, proc_status, &fw_rc, 1);
|
|
}
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_h2c_ack_pwr_trk_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
|
|
{
|
|
u8 seq_num;
|
|
u8 fw_rc;
|
|
struct halmac_pwr_tracking_state *state;
|
|
enum halmac_cmd_process_status proc_status;
|
|
|
|
state = &adapter->halmac_state.pwr_trk_state;
|
|
|
|
seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
|
|
PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
if (seq_num != state->seq_num) {
|
|
PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_ERR("[ERR]not cmd sending\n");
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
|
|
state->fw_rc = fw_rc;
|
|
|
|
if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
|
|
proc_status = HALMAC_CMD_PROCESS_DONE;
|
|
state->proc_status = proc_status;
|
|
PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
|
|
NULL, 0);
|
|
} else {
|
|
proc_status = HALMAC_CMD_PROCESS_ERROR;
|
|
state->proc_status = proc_status;
|
|
PLTFM_EVENT_SIG(HALMAC_FEATURE_POWER_TRACKING, proc_status,
|
|
&fw_rc, 1);
|
|
}
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
enum halmac_ret_status
|
|
get_psd_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
|
|
{
|
|
u8 seg_id;
|
|
u8 seg_size;
|
|
u8 seq_num;
|
|
u16 total_size;
|
|
enum halmac_cmd_process_status proc_status;
|
|
struct halmac_psd_state *state = &adapter->halmac_state.psd_state;
|
|
|
|
seq_num = (u8)PSD_DATA_GET_H2C_SEQ(buf);
|
|
PLTFM_MSG_TRACE("[TRACE]seq num : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
if (seq_num != state->seq_num) {
|
|
PLTFM_MSG_ERR("[ERR]seq num mismatch : h2c->%d c2h->%d\n",
|
|
state->seq_num, seq_num);
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
|
|
PLTFM_MSG_ERR("[ERR]not cmd sending\n");
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(buf);
|
|
seg_id = (u8)PSD_DATA_GET_SEGMENT_ID(buf);
|
|
seg_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(buf);
|
|
state->data_size = total_size;
|
|
|
|
if (!state->data)
|
|
state->data = (u8 *)PLTFM_MALLOC(state->data_size);
|
|
|
|
if (seg_id == 0)
|
|
state->seg_size = seg_size;
|
|
|
|
PLTFM_MEMCPY(state->data + seg_id * state->seg_size,
|
|
buf + C2H_DATA_OFFSET_88XX, seg_size);
|
|
|
|
if (PSD_DATA_GET_END_SEGMENT(buf) == 0)
|
|
return HALMAC_RET_SUCCESS;
|
|
|
|
proc_status = HALMAC_CMD_PROCESS_DONE;
|
|
state->proc_status = proc_status;
|
|
|
|
PLTFM_EVENT_SIG(HALMAC_FEATURE_PSD, proc_status, state->data,
|
|
state->data_size);
|
|
|
|
return HALMAC_RET_SUCCESS;
|
|
}
|
|
|
|
#endif /* HALMAC_88XX_SUPPORT */
|