diff options
Diffstat (limited to 'drivers/staging/rtlwifi/halmac/rtl_halmac.c')
-rw-r--r-- | drivers/staging/rtlwifi/halmac/rtl_halmac.c | 1373 |
1 files changed, 0 insertions, 1373 deletions
diff --git a/drivers/staging/rtlwifi/halmac/rtl_halmac.c b/drivers/staging/rtlwifi/halmac/rtl_halmac.c deleted file mode 100644 index 7bfc9620479a..000000000000 --- a/drivers/staging/rtlwifi/halmac/rtl_halmac.c +++ /dev/null @@ -1,1373 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2016 Realtek Corporation. - * - * Contact Information: - * wlanfae <wlanfae@realtek.com> - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger <Larry.Finger@lwfinger.net> - * - *****************************************************************************/ - -#include "halmac_api.h" -#include "rtl_halmac.h" -#include <linux/module.h> -#include <linux/vmalloc.h> - -#define DEFAULT_INDICATOR_TIMELMT msecs_to_jiffies(1000) /* ms */ -#define FIRMWARE_MAX_SIZE HALMAC_FW_SIZE_MAX_88XX - -static struct rtl_halmac_ops rtl_halmac_operation = { - .halmac_init_adapter = rtl_halmac_init_adapter, - .halmac_deinit_adapter = rtl_halmac_deinit_adapter, - .halmac_init_hal = rtl_halmac_init_hal, - .halmac_deinit_hal = rtl_halmac_deinit_hal, - .halmac_poweron = rtl_halmac_poweron, - .halmac_poweroff = rtl_halmac_poweroff, - - .halmac_phy_power_switch = rtl_halmac_phy_power_switch, - .halmac_set_mac_address = rtl_halmac_set_mac_address, - .halmac_set_bssid = rtl_halmac_set_bssid, - - .halmac_get_physical_efuse_size = rtl_halmac_get_physical_efuse_size, - .halmac_read_physical_efuse_map = rtl_halmac_read_physical_efuse_map, - .halmac_get_logical_efuse_size = rtl_halmac_get_logical_efuse_size, - .halmac_read_logical_efuse_map = rtl_halmac_read_logical_efuse_map, - - .halmac_set_bandwidth = rtl_halmac_set_bandwidth, - - .halmac_c2h_handle = rtl_halmac_c2h_handle, - - .halmac_chk_txdesc = rtl_halmac_chk_txdesc, -}; - -struct rtl_halmac_ops *rtl_halmac_get_ops_pointer(void) -{ - return &rtl_halmac_operation; -} -EXPORT_SYMBOL(rtl_halmac_get_ops_pointer); - -/* - * Driver API for HALMAC operations - */ - -static u8 _halmac_reg_read_8(void *p, u32 offset) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - return rtl_read_byte(rtlpriv, offset); -} - -static u16 _halmac_reg_read_16(void *p, u32 offset) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - return rtl_read_word(rtlpriv, offset); -} - -static u32 _halmac_reg_read_32(void *p, u32 offset) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - return rtl_read_dword(rtlpriv, offset); -} - -static void _halmac_reg_write_8(void *p, u32 offset, u8 val) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - rtl_write_byte(rtlpriv, offset, val); -} - -static void _halmac_reg_write_16(void *p, u32 offset, u16 val) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - rtl_write_word(rtlpriv, offset, val); -} - -static void _halmac_reg_write_32(void *p, u32 offset, u32 val) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - rtl_write_dword(rtlpriv, offset, val); -} - -static bool _halmac_write_data_rsvd_page(void *p, u8 *buf, u32 size) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - if (rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page && - rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page(rtlpriv, buf, - size)) - return true; - - return false; -} - -static bool _halmac_write_data_h2c(void *p, u8 *buf, u32 size) -{ - struct rtl_priv *rtlpriv = (struct rtl_priv *)p; - - if (rtlpriv->cfg->ops->halmac_cb_write_data_h2c && - rtlpriv->cfg->ops->halmac_cb_write_data_h2c(rtlpriv, buf, size)) - return true; - - return false; -} - -static const char *const RTL_HALMAC_FEATURE_NAME[] = { - "HALMAC_FEATURE_CFG_PARA", - "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE", - "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE", - "HALMAC_FEATURE_UPDATE_PACKET", - "HALMAC_FEATURE_UPDATE_DATAPACK", - "HALMAC_FEATURE_RUN_DATAPACK", - "HALMAC_FEATURE_CHANNEL_SWITCH", - "HALMAC_FEATURE_IQK", - "HALMAC_FEATURE_POWER_TRACKING", - "HALMAC_FEATURE_PSD", - "HALMAC_FEATURE_ALL"}; - -static inline bool is_valid_id_status(struct rtl_priv *rtlpriv, - enum halmac_feature_id id, - enum halmac_cmd_process_status status) -{ - switch (id) { - case HALMAC_FEATURE_CFG_PARA: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - if (status != HALMAC_CMD_PROCESS_DONE) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: <WARN> id(%d) unspecified status(%d)!\n", - __func__, id, status); - } - break; - case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - if (status != HALMAC_CMD_PROCESS_DONE) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: <WARN> id(%d) unspecified status(%d)!\n", - __func__, id, status); - } - break; - case HALMAC_FEATURE_UPDATE_PACKET: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_UPDATE_DATAPACK: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_RUN_DATAPACK: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_CHANNEL_SWITCH: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_IQK: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_POWER_TRACKING: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_PSD: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - case HALMAC_FEATURE_ALL: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__, - RTL_HALMAC_FEATURE_NAME[id]); - break; - default: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: unknown feature id(%d)\n", __func__, id); - return false; - } - - return true; -} - -static int init_halmac_event_with_waittime(struct rtl_priv *rtlpriv, - enum halmac_feature_id id, u8 *buf, - u32 size, u32 time) -{ - struct completion *comp; - - if (!rtlpriv->halmac.indicator[id].comp) { - comp = kzalloc(sizeof(*comp), GFP_KERNEL); - if (!comp) - return -ENOMEM; - } else { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: <WARN> id(%d) sctx is not NULL!!\n", __func__, - id); - comp = rtlpriv->halmac.indicator[id].comp; - rtlpriv->halmac.indicator[id].comp = NULL; - } - - init_completion(comp); - rtlpriv->halmac.indicator[id].wait_ms = time; - - rtlpriv->halmac.indicator[id].buffer = buf; - rtlpriv->halmac.indicator[id].buf_size = size; - rtlpriv->halmac.indicator[id].ret_size = 0; - rtlpriv->halmac.indicator[id].status = 0; - /* fill sctx at least to sure other variables are all ready! */ - rtlpriv->halmac.indicator[id].comp = comp; - - return 0; -} - -static inline int init_halmac_event(struct rtl_priv *rtlpriv, - enum halmac_feature_id id, u8 *buf, - u32 size) -{ - return init_halmac_event_with_waittime(rtlpriv, id, buf, size, - DEFAULT_INDICATOR_TIMELMT); -} - -static void free_halmac_event(struct rtl_priv *rtlpriv, - enum halmac_feature_id id) -{ - struct completion *comp; - - if (!rtlpriv->halmac.indicator[id].comp) - return; - - comp = rtlpriv->halmac.indicator[id].comp; - rtlpriv->halmac.indicator[id].comp = NULL; - kfree(comp); -} - -static int wait_halmac_event(struct rtl_priv *rtlpriv, - enum halmac_feature_id id) -{ - struct completion *comp; - int ret; - - comp = rtlpriv->halmac.indicator[id].comp; - if (!comp) - return -1; - - ret = wait_for_completion_timeout( - comp, rtlpriv->halmac.indicator[id].wait_ms); - free_halmac_event(rtlpriv, id); - if (ret > 0) - return 0; - - return -1; -} - -/* - * Return: - * Always return true, HALMAC don't care the return value. - */ -static bool -_halmac_event_indication(void *p, enum halmac_feature_id feature_id, - enum halmac_cmd_process_status process_status, u8 *buf, - u32 size) -{ - struct rtl_priv *rtlpriv; - struct rtl_halmac_indicator *tbl, *indicator; - struct completion *comp; - u32 cpsz; - bool ret; - - rtlpriv = (struct rtl_priv *)p; - tbl = rtlpriv->halmac.indicator; - - ret = is_valid_id_status(rtlpriv, feature_id, process_status); - if (!ret) - goto exit; - - indicator = &tbl[feature_id]; - indicator->status = process_status; - indicator->ret_size = size; - if (!indicator->comp) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: No feature id(%d) waiting!!\n", __func__, - feature_id); - goto exit; - } - comp = indicator->comp; - - if (process_status == HALMAC_CMD_PROCESS_ERROR) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: Something wrong id(%d)!!\n", __func__, - feature_id); - complete(comp); /* may provide error code */ - goto exit; - } - - if (size > indicator->buf_size) { - RT_TRACE( - rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n", - __func__, feature_id, indicator->buf_size, size); - cpsz = indicator->buf_size; - } else { - cpsz = size; - } - - if (cpsz && indicator->buffer) - memcpy(indicator->buffer, buf, cpsz); - - complete(comp); - -exit: - return true; -} - -static struct halmac_platform_api rtl_halmac_platform_api = { - /* R/W register */ - .REG_READ_8 = _halmac_reg_read_8, - .REG_READ_16 = _halmac_reg_read_16, - .REG_READ_32 = _halmac_reg_read_32, - .REG_WRITE_8 = _halmac_reg_write_8, - .REG_WRITE_16 = _halmac_reg_write_16, - .REG_WRITE_32 = _halmac_reg_write_32, - - /* Write data */ - /* impletement in HAL-IC level */ - .SEND_RSVD_PAGE = _halmac_write_data_rsvd_page, - .SEND_H2C_PKT = _halmac_write_data_h2c, - - .EVENT_INDICATION = _halmac_event_indication, -}; - -static int init_priv(struct rtl_halmac *halmac) -{ - struct rtl_halmac_indicator *indicator; - u32 count, size; - - halmac->send_general_info = 0; - - count = HALMAC_FEATURE_ALL + 1; - size = sizeof(*indicator) * count; - indicator = kzalloc(size, GFP_KERNEL); - if (!indicator) - return -ENOMEM; - halmac->indicator = indicator; - - return 0; -} - -static void deinit_priv(struct rtl_halmac *halmac) -{ - struct rtl_halmac_indicator *indicator; - - indicator = halmac->indicator; - halmac->indicator = NULL; - kfree(indicator); -} - -int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_interface intf; - enum halmac_ret_status status; - int err = 0; - struct halmac_platform_api *pf_api = &rtl_halmac_platform_api; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (halmac) { - err = 0; - goto out; - } - - err = init_priv(&rtlpriv->halmac); - if (err) - goto out; - - intf = HALMAC_INTERFACE_PCIE; - status = halmac_init_adapter(rtlpriv, pf_api, intf, &halmac, &api); - if (status != HALMAC_RET_SUCCESS) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s: halmac_init_adapter fail!(status=%d)\n", __func__, - status); - err = -1; - goto out; - } - - rtlpriv->halmac.internal = halmac; - -out: - if (err) - rtl_halmac_deinit_adapter(rtlpriv); - - return err; -} - -int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - enum halmac_ret_status status; - int err = 0; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) { - err = 0; - goto out; - } - - deinit_priv(&rtlpriv->halmac); - - halmac_halt_api(halmac); - - status = halmac_deinit_adapter(halmac); - rtlpriv->halmac.internal = NULL; - if (status != HALMAC_RET_SUCCESS) { - err = -1; - goto out; - } - -out: - return err; -} - -int rtl_halmac_poweron(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - goto out; - - api = HALMAC_GET_API(halmac); - - status = api->halmac_pre_init_system_cfg(halmac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON); - if (status != HALMAC_RET_SUCCESS) - goto out; - - status = api->halmac_init_system_cfg(halmac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_poweroff(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - goto out; - - api = HALMAC_GET_API(halmac); - - status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -/* - * Note: - * When this function return, the register REG_RCR may be changed. - */ -int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv, - enum halmac_drv_info info) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(halmac); - - status = api->halmac_cfg_drv_info(halmac, info); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -static enum halmac_ret_status init_mac_flow(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - u8 wifi_test = 0; - int err; - - halmac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(halmac); - - if (wifi_test) - status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_WMM); - else - status = api->halmac_init_mac_cfg(halmac, - HALMAC_TRX_MODE_NORMAL); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = rtl_halmac_rx_agg_switch(rtlpriv, true); - if (err) - goto out; - - if (rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7]) - status = api->halmac_cfg_operation_mode( - halmac, HALMAC_WIRELESS_MODE_AC); - else if (rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]) - status = api->halmac_cfg_operation_mode(halmac, - HALMAC_WIRELESS_MODE_N); - else if (rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M]) - status = api->halmac_cfg_operation_mode(halmac, - HALMAC_WIRELESS_MODE_G); - else - status = api->halmac_cfg_operation_mode(halmac, - HALMAC_WIRELESS_MODE_B); - if (status != HALMAC_RET_SUCCESS) - goto out; - -out: - return status; -} - -static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv) -{ - enum halmac_rf_type rf_mac; - - switch (rf_drv) { - case RF_1T2R: - rf_mac = HALMAC_RF_1T2R; - break; - case RF_2T2R: - rf_mac = HALMAC_RF_2T2R; - break; - case RF_1T1R: - rf_mac = HALMAC_RF_1T1R; - break; - case RF_2T2R_GREEN: - rf_mac = HALMAC_RF_2T2R_GREEN; - break; - default: - rf_mac = (enum halmac_rf_type)rf_drv; - break; - } - - return rf_mac; -} - -static int _send_general_info(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - struct halmac_general_info info; - enum halmac_ret_status status; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - return -1; - api = HALMAC_GET_API(halmac); - - memset(&info, 0, sizeof(info)); - info.rfe_type = rtlpriv->rtlhal.rfe_type; - info.rf_type = _rf_type_drv2halmac(rtlpriv->phy.rf_type); - - status = api->halmac_send_general_info(halmac, &info); - switch (status) { - case HALMAC_RET_SUCCESS: - break; - case HALMAC_RET_NO_DLFW: - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_WARNING, - "%s: halmac_send_general_info() fail because fw not dl!\n", - __func__); - /* fall through */ - default: - return -1; - } - - return 0; -} - -/* - * Notices: - * Make sure - * 1. rtl_hal_get_hwreg(HW_VAR_RF_TYPE) - * 2. HAL_DATA_TYPE.rfe_type - * already ready for use before calling this function. - */ -static int _halmac_init_hal(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - bool ok; - bool fw_ok = false; - int err, err_ret = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - goto out; - api = HALMAC_GET_API(halmac); - - /* StatePowerOff */ - - /* SKIP: halmac_init_adapter (Already done before) */ - - /* halmac_pre_Init_system_cfg */ - /* halmac_mac_power_switch(on) */ - /* halmac_Init_system_cfg */ - err = rtl_halmac_poweron(rtlpriv); - if (err) - goto out; - - /* StatePowerOn */ - - /* DownloadFW */ - rtlpriv->halmac.send_general_info = 0; - if (fw && fwsize) { - err = rtl_halmac_dlfw(rtlpriv, fw, fwsize); - if (err) - goto out; - fw_ok = true; - } - - /* InitMACFlow */ - status = init_mac_flow(rtlpriv); - if (status != HALMAC_RET_SUCCESS) - goto out; - - /* halmac_send_general_info */ - if (fw_ok) { - rtlpriv->halmac.send_general_info = 0; - err = _send_general_info(rtlpriv); - if (err) - goto out; - } else { - rtlpriv->halmac.send_general_info = 1; - } - - /* Init Phy parameter-MAC */ - if (rtlpriv->cfg->ops->halmac_cb_init_mac_register) - ok = rtlpriv->cfg->ops->halmac_cb_init_mac_register(rtlpriv); - else - ok = false; - - if (!ok) - goto out; - - /* StateMacInitialized */ - - /* halmac_cfg_drv_info */ - err = rtl_halmac_config_rx_info(rtlpriv, HALMAC_DRV_INFO_PHY_STATUS); - if (err) - goto out; - - /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */ - /* Init BB, RF */ - if (rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register) - ok = rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register(rtlpriv); - else - ok = false; - - if (!ok) - goto out; - - status = api->halmac_init_interface_cfg(halmac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - /* SKIP: halmac_verify_platform_api */ - /* SKIP: halmac_h2c_lb */ - - /* StateRxIdle */ - - err_ret = 0; -out: - return err_ret; -} - -int rtl_halmac_init_hal(struct rtl_priv *rtlpriv) -{ - if (!rtlpriv->rtlhal.pfirmware || rtlpriv->rtlhal.fwsize == 0) - return -1; - - return _halmac_init_hal(rtlpriv, rtlpriv->rtlhal.pfirmware, - rtlpriv->rtlhal.fwsize); -} - -int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - goto out; - api = HALMAC_GET_API(halmac); - - status = api->halmac_deinit_interface_cfg(halmac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - /* rtw_hal_power_off(adapter); */ - status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_self_verify(struct rtl_priv *rtlpriv) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - int err = -1; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_verify_platform_api(mac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - status = api->halmac_h2c_lb(mac); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - struct halmac_fw_version fw_version; - int err = 0; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - if ((!fw) || (!fwsize)) - return -1; - - /* 1. Driver Stop Tx */ - /* ToDo */ - - /* 2. Driver Check Tx FIFO is empty */ - /* ToDo */ - - /* 3. Config MAX download size */ - api->halmac_cfg_max_dl_size(mac, 0x1000); - - /* 4. Download Firmware */ - mac->h2c_packet_seq = 0; - status = api->halmac_download_firmware(mac, fw, fwsize); - if (status != HALMAC_RET_SUCCESS) - return -1; - - status = api->halmac_get_fw_version(mac, &fw_version); - if (status == HALMAC_RET_SUCCESS) { - rtlpriv->rtlhal.fw_version = fw_version.version; - rtlpriv->rtlhal.fw_subversion = - (fw_version.sub_version << 8) | (fw_version.sub_index); - - RT_TRACE( - rtlpriv, COMP_HALMAC, DBG_DMESG, - "halmac report firmware version %04X.%04X\n", - rtlpriv->rtlhal.fw_version, - rtlpriv->rtlhal.fw_subversion); - } - - if (rtlpriv->halmac.send_general_info) { - rtlpriv->halmac.send_general_info = 0; - err = _send_general_info(rtlpriv); - } - - /* 5. Driver resume TX if needed */ - /* ToDo */ - - /* 6. Reset driver variables if needed */ - /*hal->LastHMEBoxNum = 0;*/ - - return err; -} - -/* - * Description: - * Power on/off BB/RF domain. - * - * Parameters: - * enable true/false for power on/off - * - * Return: - * 0 Success - * others Fail - */ -int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - enum halmac_ret_status status; - - halmac = rtlpriv_to_halmac(rtlpriv); - if (!halmac) - return -1; - api = HALMAC_GET_API(halmac); - - status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -static bool _is_fw_read_cmd_down(struct rtl_priv *rtlpriv, u8 msgbox_num) -{ - bool read_down = false; - int retry_cnts = 100; - u8 valid; - - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - "%s, reg_1cc(%x), msg_box(%d)...\n", __func__, - rtl_read_byte(rtlpriv, REG_HMETFR), msgbox_num); - - do { - valid = rtl_read_byte(rtlpriv, REG_HMETFR) & BIT(msgbox_num); - if (valid == 0) - read_down = true; - else - mdelay(1); - } while ((!read_down) && (retry_cnts--)); - - return read_down; -} - -int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c) -{ - u8 h2c_box_num = 0; - u32 msgbox_addr = 0; - u32 msgbox_ex_addr = 0; - __le32 h2c_cmd = 0; - __le32 h2c_cmd_ex = 0; - s32 ret = -1; - unsigned long flag = 0; - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - - if (!h2c) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: pbuf is NULL\n", - __func__); - return ret; - } - - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - - /* pay attention to if race condition happened in H2C cmd setting */ - h2c_box_num = rtlhal->last_hmeboxnum; - - if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) { - RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, - " fw read cmd failed...\n"); - goto exit; - } - - /* Write Ext command(byte 4 -7) */ - msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE); - memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE); - rtl_write_dword(rtlpriv, msgbox_ex_addr, le32_to_cpu(h2c_cmd_ex)); - - /* Write command (byte 0 -3 ) */ - msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE); - memcpy((u8 *)(&h2c_cmd), h2c, 4); - rtl_write_dword(rtlpriv, msgbox_addr, le32_to_cpu(h2c_cmd)); - - /* update last msg box number */ - rtlhal->last_hmeboxnum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS; - ret = 0; - -exit: - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - return ret; -} - -int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_get_c2h_info(mac, c2h, size); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u32 val; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_get_efuse_size(mac, &val); - if (status != HALMAC_RET_SUCCESS) - return -1; - - *size = val; - return 0; -} - -int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map, - u32 size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - enum halmac_feature_id id; - int ret; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE; - - ret = init_halmac_event(rtlpriv, id, map, size); - if (ret) - return -1; - - status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV); - if (status != HALMAC_RET_SUCCESS) { - free_halmac_event(rtlpriv, id); - return -1; - } - - ret = wait_halmac_event(rtlpriv, id); - if (ret) - return -1; - - return 0; -} - -int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset, - u32 cnt, u8 *data) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u8 v; - u32 i; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - for (i = 0; i < cnt; i++) { - status = api->halmac_read_efuse(mac, offset + i, &v); - if (status != HALMAC_RET_SUCCESS) - return -1; - data[i] = v; - } - - return 0; -} - -int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset, - u32 cnt, u8 *data) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u32 i; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - for (i = 0; i < cnt; i++) { - status = api->halmac_write_efuse(mac, offset + i, data[i]); - if (status != HALMAC_RET_SUCCESS) - return -1; - } - - return 0; -} - -int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u32 val; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_get_logical_efuse_size(mac, &val); - if (status != HALMAC_RET_SUCCESS) - return -1; - - *size = val; - return 0; -} - -int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map, - u32 size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - enum halmac_feature_id id; - int ret; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE; - - ret = init_halmac_event(rtlpriv, id, map, size); - if (ret) - return -1; - - status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO); - if (status != HALMAC_RET_SUCCESS) { - free_halmac_event(rtlpriv, id); - return -1; - } - - ret = wait_halmac_event(rtlpriv, id); - if (ret) - return -1; - - return 0; -} - -int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map, - u32 size, u8 *maskmap, u32 masksize) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - struct halmac_pg_efuse_info pginfo; - enum halmac_ret_status status; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - pginfo.efuse_map = map; - pginfo.efuse_map_size = size; - pginfo.efuse_mask = maskmap; - pginfo.efuse_mask_size = masksize; - - status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt, - u8 *data) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u8 v; - u32 i; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - for (i = 0; i < cnt; i++) { - status = api->halmac_read_logical_efuse(mac, offset + i, &v); - if (status != HALMAC_RET_SUCCESS) - return -1; - data[i] = v; - } - - return 0; -} - -int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, - u32 cnt, u8 *data) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u32 i; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - for (i = 0; i < cnt; i++) { - status = api->halmac_write_logical_efuse(mac, offset + i, - data[i]); - if (status != HALMAC_RET_SUCCESS) - return -1; - } - - return 0; -} - -int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - u8 port; - union halmac_wlan_addr hwa; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(halmac); - - port = hwport; - memset(&hwa, 0, sizeof(hwa)); - memcpy(hwa.address, addr, 6); - - status = api->halmac_cfg_mac_addr(halmac, port, &hwa); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_set_bssid(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - u8 port; - union halmac_wlan_addr hwa; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(halmac); - port = hwport; - - memset(&hwa, 0, sizeof(union halmac_wlan_addr)); - memcpy(hwa.address, addr, 6); - status = api->halmac_cfg_bssid(halmac, port, &hwa); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel, - u8 pri_ch_idx, u8 bw) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -int rtl_halmac_get_hw_value(struct rtl_priv *rtlpriv, enum halmac_hw_id hw_id, - void *pvalue) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_get_hw_value(mac, hw_id, pvalue); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv, - enum hal_fifo_sel halmac_fifo_sel) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - u8 *pfifo_map = NULL; - u32 fifo_size = 0; - s8 ret = 0; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel); - if (fifo_size) - pfifo_map = vmalloc(fifo_size); - if (!pfifo_map) - return -1; - - status = api->halmac_dump_fifo(mac, halmac_fifo_sel, 0, fifo_size, - pfifo_map); - - if (status != HALMAC_RET_SUCCESS) { - ret = -1; - goto _exit; - } - -_exit: - if (pfifo_map) - vfree(pfifo_map); - return ret; -} - -int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable) -{ - struct halmac_adapter *halmac; - struct halmac_api *api; - struct halmac_rxagg_cfg rxaggcfg; - enum halmac_ret_status status; - int err = -1; - - halmac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(halmac); - memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg)); - - if (enable) { - /* enable RX agg. */ - /* PCIE do nothing */ - } else { - /* disable RX agg. */ - rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE; - } - - status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg); - if (status != HALMAC_RET_SUCCESS) - goto out; - - err = 0; -out: - return err; -} - -int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason) -{ - u8 val8; - int err = -1; - - val8 = rtl_read_byte(rtlpriv, 0x1C7); - if (val8 == 0xEA) - goto out; - - *reason = val8; - err = 0; -out: - return err; -} - -/* - * Description: - * Get RX driver info size. RX driver info is a small memory space between - * scriptor and RX payload. - * - * +-------------------------+ - * | RX descriptor | - * | usually 24 bytes | - * +-------------------------+ - * | RX driver info | - * | depends on driver cfg | - * +-------------------------+ - * | RX paylad | - * | | - * +-------------------------+ - * - * Parameter: - * d pointer to struct dvobj_priv of driver - * sz rx driver info size in bytes. - * - * Rteurn: - * 0 Success - * other Fail - */ -int rtl_halmac_get_drv_info_sz(struct rtl_priv *rtlpriv, u8 *sz) -{ - /* enum halmac_ret_status status; */ - u8 dw = 6; /* max number */ - - *sz = dw * 8; - return 0; -} - -int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *rtlpriv, u16 *drv_pg) -{ - enum halmac_ret_status status; - struct halmac_adapter *halmac = rtlpriv_to_halmac(rtlpriv); - struct halmac_api *api = HALMAC_GET_API(halmac); - - status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, - drv_pg); - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size) -{ - struct halmac_adapter *mac; - struct halmac_api *api; - enum halmac_ret_status status; - - mac = rtlpriv_to_halmac(rtlpriv); - api = HALMAC_GET_API(mac); - - status = api->halmac_chk_txdesc(mac, txdesc, size); - - if (status != HALMAC_RET_SUCCESS) - return -1; - - return 0; -} - -MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); -MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); |